@maadb/core 0.15.2 → 0.17.0

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 (69) hide show
  1. package/dist/engine/create-contract.d.ts +10 -0
  2. package/dist/engine/create-contract.d.ts.map +1 -0
  3. package/dist/engine/create-contract.js +128 -0
  4. package/dist/engine/create-contract.js.map +1 -0
  5. package/dist/engine/document-receipt-types.d.ts +46 -0
  6. package/dist/engine/document-receipt-types.d.ts.map +1 -0
  7. package/dist/engine/document-receipt-types.js +2 -0
  8. package/dist/engine/document-receipt-types.js.map +1 -0
  9. package/dist/engine/document-receipt.d.ts +22 -0
  10. package/dist/engine/document-receipt.d.ts.map +1 -0
  11. package/dist/engine/document-receipt.js +262 -0
  12. package/dist/engine/document-receipt.js.map +1 -0
  13. package/dist/engine/guarded-create-types.d.ts +40 -0
  14. package/dist/engine/guarded-create-types.d.ts.map +1 -0
  15. package/dist/engine/guarded-create-types.js +2 -0
  16. package/dist/engine/guarded-create-types.js.map +1 -0
  17. package/dist/engine/guarded-create.d.ts +28 -0
  18. package/dist/engine/guarded-create.d.ts.map +1 -0
  19. package/dist/engine/guarded-create.js +100 -0
  20. package/dist/engine/guarded-create.js.map +1 -0
  21. package/dist/engine/index.d.ts +9 -0
  22. package/dist/engine/index.d.ts.map +1 -1
  23. package/dist/engine/index.js +78 -0
  24. package/dist/engine/index.js.map +1 -1
  25. package/dist/engine/writes.d.ts +13 -1
  26. package/dist/engine/writes.d.ts.map +1 -1
  27. package/dist/engine/writes.js +20 -11
  28. package/dist/engine/writes.js.map +1 -1
  29. package/dist/engine.d.ts +2 -0
  30. package/dist/engine.d.ts.map +1 -1
  31. package/dist/engine.js +1 -0
  32. package/dist/engine.js.map +1 -1
  33. package/dist/errors.d.ts +1 -1
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/errors.js.map +1 -1
  36. package/dist/git/exact-blob.d.ts +17 -0
  37. package/dist/git/exact-blob.d.ts.map +1 -0
  38. package/dist/git/exact-blob.js +107 -0
  39. package/dist/git/exact-blob.js.map +1 -0
  40. package/dist/instance/pool.d.ts +10 -0
  41. package/dist/instance/pool.d.ts.map +1 -1
  42. package/dist/instance/pool.js +61 -7
  43. package/dist/instance/pool.js.map +1 -1
  44. package/dist/mcp/kinds.d.ts.map +1 -1
  45. package/dist/mcp/kinds.js +2 -0
  46. package/dist/mcp/kinds.js.map +1 -1
  47. package/dist/mcp/roles.d.ts.map +1 -1
  48. package/dist/mcp/roles.js +2 -1
  49. package/dist/mcp/roles.js.map +1 -1
  50. package/dist/mcp/server.d.ts.map +1 -1
  51. package/dist/mcp/server.js +5 -0
  52. package/dist/mcp/server.js.map +1 -1
  53. package/dist/mcp/tools/document-receipt.d.ts +12 -0
  54. package/dist/mcp/tools/document-receipt.d.ts.map +1 -0
  55. package/dist/mcp/tools/document-receipt.js +19 -0
  56. package/dist/mcp/tools/document-receipt.js.map +1 -0
  57. package/dist/mcp/tools/guarded-create.d.ts +28 -0
  58. package/dist/mcp/tools/guarded-create.d.ts.map +1 -0
  59. package/dist/mcp/tools/guarded-create.js +68 -0
  60. package/dist/mcp/tools/guarded-create.js.map +1 -0
  61. package/dist/mcp/with-session.d.ts +3 -0
  62. package/dist/mcp/with-session.d.ts.map +1 -1
  63. package/dist/mcp/with-session.js +131 -8
  64. package/dist/mcp/with-session.js.map +1 -1
  65. package/dist/schema/loader.d.ts +12 -1
  66. package/dist/schema/loader.d.ts.map +1 -1
  67. package/dist/schema/loader.js +48 -15
  68. package/dist/schema/loader.js.map +1 -1
  69. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ import { type Registry, type SchemaStore } from '../types.js';
2
+ import type { CreateContract } from './guarded-create-types.js';
3
+ import type { EngineContext } from './context.js';
4
+ /** No registry activation, directory creation, index rebuild, or stale fallback. */
5
+ export declare function freshCreateContract(ctx: EngineContext, type: string, signal?: AbortSignal): Promise<{
6
+ contract: CreateContract;
7
+ registry: Registry;
8
+ schemaStore: SchemaStore;
9
+ }>;
10
+ //# sourceMappingURL=create-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-contract.d.ts","sourceRoot":"","sources":["../../src/engine/create-contract.ts"],"names":[],"mappings":"AAMA,OAAO,EAAwE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAKpI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA4BlD,oFAAoF;AACpF,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IACzG,QAAQ,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC;CACxE,CAAC,CA+ED"}
@@ -0,0 +1,128 @@
1
+ import path from 'node:path';
2
+ import { lstatSync } from 'node:fs';
3
+ import yaml from 'js-yaml';
4
+ import { createRequire } from 'node:module';
5
+ import { z } from 'zod';
6
+ import { loadSchemasFromSnapshot } from '../schema/loader.js';
7
+ import { buildSubtypeMap, DEFAULT_SUBTYPE_MAP, PRIMITIVES, docType, schemaRef } from '../types.js';
8
+ import { canonicalJson, rawSha256, readWorkingReceipt, readWorkingReceiptSnapshot } from './document-receipt.js';
9
+ import { isSafeProjectRelativePath, isSafeSchemaRef, isWritePathContainedIn } from './pathguard.js';
10
+ import { ReceiptError } from '../git/exact-blob.js';
11
+ const engineVersion = createRequire(import.meta.url)('../../package.json').version;
12
+ const typeDefinition = z.object({
13
+ path: z.string().min(1), id_prefix: z.string().regex(/^[a-z0-9]{2,5}$/),
14
+ schema: z.string().refine(isSafeSchemaRef), template: z.string().min(1).optional(),
15
+ }).passthrough();
16
+ const registryDefinition = z.object({
17
+ types: z.record(z.string().regex(/^[a-z][a-z0-9_]*$/), typeDefinition),
18
+ extraction: z.object({ subtypes: z.record(z.string(), z.enum(PRIMITIVES)).optional() }).passthrough().optional(),
19
+ }).passthrough();
20
+ function parseSource(raw) {
21
+ const text = raw.replace(/^\uFEFF/, '');
22
+ const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
23
+ const value = yaml.load(match ? match[1] : text, { schema: yaml.CORE_SCHEMA });
24
+ canonicalJson(value);
25
+ return value;
26
+ }
27
+ /** Ordered map entries retain schema field ordering, which affects serialization. */
28
+ function effectiveContract(registry, schemas) {
29
+ return JSON.parse(canonicalJson({
30
+ types: [...registry.types], extraction: registry.extraction, subtypeMap: registry.subtypeMap,
31
+ schemas: [...schemas.schemas].map(([ref, schema]) => [ref, { ...schema, fields: [...schema.fields] }]),
32
+ }));
33
+ }
34
+ /** No registry activation, directory creation, index rebuild, or stale fallback. */
35
+ export async function freshCreateContract(ctx, type, signal) {
36
+ const sources = Object.create(null);
37
+ const capturedBytes = new Map();
38
+ const cachedFiles = new Map();
39
+ let total = 0;
40
+ const read = async (relative) => {
41
+ if (Object.hasOwn(sources, relative))
42
+ return sources[relative];
43
+ if (Object.keys(sources).length >= 129)
44
+ throw new ReceiptError('SCHEMA_INVALID', 'Too many contract dependencies');
45
+ const captured = await readWorkingReceiptSnapshot(ctx.projectRoot, relative, signal);
46
+ const { bytes } = captured;
47
+ total += bytes.length;
48
+ if (total > 256 * 1024)
49
+ throw new ReceiptError('RESPONSE_TOO_LARGE', 'Schema dependency snapshot exceeds 256 KiB');
50
+ const text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
51
+ sources[relative] = text;
52
+ capturedBytes.set(relative, bytes);
53
+ cachedFiles.set(path.join(ctx.projectRoot, relative), { mtimeMs: captured.mtimeMs, size: captured.size });
54
+ return text;
55
+ };
56
+ const parsed = registryDefinition.parse(parseSource(await read('_registry/object_types.yaml')));
57
+ const entries = Object.entries(parsed.types);
58
+ if (entries.length === 0 || entries.length > 64)
59
+ throw new ReceiptError('SCHEMA_INVALID', 'Contract requires 1 to 64 registered types');
60
+ const registry = { types: new Map(), extraction: { subtypes: parsed.extraction?.subtypes ?? {} },
61
+ subtypeMap: buildSubtypeMap(DEFAULT_SUBTYPE_MAP, parsed.extraction?.subtypes) };
62
+ const prefixes = new Set();
63
+ for (const [name, def] of entries) {
64
+ if (prefixes.has(def.id_prefix))
65
+ throw new ReceiptError('REGISTRY_INVALID', 'Duplicate registry prefix');
66
+ prefixes.add(def.id_prefix);
67
+ for (const relative of [def.path, ...(def.template ? [def.template] : [])]) {
68
+ if (!isSafeProjectRelativePath(relative) || !isWritePathContainedIn(path.join(ctx.projectRoot, relative), ctx.projectRoot)) {
69
+ throw new ReceiptError('PATH_OUTSIDE_PROJECT', 'Contract dependency escapes project');
70
+ }
71
+ }
72
+ let directory = ctx.projectRoot;
73
+ for (const component of def.path.split('/').filter(Boolean)) {
74
+ directory = path.join(directory, component);
75
+ try {
76
+ const entry = lstatSync(directory);
77
+ if (entry.isSymbolicLink() || !entry.isDirectory())
78
+ throw new ReceiptError('PATH_OUTSIDE_PROJECT', 'Create directory must be a real directory');
79
+ }
80
+ catch (error) {
81
+ if (error.code !== 'ENOENT')
82
+ throw error;
83
+ }
84
+ }
85
+ registry.types.set(docType(name), { name: docType(name), path: def.path, idPrefix: def.id_prefix,
86
+ schemaRef: schemaRef(def.schema), template: def.template ?? null });
87
+ const schema = parseSource(await read(`_schema/${def.schema}.yaml`));
88
+ // Refuse malformed top-level shapes that the legacy loader tolerates.
89
+ z.object({ type: z.literal(name), version: z.number().int().positive().optional(),
90
+ required: z.array(z.string()).optional(), fields: z.record(z.string(), z.object({ type: z.string() }).passthrough()),
91
+ template: z.object({ headings: z.array(z.object({ level: z.number().int().min(1).max(6),
92
+ text: z.string(), id: z.string().nullable().optional() }).passthrough()) }).passthrough().optional(),
93
+ }).passthrough().parse(schema);
94
+ if (def.template)
95
+ await read(def.template);
96
+ }
97
+ if (!registry.types.has(docType(type)))
98
+ throw new ReceiptError('UNKNOWN_TYPE', 'Unknown contract document type');
99
+ // Validate exactly the bounded captured sources, with no disk-reader fallback.
100
+ // Both effective identity and document preparation use this validated store.
101
+ // Decode like the legacy disk reader (including BOMs); capture already checked
102
+ // UTF-8 validity. Keep the existing source projection and parser behavior.
103
+ const schemaSources = new Map([...registry.types.values()].map(def => [def.schemaRef, capturedBytes.get(`_schema/${def.schemaRef}.yaml`).toString('utf8')]));
104
+ const loaded = await loadSchemasFromSnapshot(registry, schemaSources, { signal, cachedFiles });
105
+ if (signal?.aborted)
106
+ throw new ReceiptError('REQUEST_TIMEOUT', 'Schema snapshot validation cancelled');
107
+ if (!loaded.ok)
108
+ throw new ReceiptError('SCHEMA_INVALID', 'Fresh schema validation failed');
109
+ for (const [relative, expected] of Object.entries(sources)) {
110
+ const actual = await readWorkingReceipt(ctx.projectRoot, relative, signal);
111
+ if (!actual.equals(Buffer.from(expected)))
112
+ throw new ReceiptError('SCHEMA_CONTRACT_CHANGED', 'Schema changed during observation');
113
+ }
114
+ const schemaContract = {
115
+ projection: 'create-schema-v1', engineVersion,
116
+ contentProjection: 'document-content-v1',
117
+ sources, effective: effectiveContract(registry, loaded.value),
118
+ };
119
+ const canonical = canonicalJson(schemaContract);
120
+ if (Buffer.byteLength(canonical) > 512 * 1024)
121
+ throw new ReceiptError('RESPONSE_TOO_LARGE', 'Complete schema contract exceeds bound');
122
+ return { registry, schemaStore: loaded.value, contract: {
123
+ contract: 'create-contract-v1', docType: type, schemaDigest: rawSha256(Buffer.from(canonical)),
124
+ schemaProjection: 'create-schema-v1', contentProjection: 'document-content-v1', schemaContract,
125
+ effectiveHistoryMode: ctx.history?.config.effectiveMode ?? 'feed',
126
+ } };
127
+ }
128
+ //# sourceMappingURL=create-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-contract.js","sourceRoot":"","sources":["../../src/engine/create-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { HistoryMode } from '../history/types.js';
2
+ export type JsonValue = null | boolean | number | string | JsonValue[] | {
3
+ [key: string]: JsonValue;
4
+ };
5
+ export interface DocumentReceiptRequest {
6
+ contract: 'document-persistence-v1';
7
+ docType: string;
8
+ docId: string;
9
+ expectedContentDigest?: string | undefined;
10
+ }
11
+ export interface DocumentReceipt {
12
+ contract: 'document-persistence-v1';
13
+ engineVersion: string;
14
+ project: string;
15
+ docId: string;
16
+ docType: string;
17
+ observedAt: string;
18
+ effectiveHistoryMode: HistoryMode;
19
+ projection: 'document-content-v1';
20
+ expectedContentDigest: string | null;
21
+ status: 'committed_content_available' | 'unverified';
22
+ reason: null | 'index_missing' | 'index_identity_mismatch' | 'working_tree_missing' | 'working_tree_unreadable' | 'working_tree_changed' | 'working_tree_diverged' | 'history_unavailable' | 'uncommitted' | 'committed_payload_mismatch';
23
+ index: {
24
+ state: 'present' | 'missing' | 'identity_mismatch';
25
+ };
26
+ workingTree: {
27
+ state: 'matches_committed' | 'diverged' | 'missing' | 'unreadable' | 'changed' | 'not_checked';
28
+ rawSha256: string | null;
29
+ contentDigest: string | null;
30
+ };
31
+ committed: null | {
32
+ evidenceKind: 'git_commit_visible';
33
+ objectFormat: 'sha1' | 'sha256';
34
+ commitOid: string;
35
+ treeOid: string;
36
+ blobOid: string;
37
+ rawSha256: string;
38
+ byteLength: number;
39
+ rawMarkdown: string;
40
+ frontmatter: Record<string, JsonValue>;
41
+ body: string;
42
+ contentDigest: string;
43
+ };
44
+ expectedDigestMatch: boolean | null;
45
+ }
46
+ //# sourceMappingURL=document-receipt-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-receipt-types.d.ts","sourceRoot":"","sources":["../../src/engine/document-receipt-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACtG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,yBAAyB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C;AACD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,yBAAyB,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,WAAW,CAAC;IAClC,UAAU,EAAE,qBAAqB,CAAC;IAClC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,6BAA6B,GAAG,YAAY,CAAC;IACrD,MAAM,EAAE,IAAI,GAAG,eAAe,GAAG,yBAAyB,GAAG,sBAAsB,GAC/E,yBAAyB,GAAG,sBAAsB,GAAG,uBAAuB,GAC5E,qBAAqB,GAAG,aAAa,GAAG,4BAA4B,CAAC;IACzE,KAAK,EAAE;QAAE,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,mBAAmB,CAAA;KAAE,CAAC;IAC9D,WAAW,EAAE;QACX,KAAK,EAAE,mBAAmB,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC;QAC/F,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,CAAC;IACF,SAAS,EAAE,IAAI,GAAG;QAChB,YAAY,EAAE,oBAAoB,CAAC;QACnC,YAAY,EAAE,MAAM,GAAG,QAAQ,CAAC;QAChC,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACvC,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAAC;CACrC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=document-receipt-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-receipt-types.js","sourceRoot":"","sources":["../../src/engine/document-receipt-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { type Result } from '../errors.js';
2
+ import type { EngineContext } from './context.js';
3
+ import type { DocumentReceipt, DocumentReceiptRequest, JsonValue } from './document-receipt-types.js';
4
+ export declare const rawSha256: (bytes: Buffer) => string;
5
+ /** Explicit serialization preserves UTF-16 key ordering even for integer-like keys. */
6
+ export declare function canonicalJson(value: unknown): string;
7
+ export declare function contentDigest(id: string, type: string, frontmatter: Record<string, JsonValue>, body: string): string;
8
+ export declare function parseReceiptContent(bytes: Buffer, id: string, type: string, schema: string): {
9
+ rawMarkdown: string;
10
+ frontmatter: Record<string, JsonValue>;
11
+ body: string;
12
+ contentDigest: string;
13
+ };
14
+ export declare function readWorkingReceipt(root: string, relative: string, signal?: AbortSignal): Promise<Buffer>;
15
+ /** One bounded handle read; compare both handle and pathname identity around it. */
16
+ export declare function readWorkingReceiptSnapshot(root: string, relative: string, signal?: AbortSignal): Promise<{
17
+ bytes: Buffer;
18
+ mtimeMs: number;
19
+ size: number;
20
+ }>;
21
+ export declare function documentReceipt(ctx: EngineContext, request: DocumentReceiptRequest, project: string, signal?: AbortSignal): Promise<Result<DocumentReceipt>>;
22
+ //# sourceMappingURL=document-receipt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-receipt.d.ts","sourceRoot":"","sources":["../../src/engine/document-receipt.ts"],"names":[],"mappings":"AAMA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAI1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAItG,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,MAA0D,CAAC;AAErG,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAuCpD;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpH;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;EAqB1F;AAgBD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAE9G;AAED,oFAAoF;AACpF,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAC9G,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAC9C,CAAC,CAoCD;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,EACxG,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CA2ExD"}
@@ -0,0 +1,262 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { createRequire } from 'node:module';
3
+ import { constants } from 'node:fs';
4
+ import { lstat, open, realpath } from 'node:fs/promises';
5
+ import path from 'node:path';
6
+ import yaml from 'js-yaml';
7
+ import { ok, singleErr } from '../errors.js';
8
+ import { readExactBlob, ReceiptError, RECEIPT_MAX_BYTES, checkReceiptAbort } from '../git/exact-blob.js';
9
+ import { checkDocIdSafe } from './docid-safe.js';
10
+ import { isContainedIn } from './pathguard.js';
11
+ import { docId, docType } from '../types.js';
12
+ const version = createRequire(import.meta.url)('../../package.json').version;
13
+ export const rawSha256 = (bytes) => createHash('sha256').update(bytes).digest('hex');
14
+ /** Explicit serialization preserves UTF-16 key ordering even for integer-like keys. */
15
+ export function canonicalJson(value) {
16
+ const seen = new Set();
17
+ let nodes = 0;
18
+ let bytes = 0;
19
+ const encode = (v, depth) => {
20
+ if (++nodes > 65536 || depth > 64)
21
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Content structure exceeds bounds');
22
+ if (v === null || typeof v === 'boolean' || typeof v === 'string' || (typeof v === 'number' && Number.isFinite(v))) {
23
+ const text = JSON.stringify(v);
24
+ bytes += Buffer.byteLength(text);
25
+ if (bytes > 1024 * 1024)
26
+ throw new ReceiptError('RESPONSE_TOO_LARGE', 'Canonical content exceeds bound');
27
+ return text;
28
+ }
29
+ if (typeof v !== 'object' || !v || seen.has(v))
30
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Unsupported JSON content');
31
+ const proto = Object.getPrototypeOf(v);
32
+ if (Array.isArray(v) ? proto !== Array.prototype : proto !== Object.prototype && proto !== null) {
33
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Unsupported content prototype');
34
+ }
35
+ if (Reflect.ownKeys(v).some(key => typeof key !== 'string'))
36
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Unsupported content key');
37
+ const descriptors = Object.getOwnPropertyDescriptors(v);
38
+ for (const [key, descriptor] of Object.entries(descriptors)) {
39
+ if (Array.isArray(v) && key === 'length')
40
+ continue;
41
+ if (!('value' in descriptor) || !descriptor.enumerable)
42
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Unsupported content property');
43
+ }
44
+ seen.add(v);
45
+ let result;
46
+ if (Array.isArray(v)) {
47
+ if (Object.keys(v).length !== v.length)
48
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Sparse or decorated array');
49
+ result = '[' + Array.from(v, item => encode(item, depth + 1)).join(',') + ']';
50
+ }
51
+ else {
52
+ result = '{' + Object.keys(v).sort().map(key => {
53
+ const descriptor = Object.getOwnPropertyDescriptor(v, key);
54
+ if (!('value' in descriptor))
55
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Unsupported content accessor');
56
+ return encode(key, depth + 1) + ':' + encode(descriptor.value, depth + 1);
57
+ }).join(',') + '}';
58
+ }
59
+ seen.delete(v);
60
+ return result;
61
+ };
62
+ return encode(value, 0);
63
+ }
64
+ export function contentDigest(id, type, frontmatter, body) {
65
+ const canonical = `{"docId":${canonicalJson(id)},"docType":${canonicalJson(type)},"frontmatter":${canonicalJson(frontmatter)},"body":${canonicalJson(body)}}`;
66
+ return createHash('sha256').update(canonical, 'utf8').digest('hex');
67
+ }
68
+ export function parseReceiptContent(bytes, id, type, schema) {
69
+ if (bytes.length > RECEIPT_MAX_BYTES)
70
+ throw new ReceiptError('RESPONSE_TOO_LARGE', 'Receipt content exceeds bound');
71
+ try {
72
+ // ignoreBOM preserves it in rawMarkdown; parsing alone removes one BOM.
73
+ const rawMarkdown = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(bytes);
74
+ const text = rawMarkdown.replace(/^\uFEFF/, '');
75
+ const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
76
+ if (!match)
77
+ throw new Error('Missing frontmatter delimiters');
78
+ const parsed = yaml.load(match[1], { schema: yaml.CORE_SCHEMA, json: false });
79
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
80
+ throw new Error('Frontmatter must be a mapping');
81
+ canonicalJson(parsed);
82
+ const frontmatter = parsed;
83
+ for (const [key, expected] of [['doc_id', id], ['doc_type', type], ['schema', schema]]) {
84
+ if (!Object.hasOwn(frontmatter, key) || frontmatter[key] !== expected)
85
+ throw new Error('Document identity conflict');
86
+ }
87
+ const body = text.slice(match[0].length).replace(/\r\n/g, '\n').trim();
88
+ return { rawMarkdown, frontmatter, body, contentDigest: contentDigest(id, type, frontmatter, body) };
89
+ }
90
+ catch (error) {
91
+ if (error instanceof ReceiptError)
92
+ throw error;
93
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Receipt requires valid UTF-8, strict YAML, JSON values, and matching identity');
94
+ }
95
+ }
96
+ async function checkedPath(root, relative) {
97
+ const target = path.resolve(root, relative);
98
+ if (!isContainedIn(target, root))
99
+ throw new ReceiptError('PATH_OUTSIDE_PROJECT', 'Receipt path escapes project');
100
+ const actualRoot = await realpath(root);
101
+ let current = root;
102
+ for (const component of relative.split('/')) {
103
+ current = path.join(current, component);
104
+ const stat = await lstat(current);
105
+ if (stat.isSymbolicLink())
106
+ throw new ReceiptError('PATH_OUTSIDE_PROJECT', 'Receipt path contains a symbolic link');
107
+ }
108
+ if (!isContainedIn(await realpath(target), actualRoot))
109
+ throw new ReceiptError('PATH_OUTSIDE_PROJECT', 'Receipt path escapes project');
110
+ return target;
111
+ }
112
+ export async function readWorkingReceipt(root, relative, signal) {
113
+ return (await readWorkingReceiptSnapshot(root, relative, signal)).bytes;
114
+ }
115
+ /** One bounded handle read; compare both handle and pathname identity around it. */
116
+ export async function readWorkingReceiptSnapshot(root, relative, signal) {
117
+ checkReceiptAbort(signal);
118
+ const target = await checkedPath(root, relative);
119
+ const before = await lstat(target, { bigint: true });
120
+ if (!before.isFile())
121
+ throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Receipt target must be regular');
122
+ const handle = await open(target, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) | (constants.O_NONBLOCK ?? 0));
123
+ const same = (a, b) => a.dev === b.dev && a.ino === b.ino
124
+ && a.size === b.size && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs && b.isFile();
125
+ try {
126
+ const opened = await handle.stat({ bigint: true });
127
+ if (!same(before, opened))
128
+ throw new ReceiptError('RECEIPT_OBSERVATION_CHANGED', 'Working file changed before read');
129
+ if (opened.size > BigInt(RECEIPT_MAX_BYTES))
130
+ throw new ReceiptError('RESPONSE_TOO_LARGE', 'Working file exceeds bound');
131
+ // Cache hints come from this same handle. Bigint nanosecond identity checks
132
+ // below remain authoritative; retain native numeric stat precision for the
133
+ // existing legacy mtime/size cache comparisons.
134
+ const cached = await handle.stat();
135
+ const buffer = Buffer.alloc(Number(opened.size) + 1);
136
+ let length = 0;
137
+ while (length < buffer.length) {
138
+ checkReceiptAbort(signal);
139
+ const read = await handle.read(buffer, length, buffer.length - length, length);
140
+ if (read.bytesRead === 0)
141
+ break;
142
+ length += read.bytesRead;
143
+ }
144
+ const after = await handle.stat({ bigint: true });
145
+ let named;
146
+ try {
147
+ await checkedPath(root, relative);
148
+ named = await lstat(target, { bigint: true });
149
+ }
150
+ catch {
151
+ throw new ReceiptError('RECEIPT_OBSERVATION_CHANGED', 'Working pathname changed during read');
152
+ }
153
+ if (!same(opened, after) || !same(after, named) || BigInt(length) !== opened.size) {
154
+ throw new ReceiptError('RECEIPT_OBSERVATION_CHANGED', 'Working file changed during read');
155
+ }
156
+ checkReceiptAbort(signal);
157
+ return { bytes: buffer.subarray(0, length), mtimeMs: cached.mtimeMs, size: cached.size };
158
+ }
159
+ finally {
160
+ await handle.close();
161
+ }
162
+ }
163
+ export async function documentReceipt(ctx, request, project, signal) {
164
+ try {
165
+ checkReceiptAbort(signal);
166
+ if (request.contract !== 'document-persistence-v1' || typeof request.docType !== 'string'
167
+ || Buffer.byteLength(request.docType) > 256 || !/^[a-zA-Z0-9_][a-zA-Z0-9_-]*$/.test(request.docType)
168
+ || (request.expectedContentDigest !== undefined && !/^[0-9a-f]{64}$/.test(request.expectedContentDigest))) {
169
+ return singleErr('INVALID_FIELDS', 'Invalid document receipt request');
170
+ }
171
+ const unsafe = checkDocIdSafe(request.docId);
172
+ if (unsafe)
173
+ return singleErr('INVALID_DOC_ID', unsafe.message);
174
+ const registered = ctx.registry.types.get(docType(request.docType));
175
+ if (!registered)
176
+ return singleErr('UNKNOWN_TYPE', 'Unknown receipt document type');
177
+ const target = path.resolve(ctx.projectRoot, registered.path, `${request.docId}.md`);
178
+ if (!isContainedIn(target, ctx.projectRoot))
179
+ return singleErr('PATH_OUTSIDE_PROJECT', 'Receipt path escapes project');
180
+ const relative = path.relative(ctx.projectRoot, target).split(path.sep).join('/');
181
+ const identity = () => {
182
+ const row = ctx.backend.getDocument(docId(request.docId));
183
+ if (!row)
184
+ return 'missing';
185
+ return row.docId === request.docId && row.docType === request.docType && row.schemaRef === registered.schemaRef
186
+ && row.filePath.replace(/\\/g, '/') === relative ? 'present' : 'identity_mismatch';
187
+ };
188
+ const initial = identity();
189
+ const registeredIdentity = `${registered.path}\0${registered.schemaRef}`;
190
+ const receipt = {
191
+ contract: 'document-persistence-v1', engineVersion: version, project, docId: request.docId, docType: request.docType,
192
+ observedAt: new Date().toISOString(), effectiveHistoryMode: ctx.history?.config.effectiveMode ?? 'feed',
193
+ projection: 'document-content-v1', expectedContentDigest: request.expectedContentDigest ?? null,
194
+ status: 'unverified', reason: null, index: { state: initial },
195
+ workingTree: { state: 'not_checked', rawSha256: null, contentDigest: null }, committed: null, expectedDigestMatch: null,
196
+ };
197
+ const finish = () => {
198
+ checkReceiptAbort(signal);
199
+ if (identity() !== initial || ctx.registry.types.get(docType(request.docType)) !== registered
200
+ || `${registered.path}\0${registered.schemaRef}` !== registeredIdentity || ctx.schemaStore.isStale()) {
201
+ throw new ReceiptError('RECEIPT_OBSERVATION_CHANGED', 'Receipt index or configuration changed');
202
+ }
203
+ receipt.observedAt = new Date().toISOString();
204
+ return ok(receipt);
205
+ };
206
+ if (initial !== 'present') {
207
+ receipt.reason = initial === 'missing' ? 'index_missing' : 'index_identity_mismatch';
208
+ return finish();
209
+ }
210
+ if (!ctx.gitLayer || !ctx.history || receipt.effectiveHistoryMode === 'feed') {
211
+ receipt.reason = 'history_unavailable';
212
+ return finish();
213
+ }
214
+ const evidence = await readExactBlob(ctx.projectRoot, relative, signal);
215
+ if (!evidence) {
216
+ receipt.reason = 'uncommitted';
217
+ return finish();
218
+ }
219
+ const committed = parseReceiptContent(evidence.bytes, request.docId, request.docType, registered.schemaRef);
220
+ let working;
221
+ try {
222
+ working = await readWorkingReceipt(ctx.projectRoot, relative, signal);
223
+ }
224
+ catch (error) {
225
+ if (error instanceof ReceiptError && error.code === 'RECEIPT_OBSERVATION_CHANGED') {
226
+ receipt.reason = 'working_tree_changed';
227
+ receipt.workingTree.state = 'changed';
228
+ }
229
+ else if (error.code === 'ENOENT') {
230
+ receipt.reason = 'working_tree_missing';
231
+ receipt.workingTree.state = 'missing';
232
+ }
233
+ else if (['EACCES', 'EPERM'].includes(error.code ?? '')) {
234
+ receipt.reason = 'working_tree_unreadable';
235
+ receipt.workingTree.state = 'unreadable';
236
+ }
237
+ else
238
+ throw error;
239
+ return finish();
240
+ }
241
+ const parsedWorking = parseReceiptContent(working, request.docId, request.docType, registered.schemaRef);
242
+ receipt.workingTree.rawSha256 = rawSha256(working);
243
+ receipt.workingTree.contentDigest = parsedWorking.contentDigest;
244
+ if (parsedWorking.contentDigest !== committed.contentDigest) {
245
+ receipt.reason = 'working_tree_diverged';
246
+ receipt.workingTree.state = 'diverged';
247
+ return finish();
248
+ }
249
+ receipt.workingTree.state = 'matches_committed';
250
+ receipt.committed = { evidenceKind: 'git_commit_visible', objectFormat: evidence.objectFormat,
251
+ commitOid: evidence.commitOid, treeOid: evidence.treeOid, blobOid: evidence.blobOid,
252
+ byteLength: evidence.bytes.length, rawSha256: rawSha256(evidence.bytes), ...committed };
253
+ receipt.status = 'committed_content_available';
254
+ receipt.expectedDigestMatch = request.expectedContentDigest === undefined ? null : request.expectedContentDigest === committed.contentDigest;
255
+ return finish();
256
+ }
257
+ catch (error) {
258
+ return error instanceof ReceiptError ? singleErr(error.code, error.message)
259
+ : singleErr('RECEIPT_STORAGE_ERROR', 'Receipt storage could not be read');
260
+ }
261
+ }
262
+ //# sourceMappingURL=document-receipt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-receipt.js","sourceRoot":"","sources":["../../src/engine/document-receipt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { JsonValue } from './document-receipt-types.js';
2
+ import type { HistoryMode } from '../history/types.js';
3
+ import type { MaadError } from '../errors.js';
4
+ import type { CreateResult } from './types.js';
5
+ export interface CreateContractRequest {
6
+ contract: 'create-contract-v1';
7
+ docType: string;
8
+ }
9
+ export interface CreateContract {
10
+ contract: 'create-contract-v1';
11
+ docType: string;
12
+ schemaDigest: string;
13
+ schemaProjection: 'create-schema-v1';
14
+ contentProjection: 'document-content-v1';
15
+ effectiveHistoryMode: HistoryMode;
16
+ /** Complete, JSON-compatible input to the schema digest. */
17
+ schemaContract: JsonValue;
18
+ }
19
+ export interface GuardedCreateRequest {
20
+ contract: 'guarded-create-v1';
21
+ docType: string;
22
+ docId: string;
23
+ fields: Record<string, JsonValue>;
24
+ body: string;
25
+ expectedSchemaDigest: string;
26
+ expectedContentDigest: string;
27
+ allowedHistoryModes: HistoryMode[];
28
+ }
29
+ /** Trusted in-process routing hooks; never part of the wire request. */
30
+ export interface GuardedCreateOptions {
31
+ signal?: AbortSignal;
32
+ validateAccess?: () => MaadError | null;
33
+ }
34
+ export interface GuardedCreateResult extends CreateResult {
35
+ contract: 'guarded-create-v1';
36
+ schemaDigest: string;
37
+ contentDigest: string;
38
+ effectiveHistoryMode: HistoryMode;
39
+ }
40
+ //# sourceMappingURL=guarded-create-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guarded-create-types.d.ts","sourceRoot":"","sources":["../../src/engine/guarded-create-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,iBAAiB,EAAE,qBAAqB,CAAC;IACzC,oBAAoB,EAAE,WAAW,CAAC;IAClC,4DAA4D;IAC5D,cAAc,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,WAAW,EAAE,CAAC;CACpC;AAED,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,WAAW,CAAC;CACnC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=guarded-create-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guarded-create-types.js","sourceRoot":"","sources":["../../src/engine/guarded-create-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ import { type Result } from '../errors.js';
3
+ import { type Registry, type SchemaStore } from '../types.js';
4
+ import type { EngineContext } from './context.js';
5
+ import type { GuardedCreateRequest, GuardedCreateOptions, GuardedCreateResult } from './guarded-create-types.js';
6
+ export declare const createContractRequestSchema: z.ZodObject<{
7
+ contract: z.ZodLiteral<"create-contract-v1">;
8
+ docType: z.ZodString;
9
+ }, z.core.$strict>;
10
+ export declare const guardedCreateRequestSchema: z.ZodObject<{
11
+ contract: z.ZodLiteral<"guarded-create-v1">;
12
+ docType: z.ZodString;
13
+ docId: z.ZodString;
14
+ fields: z.ZodRecord<z.ZodString, z.ZodUnknown>;
15
+ body: z.ZodString;
16
+ expectedSchemaDigest: z.ZodString;
17
+ expectedContentDigest: z.ZodString;
18
+ allowedHistoryModes: z.ZodArray<z.ZodEnum<{
19
+ audit: "audit";
20
+ feed: "feed";
21
+ read: "read";
22
+ batch: "batch";
23
+ snapshot: "snapshot";
24
+ }>>;
25
+ }, z.core.$strict>;
26
+ export declare function admissionError(error: unknown): Result<never>;
27
+ export declare function guardedCreate(ctx: EngineContext, request: GuardedCreateRequest, options: GuardedCreateOptions, isReady: () => boolean, onAdmitted: (registry: Registry, schemaStore: SchemaStore) => void): Promise<Result<GuardedCreateResult>>;
28
+ //# sourceMappingURL=guarded-create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guarded-create.d.ts","sourceRoot":"","sources":["../../src/engine/guarded-create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAsB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAW,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAMvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEjH,eAAO,MAAM,2BAA2B;;;kBAE7B,CAAC;AACZ,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;kBAQ5B,CAAC;AAEZ,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAG5D;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,oBAAoB,EACnF,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,OAAO,EACrD,UAAU,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAyD1G"}