@maadb/core 0.16.0 → 0.18.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 (87) hide show
  1. package/README.md +2 -0
  2. package/dist/client/complete-delivery.d.ts +5 -0
  3. package/dist/client/complete-delivery.d.ts.map +1 -0
  4. package/dist/client/complete-delivery.js +38 -0
  5. package/dist/client/complete-delivery.js.map +1 -0
  6. package/dist/engine/compact-json.d.ts +12 -0
  7. package/dist/engine/compact-json.d.ts.map +1 -0
  8. package/dist/engine/compact-json.js +87 -0
  9. package/dist/engine/compact-json.js.map +1 -0
  10. package/dist/engine/context.d.ts +1 -0
  11. package/dist/engine/context.d.ts.map +1 -1
  12. package/dist/engine/context.js.map +1 -1
  13. package/dist/engine/contract-preparation-cache.d.ts +9 -0
  14. package/dist/engine/contract-preparation-cache.d.ts.map +1 -0
  15. package/dist/engine/contract-preparation-cache.js +31 -0
  16. package/dist/engine/contract-preparation-cache.js.map +1 -0
  17. package/dist/engine/create-contract.d.ts +11 -0
  18. package/dist/engine/create-contract.d.ts.map +1 -0
  19. package/dist/engine/create-contract.js +141 -0
  20. package/dist/engine/create-contract.js.map +1 -0
  21. package/dist/engine/delivery-json.d.ts +7 -0
  22. package/dist/engine/delivery-json.d.ts.map +1 -0
  23. package/dist/engine/delivery-json.js +6 -0
  24. package/dist/engine/delivery-json.js.map +1 -0
  25. package/dist/engine/document-receipt.d.ts +11 -2
  26. package/dist/engine/document-receipt.d.ts.map +1 -1
  27. package/dist/engine/document-receipt.js +19 -5
  28. package/dist/engine/document-receipt.js.map +1 -1
  29. package/dist/engine/guarded-create-types.d.ts +40 -0
  30. package/dist/engine/guarded-create-types.d.ts.map +1 -0
  31. package/dist/engine/guarded-create-types.js +2 -0
  32. package/dist/engine/guarded-create-types.js.map +1 -0
  33. package/dist/engine/guarded-create.d.ts +28 -0
  34. package/dist/engine/guarded-create.d.ts.map +1 -0
  35. package/dist/engine/guarded-create.js +100 -0
  36. package/dist/engine/guarded-create.js.map +1 -0
  37. package/dist/engine/index.d.ts +9 -0
  38. package/dist/engine/index.d.ts.map +1 -1
  39. package/dist/engine/index.js +65 -0
  40. package/dist/engine/index.js.map +1 -1
  41. package/dist/engine/writes.d.ts +13 -1
  42. package/dist/engine/writes.d.ts.map +1 -1
  43. package/dist/engine/writes.js +20 -11
  44. package/dist/engine/writes.js.map +1 -1
  45. package/dist/engine.d.ts +4 -0
  46. package/dist/engine.d.ts.map +1 -1
  47. package/dist/engine.js +2 -0
  48. package/dist/engine.js.map +1 -1
  49. package/dist/errors.d.ts +1 -1
  50. package/dist/errors.d.ts.map +1 -1
  51. package/dist/errors.js.map +1 -1
  52. package/dist/instance/pool.d.ts.map +1 -1
  53. package/dist/instance/pool.js +4 -1
  54. package/dist/instance/pool.js.map +1 -1
  55. package/dist/mcp/complete-delivery.d.ts +38 -0
  56. package/dist/mcp/complete-delivery.d.ts.map +1 -0
  57. package/dist/mcp/complete-delivery.js +126 -0
  58. package/dist/mcp/complete-delivery.js.map +1 -0
  59. package/dist/mcp/kinds.d.ts.map +1 -1
  60. package/dist/mcp/kinds.js +2 -1
  61. package/dist/mcp/kinds.js.map +1 -1
  62. package/dist/mcp/response.d.ts +4 -14
  63. package/dist/mcp/response.d.ts.map +1 -1
  64. package/dist/mcp/response.js +11 -16
  65. package/dist/mcp/response.js.map +1 -1
  66. package/dist/mcp/roles.js +2 -2
  67. package/dist/mcp/roles.js.map +1 -1
  68. package/dist/mcp/server.d.ts.map +1 -1
  69. package/dist/mcp/server.js +3 -0
  70. package/dist/mcp/server.js.map +1 -1
  71. package/dist/mcp/tools/document-receipt.d.ts +5 -0
  72. package/dist/mcp/tools/document-receipt.d.ts.map +1 -1
  73. package/dist/mcp/tools/document-receipt.js +11 -2
  74. package/dist/mcp/tools/document-receipt.js.map +1 -1
  75. package/dist/mcp/tools/guarded-create.d.ts +33 -0
  76. package/dist/mcp/tools/guarded-create.d.ts.map +1 -0
  77. package/dist/mcp/tools/guarded-create.js +73 -0
  78. package/dist/mcp/tools/guarded-create.js.map +1 -0
  79. package/dist/mcp/with-session.d.ts +2 -0
  80. package/dist/mcp/with-session.d.ts.map +1 -1
  81. package/dist/mcp/with-session.js +55 -20
  82. package/dist/mcp/with-session.js.map +1 -1
  83. package/dist/schema/loader.d.ts +12 -1
  84. package/dist/schema/loader.d.ts.map +1 -1
  85. package/dist/schema/loader.js +48 -15
  86. package/dist/schema/loader.js.map +1 -1
  87. package/package.json +1 -1
package/README.md CHANGED
@@ -25,6 +25,8 @@ MAADb stores records as markdown files with YAML frontmatter for structured fiel
25
25
 
26
26
  MAADb works as a context engine for AI agents — a place to hold the information they need to keep working, when that context still needs structure. Records are typed, relationships are queryable through MCP, and the data stays as readable markdown on disk. Common shapes: agent memory, project state, ongoing case files. For high-throughput transactional data or pure semantic retrieval at scale, purpose-built tools serve better.
27
27
 
28
+ Guarded-write consumers can use [compact complete contracts and receipt pages](docs/complete-delivery.md), with separate query and contract response budgets.
29
+
28
30
  ## Quick example
29
31
 
30
32
  A record lives as markdown with a schema-validated YAML header:
@@ -0,0 +1,5 @@
1
+ import type { DeliveryPage } from '../mcp/complete-delivery.js';
2
+ import type { JsonValue } from '../engine/document-receipt-types.js';
3
+ /** Assemble only complete, ordered, unexpired observations. Never accepts a summary. */
4
+ export declare function assembleCompleteDelivery(pages: readonly DeliveryPage[], now?: number): JsonValue;
5
+ //# sourceMappingURL=complete-delivery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete-delivery.d.ts","sourceRoot":"","sources":["../../src/client/complete-delivery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAErE,wFAAwF;AACxF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,SAAa,GAAG,SAAS,CA2BpG"}
@@ -0,0 +1,38 @@
1
+ import { rawSha256 } from '../engine/document-receipt.js';
2
+ import { canonicalDeliveryJson } from '../engine/delivery-json.js';
3
+ import { expandCompactJson } from '../engine/compact-json.js';
4
+ /** Assemble only complete, ordered, unexpired observations. Never accepts a summary. */
5
+ export function assembleCompleteDelivery(pages, now = Date.now()) {
6
+ if (!Array.isArray(pages))
7
+ throw new Error('Invalid delivery pages');
8
+ const first = pages[0];
9
+ if (!first || pages.length > 1024 || first.totalBytes > 1024 * 1024 || first.totalBytes <= 0
10
+ || first.totalCharacters > 1024 * 1024 || first.totalCharacters <= 0)
11
+ throw new Error('Invalid delivery bounds');
12
+ let offset = 0;
13
+ const chunks = [];
14
+ for (const [index, page] of pages.entries()) {
15
+ if (![page.totalBytes, page.totalCharacters, page.offset, page.endOffset, page.expiresAt].every(Number.isSafeInteger)
16
+ || typeof page.chunk !== 'string' || !/^[0-9a-f]{64}$/.test(page.digest) || !/^[0-9a-f]{64}$/.test(page.packedDigest)
17
+ || page.delivery !== 'complete-json-v1' || page.encoding !== 'shape-json-v1'
18
+ || page.snapshotId !== first.snapshotId || page.digest !== first.digest || page.packedDigest !== first.packedDigest
19
+ || page.totalBytes !== first.totalBytes || page.totalCharacters !== first.totalCharacters
20
+ || page.expiresAt !== first.expiresAt || page.expiresAt <= now || page.offset !== offset
21
+ || page.endOffset !== page.offset + page.chunk.length || page.endOffset > first.totalCharacters
22
+ || page.endOffset <= page.offset || page.complete !== (page.endOffset === first.totalCharacters)
23
+ || page.complete !== (index === pages.length - 1)
24
+ || page.nextCursor !== (page.complete ? null : `${page.snapshotId}:${page.endOffset}`))
25
+ throw new Error('Incomplete or mixed delivery');
26
+ chunks.push(page.chunk);
27
+ offset = page.endOffset;
28
+ }
29
+ const packed = chunks.join('');
30
+ if (offset !== first.totalCharacters || Buffer.byteLength(packed) !== first.totalBytes
31
+ || rawSha256(Buffer.from(packed)) !== first.packedDigest)
32
+ throw new Error('Delivery integrity mismatch');
33
+ const data = expandCompactJson(JSON.parse(packed));
34
+ if (rawSha256(Buffer.from(canonicalDeliveryJson(data))) !== first.digest)
35
+ throw new Error('Complete digest mismatch');
36
+ return data;
37
+ }
38
+ //# sourceMappingURL=complete-delivery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete-delivery.js","sourceRoot":"","sources":["../../src/client/complete-delivery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { JsonValue } from './document-receipt-types.js';
2
+ export interface CompactJson {
3
+ encoding: 'shape-json-v1';
4
+ /** Each shape lists value keys, then keys whose value is exactly null. */
5
+ shapes: [string[], string[]][];
6
+ value: JsonValue;
7
+ }
8
+ /** Lossless JSON encoding. Arrays use [0,...items], objects [1,shape,...values]. */
9
+ export declare function compactJson(input: unknown): CompactJson;
10
+ /** Reference decoder: bounded input, exact arity, no prototype assignment. */
11
+ export declare function expandCompactJson(input: CompactJson): JsonValue;
12
+ //# sourceMappingURL=compact-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact-json.d.ts","sourceRoot":"","sources":["../../src/engine/compact-json.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,0EAA0E;IAC1E,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC/B,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAgBvD;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAkD/D"}
@@ -0,0 +1,87 @@
1
+ import { canonicalJson } from './document-receipt.js';
2
+ import { canonicalDeliveryJson, DELIVERY_JSON_LIMITS } from './delivery-json.js';
3
+ /** Lossless JSON encoding. Arrays use [0,...items], objects [1,shape,...values]. */
4
+ export function compactJson(input) {
5
+ const source = JSON.parse(canonicalDeliveryJson(input));
6
+ const shapes = [];
7
+ const indices = new Map();
8
+ const encode = (value) => {
9
+ if (value === null || typeof value !== 'object')
10
+ return value;
11
+ if (Array.isArray(value))
12
+ return [0, ...value.map(encode)];
13
+ const keys = Object.keys(value).sort();
14
+ const shape = [keys.filter(k => value[k] !== null), keys.filter(k => value[k] === null)];
15
+ const signature = JSON.stringify(shape);
16
+ let index = indices.get(signature);
17
+ if (index === undefined) {
18
+ index = shapes.length;
19
+ shapes.push(shape);
20
+ indices.set(signature, index);
21
+ }
22
+ return [1, index, ...shape[0].map(k => encode(value[k]))];
23
+ };
24
+ const value = encode(source);
25
+ return { encoding: 'shape-json-v1', shapes, value };
26
+ }
27
+ /** Reference decoder: bounded input, exact arity, no prototype assignment. */
28
+ export function expandCompactJson(input) {
29
+ // Tags add nodes that are absent from the expanded value. Bound shapes
30
+ // independently; the decoder and final canonicalization bound expanded data.
31
+ canonicalJson({ encoding: input.encoding, shapes: input.shapes }, {
32
+ nodes: DELIVERY_JSON_LIMITS.nodes * 4, depth: 5, scalarBytes: DELIVERY_JSON_LIMITS.scalarBytes,
33
+ });
34
+ if (input.encoding !== 'shape-json-v1' || !Array.isArray(input.shapes))
35
+ throw new Error('Invalid compact encoding');
36
+ for (const shape of input.shapes) {
37
+ if (!Array.isArray(shape) || shape.length !== 2 || !shape.every(keys => Array.isArray(keys) && keys.every(k => typeof k === 'string'))
38
+ || new Set(shape.flat()).size !== shape.flat().length)
39
+ throw new Error('Invalid compact shape');
40
+ }
41
+ let nodes = 0;
42
+ let bytes = 0;
43
+ const charge = (count, size, depth) => {
44
+ nodes += count;
45
+ bytes += size;
46
+ if (nodes > DELIVERY_JSON_LIMITS.nodes || depth > DELIVERY_JSON_LIMITS.depth || bytes > DELIVERY_JSON_LIMITS.scalarBytes)
47
+ throw new Error('Compact structure exceeds bounds');
48
+ };
49
+ // Charge repeated property names and omitted nulls before allocating each
50
+ // object. A small shape table must not amplify into unbounded decoded data.
51
+ const costs = input.shapes.map(([keys, nullKeys]) => ({
52
+ nodes: keys.length + nullKeys.length * 2,
53
+ bytes: [...keys, ...nullKeys].reduce((sum, key) => sum + Buffer.byteLength(JSON.stringify(key)), nullKeys.length * 4),
54
+ }));
55
+ const decode = (value, depth) => {
56
+ charge(1, 0, depth);
57
+ if (value === null || typeof value !== 'object') {
58
+ if (!(value === null || typeof value === 'string' || typeof value === 'boolean' || (typeof value === 'number' && Number.isFinite(value))))
59
+ throw new Error('Invalid compact primitive');
60
+ charge(0, Buffer.byteLength(JSON.stringify(value)), depth);
61
+ return value;
62
+ }
63
+ if (!Array.isArray(value))
64
+ throw new Error('Invalid compact node');
65
+ if (value[0] === 0) {
66
+ const result = [];
67
+ for (let i = 1; i < value.length; i++)
68
+ result.push(decode(value[i], depth + 1));
69
+ return result;
70
+ }
71
+ const index = value[1];
72
+ const shape = typeof index === 'number' && Number.isInteger(index) ? input.shapes[index] : undefined;
73
+ if (value[0] !== 1 || !shape || value.length !== shape[0].length + 2)
74
+ throw new Error('Invalid compact object');
75
+ const cost = costs[index];
76
+ charge(cost.nodes, cost.bytes, cost.nodes ? depth + 1 : depth);
77
+ const result = Object.create(null);
78
+ for (const key of shape[1])
79
+ result[key] = null;
80
+ shape[0].forEach((key, i) => { result[key] = decode(value[i + 2], depth + 1); });
81
+ return result;
82
+ };
83
+ const value = decode(input.value, 0);
84
+ canonicalDeliveryJson(value);
85
+ return value;
86
+ }
87
+ //# sourceMappingURL=compact-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact-json.js","sourceRoot":"","sources":["../../src/engine/compact-json.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,7 @@ export interface CommitFailureTracker {
21
21
  }
22
22
  export declare function newCommitFailureTracker(): CommitFailureTracker;
23
23
  export interface EngineContext {
24
+ contractPreparationCache?: import('./contract-preparation-cache.js').ContractPreparationCache;
24
25
  projectRoot: string;
25
26
  registry: Registry;
26
27
  schemaStore: SchemaStore;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/engine/context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IAClD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAS9D;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,oBAAoB,CAAC;IACrC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAkC/F"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/engine/context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IAClD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,CAS9D;AAED,MAAM,WAAW,aAAa;IAC5B,wBAAwB,CAAC,EAAE,OAAO,iCAAiC,EAAE,wBAAwB,CAAC;IAC9F,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,oBAAoB,CAAC;IACrC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAkC/F"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/engine/context.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6DAA6D;AAC7D,+EAA+E;AAS/E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAiBjD,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAiCD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAkB,EAAE,IAAmB;IACrE,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC7D,oEAAoE;IACpE,4EAA4E;IAC5E,4DAA4D;IAC5D,MAAM,QAAQ,GAAkB,GAAG,CAAC,cAAc,KAAK,SAAS;QAC9D,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,cAAc,EAAE;QAC3C,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO;QACzB,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,CAAC,QAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChD,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChC,GAAG,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC3B,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrD,GAAG,CAAC,cAAc,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;QAC3C,GAAG,CAAC,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;QACjD,GAAG,CAAC,cAAc,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5C,GAAG,CAAC,cAAc,CAAC,SAAS,GAAG,IAAI,CAAC,KAAe,CAAC;QACpD,gBAAgB,CAAC;YACf,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,KAAe;YAC5B,QAAQ,EAAE,IAAI,CAAC,OAAiB;YAChC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;SAC9B,CAAC,CAAC;QACH,wEAAwE;QACxE,yDAAyD;QACzD,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,yBAAyB,IAAI,CAAC,KAAe,KAAK,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/engine/context.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6DAA6D;AAC7D,+EAA+E;AAS/E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAiBjD,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAkCD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAkB,EAAE,IAAmB;IACrE,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC7D,oEAAoE;IACpE,4EAA4E;IAC5E,4DAA4D;IAC5D,MAAM,QAAQ,GAAkB,GAAG,CAAC,cAAc,KAAK,SAAS;QAC9D,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,cAAc,EAAE;QAC3C,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO;QACzB,CAAC,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,CAAC,QAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChD,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAChC,GAAG,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC3B,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrD,GAAG,CAAC,cAAc,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;QAC3C,GAAG,CAAC,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;QACjD,GAAG,CAAC,cAAc,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5C,GAAG,CAAC,cAAc,CAAC,SAAS,GAAG,IAAI,CAAC,KAAe,CAAC;QACpD,gBAAgB,CAAC;YACf,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,KAAe;YAC5B,QAAQ,EAAE,IAAI,CAAC,OAAiB;YAChC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;SAC9B,CAAC,CAAC;QACH,wEAAwE;QACxE,yDAAyD;QACzD,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,yBAAyB,IAAI,CAAC,KAAe,KAAK,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { SchemaStore } from '../types.js';
2
+ /** One bounded, private preparation per engine; never stores authority or history. */
3
+ export declare class ContractPreparationCache {
4
+ private entry;
5
+ clear(): void;
6
+ get(key: string, cachedFiles: SchemaStore['cachedFiles']): SchemaStore | undefined;
7
+ set(key: string, store: SchemaStore): void;
8
+ }
9
+ //# sourceMappingURL=contract-preparation-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-preparation-cache.d.ts","sourceRoot":"","sources":["../../src/engine/contract-preparation-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,sFAAsF;AACtF,qBAAa,wBAAwB;IACnC,OAAO,CAAC,KAAK,CAA+D;IAE5E,KAAK,IAAI,IAAI;IAEb,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC,GAAG,WAAW,GAAG,SAAS;IAkBlF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI;CAG3C"}
@@ -0,0 +1,31 @@
1
+ import { statSync } from 'node:fs';
2
+ /** One bounded, private preparation per engine; never stores authority or history. */
3
+ export class ContractPreparationCache {
4
+ entry;
5
+ clear() { this.entry = undefined; }
6
+ get(key, cachedFiles) {
7
+ if (this.entry?.key !== key)
8
+ return undefined;
9
+ // Neither callers nor the activated legacy store can mutate cached definitions.
10
+ const schemas = structuredClone(this.entry.schemas);
11
+ const files = new Map(cachedFiles);
12
+ return {
13
+ schemas, cachedFiles: files,
14
+ getSchema: ref => schemas.get(ref),
15
+ getSchemaForType: type => [...schemas.values()].find(schema => schema.type === type),
16
+ isStale: () => [...files].some(([file, expected]) => {
17
+ try {
18
+ const actual = statSync(file);
19
+ return actual.mtimeMs !== expected.mtimeMs || actual.size !== expected.size;
20
+ }
21
+ catch {
22
+ return true;
23
+ }
24
+ }),
25
+ };
26
+ }
27
+ set(key, store) {
28
+ this.entry = { key, schemas: structuredClone(store.schemas) };
29
+ }
30
+ }
31
+ //# sourceMappingURL=contract-preparation-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-preparation-cache.js","sourceRoot":"","sources":["../../src/engine/contract-preparation-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,sFAAsF;AACtF,MAAM,OAAO,wBAAwB;IAC3B,KAAK,CAA+D;IAE5E,KAAK,KAAW,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC;IAEzC,GAAG,CAAC,GAAW,EAAE,WAAuC;QACtD,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG;YAAE,OAAO,SAAS,CAAC;QAC9C,gFAAgF;QAChF,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;QACnC,OAAO;YACL,OAAO,EAAE,WAAW,EAAE,KAAK;YAC3B,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAClC,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC;YACpF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE;gBAClD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAC9B,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC;gBAC9E,CAAC;gBAAC,MAAM,CAAC;oBAAC,OAAO,IAAI,CAAC;gBAAC,CAAC;YAC1B,CAAC,CAAC;SACH,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAkB;QACjC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;IAChE,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import { type Registry, type SchemaStore } from '../types.js';
2
+ import type { CreateContract } from './guarded-create-types.js';
3
+ import type { ContractPreparationCache } from './contract-preparation-cache.js';
4
+ import type { EngineContext } from './context.js';
5
+ /** No registry activation, directory creation, index rebuild, or stale fallback. */
6
+ export declare function freshCreateContract(ctx: EngineContext, type: string, signal?: AbortSignal, cache?: ContractPreparationCache): Promise<{
7
+ contract: CreateContract;
8
+ registry: Registry;
9
+ schemaStore: SchemaStore;
10
+ }>;
11
+ //# 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,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAChF,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,EAAE,KAAK,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC;IAC3I,QAAQ,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,WAAW,CAAC;CACxE,CAAC,CA2FD"}
@@ -0,0 +1,141 @@
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, cache) {
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
+ await read(`_schema/${def.schema}.yaml`);
88
+ if (def.template)
89
+ await read(def.template);
90
+ }
91
+ if (!registry.types.has(docType(type)))
92
+ throw new ReceiptError('UNKNOWN_TYPE', 'Unknown contract document type');
93
+ // Validate exactly the bounded captured sources, with no disk-reader fallback.
94
+ // Both effective identity and document preparation use this validated store.
95
+ // Decode like the legacy disk reader (including BOMs); capture already checked
96
+ // UTF-8 validity. Keep the existing source projection and parser behavior.
97
+ const schemaSources = new Map([...registry.types.values()].map(def => [def.schemaRef, capturedBytes.get(`_schema/${def.schemaRef}.yaml`).toString('utf8')]));
98
+ // Identity includes every captured dependency, not mtime/size or a type-only key.
99
+ const preparationKey = rawSha256(Buffer.from(canonicalJson([...capturedBytes].map(([file, bytes]) => [file, rawSha256(bytes)]))));
100
+ let prepared = cache?.get(preparationKey, cachedFiles);
101
+ if (!prepared) {
102
+ cache?.clear();
103
+ for (const [name, def] of entries) {
104
+ const schema = parseSource(sources[`_schema/${def.schema}.yaml`]);
105
+ // Refuse malformed top-level shapes that the legacy loader tolerates.
106
+ z.object({ type: z.literal(name), version: z.number().int().positive().optional(),
107
+ required: z.array(z.string()).optional(), fields: z.record(z.string(), z.object({ type: z.string() }).passthrough()),
108
+ template: z.object({ headings: z.array(z.object({ level: z.number().int().min(1).max(6),
109
+ text: z.string(), id: z.string().nullable().optional() }).passthrough()) }).passthrough().optional(),
110
+ }).passthrough().parse(schema);
111
+ }
112
+ const loaded = await loadSchemasFromSnapshot(registry, schemaSources, { signal, cachedFiles });
113
+ if (signal?.aborted)
114
+ throw new ReceiptError('REQUEST_TIMEOUT', 'Schema snapshot validation cancelled');
115
+ if (!loaded.ok)
116
+ throw new ReceiptError('SCHEMA_INVALID', 'Fresh schema validation failed');
117
+ prepared = loaded.value;
118
+ }
119
+ if (signal?.aborted)
120
+ throw new ReceiptError('REQUEST_TIMEOUT', 'Schema snapshot validation cancelled');
121
+ for (const [relative, expected] of Object.entries(sources)) {
122
+ const actual = await readWorkingReceipt(ctx.projectRoot, relative, signal);
123
+ if (!actual.equals(Buffer.from(expected)))
124
+ throw new ReceiptError('SCHEMA_CONTRACT_CHANGED', 'Schema changed during observation');
125
+ }
126
+ const schemaContract = {
127
+ projection: 'create-schema-v1', engineVersion,
128
+ contentProjection: 'document-content-v1',
129
+ sources, effective: effectiveContract(registry, prepared),
130
+ };
131
+ const canonical = canonicalJson(schemaContract);
132
+ if (Buffer.byteLength(canonical) > 512 * 1024)
133
+ throw new ReceiptError('RESPONSE_TOO_LARGE', 'Complete schema contract exceeds bound');
134
+ cache?.set(preparationKey, prepared);
135
+ return { registry, schemaStore: prepared, contract: {
136
+ contract: 'create-contract-v1', docType: type, schemaDigest: rawSha256(Buffer.from(canonical)),
137
+ schemaProjection: 'create-schema-v1', contentProjection: 'document-content-v1', schemaContract,
138
+ effectiveHistoryMode: ctx.history?.config.effectiveMode ?? 'feed',
139
+ } };
140
+ }
141
+ //# 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,7 @@
1
+ export declare const DELIVERY_JSON_LIMITS: Readonly<{
2
+ nodes: number;
3
+ depth: number;
4
+ scalarBytes: number;
5
+ }>;
6
+ export declare const canonicalDeliveryJson: (value: unknown) => string;
7
+ //# sourceMappingURL=delivery-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-json.d.ts","sourceRoot":"","sources":["../../src/engine/delivery-json.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,oBAAoB;;;;EAAqF,CAAC;AACvH,eAAO,MAAM,qBAAqB,GAAI,OAAO,OAAO,KAAG,MAAoD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { canonicalJson } from './document-receipt.js';
2
+ // Delivery contains an already-validated v1 value plus receipt/contract metadata
3
+ // and raw content copies. These allowances do not change v1 admission limits.
4
+ export const DELIVERY_JSON_LIMITS = Object.freeze({ nodes: 65536 + 256, depth: 64 + 4, scalarBytes: 2 * 1024 * 1024 });
5
+ export const canonicalDeliveryJson = (value) => canonicalJson(value, DELIVERY_JSON_LIMITS);
6
+ //# sourceMappingURL=delivery-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-json.js","sourceRoot":"","sources":["../../src/engine/delivery-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,iFAAiF;AACjF,8EAA8E;AAC9E,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;AACvH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC"}
@@ -3,7 +3,11 @@ import type { EngineContext } from './context.js';
3
3
  import type { DocumentReceipt, DocumentReceiptRequest, JsonValue } from './document-receipt-types.js';
4
4
  export declare const rawSha256: (bytes: Buffer) => string;
5
5
  /** Explicit serialization preserves UTF-16 key ordering even for integer-like keys. */
6
- export declare function canonicalJson(value: unknown): string;
6
+ export declare function canonicalJson(value: unknown, limits?: {
7
+ nodes: number;
8
+ depth: number;
9
+ scalarBytes: number;
10
+ }): string;
7
11
  export declare function contentDigest(id: string, type: string, frontmatter: Record<string, JsonValue>, body: string): string;
8
12
  export declare function parseReceiptContent(bytes: Buffer, id: string, type: string, schema: string): {
9
13
  rawMarkdown: string;
@@ -11,7 +15,12 @@ export declare function parseReceiptContent(bytes: Buffer, id: string, type: str
11
15
  body: string;
12
16
  contentDigest: string;
13
17
  };
14
- /** One bounded handle read; compare both handle and pathname identity around it. */
15
18
  export declare function readWorkingReceipt(root: string, relative: string, signal?: AbortSignal): Promise<Buffer>;
19
+ /** One bounded handle read; compare both handle and pathname identity around it. */
20
+ export declare function readWorkingReceiptSnapshot(root: string, relative: string, signal?: AbortSignal): Promise<{
21
+ bytes: Buffer;
22
+ mtimeMs: number;
23
+ size: number;
24
+ }>;
16
25
  export declare function documentReceipt(ctx: EngineContext, request: DocumentReceiptRequest, project: string, signal?: AbortSignal): Promise<Result<DocumentReceipt>>;
17
26
  //# sourceMappingURL=document-receipt.d.ts.map
@@ -1 +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,CAkCpD;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,oFAAoF;AACpF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAgC9G;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"}
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,EAAE,MAAM;;;;CAAwD,GAAG,MAAM,CAuCpH;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"}
@@ -12,17 +12,17 @@ import { docId, docType } from '../types.js';
12
12
  const version = createRequire(import.meta.url)('../../package.json').version;
13
13
  export const rawSha256 = (bytes) => createHash('sha256').update(bytes).digest('hex');
14
14
  /** Explicit serialization preserves UTF-16 key ordering even for integer-like keys. */
15
- export function canonicalJson(value) {
15
+ export function canonicalJson(value, limits = { nodes: 65536, depth: 64, scalarBytes: 1024 * 1024 }) {
16
16
  const seen = new Set();
17
17
  let nodes = 0;
18
18
  let bytes = 0;
19
19
  const encode = (v, depth) => {
20
- if (++nodes > 65536 || depth > 64)
20
+ if (++nodes > limits.nodes || depth > limits.depth)
21
21
  throw new ReceiptError('RECEIPT_CONTENT_INVALID', 'Content structure exceeds bounds');
22
22
  if (v === null || typeof v === 'boolean' || typeof v === 'string' || (typeof v === 'number' && Number.isFinite(v))) {
23
23
  const text = JSON.stringify(v);
24
24
  bytes += Buffer.byteLength(text);
25
- if (bytes > 1024 * 1024)
25
+ if (bytes > limits.scalarBytes)
26
26
  throw new ReceiptError('RESPONSE_TOO_LARGE', 'Canonical content exceeds bound');
27
27
  return text;
28
28
  }
@@ -34,6 +34,13 @@ export function canonicalJson(value) {
34
34
  }
35
35
  if (Reflect.ownKeys(v).some(key => typeof key !== 'string'))
36
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
+ }
37
44
  seen.add(v);
38
45
  let result;
39
46
  if (Array.isArray(v)) {
@@ -102,8 +109,11 @@ async function checkedPath(root, relative) {
102
109
  throw new ReceiptError('PATH_OUTSIDE_PROJECT', 'Receipt path escapes project');
103
110
  return target;
104
111
  }
105
- /** One bounded handle read; compare both handle and pathname identity around it. */
106
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) {
107
117
  checkReceiptAbort(signal);
108
118
  const target = await checkedPath(root, relative);
109
119
  const before = await lstat(target, { bigint: true });
@@ -118,6 +128,10 @@ export async function readWorkingReceipt(root, relative, signal) {
118
128
  throw new ReceiptError('RECEIPT_OBSERVATION_CHANGED', 'Working file changed before read');
119
129
  if (opened.size > BigInt(RECEIPT_MAX_BYTES))
120
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();
121
135
  const buffer = Buffer.alloc(Number(opened.size) + 1);
122
136
  let length = 0;
123
137
  while (length < buffer.length) {
@@ -140,7 +154,7 @@ export async function readWorkingReceipt(root, relative, signal) {
140
154
  throw new ReceiptError('RECEIPT_OBSERVATION_CHANGED', 'Working file changed during read');
141
155
  }
142
156
  checkReceiptAbort(signal);
143
- return buffer.subarray(0, length);
157
+ return { bytes: buffer.subarray(0, length), mtimeMs: cached.mtimeMs, size: cached.size };
144
158
  }
145
159
  finally {
146
160
  await handle.close();