@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.
- package/LICENSE +202 -0
- package/NOTICE +29 -0
- package/README.md +34 -2
- package/dist/agent-entry.d.ts +291 -0
- package/dist/agent-entry.js +153 -0
- package/dist/agent-guidance-error.d.ts +15 -0
- package/dist/agent-guidance-error.js +46 -0
- package/dist/auth.d.ts +124 -0
- package/dist/auth.js +165 -0
- package/dist/index.d.ts +290 -0
- package/dist/index.js +166 -0
- package/dist/internal/contracts/artifact.d.ts +120 -0
- package/dist/internal/contracts/artifact.js +103 -0
- package/dist/internal/contracts/collection-control.d.ts +160 -0
- package/dist/internal/contracts/collection-control.js +69 -0
- package/dist/internal/contracts/collection.d.ts +263 -0
- package/dist/internal/contracts/collection.js +174 -0
- package/dist/internal/contracts/common.d.ts +17 -0
- package/dist/internal/contracts/common.js +16 -0
- package/dist/internal/contracts/currentness.d.ts +477 -0
- package/dist/internal/contracts/currentness.js +221 -0
- package/dist/internal/contracts/event.d.ts +60 -0
- package/dist/internal/contracts/event.js +35 -0
- package/dist/internal/contracts/evidence.d.ts +202 -0
- package/dist/internal/contracts/evidence.js +171 -0
- package/dist/internal/contracts/index.d.ts +54 -0
- package/dist/internal/contracts/index.js +54 -0
- package/dist/internal/contracts/material-capability.d.ts +88 -0
- package/dist/internal/contracts/material-capability.js +8 -0
- package/dist/internal/contracts/material-carrier.d.ts +104 -0
- package/dist/internal/contracts/material-carrier.js +15 -0
- package/dist/internal/contracts/material-context.d.ts +28 -0
- package/dist/internal/contracts/material-context.js +9 -0
- package/dist/internal/contracts/material-read.d.ts +152 -0
- package/dist/internal/contracts/material-read.js +12 -0
- package/dist/internal/contracts/observation.d.ts +75 -0
- package/dist/internal/contracts/observation.js +39 -0
- package/dist/internal/contracts/persistence.d.ts +370 -0
- package/dist/internal/contracts/persistence.js +239 -0
- package/dist/internal/contracts/project-intent.d.ts +218 -0
- package/dist/internal/contracts/project-intent.js +121 -0
- package/dist/internal/contracts/projection.d.ts +380 -0
- package/dist/internal/contracts/projection.js +194 -0
- package/dist/internal/contracts/public-reference.d.ts +237 -0
- package/dist/internal/contracts/public-reference.js +87 -0
- package/dist/internal/contracts/reference-record.d.ts +124 -0
- package/dist/internal/contracts/reference-record.js +55 -0
- package/dist/internal/contracts/remote-file.d.ts +128 -0
- package/dist/internal/contracts/remote-file.js +159 -0
- package/dist/internal/contracts/resource-scope.d.ts +40 -0
- package/dist/internal/contracts/resource-scope.js +38 -0
- package/dist/internal/contracts/review-packet.d.ts +274 -0
- package/dist/internal/contracts/review-packet.js +61 -0
- package/dist/internal/contracts/review-plane.d.ts +90 -0
- package/dist/internal/contracts/review-plane.js +89 -0
- package/dist/internal/contracts/rich-document.d.ts +641 -0
- package/dist/internal/contracts/rich-document.js +184 -0
- package/dist/internal/contracts/runtime-compatibility.d.ts +22 -0
- package/dist/internal/contracts/runtime-compatibility.js +55 -0
- package/dist/internal/contracts/runtime.d.ts +59 -0
- package/dist/internal/contracts/runtime.js +68 -0
- package/dist/internal/contracts/scheduler.d.ts +348 -0
- package/dist/internal/contracts/scheduler.js +256 -0
- package/dist/internal/contracts/signal.d.ts +113 -0
- package/dist/internal/contracts/signal.js +77 -0
- package/dist/internal/contracts/source-governance.d.ts +375 -0
- package/dist/internal/contracts/source-governance.js +194 -0
- package/dist/internal/contracts/source.d.ts +62 -0
- package/dist/internal/contracts/source.js +32 -0
- package/dist/internal/contracts/tenant-budget.d.ts +59 -0
- package/dist/internal/contracts/tenant-budget.js +34 -0
- package/dist/internal/contracts/tenant-collection-request.d.ts +209 -0
- package/dist/internal/contracts/tenant-collection-request.js +58 -0
- package/dist/internal/contracts/tenant-collection.d.ts +199 -0
- package/dist/internal/contracts/tenant-collection.js +66 -0
- package/dist/internal/contracts/tenant-currentness.d.ts +117 -0
- package/dist/internal/contracts/tenant-currentness.js +26 -0
- package/dist/internal/contracts/tenant-management.d.ts +286 -0
- package/dist/internal/contracts/tenant-management.js +27 -0
- package/dist/internal/contracts/tenant-material-api.d.ts +584 -0
- package/dist/internal/contracts/tenant-material-api.js +46 -0
- package/dist/internal/contracts/tenant-material-json-schema.js +16 -0
- package/dist/internal/contracts/tenant-pdf-text.d.ts +27 -0
- package/dist/internal/contracts/tenant-pdf-text.js +13 -0
- package/dist/internal/contracts/tenant-project-control.d.ts +94 -0
- package/dist/internal/contracts/tenant-project-control.js +19 -0
- package/dist/internal/contracts/tenant-public-reference.d.ts +179 -0
- package/dist/internal/contracts/tenant-public-reference.js +26 -0
- package/dist/internal/contracts/tenant-resource-api.d.ts +738 -0
- package/dist/internal/contracts/tenant-resource-api.js +70 -0
- package/dist/internal/contracts/tenant-resource.d.ts +298 -0
- package/dist/internal/contracts/tenant-resource.js +118 -0
- package/dist/internal/contracts/tenant-rich-document.d.ts +317 -0
- package/dist/internal/contracts/tenant-rich-document.js +17 -0
- package/dist/internal/contracts/tenant-source-binding.d.ts +44 -0
- package/dist/internal/contracts/tenant-source-binding.js +33 -0
- package/dist/internal/contracts/tenant-source-bridge.d.ts +70 -0
- package/dist/internal/contracts/tenant-source-bridge.js +9 -0
- package/dist/internal/contracts/tenant-source-cutover.d.ts +226 -0
- package/dist/internal/contracts/tenant-source-cutover.js +26 -0
- package/dist/internal/contracts/tenant-source-document.d.ts +163 -0
- package/dist/internal/contracts/tenant-source-document.js +38 -0
- package/dist/internal/contracts/tenant-source-lease.d.ts +1 -0
- package/dist/internal/contracts/tenant-source-lease.js +5 -0
- package/dist/internal/contracts/tenant-source.d.ts +223 -0
- package/dist/internal/contracts/tenant-source.js +83 -0
- package/dist/internal/contracts/tenant-web-collection.d.ts +287 -0
- package/dist/internal/contracts/tenant-web-collection.js +118 -0
- package/dist/internal/contracts/tenant-web-content-plan.d.ts +86 -0
- package/dist/internal/contracts/tenant-web-content-plan.js +39 -0
- package/dist/internal/contracts/tenant-web-content-result.d.ts +63 -0
- package/dist/internal/contracts/tenant-web-content-result.js +15 -0
- package/dist/internal/contracts/tenant-web-content.d.ts +383 -0
- package/dist/internal/contracts/tenant-web-content.js +16 -0
- package/dist/internal/contracts/tenant-web-crawl.d.ts +310 -0
- package/dist/internal/contracts/tenant-web-crawl.js +55 -0
- package/dist/internal/contracts/tenant-web-dynamic.d.ts +698 -0
- package/dist/internal/contracts/tenant-web-dynamic.js +68 -0
- package/dist/internal/contracts/tenant-web-results.d.ts +66 -0
- package/dist/internal/contracts/tenant-web-results.js +41 -0
- package/dist/internal/contracts/tenant-web-workflow.d.ts +494 -0
- package/dist/internal/contracts/tenant-web-workflow.js +29 -0
- package/dist/internal/serving-contracts/agent-catalog.d.ts +70 -0
- package/dist/internal/serving-contracts/agent-catalog.js +56 -0
- package/dist/internal/serving-contracts/agent-entry.d.ts +13148 -0
- package/dist/internal/serving-contracts/agent-entry.js +57 -0
- package/dist/internal/serving-contracts/agent-guidance-shapes.d.ts +263 -0
- package/dist/internal/serving-contracts/agent-guidance-shapes.js +12 -0
- package/dist/internal/serving-contracts/agent-input-hints.d.ts +24 -0
- package/dist/internal/serving-contracts/agent-input-hints.js +104 -0
- package/dist/internal/serving-contracts/body-search.d.ts +231 -0
- package/dist/internal/serving-contracts/body-search.js +16 -0
- package/dist/internal/serving-contracts/consumer.d.ts +989 -0
- package/dist/internal/serving-contracts/consumer.js +45 -0
- package/dist/internal/serving-contracts/core.d.ts +333 -0
- package/dist/internal/serving-contracts/core.js +76 -0
- package/dist/internal/serving-contracts/http.d.ts +2874 -0
- package/dist/internal/serving-contracts/http.js +64 -0
- package/dist/internal/serving-contracts/index.d.ts +24 -0
- package/dist/internal/serving-contracts/index.js +25 -0
- package/dist/internal/serving-contracts/management.d.ts +424 -0
- package/dist/internal/serving-contracts/management.js +15 -0
- package/dist/internal/serving-contracts/material-capabilities.d.ts +508 -0
- package/dist/internal/serving-contracts/material-capabilities.js +14 -0
- package/dist/internal/serving-contracts/material-index-status.d.ts +55 -0
- package/dist/internal/serving-contracts/material-index-status.js +5 -0
- package/dist/internal/serving-contracts/mcp.d.ts +2218 -0
- package/dist/internal/serving-contracts/mcp.js +140 -0
- package/dist/internal/serving-contracts/tenant-governance.d.ts +236 -0
- package/dist/internal/serving-contracts/tenant-governance.js +13 -0
- package/dist/internal/serving-contracts/tenant-management.d.ts +6276 -0
- package/dist/internal/serving-contracts/tenant-management.js +89 -0
- package/dist/internal/serving-contracts/tenant-project.d.ts +7550 -0
- package/dist/internal/serving-contracts/tenant-project.js +39 -0
- package/dist/internal/serving-contracts/tenant-runtime.d.ts +9674 -0
- package/dist/internal/serving-contracts/tenant-runtime.js +37 -0
- package/dist/internal/serving-contracts/tenant-session.d.ts +87 -0
- package/dist/internal/serving-contracts/tenant-session.js +8 -0
- package/dist/internal/serving-contracts/tenant-web-content.d.ts +4606 -0
- package/dist/internal/serving-contracts/tenant-web-content.js +20 -0
- package/dist/internal/serving-contracts/tenant-web-crawl.d.ts +2958 -0
- package/dist/internal/serving-contracts/tenant-web-crawl.js +13 -0
- package/dist/internal/serving-contracts/tenant-web-dynamic.d.ts +3902 -0
- package/dist/internal/serving-contracts/tenant-web-dynamic.js +20 -0
- package/dist/internal/serving-contracts/tenant-web-workflow.d.ts +5750 -0
- package/dist/internal/serving-contracts/tenant-web-workflow.js +36 -0
- package/dist/internal/serving-contracts/tenant-web.d.ts +6418 -0
- package/dist/internal/serving-contracts/tenant-web.js +53 -0
- package/dist/internal/serving-contracts/tenant-workspace.d.ts +6451 -0
- package/dist/internal/serving-contracts/tenant-workspace.js +28 -0
- package/dist/internal/serving-contracts/workflow.d.ts +439 -0
- package/dist/internal/serving-contracts/workflow.js +37 -0
- package/dist/material-stream.d.ts +18 -0
- package/dist/material-stream.js +29 -0
- package/dist/oauth.d.ts +268 -0
- package/dist/oauth.js +539 -0
- package/dist/resource.d.ts +88 -0
- package/dist/resource.js +123 -0
- package/dist/session.d.ts +4 -0
- package/dist/session.js +3 -0
- package/dist/tenant-client.d.ts +169 -0
- package/dist/tenant-client.js +58 -0
- package/dist/tenant-management.d.ts +240 -0
- package/dist/tenant-management.js +149 -0
- package/dist/tenant-project.d.ts +57 -0
- package/dist/tenant-project.js +63 -0
- package/dist/tenant-runtime.d.ts +174 -0
- package/dist/tenant-runtime.js +17 -0
- package/dist/tenant-web-content.d.ts +44 -0
- package/dist/tenant-web-content.js +70 -0
- package/dist/tenant-web-crawl.d.ts +42 -0
- package/dist/tenant-web-crawl.js +39 -0
- package/dist/tenant-web-dynamic.d.ts +42 -0
- package/dist/tenant-web-dynamic.js +39 -0
- package/dist/tenant-web-workflow.d.ts +43 -0
- package/dist/tenant-web-workflow.js +63 -0
- package/dist/tenant-web.d.ts +42 -0
- package/dist/tenant-web.js +39 -0
- package/dist/tenant-workspace.d.ts +36 -0
- package/dist/tenant-workspace.js +21 -0
- package/dist/token-provider.d.ts +14 -0
- package/dist/token-provider.js +21 -0
- package/package.json +45 -3
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** Provider 16 的格式 2 资源读取合同;旧 Project/Tenant wire 保持其严格 schema。 */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { stableUriSchema, projectKeySchema, sha256Schema, accessClassificationSchema } from './common.js';
|
|
4
|
+
import { materialContextSchema } from './material-context.js';
|
|
5
|
+
import { materialAuthorityPolicySchema, resourceScopeSchema, parseTenantResourceRef, tenantStorageKey } from './resource-scope.js';
|
|
6
|
+
import { tenantResourceOriginSchema } from './tenant-resource.js';
|
|
7
|
+
import { rawRetrievalDecisionSchema, rawContentDescriptorSchema } from './material-read.js';
|
|
8
|
+
import { materialResourceTypeSchema } from './material-carrier.js';
|
|
9
|
+
import { tenantMaterialProviderSchema, tenantMaterialDataSchemas } from './tenant-material-api.js';
|
|
10
|
+
export const resourceOriginSchema = z.union([tenantResourceOriginSchema, z.object({ type: z.literal('LEGACY_PROJECT'), projectKey: projectKeySchema, projectRef: stableUriSchema }).strict()]);
|
|
11
|
+
export const resourceDirectoryItemSchema = z.object({
|
|
12
|
+
ref: stableUriSchema, ownerTenantId: resourceScopeSchema.options[0].shape.tenantId, resourceType: materialResourceTypeSchema,
|
|
13
|
+
origin: resourceOriginSchema, identityHash: sha256Schema, identityKind: z.enum(['CAS_BYTES', 'REFERENCE_RECORD_DIGEST']),
|
|
14
|
+
kind: z.string().min(1).max(128), classification: accessClassificationSchema, mediaType: z.string().min(1).max(256),
|
|
15
|
+
title: z.string().max(512), summary: z.string().max(1024), decision: rawRetrievalDecisionSchema,
|
|
16
|
+
}).strict().superRefine((value, ctx) => {
|
|
17
|
+
if (value.origin.type === 'LEGACY_PROJECT') {
|
|
18
|
+
if (value.origin.projectRef !== `knowledge-project://${value.origin.projectKey}/tenant/${encodeURIComponent(value.ownerTenantId)}` || value.identityKind !== (value.resourceType === 'reference' ? 'REFERENCE_RECORD_DIGEST' : 'CAS_BYTES'))
|
|
19
|
+
ctx.addIssue({ code: 'custom', path: ['origin'], message: 'Legacy origin/identity mismatch' });
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
const ref = parseTenantResourceRef(value.ref), key = tenantStorageKey(value.ownerTenantId);
|
|
23
|
+
if (!ref || ref.storageKey !== key || ref.resourceType !== value.resourceType || value.identityKind !== 'CAS_BYTES')
|
|
24
|
+
ctx.addIssue({ code: 'custom', path: ['ref'], message: 'Native owner/resource identity mismatch' });
|
|
25
|
+
if (value.origin.type === 'TENANT_AUTHOR' && value.origin.actor.tenantId !== value.ownerTenantId)
|
|
26
|
+
ctx.addIssue({ code: 'custom', path: ['origin'], message: 'Author Tenant mismatch' });
|
|
27
|
+
if (value.origin.type === 'TENANT_SOURCE') {
|
|
28
|
+
const prefix = `tenant-source://${key}/${encodeURIComponent(value.origin.sourceId)}`;
|
|
29
|
+
if (value.origin.sourceRef !== prefix || !value.origin.sourceRevisionRef.startsWith(prefix + '/v/') || !/^[a-f0-9]{64}$/.test(value.origin.sourceRevisionRef.slice(prefix.length + 3)))
|
|
30
|
+
ctx.addIssue({ code: 'custom', path: ['origin'], message: 'Source Tenant/revision mismatch' });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const context = { projectRef: stableUriSchema.optional() }, position = z.string().min(1).max(4096).optional(), limit = z.number().int().min(1).max(100).optional();
|
|
35
|
+
const filters = { resourceType: materialResourceTypeSchema.optional(), sourceProjectKey: projectKeySchema.optional(), refPrefix: z.string().max(256).regex(/^[a-z][a-z0-9+.-]*:\/\/[!-~]*$/i).optional() };
|
|
36
|
+
const ref = z.object({ ...context, ref: stableUriSchema }).strict();
|
|
37
|
+
export const resourceToolSchemas = {
|
|
38
|
+
knowledge_resource_list: z.object({ ...context, after: position, limit, ...filters }).strict(),
|
|
39
|
+
knowledge_resource_describe: ref, knowledge_resource_read: ref, knowledge_resource_capabilities: ref,
|
|
40
|
+
knowledge_resource_search: z.object({ ...context, after: position, limit, ...filters, query: z.string().min(2).max(200) }).strict(),
|
|
41
|
+
knowledge_resource_window: z.object(context).strict(),
|
|
42
|
+
knowledge_resource_changes: z.object({ ...context, after: position, limit }).strict(),
|
|
43
|
+
knowledge_resource_counts: z.object({ ...context, after: position, limit }).strict(),
|
|
44
|
+
knowledge_resource_index_status: z.object(context).strict(),
|
|
45
|
+
knowledge_resource_media: ref.extend({ afterOrdinal: z.number().int().min(-1).safe().optional(), limit, documentRef: stableUriSchema.optional() }).strict(),
|
|
46
|
+
};
|
|
47
|
+
const count = z.number().int().nonnegative().safe(), cursor = z.string().max(4096).nullable(), item = resourceDirectoryItemSchema.nullable(), items = z.array(resourceDirectoryItemSchema).max(100);
|
|
48
|
+
const representation = z.object({ state: z.enum(['READY', 'UNSUPPORTED', 'MISSING', 'INTEGRITY_MISMATCH', 'DENIED']), format: z.enum(['JSON', 'BYTES']), transfer: z.enum(['BUFFERED_JSON', 'VERIFIED_STREAM', 'UNSUPPORTED']), contentHash: sha256Schema.nullable(), mediaType: z.string().min(1).max(256), byteLength: count.nullable(), methods: z.array(z.enum(['GET', 'HEAD', 'POST'])).max(3), range: z.enum(['SINGLE', 'NONE']), verification: z.literal('ON_READ'), verificationChunkBytes: count.nullable() }).strict();
|
|
49
|
+
export const resourceDataSchemas = {
|
|
50
|
+
knowledge_resource_list: z.object({ items, nextAfter: cursor }).strict(),
|
|
51
|
+
knowledge_resource_describe: z.object({ item, byteLength: count.nullable(), downloadUrl: z.string().max(8192).nullable() }).strict(),
|
|
52
|
+
knowledge_resource_read: z.object({ item, byteLength: count.nullable(), decision: rawRetrievalDecisionSchema, descriptor: rawContentDescriptorSchema.nullable(), delivery: z.enum(['INLINE_BASE64', 'DOWNLOAD', 'UNAVAILABLE']), contentBase64: z.string().max(43692).nullable(), downloadUrl: z.string().max(8192).nullable(), verification: z.enum(['VERIFIED', 'NOT_VERIFIED']) }).strict(),
|
|
53
|
+
knowledge_resource_capabilities: z.object({ item, materialAccess: rawRetrievalDecisionSchema, representation: representation.nullable() }).strict(),
|
|
54
|
+
knowledge_resource_search: z.object({ items, nextAfter: cursor, coverage: z.literal('INDEXED_DESCRIPTIONS_ONLY') }).strict(),
|
|
55
|
+
knowledge_resource_window: z.object({ headSeq: count, retainedThroughSeq: count, headCursor: z.string().max(4096), retentionCursor: z.string().max(4096), epoch: z.literal('TENANT_RESOURCE_V1') }).strict(),
|
|
56
|
+
knowledge_resource_changes: z.object({ items: z.array(z.object({ seq: count, eventType: z.string().min(1).max(128), artifactRef: stableUriSchema.nullable(), contentHash: sha256Schema.nullable(), routeId: z.string().max(128).nullable(), createdAt: z.string().datetime({ offset: true }) }).strict()).max(100), nextAfter: cursor }).strict(),
|
|
57
|
+
knowledge_resource_counts: z.object({ owned: count, granted: count, available: count, resourceTypes: z.array(z.object({ resourceType: materialResourceTypeSchema, total: count }).strict()).max(100), nextAfter: cursor, coverage: z.literal('CURRENT_AUTHORIZED_DIRECTORY') }).strict(),
|
|
58
|
+
knowledge_resource_index_status: z.object({ registered: count, indexed: count, unindexed: count, state: z.enum(['SYNCED_AS_OF_LAST_OBSERVATION', 'PARTIAL_BACKFILL']), canonicalInventory: z.literal('NOT_SCANNED'), coverage: z.literal('CURRENT_AUTHORIZED_DIRECTORY') }).strict(),
|
|
59
|
+
knowledge_resource_media: tenantMaterialDataSchemas.knowledge_material_media,
|
|
60
|
+
};
|
|
61
|
+
export const resourceEnvelopeSchema = z.object({ schemaVersion: z.literal(2), context: materialContextSchema, policy: materialAuthorityPolicySchema, data: z.unknown() }).strict().superRefine((value, ctx) => {
|
|
62
|
+
const c = value.context, expected = c.type === 'TENANT' ? `knowledge-tenant://tenant/${encodeURIComponent(c.tenantId)}` : `knowledge-project://${c.projectKey}/tenant/${encodeURIComponent(c.tenantId)}`;
|
|
63
|
+
if ((value.policy === 'TENANT_NATIVE') !== (c.type === 'TENANT') || (c.type === 'TENANT' ? c.tenantRef : c.projectRef) !== expected)
|
|
64
|
+
ctx.addIssue({ code: 'custom', path: ['context'], message: 'Context/policy identity mismatch' });
|
|
65
|
+
});
|
|
66
|
+
export const resourceToolInputSchemas = Object.fromEntries(Object.entries(resourceToolSchemas).map(([name, schema]) => [name, z.toJSONSchema(schema, { target: 'draft-07' })]));
|
|
67
|
+
export const resourceToolOutputSchemas = Object.fromEntries(Object.entries(resourceDataSchemas).map(([name, data]) => [name, z.toJSONSchema(resourceEnvelopeSchema.safeExtend({ data }), { target: 'draft-07' })]));
|
|
68
|
+
export const tenantResourceProviderSchema = tenantMaterialProviderSchema.extend({ schemaVersion: z.literal(16), materialSchemaVersion: z.literal(2), capabilities: z.tuple([z.literal('TENANT_RESOURCE_V1'), z.literal('TENANT_AUTHORITY_V1')]), legacyProviderEndpoint: stableUriSchema });
|
|
69
|
+
export const resourceHttpContractSchema = z.object({ schemaVersion: z.literal(2), context: materialContextSchema, policy: materialAuthorityPolicySchema, capabilities: z.tuple([z.literal('TENANT_RESOURCE_V1'), z.literal('TENANT_AUTHORITY_V1')]), callEndpoint: z.string().min(1).max(8192), fileEndpoint: z.string().min(1).max(8192), tools: z.array(z.string()).max(32), inlineMaxBytes: z.literal(32768), readBufferMaxBytes: z.literal(16777216), fileMethods: z.tuple([z.literal('GET'), z.literal('HEAD'), z.literal('POST')]), verificationChunkBytes: z.literal(65536), requestMaxBytes: z.literal(131072), resultMaxBytes: z.literal(524288) }).strict().superRefine((value, ctx) => { if (!resourceEnvelopeSchema.safeParse({ schemaVersion: 2, context: value.context, policy: value.policy, data: null }).success)
|
|
70
|
+
ctx.addIssue({ code: 'custom', path: ['context'], message: 'Context/policy identity mismatch' }); });
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/** 租户原生不可变信封保留类型事实;不以项目占位或审核状态判断原文读取。 */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const tenantResourceFactsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
|
+
type: z.ZodLiteral<"ARTIFACT">;
|
|
5
|
+
metadata: z.ZodObject<{
|
|
6
|
+
artifactId: z.ZodString;
|
|
7
|
+
kind: z.ZodEnum<{
|
|
8
|
+
SIGNAL_GENERATION: "SIGNAL_GENERATION";
|
|
9
|
+
RESEARCH: "RESEARCH";
|
|
10
|
+
REVIEW: "REVIEW";
|
|
11
|
+
KNOWLEDGE: "KNOWLEDGE";
|
|
12
|
+
INSIGHT: "INSIGHT";
|
|
13
|
+
}>;
|
|
14
|
+
status: z.ZodEnum<{
|
|
15
|
+
GENERATED: "GENERATED";
|
|
16
|
+
DRAFT: "DRAFT";
|
|
17
|
+
READY_FOR_REVIEW: "READY_FOR_REVIEW";
|
|
18
|
+
REWORK_REQUIRED: "REWORK_REQUIRED";
|
|
19
|
+
APPROVED: "APPROVED";
|
|
20
|
+
REJECTED: "REJECTED";
|
|
21
|
+
SUPERSEDED: "SUPERSEDED";
|
|
22
|
+
}>;
|
|
23
|
+
version: z.ZodNumber;
|
|
24
|
+
title: z.ZodOptional<z.ZodString>;
|
|
25
|
+
observedAt: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
26
|
+
validUntil: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
27
|
+
evidenceRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
28
|
+
relatedRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
29
|
+
supersedesRef: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
30
|
+
sourceMaterialRefs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
33
|
+
type: z.ZodLiteral<"EVIDENCE">;
|
|
34
|
+
metadata: z.ZodObject<{
|
|
35
|
+
observedAt: z.ZodISODateTime;
|
|
36
|
+
sourceIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
37
|
+
runtimeNodeId: z.ZodString;
|
|
38
|
+
request: z.ZodOptional<z.ZodObject<{
|
|
39
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
40
|
+
method: z.ZodLiteral<"POST">;
|
|
41
|
+
bodyContentHash: z.ZodString;
|
|
42
|
+
bodyMediaType: z.ZodLiteral<"application/x-www-form-urlencoded">;
|
|
43
|
+
bodyByteLength: z.ZodNumber;
|
|
44
|
+
}, z.core.$strict>>;
|
|
45
|
+
sourceId: z.ZodString;
|
|
46
|
+
sourceRevisionRef: z.ZodOptional<z.ZodString>;
|
|
47
|
+
collectionBatchRef: z.ZodOptional<z.ZodString>;
|
|
48
|
+
reviewHints: z.ZodOptional<z.ZodObject<{
|
|
49
|
+
pageRanges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
50
|
+
startPage: z.ZodNumber;
|
|
51
|
+
endPage: z.ZodNumber;
|
|
52
|
+
}, z.core.$strict>>>;
|
|
53
|
+
timeRanges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
54
|
+
startMs: z.ZodNumber;
|
|
55
|
+
endMs: z.ZodNumber;
|
|
56
|
+
}, z.core.$strict>>>;
|
|
57
|
+
frameTimestampsMs: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
58
|
+
}, z.core.$strict>>;
|
|
59
|
+
evidenceId: z.ZodString;
|
|
60
|
+
collector: z.ZodObject<{
|
|
61
|
+
collectorId: z.ZodString;
|
|
62
|
+
version: z.ZodString;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
canonicalUri: z.ZodOptional<z.ZodString>;
|
|
65
|
+
sourceSetRef: z.ZodOptional<z.ZodString>;
|
|
66
|
+
sourceItemId: z.ZodOptional<z.ZodString>;
|
|
67
|
+
collectionTaskId: z.ZodOptional<z.ZodString>;
|
|
68
|
+
parentEvidenceRef: z.ZodOptional<z.ZodString>;
|
|
69
|
+
}, z.core.$strict>;
|
|
70
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
71
|
+
type: z.ZodLiteral<"REFERENCE">;
|
|
72
|
+
metadata: z.ZodObject<{
|
|
73
|
+
version: z.ZodNumber;
|
|
74
|
+
supersedesRef: z.ZodNullable<z.ZodString>;
|
|
75
|
+
effectiveFrom: z.ZodNullable<z.ZodISODateTime>;
|
|
76
|
+
effectiveUntil: z.ZodNullable<z.ZodISODateTime>;
|
|
77
|
+
authority: z.ZodString;
|
|
78
|
+
currentness: z.ZodObject<{
|
|
79
|
+
state: z.ZodEnum<{
|
|
80
|
+
DUE: "DUE";
|
|
81
|
+
CURRENT: "CURRENT";
|
|
82
|
+
STALE: "STALE";
|
|
83
|
+
UNAVAILABLE: "UNAVAILABLE";
|
|
84
|
+
NOT_COVERED: "NOT_COVERED";
|
|
85
|
+
}>;
|
|
86
|
+
action: z.ZodEnum<{
|
|
87
|
+
ALLOW: "ALLOW";
|
|
88
|
+
REVIEW_REQUIRED: "REVIEW_REQUIRED";
|
|
89
|
+
DENY: "DENY";
|
|
90
|
+
}>;
|
|
91
|
+
assessedAt: z.ZodISODateTime;
|
|
92
|
+
validUntil: z.ZodNullable<z.ZodISODateTime>;
|
|
93
|
+
}, z.core.$strict>;
|
|
94
|
+
jurisdiction: z.ZodNullable<z.ZodString>;
|
|
95
|
+
sourceRefs: z.ZodArray<z.ZodString>;
|
|
96
|
+
corpusKey: z.ZodString;
|
|
97
|
+
recordKey: z.ZodString;
|
|
98
|
+
recordType: z.ZodString;
|
|
99
|
+
digest: z.ZodString;
|
|
100
|
+
selectors: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
101
|
+
}, z.core.$strict>;
|
|
102
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
103
|
+
type: z.ZodLiteral<"CARRIER">;
|
|
104
|
+
metadata: z.ZodObject<{
|
|
105
|
+
kind: z.ZodString;
|
|
106
|
+
title: z.ZodString;
|
|
107
|
+
summary: z.ZodString;
|
|
108
|
+
sourceRefs: z.ZodArray<z.ZodString>;
|
|
109
|
+
observedAt: z.ZodISODateTime;
|
|
110
|
+
}, z.core.$strict>;
|
|
111
|
+
}, z.core.$strict>], "type">;
|
|
112
|
+
export declare const tenantResourceOriginSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
113
|
+
type: z.ZodLiteral<"TENANT_AUTHOR">;
|
|
114
|
+
actor: z.ZodObject<{
|
|
115
|
+
tenantId: z.ZodString;
|
|
116
|
+
userId: z.ZodString;
|
|
117
|
+
agentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
118
|
+
}, z.core.$strict>;
|
|
119
|
+
submittedAt: z.ZodISODateTime;
|
|
120
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
121
|
+
type: z.ZodLiteral<"TENANT_SOURCE">;
|
|
122
|
+
sourceId: z.ZodString;
|
|
123
|
+
sourceRef: z.ZodString;
|
|
124
|
+
sourceRevisionRef: z.ZodString;
|
|
125
|
+
collector: z.ZodObject<{
|
|
126
|
+
collectorId: z.ZodString;
|
|
127
|
+
version: z.ZodString;
|
|
128
|
+
}, z.core.$strict>;
|
|
129
|
+
runtimeNodeId: z.ZodString;
|
|
130
|
+
observedAt: z.ZodISODateTime;
|
|
131
|
+
}, z.core.$strict>], "type">;
|
|
132
|
+
export declare const tenantResourceManifestSchema: z.ZodObject<{
|
|
133
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
134
|
+
ownerTenantId: z.ZodString;
|
|
135
|
+
resourceId: z.ZodString;
|
|
136
|
+
resourceType: z.ZodString;
|
|
137
|
+
version: z.ZodNumber;
|
|
138
|
+
ref: z.ZodString;
|
|
139
|
+
identityRef: z.ZodString;
|
|
140
|
+
contentHash: z.ZodString;
|
|
141
|
+
byteLength: z.ZodNumber;
|
|
142
|
+
mediaType: z.ZodString;
|
|
143
|
+
access: z.ZodEnum<{
|
|
144
|
+
PUBLIC: "PUBLIC";
|
|
145
|
+
PUBLIC_METADATA: "PUBLIC_METADATA";
|
|
146
|
+
TENANT: "TENANT";
|
|
147
|
+
INTERNAL: "INTERNAL";
|
|
148
|
+
FDE_INTERNAL: "FDE_INTERNAL";
|
|
149
|
+
ACCESS_CONTROLLED: "ACCESS_CONTROLLED";
|
|
150
|
+
UNKNOWN: "UNKNOWN";
|
|
151
|
+
}>;
|
|
152
|
+
createdAt: z.ZodISODateTime;
|
|
153
|
+
origin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
154
|
+
type: z.ZodLiteral<"TENANT_AUTHOR">;
|
|
155
|
+
actor: z.ZodObject<{
|
|
156
|
+
tenantId: z.ZodString;
|
|
157
|
+
userId: z.ZodString;
|
|
158
|
+
agentId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
159
|
+
}, z.core.$strict>;
|
|
160
|
+
submittedAt: z.ZodISODateTime;
|
|
161
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
162
|
+
type: z.ZodLiteral<"TENANT_SOURCE">;
|
|
163
|
+
sourceId: z.ZodString;
|
|
164
|
+
sourceRef: z.ZodString;
|
|
165
|
+
sourceRevisionRef: z.ZodString;
|
|
166
|
+
collector: z.ZodObject<{
|
|
167
|
+
collectorId: z.ZodString;
|
|
168
|
+
version: z.ZodString;
|
|
169
|
+
}, z.core.$strict>;
|
|
170
|
+
runtimeNodeId: z.ZodString;
|
|
171
|
+
observedAt: z.ZodISODateTime;
|
|
172
|
+
}, z.core.$strict>], "type">;
|
|
173
|
+
facts: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
174
|
+
type: z.ZodLiteral<"ARTIFACT">;
|
|
175
|
+
metadata: z.ZodObject<{
|
|
176
|
+
artifactId: z.ZodString;
|
|
177
|
+
kind: z.ZodEnum<{
|
|
178
|
+
SIGNAL_GENERATION: "SIGNAL_GENERATION";
|
|
179
|
+
RESEARCH: "RESEARCH";
|
|
180
|
+
REVIEW: "REVIEW";
|
|
181
|
+
KNOWLEDGE: "KNOWLEDGE";
|
|
182
|
+
INSIGHT: "INSIGHT";
|
|
183
|
+
}>;
|
|
184
|
+
status: z.ZodEnum<{
|
|
185
|
+
GENERATED: "GENERATED";
|
|
186
|
+
DRAFT: "DRAFT";
|
|
187
|
+
READY_FOR_REVIEW: "READY_FOR_REVIEW";
|
|
188
|
+
REWORK_REQUIRED: "REWORK_REQUIRED";
|
|
189
|
+
APPROVED: "APPROVED";
|
|
190
|
+
REJECTED: "REJECTED";
|
|
191
|
+
SUPERSEDED: "SUPERSEDED";
|
|
192
|
+
}>;
|
|
193
|
+
version: z.ZodNumber;
|
|
194
|
+
title: z.ZodOptional<z.ZodString>;
|
|
195
|
+
observedAt: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
196
|
+
validUntil: z.ZodDefault<z.ZodNullable<z.ZodISODateTime>>;
|
|
197
|
+
evidenceRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
198
|
+
relatedRefs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
199
|
+
supersedesRef: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
200
|
+
sourceMaterialRefs: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
201
|
+
}, z.core.$strict>;
|
|
202
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
203
|
+
type: z.ZodLiteral<"EVIDENCE">;
|
|
204
|
+
metadata: z.ZodObject<{
|
|
205
|
+
observedAt: z.ZodISODateTime;
|
|
206
|
+
sourceIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
207
|
+
runtimeNodeId: z.ZodString;
|
|
208
|
+
request: z.ZodOptional<z.ZodObject<{
|
|
209
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
210
|
+
method: z.ZodLiteral<"POST">;
|
|
211
|
+
bodyContentHash: z.ZodString;
|
|
212
|
+
bodyMediaType: z.ZodLiteral<"application/x-www-form-urlencoded">;
|
|
213
|
+
bodyByteLength: z.ZodNumber;
|
|
214
|
+
}, z.core.$strict>>;
|
|
215
|
+
sourceId: z.ZodString;
|
|
216
|
+
sourceRevisionRef: z.ZodOptional<z.ZodString>;
|
|
217
|
+
collectionBatchRef: z.ZodOptional<z.ZodString>;
|
|
218
|
+
reviewHints: z.ZodOptional<z.ZodObject<{
|
|
219
|
+
pageRanges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
220
|
+
startPage: z.ZodNumber;
|
|
221
|
+
endPage: z.ZodNumber;
|
|
222
|
+
}, z.core.$strict>>>;
|
|
223
|
+
timeRanges: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
224
|
+
startMs: z.ZodNumber;
|
|
225
|
+
endMs: z.ZodNumber;
|
|
226
|
+
}, z.core.$strict>>>;
|
|
227
|
+
frameTimestampsMs: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
|
|
228
|
+
}, z.core.$strict>>;
|
|
229
|
+
evidenceId: z.ZodString;
|
|
230
|
+
collector: z.ZodObject<{
|
|
231
|
+
collectorId: z.ZodString;
|
|
232
|
+
version: z.ZodString;
|
|
233
|
+
}, z.core.$strict>;
|
|
234
|
+
canonicalUri: z.ZodOptional<z.ZodString>;
|
|
235
|
+
sourceSetRef: z.ZodOptional<z.ZodString>;
|
|
236
|
+
sourceItemId: z.ZodOptional<z.ZodString>;
|
|
237
|
+
collectionTaskId: z.ZodOptional<z.ZodString>;
|
|
238
|
+
parentEvidenceRef: z.ZodOptional<z.ZodString>;
|
|
239
|
+
}, z.core.$strict>;
|
|
240
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
241
|
+
type: z.ZodLiteral<"REFERENCE">;
|
|
242
|
+
metadata: z.ZodObject<{
|
|
243
|
+
version: z.ZodNumber;
|
|
244
|
+
supersedesRef: z.ZodNullable<z.ZodString>;
|
|
245
|
+
effectiveFrom: z.ZodNullable<z.ZodISODateTime>;
|
|
246
|
+
effectiveUntil: z.ZodNullable<z.ZodISODateTime>;
|
|
247
|
+
authority: z.ZodString;
|
|
248
|
+
currentness: z.ZodObject<{
|
|
249
|
+
state: z.ZodEnum<{
|
|
250
|
+
DUE: "DUE";
|
|
251
|
+
CURRENT: "CURRENT";
|
|
252
|
+
STALE: "STALE";
|
|
253
|
+
UNAVAILABLE: "UNAVAILABLE";
|
|
254
|
+
NOT_COVERED: "NOT_COVERED";
|
|
255
|
+
}>;
|
|
256
|
+
action: z.ZodEnum<{
|
|
257
|
+
ALLOW: "ALLOW";
|
|
258
|
+
REVIEW_REQUIRED: "REVIEW_REQUIRED";
|
|
259
|
+
DENY: "DENY";
|
|
260
|
+
}>;
|
|
261
|
+
assessedAt: z.ZodISODateTime;
|
|
262
|
+
validUntil: z.ZodNullable<z.ZodISODateTime>;
|
|
263
|
+
}, z.core.$strict>;
|
|
264
|
+
jurisdiction: z.ZodNullable<z.ZodString>;
|
|
265
|
+
sourceRefs: z.ZodArray<z.ZodString>;
|
|
266
|
+
corpusKey: z.ZodString;
|
|
267
|
+
recordKey: z.ZodString;
|
|
268
|
+
recordType: z.ZodString;
|
|
269
|
+
digest: z.ZodString;
|
|
270
|
+
selectors: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
271
|
+
}, z.core.$strict>;
|
|
272
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
273
|
+
type: z.ZodLiteral<"CARRIER">;
|
|
274
|
+
metadata: z.ZodObject<{
|
|
275
|
+
kind: z.ZodString;
|
|
276
|
+
title: z.ZodString;
|
|
277
|
+
summary: z.ZodString;
|
|
278
|
+
sourceRefs: z.ZodArray<z.ZodString>;
|
|
279
|
+
observedAt: z.ZodISODateTime;
|
|
280
|
+
}, z.core.$strict>;
|
|
281
|
+
}, z.core.$strict>], "type">;
|
|
282
|
+
}, z.core.$strict>;
|
|
283
|
+
export type TenantResourceManifest = z.infer<typeof tenantResourceManifestSchema>;
|
|
284
|
+
export type TenantResourceFacts = z.infer<typeof tenantResourceFactsSchema>;
|
|
285
|
+
export type TenantResourceOrigin = z.infer<typeof tenantResourceOriginSchema>;
|
|
286
|
+
export declare const tenantProjectionIntentSchema: z.ZodObject<{
|
|
287
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
288
|
+
ref: z.ZodString;
|
|
289
|
+
manifestRevision: z.ZodString;
|
|
290
|
+
createdAt: z.ZodISODateTime;
|
|
291
|
+
}, z.core.$strict>;
|
|
292
|
+
export type TenantProjectionIntent = z.infer<typeof tenantProjectionIntentSchema>;
|
|
293
|
+
/** 存储、Catalog 与 Identity 共用同一 manifest 身份;undefined 等价于 JSON 省略。 */
|
|
294
|
+
export declare function tenantResourceManifestRevision(raw: TenantResourceManifest): string;
|
|
295
|
+
/** Reference 语义摘要与 CAS 字节摘要分开;只正规化集合字段,不改原始 payload 字节。 */
|
|
296
|
+
export declare function tenantReferenceRecordDigest(tenantId: string, access: unknown, metadata: Extract<TenantResourceFacts, {
|
|
297
|
+
type: 'REFERENCE';
|
|
298
|
+
}>['metadata'], payload: unknown): string;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/** 租户原生不可变信封保留类型事实;不以项目占位或审核状态判断原文读取。 */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { accessClassificationSchema, idSchema, isoDateTimeSchema, sha256Schema, stableUriSchema } from './common.js';
|
|
5
|
+
import { artifactManifestSchema } from './artifact.js';
|
|
6
|
+
import { evidenceRefSchema } from './evidence.js';
|
|
7
|
+
import { referenceCorpusSummarySchema } from './reference-record.js';
|
|
8
|
+
import { knowledgeActorContextSchema } from './project-intent.js';
|
|
9
|
+
import { materialResourceTypeSchema } from './material-carrier.js';
|
|
10
|
+
import { materialTenantIdSchema } from './material-context.js';
|
|
11
|
+
import { tenantResourceIdentitySchema, tenantResourceRefs, tenantStorageKey, tenantResourceRefSchema } from './resource-scope.js';
|
|
12
|
+
// 取原有字段验证器,旧 schema/DTO 原样保留;新信封的身份关系在下方集中验证。
|
|
13
|
+
const artifactFacts = z.object({ ...artifactManifestSchema.shape }).omit({ schemaVersion: true, projectKey: true, projectRef: true, ref: true, identityRef: true, contentHash: true, mediaType: true, byteLength: true, access: true, createdAt: true }).extend({ sourceMaterialRefs: z.array(stableUriSchema).max(256).optional() }).strict();
|
|
14
|
+
const evidenceFacts = z.object({ ...evidenceRefSchema.shape }).omit({ schemaVersion: true, projectKey: true, projectRef: true, recoveryProvenance: true, contentHash: true, mediaType: true, byteLength: true, access: true }).extend({ parentEvidenceRef: tenantResourceRefSchema.optional() }).strict();
|
|
15
|
+
const referenceFacts = z.object({ ...referenceCorpusSummarySchema.shape }).omit({ schemaVersion: true, projectKey: true, projectRef: true, recordRef: true, access: true }).strict();
|
|
16
|
+
export const tenantResourceFactsSchema = z.discriminatedUnion('type', [
|
|
17
|
+
z.object({ type: z.literal('ARTIFACT'), metadata: artifactFacts }).strict(),
|
|
18
|
+
z.object({ type: z.literal('EVIDENCE'), metadata: evidenceFacts }).strict(),
|
|
19
|
+
z.object({ type: z.literal('REFERENCE'), metadata: referenceFacts }).strict(),
|
|
20
|
+
z.object({ type: z.literal('CARRIER'), metadata: z.object({ kind: z.string().min(1).max(128), title: z.string().max(512), summary: z.string().max(1024), sourceRefs: z.array(stableUriSchema).min(1).max(128), observedAt: isoDateTimeSchema }).strict() }).strict(),
|
|
21
|
+
]);
|
|
22
|
+
export const tenantResourceOriginSchema = z.discriminatedUnion('type', [
|
|
23
|
+
z.object({ type: z.literal('TENANT_AUTHOR'), actor: knowledgeActorContextSchema, submittedAt: isoDateTimeSchema }).strict(),
|
|
24
|
+
z.object({ type: z.literal('TENANT_SOURCE'), sourceId: idSchema, sourceRef: stableUriSchema, sourceRevisionRef: stableUriSchema, collector: evidenceRefSchema.shape.collector, runtimeNodeId: idSchema, observedAt: isoDateTimeSchema }).strict(),
|
|
25
|
+
]);
|
|
26
|
+
export const tenantResourceManifestSchema = z.object({
|
|
27
|
+
schemaVersion: z.literal(2), ownerTenantId: materialTenantIdSchema,
|
|
28
|
+
resourceId: tenantResourceIdentitySchema.shape.resourceId, resourceType: materialResourceTypeSchema,
|
|
29
|
+
version: tenantResourceIdentitySchema.shape.version, ref: stableUriSchema, identityRef: stableUriSchema,
|
|
30
|
+
contentHash: sha256Schema, byteLength: z.number().int().nonnegative().safe(), mediaType: z.string().trim().min(1).max(256),
|
|
31
|
+
access: accessClassificationSchema, createdAt: isoDateTimeSchema,
|
|
32
|
+
origin: tenantResourceOriginSchema, facts: tenantResourceFactsSchema,
|
|
33
|
+
}).strict().superRefine((value, ctx) => {
|
|
34
|
+
const expected = tenantResourceRefs({ tenantId: value.ownerTenantId, resourceType: value.resourceType, resourceId: value.resourceId, version: value.version });
|
|
35
|
+
for (const name of ['ref', 'identityRef'])
|
|
36
|
+
if (value[name] !== expected[name])
|
|
37
|
+
ctx.addIssue({ code: 'custom', path: [name], message: 'Tenant resource identity mismatch' });
|
|
38
|
+
const kind = value.facts.type.toLowerCase();
|
|
39
|
+
if (value.facts.type === 'CARRIER' ? ['artifact', 'evidence', 'reference', 'media'].includes(value.resourceType) : value.resourceType !== kind)
|
|
40
|
+
ctx.addIssue({ code: 'custom', path: ['resourceType'], message: 'Resource type must retain its factual carrier' });
|
|
41
|
+
if (value.origin.type === 'TENANT_AUTHOR') {
|
|
42
|
+
if (value.origin.actor.tenantId !== value.ownerTenantId)
|
|
43
|
+
ctx.addIssue({ code: 'custom', path: ['origin'], message: 'Author must belong to the resource Tenant' });
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const prefix = `tenant-source://${tenantStorageKey(value.ownerTenantId)}/${encodeURIComponent(value.origin.sourceId)}`;
|
|
47
|
+
if (value.origin.sourceRef !== prefix || !value.origin.sourceRevisionRef.startsWith(prefix + '/v/') || !/^[a-f0-9]{64}$/.test(value.origin.sourceRevisionRef.slice(prefix.length + 3)))
|
|
48
|
+
ctx.addIssue({ code: 'custom', path: ['origin'], message: 'Source must retain exact Tenant/source/revision identity' });
|
|
49
|
+
}
|
|
50
|
+
if (value.facts.type === 'ARTIFACT') {
|
|
51
|
+
const m = value.facts.metadata;
|
|
52
|
+
if (m.artifactId !== value.resourceId || m.version !== value.version)
|
|
53
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Artifact identity/version mismatch' });
|
|
54
|
+
if (m.validUntil && m.observedAt && Date.parse(m.validUntil) < Date.parse(m.observedAt))
|
|
55
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Invalid Artifact validity interval' });
|
|
56
|
+
if (m.kind === 'SIGNAL_GENERATION' && (m.version !== 1 || m.status !== 'GENERATED') || ['KNOWLEDGE', 'INSIGHT'].includes(m.kind) && m.status === 'GENERATED')
|
|
57
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Invalid Artifact lifecycle' });
|
|
58
|
+
const previous = value.version > 1 ? tenantResourceRefs({ tenantId: value.ownerTenantId, resourceType: value.resourceType, resourceId: value.resourceId, version: value.version - 1 }).ref : null;
|
|
59
|
+
if (m.supersedesRef !== previous)
|
|
60
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Artifact must retain immediate predecessor' });
|
|
61
|
+
}
|
|
62
|
+
if (value.facts.type === 'EVIDENCE') {
|
|
63
|
+
const m = value.facts.metadata;
|
|
64
|
+
if (m.parentEvidenceRef) {
|
|
65
|
+
const parent = new URL(m.parentEvidenceRef);
|
|
66
|
+
if (parent.hostname !== tenantStorageKey(value.ownerTenantId) || !parent.pathname.startsWith('/evidence/') || m.parentEvidenceRef === value.ref)
|
|
67
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Media parent must be another native Tenant Evidence' });
|
|
68
|
+
}
|
|
69
|
+
if (m.evidenceId !== value.resourceId || value.version !== 1 || Boolean(m.sourceSetRef) !== Boolean(m.sourceItemId) || Boolean(m.collectionBatchRef) !== Boolean(m.collectionTaskId))
|
|
70
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Evidence identity/bindings mismatch' });
|
|
71
|
+
if (value.origin.type === 'TENANT_SOURCE' && (m.sourceId !== value.origin.sourceId || m.runtimeNodeId !== value.origin.runtimeNodeId || m.observedAt !== value.origin.observedAt || m.sourceRevisionRef !== value.origin.sourceRevisionRef || JSON.stringify(m.collector) !== JSON.stringify(value.origin.collector)))
|
|
72
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Evidence must preserve acquisition provenance' });
|
|
73
|
+
}
|
|
74
|
+
if (value.facts.type === 'REFERENCE') {
|
|
75
|
+
const m = value.facts.metadata;
|
|
76
|
+
if (m.version !== value.version || m.effectiveFrom && m.effectiveUntil && Date.parse(m.effectiveUntil) <= Date.parse(m.effectiveFrom))
|
|
77
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Reference version/validity mismatch' });
|
|
78
|
+
const previous = value.version > 1 ? tenantResourceRefs({ tenantId: value.ownerTenantId, resourceType: value.resourceType, resourceId: value.resourceId, version: value.version - 1 }).ref : null;
|
|
79
|
+
if (m.supersedesRef !== previous)
|
|
80
|
+
ctx.addIssue({ code: 'custom', path: ['facts'], message: 'Reference must retain immediate predecessor' });
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
export const tenantProjectionIntentSchema = z.object({ schemaVersion: z.literal(2), ref: tenantResourceRefSchema, manifestRevision: sha256Schema, createdAt: isoDateTimeSchema }).strict();
|
|
84
|
+
/** 存储、Catalog 与 Identity 共用同一 manifest 身份;undefined 等价于 JSON 省略。 */
|
|
85
|
+
export function tenantResourceManifestRevision(raw) {
|
|
86
|
+
const json = JSON.stringify(tenantResourceManifestSchema.parse(raw));
|
|
87
|
+
if (Buffer.byteLength(json + '\n') > 64 * 1024)
|
|
88
|
+
throw new Error('TENANT_RESOURCE_MANIFEST_TOO_LARGE');
|
|
89
|
+
const canonical = (value) => { if (value === null || typeof value !== 'object')
|
|
90
|
+
return JSON.stringify(value); if (Array.isArray(value))
|
|
91
|
+
return '[' + value.map(canonical).join(',') + ']'; const row = value; return '{' + Object.keys(row).sort().map(key => JSON.stringify(key) + ':' + canonical(row[key])).join(',') + '}'; };
|
|
92
|
+
return 'sha256:' + createHash('sha256').update(canonical(JSON.parse(json))).digest('hex');
|
|
93
|
+
}
|
|
94
|
+
/** Reference 语义摘要与 CAS 字节摘要分开;只正规化集合字段,不改原始 payload 字节。 */
|
|
95
|
+
export function tenantReferenceRecordDigest(tenantId, access, metadata, payload) {
|
|
96
|
+
const parsed = tenantResourceFactsSchema.parse({ type: 'REFERENCE', metadata });
|
|
97
|
+
if (parsed.type !== 'REFERENCE')
|
|
98
|
+
throw new Error('TENANT_REFERENCE_FACTS_REQUIRED');
|
|
99
|
+
const m = parsed.metadata, selectors = m.selectors ? Object.fromEntries(Object.keys(m.selectors).sort().map(key => [key, [...new Set(m.selectors[key])].sort()])) : undefined;
|
|
100
|
+
const basis = { tenantId: materialTenantIdSchema.parse(tenantId), corpusKey: m.corpusKey, recordKey: m.recordKey, recordType: m.recordType, access: accessClassificationSchema.parse(access), authority: m.authority, jurisdiction: m.jurisdiction, ...(selectors ? { selectors } : {}), sourceRefs: [...new Set(m.sourceRefs)].sort(), effectiveFrom: m.effectiveFrom, effectiveUntil: m.effectiveUntil, payload };
|
|
101
|
+
let nodes = 0;
|
|
102
|
+
const canonical = (value, depth = 0) => {
|
|
103
|
+
if (++nodes > 1_000_000 || depth > 64)
|
|
104
|
+
throw new Error('TENANT_REFERENCE_JSON_BUDGET_EXCEEDED');
|
|
105
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
106
|
+
return JSON.stringify(value);
|
|
107
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
108
|
+
return JSON.stringify(value);
|
|
109
|
+
if (Array.isArray(value))
|
|
110
|
+
return '[' + value.map(item => canonical(item, depth + 1)).join(',') + ']';
|
|
111
|
+
if (value && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype) {
|
|
112
|
+
const row = value;
|
|
113
|
+
return '{' + Object.keys(row).sort().map(key => JSON.stringify(key) + ':' + canonical(row[key], depth + 1)).join(',') + '}';
|
|
114
|
+
}
|
|
115
|
+
throw new Error('TENANT_REFERENCE_JSON_INVALID');
|
|
116
|
+
};
|
|
117
|
+
return 'sha256:' + createHash('sha256').update(canonical(basis)).digest('hex');
|
|
118
|
+
}
|