@native-knowledge/knowledge-sdk 0.0.0-stage → 0.1.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +29 -0
  3. package/README.md +34 -2
  4. package/dist/agent-entry.d.ts +291 -0
  5. package/dist/agent-entry.js +153 -0
  6. package/dist/agent-guidance-error.d.ts +15 -0
  7. package/dist/agent-guidance-error.js +46 -0
  8. package/dist/auth.d.ts +124 -0
  9. package/dist/auth.js +165 -0
  10. package/dist/index.d.ts +290 -0
  11. package/dist/index.js +166 -0
  12. package/dist/internal/contracts/artifact.d.ts +120 -0
  13. package/dist/internal/contracts/artifact.js +103 -0
  14. package/dist/internal/contracts/collection-control.d.ts +160 -0
  15. package/dist/internal/contracts/collection-control.js +69 -0
  16. package/dist/internal/contracts/collection.d.ts +263 -0
  17. package/dist/internal/contracts/collection.js +174 -0
  18. package/dist/internal/contracts/common.d.ts +17 -0
  19. package/dist/internal/contracts/common.js +16 -0
  20. package/dist/internal/contracts/currentness.d.ts +477 -0
  21. package/dist/internal/contracts/currentness.js +221 -0
  22. package/dist/internal/contracts/event.d.ts +60 -0
  23. package/dist/internal/contracts/event.js +35 -0
  24. package/dist/internal/contracts/evidence.d.ts +202 -0
  25. package/dist/internal/contracts/evidence.js +171 -0
  26. package/dist/internal/contracts/index.d.ts +54 -0
  27. package/dist/internal/contracts/index.js +54 -0
  28. package/dist/internal/contracts/material-capability.d.ts +88 -0
  29. package/dist/internal/contracts/material-capability.js +8 -0
  30. package/dist/internal/contracts/material-carrier.d.ts +104 -0
  31. package/dist/internal/contracts/material-carrier.js +15 -0
  32. package/dist/internal/contracts/material-context.d.ts +28 -0
  33. package/dist/internal/contracts/material-context.js +9 -0
  34. package/dist/internal/contracts/material-read.d.ts +152 -0
  35. package/dist/internal/contracts/material-read.js +12 -0
  36. package/dist/internal/contracts/observation.d.ts +75 -0
  37. package/dist/internal/contracts/observation.js +39 -0
  38. package/dist/internal/contracts/persistence.d.ts +370 -0
  39. package/dist/internal/contracts/persistence.js +239 -0
  40. package/dist/internal/contracts/project-intent.d.ts +218 -0
  41. package/dist/internal/contracts/project-intent.js +121 -0
  42. package/dist/internal/contracts/projection.d.ts +380 -0
  43. package/dist/internal/contracts/projection.js +194 -0
  44. package/dist/internal/contracts/public-reference.d.ts +237 -0
  45. package/dist/internal/contracts/public-reference.js +87 -0
  46. package/dist/internal/contracts/reference-record.d.ts +124 -0
  47. package/dist/internal/contracts/reference-record.js +55 -0
  48. package/dist/internal/contracts/remote-file.d.ts +128 -0
  49. package/dist/internal/contracts/remote-file.js +159 -0
  50. package/dist/internal/contracts/resource-scope.d.ts +40 -0
  51. package/dist/internal/contracts/resource-scope.js +38 -0
  52. package/dist/internal/contracts/review-packet.d.ts +274 -0
  53. package/dist/internal/contracts/review-packet.js +61 -0
  54. package/dist/internal/contracts/review-plane.d.ts +90 -0
  55. package/dist/internal/contracts/review-plane.js +89 -0
  56. package/dist/internal/contracts/rich-document.d.ts +641 -0
  57. package/dist/internal/contracts/rich-document.js +184 -0
  58. package/dist/internal/contracts/runtime-compatibility.d.ts +22 -0
  59. package/dist/internal/contracts/runtime-compatibility.js +55 -0
  60. package/dist/internal/contracts/runtime.d.ts +59 -0
  61. package/dist/internal/contracts/runtime.js +68 -0
  62. package/dist/internal/contracts/scheduler.d.ts +348 -0
  63. package/dist/internal/contracts/scheduler.js +256 -0
  64. package/dist/internal/contracts/signal.d.ts +113 -0
  65. package/dist/internal/contracts/signal.js +77 -0
  66. package/dist/internal/contracts/source-governance.d.ts +375 -0
  67. package/dist/internal/contracts/source-governance.js +194 -0
  68. package/dist/internal/contracts/source.d.ts +62 -0
  69. package/dist/internal/contracts/source.js +32 -0
  70. package/dist/internal/contracts/tenant-budget.d.ts +59 -0
  71. package/dist/internal/contracts/tenant-budget.js +34 -0
  72. package/dist/internal/contracts/tenant-collection-request.d.ts +209 -0
  73. package/dist/internal/contracts/tenant-collection-request.js +58 -0
  74. package/dist/internal/contracts/tenant-collection.d.ts +199 -0
  75. package/dist/internal/contracts/tenant-collection.js +66 -0
  76. package/dist/internal/contracts/tenant-currentness.d.ts +117 -0
  77. package/dist/internal/contracts/tenant-currentness.js +26 -0
  78. package/dist/internal/contracts/tenant-management.d.ts +286 -0
  79. package/dist/internal/contracts/tenant-management.js +27 -0
  80. package/dist/internal/contracts/tenant-material-api.d.ts +584 -0
  81. package/dist/internal/contracts/tenant-material-api.js +46 -0
  82. package/dist/internal/contracts/tenant-material-json-schema.js +16 -0
  83. package/dist/internal/contracts/tenant-pdf-text.d.ts +27 -0
  84. package/dist/internal/contracts/tenant-pdf-text.js +13 -0
  85. package/dist/internal/contracts/tenant-project-control.d.ts +94 -0
  86. package/dist/internal/contracts/tenant-project-control.js +19 -0
  87. package/dist/internal/contracts/tenant-public-reference.d.ts +179 -0
  88. package/dist/internal/contracts/tenant-public-reference.js +26 -0
  89. package/dist/internal/contracts/tenant-resource-api.d.ts +738 -0
  90. package/dist/internal/contracts/tenant-resource-api.js +70 -0
  91. package/dist/internal/contracts/tenant-resource.d.ts +298 -0
  92. package/dist/internal/contracts/tenant-resource.js +118 -0
  93. package/dist/internal/contracts/tenant-rich-document.d.ts +317 -0
  94. package/dist/internal/contracts/tenant-rich-document.js +17 -0
  95. package/dist/internal/contracts/tenant-source-binding.d.ts +44 -0
  96. package/dist/internal/contracts/tenant-source-binding.js +33 -0
  97. package/dist/internal/contracts/tenant-source-bridge.d.ts +70 -0
  98. package/dist/internal/contracts/tenant-source-bridge.js +9 -0
  99. package/dist/internal/contracts/tenant-source-cutover.d.ts +226 -0
  100. package/dist/internal/contracts/tenant-source-cutover.js +26 -0
  101. package/dist/internal/contracts/tenant-source-document.d.ts +163 -0
  102. package/dist/internal/contracts/tenant-source-document.js +38 -0
  103. package/dist/internal/contracts/tenant-source-lease.d.ts +1 -0
  104. package/dist/internal/contracts/tenant-source-lease.js +5 -0
  105. package/dist/internal/contracts/tenant-source.d.ts +223 -0
  106. package/dist/internal/contracts/tenant-source.js +83 -0
  107. package/dist/internal/contracts/tenant-web-collection.d.ts +287 -0
  108. package/dist/internal/contracts/tenant-web-collection.js +118 -0
  109. package/dist/internal/contracts/tenant-web-content-plan.d.ts +86 -0
  110. package/dist/internal/contracts/tenant-web-content-plan.js +39 -0
  111. package/dist/internal/contracts/tenant-web-content-result.d.ts +63 -0
  112. package/dist/internal/contracts/tenant-web-content-result.js +15 -0
  113. package/dist/internal/contracts/tenant-web-content.d.ts +383 -0
  114. package/dist/internal/contracts/tenant-web-content.js +16 -0
  115. package/dist/internal/contracts/tenant-web-crawl.d.ts +310 -0
  116. package/dist/internal/contracts/tenant-web-crawl.js +55 -0
  117. package/dist/internal/contracts/tenant-web-dynamic.d.ts +698 -0
  118. package/dist/internal/contracts/tenant-web-dynamic.js +68 -0
  119. package/dist/internal/contracts/tenant-web-results.d.ts +66 -0
  120. package/dist/internal/contracts/tenant-web-results.js +41 -0
  121. package/dist/internal/contracts/tenant-web-workflow.d.ts +494 -0
  122. package/dist/internal/contracts/tenant-web-workflow.js +29 -0
  123. package/dist/internal/serving-contracts/agent-catalog.d.ts +70 -0
  124. package/dist/internal/serving-contracts/agent-catalog.js +56 -0
  125. package/dist/internal/serving-contracts/agent-entry.d.ts +13148 -0
  126. package/dist/internal/serving-contracts/agent-entry.js +57 -0
  127. package/dist/internal/serving-contracts/agent-guidance-shapes.d.ts +263 -0
  128. package/dist/internal/serving-contracts/agent-guidance-shapes.js +12 -0
  129. package/dist/internal/serving-contracts/agent-input-hints.d.ts +24 -0
  130. package/dist/internal/serving-contracts/agent-input-hints.js +104 -0
  131. package/dist/internal/serving-contracts/body-search.d.ts +231 -0
  132. package/dist/internal/serving-contracts/body-search.js +16 -0
  133. package/dist/internal/serving-contracts/consumer.d.ts +989 -0
  134. package/dist/internal/serving-contracts/consumer.js +45 -0
  135. package/dist/internal/serving-contracts/core.d.ts +333 -0
  136. package/dist/internal/serving-contracts/core.js +76 -0
  137. package/dist/internal/serving-contracts/http.d.ts +2874 -0
  138. package/dist/internal/serving-contracts/http.js +64 -0
  139. package/dist/internal/serving-contracts/index.d.ts +24 -0
  140. package/dist/internal/serving-contracts/index.js +25 -0
  141. package/dist/internal/serving-contracts/management.d.ts +424 -0
  142. package/dist/internal/serving-contracts/management.js +15 -0
  143. package/dist/internal/serving-contracts/material-capabilities.d.ts +508 -0
  144. package/dist/internal/serving-contracts/material-capabilities.js +14 -0
  145. package/dist/internal/serving-contracts/material-index-status.d.ts +55 -0
  146. package/dist/internal/serving-contracts/material-index-status.js +5 -0
  147. package/dist/internal/serving-contracts/mcp.d.ts +2218 -0
  148. package/dist/internal/serving-contracts/mcp.js +140 -0
  149. package/dist/internal/serving-contracts/tenant-governance.d.ts +236 -0
  150. package/dist/internal/serving-contracts/tenant-governance.js +13 -0
  151. package/dist/internal/serving-contracts/tenant-management.d.ts +6276 -0
  152. package/dist/internal/serving-contracts/tenant-management.js +89 -0
  153. package/dist/internal/serving-contracts/tenant-project.d.ts +7550 -0
  154. package/dist/internal/serving-contracts/tenant-project.js +39 -0
  155. package/dist/internal/serving-contracts/tenant-runtime.d.ts +9674 -0
  156. package/dist/internal/serving-contracts/tenant-runtime.js +37 -0
  157. package/dist/internal/serving-contracts/tenant-session.d.ts +87 -0
  158. package/dist/internal/serving-contracts/tenant-session.js +8 -0
  159. package/dist/internal/serving-contracts/tenant-web-content.d.ts +4606 -0
  160. package/dist/internal/serving-contracts/tenant-web-content.js +20 -0
  161. package/dist/internal/serving-contracts/tenant-web-crawl.d.ts +2958 -0
  162. package/dist/internal/serving-contracts/tenant-web-crawl.js +13 -0
  163. package/dist/internal/serving-contracts/tenant-web-dynamic.d.ts +3902 -0
  164. package/dist/internal/serving-contracts/tenant-web-dynamic.js +20 -0
  165. package/dist/internal/serving-contracts/tenant-web-workflow.d.ts +5750 -0
  166. package/dist/internal/serving-contracts/tenant-web-workflow.js +36 -0
  167. package/dist/internal/serving-contracts/tenant-web.d.ts +6418 -0
  168. package/dist/internal/serving-contracts/tenant-web.js +53 -0
  169. package/dist/internal/serving-contracts/tenant-workspace.d.ts +6451 -0
  170. package/dist/internal/serving-contracts/tenant-workspace.js +28 -0
  171. package/dist/internal/serving-contracts/workflow.d.ts +439 -0
  172. package/dist/internal/serving-contracts/workflow.js +37 -0
  173. package/dist/material-stream.d.ts +18 -0
  174. package/dist/material-stream.js +29 -0
  175. package/dist/oauth.d.ts +268 -0
  176. package/dist/oauth.js +539 -0
  177. package/dist/resource.d.ts +88 -0
  178. package/dist/resource.js +123 -0
  179. package/dist/session.d.ts +4 -0
  180. package/dist/session.js +3 -0
  181. package/dist/tenant-client.d.ts +169 -0
  182. package/dist/tenant-client.js +58 -0
  183. package/dist/tenant-management.d.ts +240 -0
  184. package/dist/tenant-management.js +149 -0
  185. package/dist/tenant-project.d.ts +57 -0
  186. package/dist/tenant-project.js +63 -0
  187. package/dist/tenant-runtime.d.ts +174 -0
  188. package/dist/tenant-runtime.js +17 -0
  189. package/dist/tenant-web-content.d.ts +44 -0
  190. package/dist/tenant-web-content.js +70 -0
  191. package/dist/tenant-web-crawl.d.ts +42 -0
  192. package/dist/tenant-web-crawl.js +39 -0
  193. package/dist/tenant-web-dynamic.d.ts +42 -0
  194. package/dist/tenant-web-dynamic.js +39 -0
  195. package/dist/tenant-web-workflow.d.ts +43 -0
  196. package/dist/tenant-web-workflow.js +63 -0
  197. package/dist/tenant-web.d.ts +42 -0
  198. package/dist/tenant-web.js +39 -0
  199. package/dist/tenant-workspace.d.ts +36 -0
  200. package/dist/tenant-workspace.js +21 -0
  201. package/dist/token-provider.d.ts +14 -0
  202. package/dist/token-provider.js +21 -0
  203. package/package.json +45 -3
@@ -0,0 +1,194 @@
1
+ import { z } from 'zod';
2
+ import { accessClassificationSchema, idSchema, isoDateTimeSchema, projectKeySchema, schemaVersionSchema, stableUriSchema, } from './common.js';
3
+ export const sourceExpectationSchema = z.enum(['REQUIRED', 'OPTIONAL', 'CONDITIONAL']);
4
+ export const sourceDeclaredStateSchema = z.enum([
5
+ 'CONFIGURED',
6
+ 'PENDING_DISCOVERY',
7
+ 'KNOWN_MISSING',
8
+ 'ACCESS_CONTROLLED',
9
+ 'NEED_AUTHORIZED_SOURCE',
10
+ 'DEFERRED',
11
+ 'RETIRED',
12
+ ]);
13
+ export const sourceCoverageStateSchema = z.enum([
14
+ 'ACQUIRED',
15
+ 'CONFIGURED_UNOBSERVED',
16
+ 'PARTIAL',
17
+ 'BLOCKED',
18
+ 'ACCESS_CONTROLLED',
19
+ 'PENDING_DISCOVERY',
20
+ 'KNOWN_MISSING',
21
+ 'NEED_AUTHORIZED_SOURCE',
22
+ 'DEFERRED',
23
+ 'RETIRED',
24
+ ]);
25
+ const shortText = z.string().trim().min(1).max(512);
26
+ const roleSchema = z.string().trim().min(1).max(256);
27
+ export const sourceDiscoveryPolicySchema = z.object({
28
+ hostMode: z.enum(['ALLOWLIST', 'EVIDENCE_OBSERVED']).default('ALLOWLIST'),
29
+ allowedHosts: z.array(z.string().trim().toLowerCase().min(1).max(253)).max(256).default([]),
30
+ forbiddenHostSuffixes: z.array(z.string().trim().toLowerCase().min(1).max(253)).max(256).default([]),
31
+ allowedPathPrefixes: z.array(z.string().trim().startsWith('/').max(2048)).min(1).max(128),
32
+ }).strict().superRefine((value, ctx) => {
33
+ if (value.hostMode === 'ALLOWLIST' && !value.allowedHosts.length)
34
+ ctx.addIssue({ code: 'custom', path: ['allowedHosts'], message: 'ALLOWLIST discovery requires at least one allowed host' });
35
+ const allowed = new Set(value.allowedHosts);
36
+ for (const suffix of value.forbiddenHostSuffixes)
37
+ if (allowed.has(suffix))
38
+ ctx.addIssue({ code: 'custom', path: ['forbiddenHostSuffixes'], message: `Host cannot be both allowed and forbidden: ${suffix}` });
39
+ });
40
+ export const sourceUniverseEntrySchema = z.object({
41
+ sourceId: idSchema,
42
+ familyId: idSchema,
43
+ acquisitionSourceIds: z.array(idSchema).max(64).default([]),
44
+ expectation: sourceExpectationSchema,
45
+ authority: shortText,
46
+ access: accessClassificationSchema,
47
+ freshness: shortText,
48
+ semanticRoles: z.array(roleSchema).max(64).default([]),
49
+ locator: stableUriSchema.nullable().default(null),
50
+ declaredState: sourceDeclaredStateSchema,
51
+ expectedOwner: shortText.nullable().default(null),
52
+ requiredFor: z.array(idSchema).max(128).default([]),
53
+ discoveryPolicy: sourceDiscoveryPolicySchema.nullable().default(null),
54
+ notes: z.string().trim().max(2000).nullable().default(null),
55
+ }).strict().superRefine((value, ctx) => {
56
+ if (value.declaredState === 'CONFIGURED' && value.locator === null) {
57
+ ctx.addIssue({ code: 'custom', path: ['locator'], message: 'CONFIGURED source requires locator' });
58
+ }
59
+ if (['PENDING_DISCOVERY', 'KNOWN_MISSING', 'ACCESS_CONTROLLED', 'NEED_AUTHORIZED_SOURCE'].includes(value.declaredState) && value.expectation === 'OPTIONAL' && !value.requiredFor.length) {
60
+ ctx.addIssue({ code: 'custom', path: ['requiredFor'], message: 'unresolved optional source must declare why it is tracked' });
61
+ }
62
+ });
63
+ export const sourceUniverseSchema = z.object({
64
+ schemaVersion: schemaVersionSchema,
65
+ projectKey: projectKeySchema,
66
+ asOf: isoDateTimeSchema,
67
+ sources: z.array(sourceUniverseEntrySchema).min(1).max(5000),
68
+ }).strict().superRefine((value, ctx) => {
69
+ const ids = new Set();
70
+ for (let i = 0; i < value.sources.length; i += 1) {
71
+ const id = value.sources[i].sourceId;
72
+ if (ids.has(id))
73
+ ctx.addIssue({ code: 'custom', path: ['sources', i, 'sourceId'], message: 'sourceId must be unique' });
74
+ ids.add(id);
75
+ }
76
+ });
77
+ export const sourceCoverageEntrySchema = z.object({
78
+ sourceId: idSchema,
79
+ familyId: idSchema,
80
+ expectation: sourceExpectationSchema,
81
+ declaredState: sourceDeclaredStateSchema,
82
+ coverageState: sourceCoverageStateSchema,
83
+ configuredItemCount: z.number().int().nonnegative(),
84
+ observedItemCount: z.number().int().nonnegative(),
85
+ acquiredItemCount: z.number().int().nonnegative(),
86
+ blockedItemCount: z.number().int().nonnegative(),
87
+ accessControlledItemCount: z.number().int().nonnegative(),
88
+ evidenceRefs: z.array(stableUriSchema).max(2048),
89
+ blockers: z.array(shortText).max(256),
90
+ }).strict();
91
+ export const sourceCoverageAssessmentSchema = z.object({
92
+ schemaVersion: schemaVersionSchema,
93
+ projectKey: projectKeySchema,
94
+ assessedAt: isoDateTimeSchema,
95
+ complete: z.boolean(),
96
+ requiredSourceCount: z.number().int().nonnegative(),
97
+ coveredRequiredSourceCount: z.number().int().nonnegative(),
98
+ entries: z.array(sourceCoverageEntrySchema).max(5000),
99
+ blockers: z.array(shortText).max(1000),
100
+ }).strict();
101
+ export const sourceGapStateSchema = z.enum([
102
+ 'PENDING_DISCOVERY',
103
+ 'KNOWN_MISSING',
104
+ 'ACCESS_CONTROLLED',
105
+ 'NEED_AUTHORIZED_SOURCE',
106
+ 'DEFERRED',
107
+ ]);
108
+ export const sourceGapSchema = z.object({
109
+ schemaVersion: schemaVersionSchema,
110
+ gapId: idSchema,
111
+ projectKey: projectKeySchema,
112
+ sourceId: idSchema,
113
+ familyId: idSchema,
114
+ state: sourceGapStateSchema,
115
+ access: accessClassificationSchema,
116
+ expectedOwner: shortText.nullable(),
117
+ reason: z.string().trim().min(1).max(2000),
118
+ requiredFor: z.array(idSchema).max(128),
119
+ evidenceRefs: z.array(stableUriSchema).max(256),
120
+ recordedAt: isoDateTimeSchema,
121
+ }).strict();
122
+ const discoveryLinkIdSchema = z.string().trim().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/);
123
+ const discoveredLinkSchema = z.object({
124
+ linkId: discoveryLinkIdSchema,
125
+ url: z.url(),
126
+ locator: z.string().trim().min(1).max(2048),
127
+ parentEvidenceRef: stableUriSchema,
128
+ title: z.string().trim().min(1).max(500).optional(),
129
+ }).strict();
130
+ export const sourceDiscoveryProposalSchema = z.object({
131
+ schemaVersion: schemaVersionSchema,
132
+ projectKey: projectKeySchema,
133
+ proposalId: idSchema,
134
+ familyId: idSchema,
135
+ createdAt: isoDateTimeSchema,
136
+ observedLinks: z.array(discoveredLinkSchema).min(1).max(1000),
137
+ selectedLinkIds: z.array(discoveryLinkIdSchema).max(1000),
138
+ completeness: z.object({
139
+ claim: z.enum(['COMPLETE', 'INCOMPLETE']),
140
+ missing: z.array(z.string().trim().min(1).max(500)).max(1000),
141
+ notes: z.string().trim().max(4000).nullable().default(null),
142
+ }).strict(),
143
+ }).strict();
144
+ export const sourceDiscoveryValidationSchema = z.object({
145
+ schemaVersion: schemaVersionSchema,
146
+ projectKey: projectKeySchema,
147
+ proposalId: idSchema,
148
+ familyId: idSchema,
149
+ proposalHash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
150
+ valid: z.boolean(),
151
+ selectedSources: z.array(z.object({ linkId: idSchema, url: z.url(), parentEvidenceRef: stableUriSchema }).strict()).max(1000),
152
+ completeness: z.object({ claim: z.enum(['COMPLETE', 'INCOMPLETE']), missing: z.array(z.string()).max(1000), notes: z.string().nullable() }).strict(),
153
+ evidenceRefs: z.array(stableUriSchema).max(1000),
154
+ errors: z.array(shortText).max(1000),
155
+ warnings: z.array(shortText).max(1000),
156
+ }).strict();
157
+ export const sourceDiscoveryReceiptSchema = z.object({
158
+ schemaVersion: schemaVersionSchema,
159
+ projectKey: projectKeySchema,
160
+ proposalId: idSchema,
161
+ familyId: idSchema,
162
+ proposalHash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
163
+ state: z.enum(['COMPLETE', 'REVIEWED_PARTIAL']),
164
+ proposalRef: stableUriSchema,
165
+ reviewRef: stableUriSchema,
166
+ reviewedAt: isoDateTimeSchema,
167
+ selectedSources: z.array(z.object({ linkId: idSchema, url: z.url(), parentEvidenceRef: stableUriSchema }).strict()).max(1000),
168
+ completeness: z.object({ claim: z.enum(['COMPLETE', 'INCOMPLETE']), missing: z.array(z.string()).max(1000), notes: z.string().nullable() }).strict(),
169
+ evidenceRefs: z.array(stableUriSchema).max(1000),
170
+ configMutationPerformed: z.literal(false),
171
+ }).strict().superRefine((value, ctx) => {
172
+ if (value.state === 'COMPLETE' && (value.completeness.claim !== 'COMPLETE' || value.completeness.missing.length))
173
+ ctx.addIssue({ code: 'custom', path: ['state'], message: 'COMPLETE receipt requires complete proposal without missing sources' });
174
+ if (value.state === 'REVIEWED_PARTIAL' && value.completeness.claim !== 'INCOMPLETE')
175
+ ctx.addIssue({ code: 'custom', path: ['state'], message: 'REVIEWED_PARTIAL receipt requires INCOMPLETE proposal' });
176
+ });
177
+ export const sourceAdmissionMatchSchema = z.object({
178
+ url: z.url(),
179
+ status: z.enum(['ADMITTED', 'BLOCKED', 'MISSING', 'DUPLICATE']),
180
+ universeSourceId: idSchema.nullable(),
181
+ acquisitionSourceId: idSchema.nullable(),
182
+ concreteSourceId: idSchema.nullable(),
183
+ issues: z.array(shortText).max(128),
184
+ }).strict();
185
+ export const sourceAdmissionAssessmentSchema = z.object({
186
+ schemaVersion: schemaVersionSchema,
187
+ projectKey: projectKeySchema,
188
+ familyId: idSchema,
189
+ state: z.enum(['ADMITTED', 'BLOCKED']),
190
+ selectedSourceCount: z.number().int().nonnegative(),
191
+ matches: z.array(sourceAdmissionMatchSchema).max(1000),
192
+ blockers: z.array(shortText).max(1000),
193
+ configMutationPerformed: z.literal(false),
194
+ }).strict();
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ export declare const sourceKindSchema: z.ZodEnum<{
3
+ MANUAL: "MANUAL";
4
+ FILE: "FILE";
5
+ WEB: "WEB";
6
+ API: "API";
7
+ REPOSITORY: "REPOSITORY";
8
+ FEED: "FEED";
9
+ SOCIAL: "SOCIAL";
10
+ BROWSER: "BROWSER";
11
+ OTHER: "OTHER";
12
+ }>;
13
+ export declare const sourceDefinitionSchema: z.ZodObject<{
14
+ schemaVersion: z.ZodLiteral<1>;
15
+ sourceId: z.ZodString;
16
+ projectKey: z.ZodOptional<z.ZodString>;
17
+ kind: z.ZodEnum<{
18
+ MANUAL: "MANUAL";
19
+ FILE: "FILE";
20
+ WEB: "WEB";
21
+ API: "API";
22
+ REPOSITORY: "REPOSITORY";
23
+ FEED: "FEED";
24
+ SOCIAL: "SOCIAL";
25
+ BROWSER: "BROWSER";
26
+ OTHER: "OTHER";
27
+ }>;
28
+ authority: z.ZodString;
29
+ access: z.ZodEnum<{
30
+ PUBLIC: "PUBLIC";
31
+ PUBLIC_METADATA: "PUBLIC_METADATA";
32
+ TENANT: "TENANT";
33
+ INTERNAL: "INTERNAL";
34
+ FDE_INTERNAL: "FDE_INTERNAL";
35
+ ACCESS_CONTROLLED: "ACCESS_CONTROLLED";
36
+ UNKNOWN: "UNKNOWN";
37
+ }>;
38
+ canonicalUri: z.ZodOptional<z.ZodString>;
39
+ refreshPolicy: z.ZodString;
40
+ enabled: z.ZodBoolean;
41
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
42
+ }, z.core.$strict>;
43
+ export declare const collectorDefinitionSchema: z.ZodObject<{
44
+ schemaVersion: z.ZodLiteral<1>;
45
+ collectorId: z.ZodString;
46
+ version: z.ZodString;
47
+ supportedSourceKinds: z.ZodArray<z.ZodEnum<{
48
+ MANUAL: "MANUAL";
49
+ FILE: "FILE";
50
+ WEB: "WEB";
51
+ API: "API";
52
+ REPOSITORY: "REPOSITORY";
53
+ FEED: "FEED";
54
+ SOCIAL: "SOCIAL";
55
+ BROWSER: "BROWSER";
56
+ OTHER: "OTHER";
57
+ }>>;
58
+ capabilities: z.ZodArray<z.ZodString>;
59
+ }, z.core.$strict>;
60
+ export type SourceKind = z.infer<typeof sourceKindSchema>;
61
+ export type SourceDefinition = z.infer<typeof sourceDefinitionSchema>;
62
+ export type CollectorDefinition = z.infer<typeof collectorDefinitionSchema>;
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ import { accessClassificationSchema, idSchema, projectKeySchema, schemaVersionSchema, stableUriSchema, } from './common.js';
3
+ export const sourceKindSchema = z.enum([
4
+ 'WEB',
5
+ 'API',
6
+ 'FILE',
7
+ 'REPOSITORY',
8
+ 'FEED',
9
+ 'SOCIAL',
10
+ 'BROWSER',
11
+ 'MANUAL',
12
+ 'OTHER',
13
+ ]);
14
+ export const sourceDefinitionSchema = z.object({
15
+ schemaVersion: schemaVersionSchema,
16
+ sourceId: idSchema,
17
+ projectKey: projectKeySchema.optional(),
18
+ kind: sourceKindSchema,
19
+ authority: z.string().trim().min(1).max(256),
20
+ access: accessClassificationSchema,
21
+ canonicalUri: stableUriSchema.optional(),
22
+ refreshPolicy: z.string().trim().min(1).max(256),
23
+ enabled: z.boolean(),
24
+ tags: z.array(z.string().trim().min(1).max(128)).max(64).default([]),
25
+ }).strict();
26
+ export const collectorDefinitionSchema = z.object({
27
+ schemaVersion: schemaVersionSchema,
28
+ collectorId: idSchema,
29
+ version: z.string().trim().min(1).max(128),
30
+ supportedSourceKinds: z.array(sourceKindSchema).min(1),
31
+ capabilities: z.array(z.string().trim().min(1).max(128)).max(64),
32
+ }).strict();
@@ -0,0 +1,59 @@
1
+ /** Host-authored admission accounting, independent of business authorization and receipt schemas. */
2
+ import { z } from 'zod';
3
+ export declare const tenantBudgetPolicySchema: z.ZodObject<{
4
+ tenantId: z.ZodString;
5
+ maxInFlight: z.ZodNumber;
6
+ maxWorkUnits: z.ZodNumber;
7
+ maxRuntimeMs: z.ZodNumber;
8
+ weight: z.ZodNumber;
9
+ paused: z.ZodBoolean;
10
+ }, z.core.$strict>;
11
+ export declare const tenantBudgetConfigSchema: z.ZodObject<{
12
+ schemaVersion: z.ZodLiteral<1>;
13
+ windowSeconds: z.ZodNumber;
14
+ maxInFlight: z.ZodNumber;
15
+ maxWaitRounds: z.ZodNumber;
16
+ tenants: z.ZodArray<z.ZodObject<{
17
+ tenantId: z.ZodString;
18
+ maxInFlight: z.ZodNumber;
19
+ maxWorkUnits: z.ZodNumber;
20
+ maxRuntimeMs: z.ZodNumber;
21
+ weight: z.ZodNumber;
22
+ paused: z.ZodBoolean;
23
+ }, z.core.$strict>>;
24
+ }, z.core.$strict>;
25
+ export declare const tenantBudgetCandidateSchema: z.ZodObject<{
26
+ key: z.ZodString;
27
+ tenantId: z.ZodString;
28
+ workUnits: z.ZodNumber;
29
+ runtimeMs: z.ZodNumber;
30
+ }, z.core.$strict>;
31
+ export declare const tenantBudgetReservationSchema: z.ZodObject<{
32
+ key: z.ZodString;
33
+ tenantId: z.ZodString;
34
+ workUnits: z.ZodNumber;
35
+ runtimeMs: z.ZodNumber;
36
+ admissionId: z.ZodString;
37
+ nodeId: z.ZodString;
38
+ startedAt: z.ZodISODateTime;
39
+ expiresAt: z.ZodISODateTime;
40
+ windowStart: z.ZodISODateTime;
41
+ }, z.core.$strict>;
42
+ export declare const tenantBudgetReasonSchema: z.ZodEnum<{
43
+ READY: "READY";
44
+ TENANT_UNCONFIGURED: "TENANT_UNCONFIGURED";
45
+ PAUSED: "PAUSED";
46
+ HOST_IN_FLIGHT: "HOST_IN_FLIGHT";
47
+ TENANT_IN_FLIGHT: "TENANT_IN_FLIGHT";
48
+ WORK_BUDGET: "WORK_BUDGET";
49
+ TIME_BUDGET: "TIME_BUDGET";
50
+ WORK_ACTIVE: "WORK_ACTIVE";
51
+ }>;
52
+ export type TenantBudgetConfig = z.infer<typeof tenantBudgetConfigSchema>;
53
+ export type TenantBudgetCandidate = z.infer<typeof tenantBudgetCandidateSchema>;
54
+ export type TenantBudgetReservation = z.infer<typeof tenantBudgetReservationSchema>;
55
+ /** 两小时是整个准入的硬上限;短任务保留结算余量,合法的上限任务不因此被排除。 */
56
+ export declare function tenantLegacyAdmissionRuntimeMs(timeoutSeconds: number): number;
57
+ export type TenantBudgetReason = z.infer<typeof tenantBudgetReasonSchema>;
58
+ export declare function tenantCollectionAdmissionKey(tenantId: string, batchRef: string): string;
59
+ export declare function tenantLegacyAdmissionKey(tenantId: string, workloadId: string): string;
@@ -0,0 +1,34 @@
1
+ /** Host-authored admission accounting, independent of business authorization and receipt schemas. */
2
+ import { z } from 'zod';
3
+ import { createHash } from 'node:crypto';
4
+ import { materialTenantIdSchema } from './material-context.js';
5
+ import { isoDateTimeSchema } from './common.js';
6
+ import { parseTenantCollectionBatchRef } from './tenant-collection.js';
7
+ import { tenantStorageKey } from './resource-scope.js';
8
+ const positive = (max) => z.number().int().min(1).max(max);
9
+ export const tenantBudgetPolicySchema = z.object({ tenantId: materialTenantIdSchema, maxInFlight: positive(32), maxWorkUnits: positive(1_000_000), maxRuntimeMs: positive(86_400_000), weight: positive(8), paused: z.boolean() }).strict();
10
+ export const tenantBudgetConfigSchema = z.object({ schemaVersion: z.literal(1), windowSeconds: z.number().int().min(60).max(86400), maxInFlight: positive(128), maxWaitRounds: positive(2048), tenants: z.array(tenantBudgetPolicySchema).min(1).max(128) }).strict().superRefine((value, ctx) => {
11
+ if (new Set(value.tenants.map(t => t.tenantId)).size !== value.tenants.length || value.tenants.some(t => t.maxInFlight > value.maxInFlight) || value.tenants.reduce((sum, t) => sum + t.weight, 0) > value.maxWaitRounds)
12
+ ctx.addIssue({ code: 'custom', message: 'Unique Tenants, Host limits and weighted waiting bound are required' });
13
+ });
14
+ export const tenantBudgetCandidateSchema = z.object({ key: z.string().regex(/^[a-f0-9]{64}$/), tenantId: materialTenantIdSchema, workUnits: positive(100_000), runtimeMs: z.number().int().min(1000).max(7_200_000) }).strict();
15
+ export const tenantBudgetReservationSchema = tenantBudgetCandidateSchema.extend({ admissionId: z.string().uuid(), nodeId: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/), startedAt: isoDateTimeSchema, expiresAt: isoDateTimeSchema, windowStart: isoDateTimeSchema }).strict();
16
+ export const tenantBudgetReasonSchema = z.enum(['READY', 'TENANT_UNCONFIGURED', 'PAUSED', 'HOST_IN_FLIGHT', 'TENANT_IN_FLIGHT', 'WORK_BUDGET', 'TIME_BUDGET', 'WORK_ACTIVE']);
17
+ /** 两小时是整个准入的硬上限;短任务保留结算余量,合法的上限任务不因此被排除。 */
18
+ export function tenantLegacyAdmissionRuntimeMs(timeoutSeconds) {
19
+ if (!Number.isInteger(timeoutSeconds) || timeoutSeconds < 30 || timeoutSeconds > 7200)
20
+ throw new Error('TENANT_LEGACY_TIMEOUT_INVALID');
21
+ return Math.min(7_200_000, timeoutSeconds * 1000 + 2000);
22
+ }
23
+ export function tenantCollectionAdmissionKey(tenantId, batchRef) {
24
+ const batch = parseTenantCollectionBatchRef(batchRef);
25
+ if (!batch || batch.storageKey !== tenantStorageKey(tenantId))
26
+ throw new Error('TENANT_BUDGET_WORK_SCOPE_INVALID');
27
+ return createHash('sha256').update(JSON.stringify(['TENANT_COLLECTION_ADMISSION_V1', tenantId, batchRef])).digest('hex');
28
+ }
29
+ export function tenantLegacyAdmissionKey(tenantId, workloadId) {
30
+ materialTenantIdSchema.parse(tenantId);
31
+ if (typeof workloadId !== 'string' || workloadId.length > 256 || !/^project:[A-Za-z0-9][A-Za-z0-9._-]{0,127}:.+$/.test(workloadId))
32
+ throw new Error('TENANT_BUDGET_WORK_SCOPE_INVALID');
33
+ return createHash('sha256').update(JSON.stringify(['TENANT_LEGACY_ADMISSION_V1', tenantId, workloadId])).digest('hex');
34
+ }
@@ -0,0 +1,209 @@
1
+ import { z } from 'zod';
2
+ import type { RunReceipt } from './runtime.js';
3
+ export declare const tenantCollectionRequestAuthoritySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
+ type: z.ZodLiteral<"HOST">;
5
+ }, z.core.$strict>, z.ZodObject<{
6
+ type: z.ZodLiteral<"OAUTH">;
7
+ authorityVersion: z.ZodLiteral<2>;
8
+ clientId: z.ZodString;
9
+ grantId: z.ZodString;
10
+ resource: z.ZodString;
11
+ }, z.core.$strict>], "type">;
12
+ export declare function tenantCollectionRequestKey(requestId: string): string;
13
+ export declare function tenantCollectionRequestRef(tenantId: string, requestId: string): string;
14
+ export declare const tenantCollectionRequestSchema: z.ZodObject<{
15
+ schemaVersion: z.ZodLiteral<2>;
16
+ tenantId: z.ZodString;
17
+ requestId: z.ZodString;
18
+ requestRef: z.ZodString;
19
+ context: z.ZodDiscriminatedUnion<[z.ZodObject<{
20
+ type: z.ZodLiteral<"TENANT">;
21
+ tenantId: z.ZodString;
22
+ }, z.core.$strict>, z.ZodObject<{
23
+ type: z.ZodLiteral<"PROJECT">;
24
+ tenantId: z.ZodString;
25
+ projectKey: z.ZodString;
26
+ }, z.core.$strict>], "type">;
27
+ actor: z.ZodObject<{
28
+ tenantId: z.ZodString;
29
+ userId: z.ZodString;
30
+ agentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
31
+ }, z.core.$strict>;
32
+ authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
33
+ type: z.ZodLiteral<"HOST">;
34
+ }, z.core.$strict>, z.ZodObject<{
35
+ type: z.ZodLiteral<"OAUTH">;
36
+ authorityVersion: z.ZodLiteral<2>;
37
+ clientId: z.ZodString;
38
+ grantId: z.ZodString;
39
+ resource: z.ZodString;
40
+ }, z.core.$strict>], "type">;
41
+ plan: z.ZodObject<{
42
+ schemaVersion: z.ZodLiteral<1>;
43
+ tenantId: z.ZodString;
44
+ source: z.ZodObject<{
45
+ schemaVersion: z.ZodLiteral<1>;
46
+ tenantId: z.ZodString;
47
+ sourceId: z.ZodString;
48
+ title: z.ZodString;
49
+ semantics: z.ZodObject<{
50
+ target: z.ZodDiscriminatedUnion<[z.ZodObject<{
51
+ kind: z.ZodLiteral<"URL">;
52
+ locator: z.ZodURL;
53
+ }, z.core.$strict>, z.ZodObject<{
54
+ kind: z.ZodLiteral<"FILE">;
55
+ rootBinding: z.ZodString;
56
+ relativePath: z.ZodString;
57
+ }, z.core.$strict>, z.ZodObject<{
58
+ kind: z.ZodLiteral<"EXECUTOR">;
59
+ executorId: z.ZodString;
60
+ bindingRef: z.ZodDefault<z.ZodNullable<z.ZodString>>;
61
+ parameters: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>]>>>;
62
+ }, z.core.$strict>], "kind">;
63
+ credential: z.ZodDiscriminatedUnion<[z.ZodObject<{
64
+ type: z.ZodLiteral<"PUBLIC">;
65
+ }, z.core.$strict>, z.ZodObject<{
66
+ type: z.ZodLiteral<"BOUND">;
67
+ bindingRef: z.ZodString;
68
+ revision: z.ZodString;
69
+ }, z.core.$strict>], "type">;
70
+ executionBinding: z.ZodDefault<z.ZodNullable<z.ZodObject<{
71
+ bindingRef: z.ZodString;
72
+ revision: z.ZodString;
73
+ }, z.core.$strict>>>;
74
+ access: z.ZodEnum<{
75
+ PUBLIC: "PUBLIC";
76
+ PUBLIC_METADATA: "PUBLIC_METADATA";
77
+ TENANT: "TENANT";
78
+ INTERNAL: "INTERNAL";
79
+ FDE_INTERNAL: "FDE_INTERNAL";
80
+ ACCESS_CONTROLLED: "ACCESS_CONTROLLED";
81
+ UNKNOWN: "UNKNOWN";
82
+ }>;
83
+ sourcePolicy: z.ZodObject<{
84
+ ref: z.ZodString;
85
+ revision: z.ZodString;
86
+ acquisition: z.ZodEnum<{
87
+ ALLOW: "ALLOW";
88
+ DENY: "DENY";
89
+ }>;
90
+ propagation: z.ZodEnum<{
91
+ TENANT_ONLY: "TENANT_ONLY";
92
+ SHARE_ALLOWED: "SHARE_ALLOWED";
93
+ PUBLIC_ALLOWED: "PUBLIC_ALLOWED";
94
+ }>;
95
+ }, z.core.$strict>;
96
+ region: z.ZodNullable<z.ZodString>;
97
+ representation: z.ZodObject<{
98
+ format: z.ZodEnum<{
99
+ RICH_DOCUMENT_V1: "RICH_DOCUMENT_V1";
100
+ RAW: "RAW";
101
+ }>;
102
+ extractor: z.ZodNullable<z.ZodObject<{
103
+ id: z.ZodString;
104
+ version: z.ZodString;
105
+ }, z.core.$strict>>;
106
+ }, z.core.$strict>;
107
+ }, z.core.$strict>;
108
+ sourceRef: z.ZodString;
109
+ revision: z.ZodString;
110
+ revisionRef: z.ZodString;
111
+ semanticKey: z.ZodString;
112
+ targetId: z.ZodString;
113
+ }, z.core.$strict>;
114
+ maxResourceBytes: z.ZodNumber;
115
+ revision: z.ZodString;
116
+ planRef: z.ZodString;
117
+ workloadId: z.ZodString;
118
+ }, z.core.$strict>;
119
+ trigger: z.ZodEnum<{
120
+ MANUAL: "MANUAL";
121
+ DUE: "DUE";
122
+ }>;
123
+ cycleId: z.ZodString;
124
+ batchId: z.ZodString;
125
+ batchRef: z.ZodString;
126
+ requestedAt: z.ZodISODateTime;
127
+ }, z.core.$strict>;
128
+ export declare const tenantCollectionCompletionSchema: z.ZodUnion<readonly [z.ZodObject<{
129
+ schemaVersion: z.ZodLiteral<1>;
130
+ tenantId: z.ZodString;
131
+ requestRef: z.ZodString;
132
+ batchRef: z.ZodString;
133
+ phase: z.ZodEnum<{
134
+ RAW_REGISTERED: "RAW_REGISTERED";
135
+ DERIVED_REGISTERED: "DERIVED_REGISTERED";
136
+ }>;
137
+ evidenceRef: z.ZodString;
138
+ contentHash: z.ZodString;
139
+ runId: z.ZodString;
140
+ runtimeNodeId: z.ZodString;
141
+ completedAt: z.ZodISODateTime;
142
+ }, z.core.$strict>, z.ZodObject<{
143
+ tenantId: z.ZodString;
144
+ requestRef: z.ZodString;
145
+ batchRef: z.ZodString;
146
+ evidenceRef: z.ZodString;
147
+ contentHash: z.ZodString;
148
+ runId: z.ZodString;
149
+ runtimeNodeId: z.ZodString;
150
+ completedAt: z.ZodISODateTime;
151
+ schemaVersion: z.ZodLiteral<2>;
152
+ phase: z.ZodLiteral<"DERIVED_REGISTERED">;
153
+ documentRef: z.ZodString;
154
+ }, z.core.$strict>]>;
155
+ export declare function assertTenantCollectionCompletion(request: TenantCollectionRequest, raw: unknown): {
156
+ schemaVersion: 1;
157
+ tenantId: string;
158
+ requestRef: string;
159
+ batchRef: string;
160
+ phase: "RAW_REGISTERED" | "DERIVED_REGISTERED";
161
+ evidenceRef: string;
162
+ contentHash: string;
163
+ runId: string;
164
+ runtimeNodeId: string;
165
+ completedAt: string;
166
+ } | {
167
+ tenantId: string;
168
+ requestRef: string;
169
+ batchRef: string;
170
+ evidenceRef: string;
171
+ contentHash: string;
172
+ runId: string;
173
+ runtimeNodeId: string;
174
+ completedAt: string;
175
+ schemaVersion: 2;
176
+ phase: "DERIVED_REGISTERED";
177
+ documentRef: string;
178
+ };
179
+ export type TenantCollectionRequest = z.infer<typeof tenantCollectionRequestSchema>;
180
+ export type TenantCollectionCompletion = z.infer<typeof tenantCollectionCompletionSchema>;
181
+ /** Admission retirement is not acquisition failure or business completion. */
182
+ export declare const TENANT_REQUEST_ADMISSION_STOP_CAPABILITY = "TENANT_REQUEST_ADMISSION_STOP_V1";
183
+ export declare const tenantCollectionAdmissionStopSchema: z.ZodObject<{
184
+ schemaVersion: z.ZodLiteral<1>;
185
+ tenantId: z.ZodString;
186
+ requestRef: z.ZodString;
187
+ requestHash: z.ZodString;
188
+ reason: z.ZodEnum<{
189
+ GRANT_REVOKED: "GRANT_REVOKED";
190
+ DELEGATION_SUPERSEDED: "DELEGATION_SUPERSEDED";
191
+ }>;
192
+ stoppedAt: z.ZodISODateTime;
193
+ }, z.core.$strict>;
194
+ export type TenantCollectionAdmissionStop = z.infer<typeof tenantCollectionAdmissionStopSchema>;
195
+ /** Acquisition outcome only: a failed request is neither completed nor delegation-retired. */
196
+ export declare const tenantCollectionFailureSchema: z.ZodObject<{
197
+ schemaVersion: z.ZodLiteral<1>;
198
+ tenantId: z.ZodString;
199
+ requestRef: z.ZodString;
200
+ requestHash: z.ZodString;
201
+ batchRef: z.ZodString;
202
+ runId: z.ZodString;
203
+ runtimeNodeId: z.ZodString;
204
+ receiptHash: z.ZodString;
205
+ failedAt: z.ZodISODateTime;
206
+ errorCode: z.ZodLiteral<"TENANT_SOURCE_HTTP_TERMINAL">;
207
+ }, z.core.$strict>;
208
+ export type TenantCollectionFailure = z.infer<typeof tenantCollectionFailureSchema>;
209
+ export declare function isTenantCollectionTerminalFailure(request: Pick<TenantCollectionRequest, 'plan' | 'batchRef'>, receipt: RunReceipt): boolean;
@@ -0,0 +1,58 @@
1
+ /** 请求归因与 project-blind 批次分离;只保存委托身份,不保存可使用的 token。 */
2
+ import { createHash } from 'node:crypto';
3
+ import { z } from 'zod';
4
+ import { idSchema, isoDateTimeSchema, stableUriSchema, sha256Schema } from './common.js';
5
+ import { resourceScopeSchema, tenantStorageKey, parseTenantResourceRef, tenantResourceRefSchema } from './resource-scope.js';
6
+ import { materialTenantIdSchema } from './material-context.js';
7
+ import { knowledgeActorContextSchema } from './project-intent.js';
8
+ import { tenantCollectionPlanSchema, tenantCollectionCycleSchema, tenantCollectionBatchIdentity, tenantCapturedEvidenceIdentity } from './tenant-collection.js';
9
+ export const tenantCollectionRequestAuthoritySchema = z.discriminatedUnion('type', [
10
+ z.object({ type: z.literal('HOST') }).strict(),
11
+ z.object({ type: z.literal('OAUTH'), authorityVersion: z.literal(2), clientId: idSchema, grantId: idSchema, resource: stableUriSchema }).strict(),
12
+ ]);
13
+ export function tenantCollectionRequestKey(requestId) { return createHash('sha256').update(tenantCollectionCycleSchema.parse(requestId)).digest('hex'); }
14
+ export function tenantCollectionRequestRef(tenantId, requestId) { return `tenant-collection-request://${tenantStorageKey(tenantId)}/${tenantCollectionRequestKey(requestId)}`; }
15
+ export const tenantCollectionRequestSchema = z.object({
16
+ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, requestId: tenantCollectionCycleSchema, requestRef: stableUriSchema,
17
+ context: resourceScopeSchema, actor: knowledgeActorContextSchema, authority: tenantCollectionRequestAuthoritySchema,
18
+ plan: tenantCollectionPlanSchema, trigger: z.enum(['MANUAL', 'DUE']), cycleId: tenantCollectionCycleSchema, batchId: z.string().regex(/^batch_[a-f0-9]{64}$/), batchRef: stableUriSchema, requestedAt: isoDateTimeSchema,
19
+ }).strict().superRefine((value, ctx) => {
20
+ const expected = tenantCollectionBatchIdentity(value.tenantId, value.plan.revision, value.trigger, value.cycleId);
21
+ if (value.context.tenantId !== value.tenantId || value.actor.tenantId !== value.tenantId || value.plan.tenantId !== value.tenantId || value.requestRef !== tenantCollectionRequestRef(value.tenantId, value.requestId))
22
+ ctx.addIssue({ code: 'custom', path: ['context'], message: 'Request must retain exact Tenant/context/request identity' });
23
+ if (value.batchId !== expected.batchId || value.batchRef !== expected.batchRef)
24
+ ctx.addIssue({ code: 'custom', path: ['batchRef'], message: 'Request cannot retarget a different frozen batch' });
25
+ if (value.trigger === 'DUE' && value.authority.type !== 'HOST')
26
+ ctx.addIssue({ code: 'custom', path: ['trigger'], message: 'Only an explicit Host dispatcher may request DUE' });
27
+ });
28
+ const completionV1 = z.object({
29
+ schemaVersion: z.literal(1), tenantId: materialTenantIdSchema, requestRef: stableUriSchema, batchRef: stableUriSchema,
30
+ phase: z.enum(['RAW_REGISTERED', 'DERIVED_REGISTERED']), evidenceRef: stableUriSchema, contentHash: sha256Schema,
31
+ runId: idSchema, runtimeNodeId: idSchema, completedAt: isoDateTimeSchema,
32
+ }).strict();
33
+ export const tenantCollectionCompletionSchema = z.union([completionV1, completionV1.extend({ schemaVersion: z.literal(2), phase: z.literal('DERIVED_REGISTERED'), documentRef: tenantResourceRefSchema }).strict()]);
34
+ export function assertTenantCollectionCompletion(request, raw) {
35
+ const completion = tenantCollectionCompletionSchema.parse(raw), expected = tenantCapturedEvidenceIdentity({ tenantId: request.tenantId, batchRef: request.batchRef, sourceRevisionRef: request.plan.source.revisionRef });
36
+ const expectedPhase = request.plan.source.semantics.representation.format === 'RAW' ? 'RAW_REGISTERED' : 'DERIVED_REGISTERED';
37
+ if (completion.tenantId !== request.tenantId || completion.requestRef !== request.requestRef || completion.batchRef !== request.batchRef || completion.evidenceRef !== expected.ref || completion.phase !== expectedPhase)
38
+ throw new Error('TENANT_COLLECTION_COMPLETION_MISMATCH');
39
+ if (expectedPhase === 'DERIVED_REGISTERED') {
40
+ const document = completion.schemaVersion === 2 ? parseTenantResourceRef(completion.documentRef) : null;
41
+ if (!document || document.storageKey !== tenantStorageKey(request.tenantId) || document.resourceType !== 'source_document')
42
+ throw new Error('TENANT_COLLECTION_DERIVATION_UNPROVEN');
43
+ }
44
+ else if (completion.schemaVersion !== 1)
45
+ throw new Error('TENANT_COLLECTION_COMPLETION_MISMATCH');
46
+ return completion;
47
+ }
48
+ /** Admission retirement is not acquisition failure or business completion. */
49
+ export const TENANT_REQUEST_ADMISSION_STOP_CAPABILITY = 'TENANT_REQUEST_ADMISSION_STOP_V1';
50
+ export const tenantCollectionAdmissionStopSchema = z.object({ schemaVersion: z.literal(1), tenantId: materialTenantIdSchema, requestRef: stableUriSchema, requestHash: sha256Schema, reason: z.enum(['GRANT_REVOKED', 'DELEGATION_SUPERSEDED']), stoppedAt: isoDateTimeSchema }).strict();
51
+ /** Acquisition outcome only: a failed request is neither completed nor delegation-retired. */
52
+ export const tenantCollectionFailureSchema = z.object({
53
+ schemaVersion: z.literal(1), tenantId: materialTenantIdSchema, requestRef: stableUriSchema, requestHash: sha256Schema, batchRef: stableUriSchema,
54
+ runId: idSchema, runtimeNodeId: idSchema, receiptHash: sha256Schema, failedAt: isoDateTimeSchema, errorCode: z.literal('TENANT_SOURCE_HTTP_TERMINAL'),
55
+ }).strict();
56
+ export function isTenantCollectionTerminalFailure(request, receipt) {
57
+ return receipt.status === 'FAILED' && receipt.errorCode === 'TENANT_SOURCE_HTTP_TERMINAL' && receipt.workloadId === request.plan.workloadId && receipt.collectionBatchRef === request.batchRef && receipt.inputFingerprint === request.plan.revision && receipt.projectRef === undefined && receipt.projectIntentRef === undefined && receipt.evidenceCount === 0 && receipt.observationCount === 0 && Date.parse(receipt.finishedAt) >= Date.parse(receipt.startedAt) && request.plan.source.semantics.target.kind === 'URL' && request.plan.source.semantics.credential.type === 'PUBLIC';
58
+ }