@ttsc/unplugin 0.35.0 → 0.36.1

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 (127) hide show
  1. package/lib/core/transform/cache/TtscCachedProjectTransform.d.cts +22 -0
  2. package/lib/core/transform/cache/TtscCachedProjectTransform.d.mts +22 -0
  3. package/lib/core/transform/cache/TtscCachedProjectTransform.d.ts +22 -0
  4. package/lib/core/transform/deliverCachedTransform.js +4 -1
  5. package/lib/core/transform/deliverCachedTransform.js.map +1 -1
  6. package/lib/core/transform/deliverCachedTransform.mjs +4 -1
  7. package/lib/core/transform/deliverCachedTransform.mjs.map +1 -1
  8. package/lib/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.d.cts +16 -0
  9. package/lib/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.d.mts +16 -0
  10. package/lib/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.d.ts +16 -0
  11. package/lib/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.js +28 -0
  12. package/lib/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.js.map +1 -0
  13. package/lib/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.mjs +26 -0
  14. package/lib/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.mjs.map +1 -0
  15. package/lib/core/transform/generation/TtscGenerationProofFailures.d.cts +19 -0
  16. package/lib/core/transform/generation/TtscGenerationProofFailures.d.mts +19 -0
  17. package/lib/core/transform/generation/TtscGenerationProofFailures.d.ts +19 -0
  18. package/lib/core/transform/generation/canDeliverCompilerSnapshot.d.cts +25 -0
  19. package/lib/core/transform/generation/canDeliverCompilerSnapshot.d.mts +25 -0
  20. package/lib/core/transform/generation/canDeliverCompilerSnapshot.d.ts +25 -0
  21. package/lib/core/transform/generation/canDeliverCompilerSnapshot.js +42 -0
  22. package/lib/core/transform/generation/canDeliverCompilerSnapshot.js.map +1 -0
  23. package/lib/core/transform/generation/canDeliverCompilerSnapshot.mjs +40 -0
  24. package/lib/core/transform/generation/canDeliverCompilerSnapshot.mjs.map +1 -0
  25. package/lib/core/transform/generation/captureTransformGeneration.js +35 -11
  26. package/lib/core/transform/generation/captureTransformGeneration.js.map +1 -1
  27. package/lib/core/transform/generation/captureTransformGeneration.mjs +35 -11
  28. package/lib/core/transform/generation/captureTransformGeneration.mjs.map +1 -1
  29. package/lib/core/transform/generation/captureTransformSourceHashes.d.cts +8 -6
  30. package/lib/core/transform/generation/captureTransformSourceHashes.d.mts +8 -6
  31. package/lib/core/transform/generation/captureTransformSourceHashes.d.ts +8 -6
  32. package/lib/core/transform/generation/captureTransformSourceHashes.js +16 -8
  33. package/lib/core/transform/generation/captureTransformSourceHashes.js.map +1 -1
  34. package/lib/core/transform/generation/captureTransformSourceHashes.mjs +16 -8
  35. package/lib/core/transform/generation/captureTransformSourceHashes.mjs.map +1 -1
  36. package/lib/core/transform/generation/compilerSnapshotFailureClassifier.d.cts +18 -0
  37. package/lib/core/transform/generation/compilerSnapshotFailureClassifier.d.mts +18 -0
  38. package/lib/core/transform/generation/compilerSnapshotFailureClassifier.d.ts +18 -0
  39. package/lib/core/transform/generation/compilerSnapshotFailureClassifier.js +75 -0
  40. package/lib/core/transform/generation/compilerSnapshotFailureClassifier.js.map +1 -0
  41. package/lib/core/transform/generation/compilerSnapshotFailureClassifier.mjs +73 -0
  42. package/lib/core/transform/generation/compilerSnapshotFailureClassifier.mjs.map +1 -0
  43. package/lib/core/transform/generation/createGenerationProofFailures.d.cts +3 -3
  44. package/lib/core/transform/generation/createGenerationProofFailures.d.mts +3 -3
  45. package/lib/core/transform/generation/createGenerationProofFailures.d.ts +3 -3
  46. package/lib/core/transform/generation/createGenerationProofFailures.js +11 -4
  47. package/lib/core/transform/generation/createGenerationProofFailures.js.map +1 -1
  48. package/lib/core/transform/generation/createGenerationProofFailures.mjs +11 -4
  49. package/lib/core/transform/generation/createGenerationProofFailures.mjs.map +1 -1
  50. package/lib/core/transform/generation/mergeGenerationProofFailures.d.cts +4 -4
  51. package/lib/core/transform/generation/mergeGenerationProofFailures.d.mts +4 -4
  52. package/lib/core/transform/generation/mergeGenerationProofFailures.d.ts +4 -4
  53. package/lib/core/transform/generation/mergeGenerationProofFailures.js +11 -4
  54. package/lib/core/transform/generation/mergeGenerationProofFailures.js.map +1 -1
  55. package/lib/core/transform/generation/mergeGenerationProofFailures.mjs +11 -4
  56. package/lib/core/transform/generation/mergeGenerationProofFailures.mjs.map +1 -1
  57. package/lib/core/transform/generation/recordGenerationProofFailure.d.cts +4 -4
  58. package/lib/core/transform/generation/recordGenerationProofFailure.d.mts +4 -4
  59. package/lib/core/transform/generation/recordGenerationProofFailure.d.ts +4 -4
  60. package/lib/core/transform/generation/recordGenerationProofFailure.js +8 -4
  61. package/lib/core/transform/generation/recordGenerationProofFailure.js.map +1 -1
  62. package/lib/core/transform/generation/recordGenerationProofFailure.mjs +8 -4
  63. package/lib/core/transform/generation/recordGenerationProofFailure.mjs.map +1 -1
  64. package/lib/core/transform/generation/selectTransformAttemptDisposition.d.cts +11 -7
  65. package/lib/core/transform/generation/selectTransformAttemptDisposition.d.mts +11 -7
  66. package/lib/core/transform/generation/selectTransformAttemptDisposition.d.ts +11 -7
  67. package/lib/core/transform/generation/selectTransformAttemptDisposition.js +11 -7
  68. package/lib/core/transform/generation/selectTransformAttemptDisposition.js.map +1 -1
  69. package/lib/core/transform/generation/selectTransformAttemptDisposition.mjs +11 -7
  70. package/lib/core/transform/generation/selectTransformAttemptDisposition.mjs.map +1 -1
  71. package/lib/core/transform/generation/transformProject.js +1 -0
  72. package/lib/core/transform/generation/transformProject.js.map +1 -1
  73. package/lib/core/transform/generation/transformProject.mjs +1 -0
  74. package/lib/core/transform/generation/transformProject.mjs.map +1 -1
  75. package/lib/core/transform/validation/TtscGenerationProof.d.cts +4 -1
  76. package/lib/core/transform/validation/TtscGenerationProof.d.mts +4 -1
  77. package/lib/core/transform/validation/TtscGenerationProof.d.ts +4 -1
  78. package/lib/core/transform/validation/TtscGenerationProof.js +4 -1
  79. package/lib/core/transform/validation/TtscGenerationProof.js.map +1 -1
  80. package/lib/core/transform/validation/TtscGenerationProof.mjs +4 -1
  81. package/lib/core/transform/validation/TtscGenerationProof.mjs.map +1 -1
  82. package/lib/core/transform/validation/captureExternalInputSnapshot.js +1 -1
  83. package/lib/core/transform/validation/captureExternalInputSnapshot.js.map +1 -1
  84. package/lib/core/transform/validation/captureExternalInputSnapshot.mjs +1 -1
  85. package/lib/core/transform/validation/captureExternalInputSnapshot.mjs.map +1 -1
  86. package/lib/core/transform/validation/captureUniversalHostInputValidation.js +1 -1
  87. package/lib/core/transform/validation/captureUniversalHostInputValidation.js.map +1 -1
  88. package/lib/core/transform/validation/captureUniversalHostInputValidation.mjs +1 -1
  89. package/lib/core/transform/validation/captureUniversalHostInputValidation.mjs.map +1 -1
  90. package/lib/core/transform/validation/compilerGraphInputProofFailures.js +1 -1
  91. package/lib/core/transform/validation/compilerGraphInputProofFailures.js.map +1 -1
  92. package/lib/core/transform/validation/compilerGraphInputProofFailures.mjs +1 -1
  93. package/lib/core/transform/validation/compilerGraphInputProofFailures.mjs.map +1 -1
  94. package/lib/core/transform/validation/matchesCachedSource.d.cts +4 -2
  95. package/lib/core/transform/validation/matchesCachedSource.d.mts +4 -2
  96. package/lib/core/transform/validation/matchesCachedSource.d.ts +4 -2
  97. package/lib/core/transform/validation/matchesCachedSource.js +6 -2
  98. package/lib/core/transform/validation/matchesCachedSource.js.map +1 -1
  99. package/lib/core/transform/validation/matchesCachedSource.mjs +6 -2
  100. package/lib/core/transform/validation/matchesCachedSource.mjs.map +1 -1
  101. package/lib/core/transform/watch/evidencedWatchInput.d.cts +1 -1
  102. package/lib/core/transform/watch/evidencedWatchInput.d.mts +1 -1
  103. package/lib/core/transform/watch/evidencedWatchInput.d.ts +1 -1
  104. package/lib/core/transform/watch/evidencedWatchInput.js +6 -2
  105. package/lib/core/transform/watch/evidencedWatchInput.js.map +1 -1
  106. package/lib/core/transform/watch/evidencedWatchInput.mjs +6 -2
  107. package/lib/core/transform/watch/evidencedWatchInput.mjs.map +1 -1
  108. package/package.json +3 -3
  109. package/src/core/transform/cache/TtscCachedProjectTransform.ts +24 -0
  110. package/src/core/transform/deliverCachedTransform.ts +5 -1
  111. package/src/core/transform/filesystem/matchesNativeCompilerSnapshotFilesystem.ts +31 -0
  112. package/src/core/transform/generation/TtscGenerationProofFailures.ts +21 -0
  113. package/src/core/transform/generation/canDeliverCompilerSnapshot.ts +50 -0
  114. package/src/core/transform/generation/captureTransformGeneration.ts +50 -13
  115. package/src/core/transform/generation/captureTransformSourceHashes.ts +19 -8
  116. package/src/core/transform/generation/compilerSnapshotFailureClassifier.ts +80 -0
  117. package/src/core/transform/generation/createGenerationProofFailures.ts +13 -4
  118. package/src/core/transform/generation/mergeGenerationProofFailures.ts +13 -4
  119. package/src/core/transform/generation/recordGenerationProofFailure.ts +8 -4
  120. package/src/core/transform/generation/selectTransformAttemptDisposition.ts +14 -7
  121. package/src/core/transform/generation/transformProject.ts +1 -0
  122. package/src/core/transform/validation/TtscGenerationProof.ts +4 -1
  123. package/src/core/transform/validation/captureExternalInputSnapshot.ts +3 -1
  124. package/src/core/transform/validation/captureUniversalHostInputValidation.ts +3 -1
  125. package/src/core/transform/validation/compilerGraphInputProofFailures.ts +3 -1
  126. package/src/core/transform/validation/matchesCachedSource.ts +7 -2
  127. package/src/core/transform/watch/evidencedWatchInput.ts +7 -2
@@ -6,22 +6,24 @@ import { hostInputStateHash } from '../inputs/hostInputStateHash.mjs';
6
6
 
7
7
  /**
8
8
  * Capture native host-state hashes for source paths named by transform outputs,
9
- * including sources outside the project walk. Reads hash raw bytes; a failed
10
- * read of an observed directory retains the host-state directory marker, while
11
- * other unreadable output paths remain absent.
9
+ * including sources outside the project walk. Snapshot-only delivery instead
10
+ * preserves the compiler's recorded hash where available. Ordinary reads hash
11
+ * raw bytes; a failed read of an observed directory retains the host-state
12
+ * directory marker, while other unreadable output paths remain absent.
12
13
  *
13
14
  * The current source identity is then overwritten with the caller's selected
14
15
  * hash even when no output names it. Capture supplies its post-compile project
15
16
  * walk's disk hash when available and otherwise the delivered-text hash; that
16
17
  * fallback does not establish that the compiler observed those bytes. If the
17
- * output pass already read this source, the final assignment does not undo it.
18
+ * output pass already recorded this source for snapshot-only delivery, the
19
+ * compiler's hash keeps precedence over the caller fallback.
18
20
  *
19
- * @evidence contracts/common.md#principled-implementation Successful output keys identify source paths relative to the project; native host-state hashes become identity-keyed baselines and the caller's selected disk-or-delivery hash overrides the current identity without granting generation completeness.
21
+ * @evidence contracts/common.md#principled-implementation Successful output keys identify source paths relative to the project; native host-state hashes become identity-keyed baselines and the caller's selected disk-or-delivery hash overrides the current identity for ordinary delivery, while snapshot-only delivery preserves captured compiler hashes without granting generation completeness.
20
22
  * @evidence contracts/common.md#clear-and-simple-design This helper constructs only the source baseline map; resultFilesystem supplies native reads and envelopeDerivation supplies the generation's shared identity context.
21
23
  * @evidence contracts/common.md#prohibited-implementation-shortcuts Non-directory failed reads supply no fabricated output-source hash, and transformed output text is never hashed as source. The explicitly supplied current-source fallback is distinguished from native disk evidence; the capture owner separately decides completeness and reuse.
22
24
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs distinguish raw host state, directory markers and failed reads from the current source's caller-selected fallback and explain the output-pass read that an override cannot avoid.
23
25
  * @evidence contracts/portability.md#os-neutral-implementation Output paths are resolved with Node native semantics and compared through the envelope identity context; no case folding or OS-specific file reader is introduced.
24
- * @evidence contracts/performance.md#efficient-algorithms Object.keys allocates the full output-key array, then one pass resolves native spellings, reads and hashes each exposed source's bytes and inserts successful host states. Failed reads may stat; identity resolution may observe uncached ancestors and case capabilities. Distinct output spellings may repeat a physical read before sharing one key. Map storage grows with distinct identities and key text; the final current assignment adds no read beyond that pass.
26
+ * @evidence contracts/performance.md#efficient-algorithms Object.keys allocates the full output-key array, then one pass resolves native spellings and inserts compiler-recorded hashes for snapshot-only delivery, otherwise reading and hashing each exposed source's bytes for host state. Failed reads may stat; identity resolution may observe uncached ancestors and case capabilities. Distinct output spellings may repeat a physical read before sharing one key. Map storage grows with distinct identities and key text; the final current assignment adds no read beyond that pass.
25
27
  * @evidence contracts/performance.md#reuse-equivalent-work The caller's selected current hash and the immutable envelope's identity transaction are reused; the output pass does not memoize content reads by physical identity. The fresh map belongs to this capture rather than reusing historical content across changes.
26
28
  * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Generation capture owns the returned baseline map's lifetime; this helper acquires no retained handle or observer.
27
29
  */
@@ -38,12 +40,18 @@ currentSourceHash) {
38
40
  if (cached.result.type === "success") {
39
41
  for (const output of Object.keys(cached.result.typescript)) {
40
42
  const file = path.resolve(cached.projectRoot, output);
41
- const hash = hostInputStateHash(file, filesystem);
43
+ const hash = cached.snapshotDeliveryOnly === true &&
44
+ Object.hasOwn(cached.result.graph?.inputHashes ?? {}, output)
45
+ ? (cached.result.graph.inputHashes[output] ?? null)
46
+ : hostInputStateHash(file, filesystem);
42
47
  if (hash !== null)
43
48
  hashes[pathIdentityKey(file, identities)] = hash;
44
49
  }
45
50
  }
46
- hashes[pathIdentityKey(currentFile, identities)] = currentSourceHash;
51
+ const currentIdentity = pathIdentityKey(currentFile, identities);
52
+ if (cached.snapshotDeliveryOnly !== true ||
53
+ hashes[currentIdentity] === undefined)
54
+ hashes[currentIdentity] = currentSourceHash;
47
55
  return hashes;
48
56
  }
49
57
 
@@ -1 +1 @@
1
- {"version":3,"file":"captureTransformSourceHashes.mjs","sources":["../../../../src/core/transform/generation/captureTransformSourceHashes.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAQA;;;;;;;;;;;;;;;;;;;;AAoBG;SACa,4BAA4B;AAC1C;AACA,MAAkC;AAClC;AACA,WAAmB;AACnB;AACA,iBAAyB,EAAA;IAEzB,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;IAClD,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,eAAe;IAC7D,MAAM,MAAM,GAA2B,EAAE;IACzC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;AACpC,QAAA,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AAC1D,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;YACrD,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC;YACjD,IAAI,IAAI,KAAK,IAAI;gBAAE,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,GAAG,IAAI;QACrE;IACF;IACA,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,GAAG,iBAAiB;AACpE,IAAA,OAAO,MAAM;AACf;;;;"}
1
+ {"version":3,"file":"captureTransformSourceHashes.mjs","sources":["../../../../src/core/transform/generation/captureTransformSourceHashes.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;AAsBG;SACa,4BAA4B;AAC1C;AACA,MAAkC;AAClC;AACA,WAAmB;AACnB;AACA,iBAAyB,EAAA;IAEzB,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;IAClD,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,eAAe;IAC7D,MAAM,MAAM,GAA2B,EAAE;IACzC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;AACpC,QAAA,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AAC1D,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC;AACrD,YAAA,MAAM,IAAI,GACR,MAAM,CAAC,oBAAoB,KAAK,IAAI;AACpC,gBAAA,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,IAAI,EAAE,EAAE,MAAM;AAC1D,mBAAG,MAAM,CAAC,MAAM,CAAC,KAAM,CAAC,WAAY,CAAC,MAAM,CAAC,IAAI,IAAI;AACpD,kBAAE,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC;YAC1C,IAAI,IAAI,KAAK,IAAI;gBAAE,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,GAAG,IAAI;QACrE;IACF;IACA,MAAM,eAAe,GAAG,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC;AAChE,IAAA,IACE,MAAM,CAAC,oBAAoB,KAAK,IAAI;AACpC,QAAA,MAAM,CAAC,eAAe,CAAC,KAAK,SAAS;AAErC,QAAA,MAAM,CAAC,eAAe,CAAC,GAAG,iBAAiB;AAC7C,IAAA,OAAO,MAAM;AACf;;;;"}
@@ -0,0 +1,18 @@
1
+ import type { ITtscCompilerTransformation } from "ttsc";
2
+ import type { TtscGenerationProofFailure } from "./TtscGenerationProofFailure.cjs";
3
+ /**
4
+ * Index one native snapshot's recorded inputs for streaming freshness
5
+ * classification. The diagnostic witness limit must not decide whether a
6
+ * compilation is coherent, so compatibility is decided before diagnostic
7
+ * truncation and remains refused after the first incompatible occurrence.
8
+ *
9
+ * @evidence contracts/common.md#principled-implementation Only explicit freshness changes to recorded compiler inputs or project discovery qualify; changed configuration selection and conflicting host/compiler reads do not; missing and contradictory producer evidence stays outside this class.
10
+ * @evidence contracts/common.md#clear-and-simple-design One generation-owned classifier is shared by its proof collectors and final delivery admission.
11
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts No failure is ignored because its printable witness exceeded the diagnostic limit; unknown kinds and unrecorded plugin inputs remain refusals.
12
+ * @evidence contracts/common.md#meaningful-documentation Prose explains streaming classification, diagnostic truncation and generation ownership.
13
+ * @evidence contracts/portability.md#os-neutral-implementation Native path.resolve anchors protocol input names without guessing physical identity or case behavior.
14
+ * @evidence contracts/performance.md#efficient-algorithms Compiler observation and host hash indexes cost recorded path bytes and input counts; each failure uses a kind check and indexed lexical lookup.
15
+ * @evidence contracts/performance.md#reuse-equivalent-work Every collector for this generation borrows the same classifier and recorded-input index; another generation constructs its own view.
16
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The generation owns its path index and closure until eviction or disposal releases the generation; retained paths follow the reported input population with no separate handle.
17
+ */
18
+ export declare function compilerSnapshotFailureClassifier(result: ITtscCompilerTransformation, projectRoot: string): ((failure: TtscGenerationProofFailure) => boolean) | undefined;
@@ -0,0 +1,18 @@
1
+ import type { ITtscCompilerTransformation } from "ttsc";
2
+ import type { TtscGenerationProofFailure } from "./TtscGenerationProofFailure.mjs";
3
+ /**
4
+ * Index one native snapshot's recorded inputs for streaming freshness
5
+ * classification. The diagnostic witness limit must not decide whether a
6
+ * compilation is coherent, so compatibility is decided before diagnostic
7
+ * truncation and remains refused after the first incompatible occurrence.
8
+ *
9
+ * @evidence contracts/common.md#principled-implementation Only explicit freshness changes to recorded compiler inputs or project discovery qualify; changed configuration selection and conflicting host/compiler reads do not; missing and contradictory producer evidence stays outside this class.
10
+ * @evidence contracts/common.md#clear-and-simple-design One generation-owned classifier is shared by its proof collectors and final delivery admission.
11
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts No failure is ignored because its printable witness exceeded the diagnostic limit; unknown kinds and unrecorded plugin inputs remain refusals.
12
+ * @evidence contracts/common.md#meaningful-documentation Prose explains streaming classification, diagnostic truncation and generation ownership.
13
+ * @evidence contracts/portability.md#os-neutral-implementation Native path.resolve anchors protocol input names without guessing physical identity or case behavior.
14
+ * @evidence contracts/performance.md#efficient-algorithms Compiler observation and host hash indexes cost recorded path bytes and input counts; each failure uses a kind check and indexed lexical lookup.
15
+ * @evidence contracts/performance.md#reuse-equivalent-work Every collector for this generation borrows the same classifier and recorded-input index; another generation constructs its own view.
16
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The generation owns its path index and closure until eviction or disposal releases the generation; retained paths follow the reported input population with no separate handle.
17
+ */
18
+ export declare function compilerSnapshotFailureClassifier(result: ITtscCompilerTransformation, projectRoot: string): ((failure: TtscGenerationProofFailure) => boolean) | undefined;
@@ -0,0 +1,18 @@
1
+ import type { ITtscCompilerTransformation } from "ttsc";
2
+ import type { TtscGenerationProofFailure } from "./TtscGenerationProofFailure";
3
+ /**
4
+ * Index one native snapshot's recorded inputs for streaming freshness
5
+ * classification. The diagnostic witness limit must not decide whether a
6
+ * compilation is coherent, so compatibility is decided before diagnostic
7
+ * truncation and remains refused after the first incompatible occurrence.
8
+ *
9
+ * @evidence contracts/common.md#principled-implementation Only explicit freshness changes to recorded compiler inputs or project discovery qualify; changed configuration selection and conflicting host/compiler reads do not; missing and contradictory producer evidence stays outside this class.
10
+ * @evidence contracts/common.md#clear-and-simple-design One generation-owned classifier is shared by its proof collectors and final delivery admission.
11
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts No failure is ignored because its printable witness exceeded the diagnostic limit; unknown kinds and unrecorded plugin inputs remain refusals.
12
+ * @evidence contracts/common.md#meaningful-documentation Prose explains streaming classification, diagnostic truncation and generation ownership.
13
+ * @evidence contracts/portability.md#os-neutral-implementation Native path.resolve anchors protocol input names without guessing physical identity or case behavior.
14
+ * @evidence contracts/performance.md#efficient-algorithms Compiler observation and host hash indexes cost recorded path bytes and input counts; each failure uses a kind check and indexed lexical lookup.
15
+ * @evidence contracts/performance.md#reuse-equivalent-work Every collector for this generation borrows the same classifier and recorded-input index; another generation constructs its own view.
16
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The generation owns its path index and closure until eviction or disposal releases the generation; retained paths follow the reported input population with no separate handle.
17
+ */
18
+ export declare function compilerSnapshotFailureClassifier(result: ITtscCompilerTransformation, projectRoot: string): ((failure: TtscGenerationProofFailure) => boolean) | undefined;
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+
3
+ var path = require('node:path');
4
+
5
+ /**
6
+ * Index one native snapshot's recorded inputs for streaming freshness
7
+ * classification. The diagnostic witness limit must not decide whether a
8
+ * compilation is coherent, so compatibility is decided before diagnostic
9
+ * truncation and remains refused after the first incompatible occurrence.
10
+ *
11
+ * @evidence contracts/common.md#principled-implementation Only explicit freshness changes to recorded compiler inputs or project discovery qualify; changed configuration selection and conflicting host/compiler reads do not; missing and contradictory producer evidence stays outside this class.
12
+ * @evidence contracts/common.md#clear-and-simple-design One generation-owned classifier is shared by its proof collectors and final delivery admission.
13
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts No failure is ignored because its printable witness exceeded the diagnostic limit; unknown kinds and unrecorded plugin inputs remain refusals.
14
+ * @evidence contracts/common.md#meaningful-documentation Prose explains streaming classification, diagnostic truncation and generation ownership.
15
+ * @evidence contracts/portability.md#os-neutral-implementation Native path.resolve anchors protocol input names without guessing physical identity or case behavior.
16
+ * @evidence contracts/performance.md#efficient-algorithms Compiler observation and host hash indexes cost recorded path bytes and input counts; each failure uses a kind check and indexed lexical lookup.
17
+ * @evidence contracts/performance.md#reuse-equivalent-work Every collector for this generation borrows the same classifier and recorded-input index; another generation constructs its own view.
18
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The generation owns its path index and closure until eviction or disposal releases the generation; retained paths follow the reported input population with no separate handle.
19
+ */
20
+ function compilerSnapshotFailureClassifier(result, projectRoot) {
21
+ if (result.type !== "success" || !result.graph?.compilationSnapshot)
22
+ return undefined;
23
+ const recorded = new Map(Object.entries(result.graph.inputObservations ?? {}).map(([file, observation]) => [path.resolve(projectRoot, file), observation]));
24
+ const hostHashes = new Map(Object.entries(result.hostInputHashes ?? {}).map(([file, hash]) => [
25
+ path.resolve(projectRoot, file),
26
+ hash,
27
+ ]));
28
+ const freshnessKinds = new Set([
29
+ "content-changed",
30
+ "realpath-changed",
31
+ "graph-content-changed",
32
+ "graph-realpath-changed",
33
+ "accessible-entries-changed",
34
+ "file-exists-changed",
35
+ "directory-exists-changed",
36
+ "stat-changed",
37
+ "read-file-changed",
38
+ "native-file-changed",
39
+ "native-directory-changed",
40
+ "native-entry-changed",
41
+ "native-optional-file-changed",
42
+ "input-content-changed",
43
+ "input-metadata-changed",
44
+ "directory-membership-changed",
45
+ "directory-changed-during-walk",
46
+ "file-changed-during-read",
47
+ "project-membership-event",
48
+ "membership-policy-learned",
49
+ "snapshot-mismatch",
50
+ "changed-during-validation",
51
+ ]);
52
+ return (failure) => {
53
+ if (!freshnessKinds.has(failure.kind))
54
+ return false;
55
+ if (failure.domain === "project")
56
+ return true;
57
+ if (failure.path === undefined)
58
+ return false;
59
+ const file = path.resolve(failure.path);
60
+ const observation = recorded.get(file);
61
+ if (observation === undefined)
62
+ return false;
63
+ // A descriptor/host read must agree with the compiler's captured text.
64
+ // Merely sharing a path cannot make two different evaluation epochs coherent.
65
+ if (failure.domain === "host" && hostHashes.has(file)) {
66
+ const read = observation.readFile;
67
+ return (read !== undefined &&
68
+ hostHashes.get(file) === (read.ok ? read.hash : null));
69
+ }
70
+ return true;
71
+ };
72
+ }
73
+
74
+ exports.compilerSnapshotFailureClassifier = compilerSnapshotFailureClassifier;
75
+ //# sourceMappingURL=compilerSnapshotFailureClassifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compilerSnapshotFailureClassifier.js","sources":["../../../../src/core/transform/generation/compilerSnapshotFailureClassifier.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAKA;;;;;;;;;;;;;;AAcG;AACG,SAAU,iCAAiC,CAC/C,MAAmC,EACnC,WAAmB,EAAA;IAEnB,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,mBAAmB;AACjE,QAAA,OAAO,SAAS;AAClB,IAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,GAAG,CACtD,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,WAAW,CAAC,CACxE,CACF;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK;AACjE,QAAA,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC;QAC/B,IAAI;AACL,KAAA,CAAC,CACH;AACD,IAAA,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;QAC7B,iBAAiB;QACjB,kBAAkB;QAClB,uBAAuB;QACvB,wBAAwB;QACxB,4BAA4B;QAC5B,qBAAqB;QACrB,0BAA0B;QAC1B,cAAc;QACd,mBAAmB;QACnB,qBAAqB;QACrB,0BAA0B;QAC1B,sBAAsB;QACtB,8BAA8B;QAC9B,uBAAuB;QACvB,wBAAwB;QACxB,8BAA8B;QAC9B,+BAA+B;QAC/B,0BAA0B;QAC1B,0BAA0B;QAC1B,2BAA2B;QAC3B,mBAAmB;QACnB,2BAA2B;AAC5B,KAAA,CAAC;IACF,OAAO,CAAC,OAAO,KAAI;QACjB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,KAAK;AACnD,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;AAAE,YAAA,OAAO,IAAI;AAC7C,QAAA,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;AAAE,YAAA,OAAO,KAAK;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QACvC,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QACtC,IAAI,WAAW,KAAK,SAAS;AAAE,YAAA,OAAO,KAAK;;;AAG3C,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACrD,YAAA,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ;YACjC,QACE,IAAI,KAAK,SAAS;gBAClB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEzD;AACA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AACH;;;;"}
@@ -0,0 +1,73 @@
1
+ import path from 'node:path';
2
+
3
+ /**
4
+ * Index one native snapshot's recorded inputs for streaming freshness
5
+ * classification. The diagnostic witness limit must not decide whether a
6
+ * compilation is coherent, so compatibility is decided before diagnostic
7
+ * truncation and remains refused after the first incompatible occurrence.
8
+ *
9
+ * @evidence contracts/common.md#principled-implementation Only explicit freshness changes to recorded compiler inputs or project discovery qualify; changed configuration selection and conflicting host/compiler reads do not; missing and contradictory producer evidence stays outside this class.
10
+ * @evidence contracts/common.md#clear-and-simple-design One generation-owned classifier is shared by its proof collectors and final delivery admission.
11
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts No failure is ignored because its printable witness exceeded the diagnostic limit; unknown kinds and unrecorded plugin inputs remain refusals.
12
+ * @evidence contracts/common.md#meaningful-documentation Prose explains streaming classification, diagnostic truncation and generation ownership.
13
+ * @evidence contracts/portability.md#os-neutral-implementation Native path.resolve anchors protocol input names without guessing physical identity or case behavior.
14
+ * @evidence contracts/performance.md#efficient-algorithms Compiler observation and host hash indexes cost recorded path bytes and input counts; each failure uses a kind check and indexed lexical lookup.
15
+ * @evidence contracts/performance.md#reuse-equivalent-work Every collector for this generation borrows the same classifier and recorded-input index; another generation constructs its own view.
16
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The generation owns its path index and closure until eviction or disposal releases the generation; retained paths follow the reported input population with no separate handle.
17
+ */
18
+ function compilerSnapshotFailureClassifier(result, projectRoot) {
19
+ if (result.type !== "success" || !result.graph?.compilationSnapshot)
20
+ return undefined;
21
+ const recorded = new Map(Object.entries(result.graph.inputObservations ?? {}).map(([file, observation]) => [path.resolve(projectRoot, file), observation]));
22
+ const hostHashes = new Map(Object.entries(result.hostInputHashes ?? {}).map(([file, hash]) => [
23
+ path.resolve(projectRoot, file),
24
+ hash,
25
+ ]));
26
+ const freshnessKinds = new Set([
27
+ "content-changed",
28
+ "realpath-changed",
29
+ "graph-content-changed",
30
+ "graph-realpath-changed",
31
+ "accessible-entries-changed",
32
+ "file-exists-changed",
33
+ "directory-exists-changed",
34
+ "stat-changed",
35
+ "read-file-changed",
36
+ "native-file-changed",
37
+ "native-directory-changed",
38
+ "native-entry-changed",
39
+ "native-optional-file-changed",
40
+ "input-content-changed",
41
+ "input-metadata-changed",
42
+ "directory-membership-changed",
43
+ "directory-changed-during-walk",
44
+ "file-changed-during-read",
45
+ "project-membership-event",
46
+ "membership-policy-learned",
47
+ "snapshot-mismatch",
48
+ "changed-during-validation",
49
+ ]);
50
+ return (failure) => {
51
+ if (!freshnessKinds.has(failure.kind))
52
+ return false;
53
+ if (failure.domain === "project")
54
+ return true;
55
+ if (failure.path === undefined)
56
+ return false;
57
+ const file = path.resolve(failure.path);
58
+ const observation = recorded.get(file);
59
+ if (observation === undefined)
60
+ return false;
61
+ // A descriptor/host read must agree with the compiler's captured text.
62
+ // Merely sharing a path cannot make two different evaluation epochs coherent.
63
+ if (failure.domain === "host" && hostHashes.has(file)) {
64
+ const read = observation.readFile;
65
+ return (read !== undefined &&
66
+ hostHashes.get(file) === (read.ok ? read.hash : null));
67
+ }
68
+ return true;
69
+ };
70
+ }
71
+
72
+ export { compilerSnapshotFailureClassifier };
73
+ //# sourceMappingURL=compilerSnapshotFailureClassifier.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compilerSnapshotFailureClassifier.mjs","sources":["../../../../src/core/transform/generation/compilerSnapshotFailureClassifier.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAKA;;;;;;;;;;;;;;AAcG;AACG,SAAU,iCAAiC,CAC/C,MAAmC,EACnC,WAAmB,EAAA;IAEnB,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,mBAAmB;AACjE,QAAA,OAAO,SAAS;AAClB,IAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,GAAG,CACtD,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,WAAW,CAAC,CACxE,CACF;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK;AACjE,QAAA,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC;QAC/B,IAAI;AACL,KAAA,CAAC,CACH;AACD,IAAA,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;QAC7B,iBAAiB;QACjB,kBAAkB;QAClB,uBAAuB;QACvB,wBAAwB;QACxB,4BAA4B;QAC5B,qBAAqB;QACrB,0BAA0B;QAC1B,cAAc;QACd,mBAAmB;QACnB,qBAAqB;QACrB,0BAA0B;QAC1B,sBAAsB;QACtB,8BAA8B;QAC9B,uBAAuB;QACvB,wBAAwB;QACxB,8BAA8B;QAC9B,+BAA+B;QAC/B,0BAA0B;QAC1B,0BAA0B;QAC1B,2BAA2B;QAC3B,mBAAmB;QACnB,2BAA2B;AAC5B,KAAA,CAAC;IACF,OAAO,CAAC,OAAO,KAAI;QACjB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,KAAK;AACnD,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;AAAE,YAAA,OAAO,IAAI;AAC7C,QAAA,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;AAAE,YAAA,OAAO,KAAK;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QACvC,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QACtC,IAAI,WAAW,KAAK,SAAS;AAAE,YAAA,OAAO,KAAK;;;AAG3C,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACrD,YAAA,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ;YACjC,QACE,IAAI,KAAK,SAAS;gBAClB,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEzD;AACA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AACH;;;;"}
@@ -3,13 +3,13 @@ import type { TtscGenerationProofFailures } from "./TtscGenerationProofFailures.
3
3
  * Create a fresh proof-witness collection for one transform attempt. Its
4
4
  * recorder bounds retained entries and their deduplication identities.
5
5
  *
6
- * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants.
6
+ * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants. The optional generation classifier records complete freshness compatibility before diagnostic truncation.
7
7
  * @evidence contracts/common.md#clear-and-simple-design This constructor supplies only fresh aggregate storage; the recorder owns limits and identity composition.
8
8
  * @evidence contracts/common.md#prohibited-implementation-shortcuts An attempt receives independent storage rather than sharing mutable witnesses from an earlier compile or manufacturing an initial verdict.
9
9
  * @evidence contracts/common.md#meaningful-documentation Native prose identifies per-attempt ownership and the recorder's bounding responsibility before separated acknowledgments.
10
- * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection.
10
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
11
11
  * @evidenceExclude contracts/performance.md#efficient-algorithms Allocates an empty collection.
12
12
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work Creates a new collection per attempt by definition.
13
13
  * @evidenceExclude contracts/portability.md#os-neutral-implementation Allocates an empty collection and reads no filesystem or path.
14
14
  */
15
- export declare function createGenerationProofFailures(): TtscGenerationProofFailures;
15
+ export declare function createGenerationProofFailures(snapshotFailureClassifier?: TtscGenerationProofFailures["snapshotFailureClassifier"]): TtscGenerationProofFailures;
@@ -3,13 +3,13 @@ import type { TtscGenerationProofFailures } from "./TtscGenerationProofFailures.
3
3
  * Create a fresh proof-witness collection for one transform attempt. Its
4
4
  * recorder bounds retained entries and their deduplication identities.
5
5
  *
6
- * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants.
6
+ * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants. The optional generation classifier records complete freshness compatibility before diagnostic truncation.
7
7
  * @evidence contracts/common.md#clear-and-simple-design This constructor supplies only fresh aggregate storage; the recorder owns limits and identity composition.
8
8
  * @evidence contracts/common.md#prohibited-implementation-shortcuts An attempt receives independent storage rather than sharing mutable witnesses from an earlier compile or manufacturing an initial verdict.
9
9
  * @evidence contracts/common.md#meaningful-documentation Native prose identifies per-attempt ownership and the recorder's bounding responsibility before separated acknowledgments.
10
- * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection.
10
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
11
11
  * @evidenceExclude contracts/performance.md#efficient-algorithms Allocates an empty collection.
12
12
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work Creates a new collection per attempt by definition.
13
13
  * @evidenceExclude contracts/portability.md#os-neutral-implementation Allocates an empty collection and reads no filesystem or path.
14
14
  */
15
- export declare function createGenerationProofFailures(): TtscGenerationProofFailures;
15
+ export declare function createGenerationProofFailures(snapshotFailureClassifier?: TtscGenerationProofFailures["snapshotFailureClassifier"]): TtscGenerationProofFailures;
@@ -3,13 +3,13 @@ import type { TtscGenerationProofFailures } from "./TtscGenerationProofFailures"
3
3
  * Create a fresh proof-witness collection for one transform attempt. Its
4
4
  * recorder bounds retained entries and their deduplication identities.
5
5
  *
6
- * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants.
6
+ * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants. The optional generation classifier records complete freshness compatibility before diagnostic truncation.
7
7
  * @evidence contracts/common.md#clear-and-simple-design This constructor supplies only fresh aggregate storage; the recorder owns limits and identity composition.
8
8
  * @evidence contracts/common.md#prohibited-implementation-shortcuts An attempt receives independent storage rather than sharing mutable witnesses from an earlier compile or manufacturing an initial verdict.
9
9
  * @evidence contracts/common.md#meaningful-documentation Native prose identifies per-attempt ownership and the recorder's bounding responsibility before separated acknowledgments.
10
- * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection.
10
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
11
11
  * @evidenceExclude contracts/performance.md#efficient-algorithms Allocates an empty collection.
12
12
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work Creates a new collection per attempt by definition.
13
13
  * @evidenceExclude contracts/portability.md#os-neutral-implementation Allocates an empty collection and reads no filesystem or path.
14
14
  */
15
- export declare function createGenerationProofFailures(): TtscGenerationProofFailures;
15
+ export declare function createGenerationProofFailures(snapshotFailureClassifier?: TtscGenerationProofFailures["snapshotFailureClassifier"]): TtscGenerationProofFailures;
@@ -4,17 +4,24 @@
4
4
  * Create a fresh proof-witness collection for one transform attempt. Its
5
5
  * recorder bounds retained entries and their deduplication identities.
6
6
  *
7
- * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants.
7
+ * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants. The optional generation classifier records complete freshness compatibility before diagnostic truncation.
8
8
  * @evidence contracts/common.md#clear-and-simple-design This constructor supplies only fresh aggregate storage; the recorder owns limits and identity composition.
9
9
  * @evidence contracts/common.md#prohibited-implementation-shortcuts An attempt receives independent storage rather than sharing mutable witnesses from an earlier compile or manufacturing an initial verdict.
10
10
  * @evidence contracts/common.md#meaningful-documentation Native prose identifies per-attempt ownership and the recorder's bounding responsibility before separated acknowledgments.
11
- * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection.
11
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
12
12
  * @evidenceExclude contracts/performance.md#efficient-algorithms Allocates an empty collection.
13
13
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work Creates a new collection per attempt by definition.
14
14
  * @evidenceExclude contracts/portability.md#os-neutral-implementation Allocates an empty collection and reads no filesystem or path.
15
15
  */
16
- function createGenerationProofFailures() {
17
- return { entries: [], omitted: 0, seen: new Set() };
16
+ function createGenerationProofFailures(snapshotFailureClassifier) {
17
+ return {
18
+ entries: [],
19
+ omitted: 0,
20
+ seen: new Set(),
21
+ ...(snapshotFailureClassifier === undefined
22
+ ? {}
23
+ : { snapshotFailureClassifier, snapshotCompatible: true }),
24
+ };
18
25
  }
19
26
 
20
27
  exports.createGenerationProofFailures = createGenerationProofFailures;
@@ -1 +1 @@
1
- {"version":3,"file":"createGenerationProofFailures.js","sources":["../../../../src/core/transform/generation/createGenerationProofFailures.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;;;;;;;;;AAYG;SACa,6BAA6B,GAAA;AAC3C,IAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE;AACrD;;;;"}
1
+ {"version":3,"file":"createGenerationProofFailures.js","sources":["../../../../src/core/transform/generation/createGenerationProofFailures.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;;;;;;;;;;;AAYG;AACG,SAAU,6BAA6B,CAC3C,yBAAoF,EAAA;IAEpF,OAAO;AACL,QAAA,OAAO,EAAE,EAAE;AACX,QAAA,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,IAAI,GAAG,EAAE;QACf,IAAI,yBAAyB,KAAK;AAChC,cAAE;cACA,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;KAC7D;AACH;;;;"}
@@ -2,17 +2,24 @@
2
2
  * Create a fresh proof-witness collection for one transform attempt. Its
3
3
  * recorder bounds retained entries and their deduplication identities.
4
4
  *
5
- * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants.
5
+ * @evidence contracts/common.md#principled-implementation Empty entries, zero omitted occurrences and an empty seen set establish the recorder's initial aggregate invariants. The optional generation classifier records complete freshness compatibility before diagnostic truncation.
6
6
  * @evidence contracts/common.md#clear-and-simple-design This constructor supplies only fresh aggregate storage; the recorder owns limits and identity composition.
7
7
  * @evidence contracts/common.md#prohibited-implementation-shortcuts An attempt receives independent storage rather than sharing mutable witnesses from an earlier compile or manufacturing an initial verdict.
8
8
  * @evidence contracts/common.md#meaningful-documentation Native prose identifies per-attempt ownership and the recorder's bounding responsibility before separated acknowledgments.
9
- * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection.
9
+ * @evidence contracts/performance.md#bound-retention-and-release-resources Fresh storage transfers to the attempt owner and its terminal diagnostic sequence; recordGenerationProofFailure bounds entry and identity counts at eight, while retained witness text follows supplied lengths. This constructor owns no handle or separate historical collection. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
10
10
  * @evidenceExclude contracts/performance.md#efficient-algorithms Allocates an empty collection.
11
11
  * @evidenceExclude contracts/performance.md#reuse-equivalent-work Creates a new collection per attempt by definition.
12
12
  * @evidenceExclude contracts/portability.md#os-neutral-implementation Allocates an empty collection and reads no filesystem or path.
13
13
  */
14
- function createGenerationProofFailures() {
15
- return { entries: [], omitted: 0, seen: new Set() };
14
+ function createGenerationProofFailures(snapshotFailureClassifier) {
15
+ return {
16
+ entries: [],
17
+ omitted: 0,
18
+ seen: new Set(),
19
+ ...(snapshotFailureClassifier === undefined
20
+ ? {}
21
+ : { snapshotFailureClassifier, snapshotCompatible: true }),
22
+ };
16
23
  }
17
24
 
18
25
  export { createGenerationProofFailures };
@@ -1 +1 @@
1
- {"version":3,"file":"createGenerationProofFailures.mjs","sources":["../../../../src/core/transform/generation/createGenerationProofFailures.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEA;;;;;;;;;;;;AAYG;SACa,6BAA6B,GAAA;AAC3C,IAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE;AACrD;;;;"}
1
+ {"version":3,"file":"createGenerationProofFailures.mjs","sources":["../../../../src/core/transform/generation/createGenerationProofFailures.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEA;;;;;;;;;;;;AAYG;AACG,SAAU,6BAA6B,CAC3C,yBAAoF,EAAA;IAEpF,OAAO;AACL,QAAA,OAAO,EAAE,EAAE;AACX,QAAA,OAAO,EAAE,CAAC;QACV,IAAI,EAAE,IAAI,GAAG,EAAE;QACf,IAAI,yBAAyB,KAAK;AAChC,cAAE;cACA,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;KAC7D;AACH;;;;"}
@@ -8,18 +8,18 @@ import type { TtscGenerationProofFailures } from "./TtscGenerationProofFailures.
8
8
  * unchanged. Retained witnesses are shared references, so producers must treat
9
9
  * their classifications as fixed after recording.
10
10
  *
11
- * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries.
11
+ * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries. A positive omitted-witness summary transfers only under the same generation classifier; refusal remains sticky before diagnostic truncation.
12
12
  * @evidence contracts/common.md#clear-and-simple-design This operation coordinates aggregation without duplicating recorder limits or witness identity encoding.
13
13
  * @evidence contracts/common.md#prohibited-implementation-shortcuts Missing witnesses remain omitted rather than being silently converted into proof success or guessed unique identities.
14
14
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain shared recorder ownership and the reason lost source identities cannot be deduplicated.
15
15
  * @evidence contracts/performance.md#efficient-algorithms
16
16
  * Merge visits the source's recorder-bounded retained entries once. Each
17
17
  * delegated insertion encodes the complete witness tuple and queries its
18
- * identity, so work and temporary encoded keys retain witness-text cost even
18
+ * identity and optionally classifies lexical paths, so work and temporary encoded keys retain witness-text cost even
19
19
  * with at most eight entries. Omission addition is constant work; discarded
20
20
  * evidence is not reconstructed.
21
21
  * @evidence contracts/performance.md#reuse-equivalent-work The shared recorder reuses retained target identities to suppress duplicates across evidence families; mutable aggregate merges are not memoized.
22
- * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count.
23
- * @evidenceExclude contracts/portability.md#os-neutral-implementation Combines in-memory witness collections; it parses no path.
22
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
23
+ * @evidence contracts/portability.md#os-neutral-implementation Combines in-memory witnesses through the recorder, whose optional generation classifier owns native lexical path resolution.
24
24
  */
25
25
  export declare function mergeGenerationProofFailures(target: TtscGenerationProofFailures, source: TtscGenerationProofFailures): void;
@@ -8,18 +8,18 @@ import type { TtscGenerationProofFailures } from "./TtscGenerationProofFailures.
8
8
  * unchanged. Retained witnesses are shared references, so producers must treat
9
9
  * their classifications as fixed after recording.
10
10
  *
11
- * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries.
11
+ * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries. A positive omitted-witness summary transfers only under the same generation classifier; refusal remains sticky before diagnostic truncation.
12
12
  * @evidence contracts/common.md#clear-and-simple-design This operation coordinates aggregation without duplicating recorder limits or witness identity encoding.
13
13
  * @evidence contracts/common.md#prohibited-implementation-shortcuts Missing witnesses remain omitted rather than being silently converted into proof success or guessed unique identities.
14
14
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain shared recorder ownership and the reason lost source identities cannot be deduplicated.
15
15
  * @evidence contracts/performance.md#efficient-algorithms
16
16
  * Merge visits the source's recorder-bounded retained entries once. Each
17
17
  * delegated insertion encodes the complete witness tuple and queries its
18
- * identity, so work and temporary encoded keys retain witness-text cost even
18
+ * identity and optionally classifies lexical paths, so work and temporary encoded keys retain witness-text cost even
19
19
  * with at most eight entries. Omission addition is constant work; discarded
20
20
  * evidence is not reconstructed.
21
21
  * @evidence contracts/performance.md#reuse-equivalent-work The shared recorder reuses retained target identities to suppress duplicates across evidence families; mutable aggregate merges are not memoized.
22
- * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count.
23
- * @evidenceExclude contracts/portability.md#os-neutral-implementation Combines in-memory witness collections; it parses no path.
22
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
23
+ * @evidence contracts/portability.md#os-neutral-implementation Combines in-memory witnesses through the recorder, whose optional generation classifier owns native lexical path resolution.
24
24
  */
25
25
  export declare function mergeGenerationProofFailures(target: TtscGenerationProofFailures, source: TtscGenerationProofFailures): void;
@@ -8,18 +8,18 @@ import type { TtscGenerationProofFailures } from "./TtscGenerationProofFailures"
8
8
  * unchanged. Retained witnesses are shared references, so producers must treat
9
9
  * their classifications as fixed after recording.
10
10
  *
11
- * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries.
11
+ * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries. A positive omitted-witness summary transfers only under the same generation classifier; refusal remains sticky before diagnostic truncation.
12
12
  * @evidence contracts/common.md#clear-and-simple-design This operation coordinates aggregation without duplicating recorder limits or witness identity encoding.
13
13
  * @evidence contracts/common.md#prohibited-implementation-shortcuts Missing witnesses remain omitted rather than being silently converted into proof success or guessed unique identities.
14
14
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain shared recorder ownership and the reason lost source identities cannot be deduplicated.
15
15
  * @evidence contracts/performance.md#efficient-algorithms
16
16
  * Merge visits the source's recorder-bounded retained entries once. Each
17
17
  * delegated insertion encodes the complete witness tuple and queries its
18
- * identity, so work and temporary encoded keys retain witness-text cost even
18
+ * identity and optionally classifies lexical paths, so work and temporary encoded keys retain witness-text cost even
19
19
  * with at most eight entries. Omission addition is constant work; discarded
20
20
  * evidence is not reconstructed.
21
21
  * @evidence contracts/performance.md#reuse-equivalent-work The shared recorder reuses retained target identities to suppress duplicates across evidence families; mutable aggregate merges are not memoized.
22
- * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count.
23
- * @evidenceExclude contracts/portability.md#os-neutral-implementation Combines in-memory witness collections; it parses no path.
22
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
23
+ * @evidence contracts/portability.md#os-neutral-implementation Combines in-memory witnesses through the recorder, whose optional generation classifier owns native lexical path resolution.
24
24
  */
25
25
  export declare function mergeGenerationProofFailures(target: TtscGenerationProofFailures, source: TtscGenerationProofFailures): void;
@@ -11,24 +11,31 @@ var recordGenerationProofFailure = require('./recordGenerationProofFailure.js');
11
11
  * unchanged. Retained witnesses are shared references, so producers must treat
12
12
  * their classifications as fixed after recording.
13
13
  *
14
- * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries.
14
+ * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries. A positive omitted-witness summary transfers only under the same generation classifier; refusal remains sticky before diagnostic truncation.
15
15
  * @evidence contracts/common.md#clear-and-simple-design This operation coordinates aggregation without duplicating recorder limits or witness identity encoding.
16
16
  * @evidence contracts/common.md#prohibited-implementation-shortcuts Missing witnesses remain omitted rather than being silently converted into proof success or guessed unique identities.
17
17
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain shared recorder ownership and the reason lost source identities cannot be deduplicated.
18
18
  * @evidence contracts/performance.md#efficient-algorithms
19
19
  * Merge visits the source's recorder-bounded retained entries once. Each
20
20
  * delegated insertion encodes the complete witness tuple and queries its
21
- * identity, so work and temporary encoded keys retain witness-text cost even
21
+ * identity and optionally classifies lexical paths, so work and temporary encoded keys retain witness-text cost even
22
22
  * with at most eight entries. Omission addition is constant work; discarded
23
23
  * evidence is not reconstructed.
24
24
  * @evidence contracts/performance.md#reuse-equivalent-work The shared recorder reuses retained target identities to suppress duplicates across evidence families; mutable aggregate merges are not memoized.
25
- * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count.
26
- * @evidenceExclude contracts/portability.md#os-neutral-implementation Combines in-memory witness collections; it parses no path.
25
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
26
+ * @evidence contracts/portability.md#os-neutral-implementation Combines in-memory witnesses through the recorder, whose optional generation classifier owns native lexical path resolution.
27
27
  */
28
28
  function mergeGenerationProofFailures(target, source) {
29
29
  for (const failure of source.entries) {
30
30
  recordGenerationProofFailure.recordGenerationProofFailure(target, failure);
31
31
  }
32
+ if (target.snapshotFailureClassifier !== undefined &&
33
+ (source.snapshotCompatible === false ||
34
+ (source.omitted !== 0 &&
35
+ (source.snapshotCompatible !== true ||
36
+ source.snapshotFailureClassifier !==
37
+ target.snapshotFailureClassifier))))
38
+ target.snapshotCompatible = false;
32
39
  target.omitted = Math.min(Number.MAX_SAFE_INTEGER, target.omitted + source.omitted);
33
40
  }
34
41
 
@@ -1 +1 @@
1
- {"version":3,"file":"mergeGenerationProofFailures.js","sources":["../../../../src/core/transform/generation/mergeGenerationProofFailures.ts"],"sourcesContent":[null],"names":["recordGenerationProofFailure"],"mappings":";;;;AAGA;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACG,SAAU,4BAA4B,CAC1C,MAAmC,EACnC,MAAmC,EAAA;AAEnC,IAAA,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE;AACpC,QAAAA,yDAA4B,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/C;AACA,IAAA,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CACvB,MAAM,CAAC,gBAAgB,EACvB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAChC;AACH;;;;"}
1
+ {"version":3,"file":"mergeGenerationProofFailures.js","sources":["../../../../src/core/transform/generation/mergeGenerationProofFailures.ts"],"sourcesContent":[null],"names":["recordGenerationProofFailure"],"mappings":";;;;AAGA;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACG,SAAU,4BAA4B,CAC1C,MAAmC,EACnC,MAAmC,EAAA;AAEnC,IAAA,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE;AACpC,QAAAA,yDAA4B,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/C;AACA,IAAA,IACE,MAAM,CAAC,yBAAyB,KAAK,SAAS;AAC9C,SAAC,MAAM,CAAC,kBAAkB,KAAK,KAAK;AAClC,aAAC,MAAM,CAAC,OAAO,KAAK,CAAC;AACnB,iBAAC,MAAM,CAAC,kBAAkB,KAAK,IAAI;AACjC,oBAAA,MAAM,CAAC,yBAAyB;AAC9B,wBAAA,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;AAE3C,QAAA,MAAM,CAAC,kBAAkB,GAAG,KAAK;AACnC,IAAA,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CACvB,MAAM,CAAC,gBAAgB,EACvB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAChC;AACH;;;;"}
@@ -9,24 +9,31 @@ import { recordGenerationProofFailure } from './recordGenerationProofFailure.mjs
9
9
  * unchanged. Retained witnesses are shared references, so producers must treat
10
10
  * their classifications as fixed after recording.
11
11
  *
12
- * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries.
12
+ * @evidence contracts/common.md#principled-implementation Retained source entries use the target recorder's identity policy, while saturated addition preserves already omitted occurrence counts that cannot be recovered from source entries. A positive omitted-witness summary transfers only under the same generation classifier; refusal remains sticky before diagnostic truncation.
13
13
  * @evidence contracts/common.md#clear-and-simple-design This operation coordinates aggregation without duplicating recorder limits or witness identity encoding.
14
14
  * @evidence contracts/common.md#prohibited-implementation-shortcuts Missing witnesses remain omitted rather than being silently converted into proof success or guessed unique identities.
15
15
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain shared recorder ownership and the reason lost source identities cannot be deduplicated.
16
16
  * @evidence contracts/performance.md#efficient-algorithms
17
17
  * Merge visits the source's recorder-bounded retained entries once. Each
18
18
  * delegated insertion encodes the complete witness tuple and queries its
19
- * identity, so work and temporary encoded keys retain witness-text cost even
19
+ * identity and optionally classifies lexical paths, so work and temporary encoded keys retain witness-text cost even
20
20
  * with at most eight entries. Omission addition is constant work; discarded
21
21
  * evidence is not reconstructed.
22
22
  * @evidence contracts/performance.md#reuse-equivalent-work The shared recorder reuses retained target identities to suppress duplicates across evidence families; mutable aggregate merges are not memoized.
23
- * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count.
24
- * @evidenceExclude contracts/portability.md#os-neutral-implementation Combines in-memory witness collections; it parses no path.
23
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The target remains subject to the recorder's eight-entry/seen-key bound; merge retains no source history beyond copied witnesses and its saturated omission count. The optional borrowed classifier keeps its generation input indexes reachable while either the generation or aggregate retains it; those indexes are not subject to the diagnostic witness bound.
24
+ * @evidence contracts/portability.md#os-neutral-implementation Combines in-memory witnesses through the recorder, whose optional generation classifier owns native lexical path resolution.
25
25
  */
26
26
  function mergeGenerationProofFailures(target, source) {
27
27
  for (const failure of source.entries) {
28
28
  recordGenerationProofFailure(target, failure);
29
29
  }
30
+ if (target.snapshotFailureClassifier !== undefined &&
31
+ (source.snapshotCompatible === false ||
32
+ (source.omitted !== 0 &&
33
+ (source.snapshotCompatible !== true ||
34
+ source.snapshotFailureClassifier !==
35
+ target.snapshotFailureClassifier))))
36
+ target.snapshotCompatible = false;
30
37
  target.omitted = Math.min(Number.MAX_SAFE_INTEGER, target.omitted + source.omitted);
31
38
  }
32
39