@remnic/core 9.51.1 → 9.52.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 (234) hide show
  1. package/dist/access-admin-ops-surface.d.ts +6 -5
  2. package/dist/access-admin-ops-surface.js +16 -16
  3. package/dist/access-authorization-probe.d.ts +6 -5
  4. package/dist/access-authorization-probe.js +17 -17
  5. package/dist/access-boundary.d.ts +6 -5
  6. package/dist/access-boundary.js +16 -16
  7. package/dist/access-cli.js +39 -39
  8. package/dist/access-extraction-force-flush.d.ts +6 -5
  9. package/dist/access-extraction-force-flush.js +16 -16
  10. package/dist/access-http-lcm-compaction.d.ts +6 -5
  11. package/dist/access-http-lifecycle-flush.d.ts +6 -5
  12. package/dist/access-http-offline-stream.d.ts +6 -5
  13. package/dist/access-http-query.js +16 -16
  14. package/dist/access-http.d.ts +6 -5
  15. package/dist/access-http.js +22 -22
  16. package/dist/access-identity-continuity-surface.d.ts +5 -4
  17. package/dist/access-identity-continuity-surface.js +16 -16
  18. package/dist/access-lcm-surface.d.ts +6 -5
  19. package/dist/access-lcm-surface.js +16 -16
  20. package/dist/access-mcp.d.ts +6 -5
  21. package/dist/access-mcp.js +20 -20
  22. package/dist/access-namespace-preflight.js +16 -16
  23. package/dist/access-observe-write-surface.d.ts +6 -5
  24. package/dist/access-observe-write-surface.js +16 -16
  25. package/dist/access-offline-manifest.d.ts +5 -4
  26. package/dist/access-operations-batch.js +17 -17
  27. package/dist/access-operations.d.ts +9 -8
  28. package/dist/access-operations.js +19 -19
  29. package/dist/access-recall-concurrency.d.ts +6 -5
  30. package/dist/access-recall-concurrency.js +16 -16
  31. package/dist/access-recall-response.d.ts +6 -5
  32. package/dist/access-recall-response.js +16 -16
  33. package/dist/access-recall-surface.d.ts +6 -5
  34. package/dist/access-recall-surface.js +16 -16
  35. package/dist/access-schema.d.ts +88 -88
  36. package/dist/{access-service-BY0KJ44c.d.ts → access-service-Cbk3bNbD.d.ts} +3 -3
  37. package/dist/access-service-helpers.d.ts +6 -5
  38. package/dist/access-service.d.ts +6 -5
  39. package/dist/access-service.js +16 -16
  40. package/dist/access-surface-catalog.d.ts +6 -5
  41. package/dist/access-wearables-meetings-surface.d.ts +2 -2
  42. package/dist/bootstrap.d.ts +5 -4
  43. package/dist/briefing.d.ts +1 -1
  44. package/dist/briefing.js +7 -7
  45. package/dist/buffer.d.ts +1 -1
  46. package/dist/{capsule-merge-XMFBXVDP.js → capsule-merge-HCJJMLPS.js} +4 -4
  47. package/dist/causal-consolidation.js +8 -8
  48. package/dist/{chunk-PWN32TAG.js → chunk-2ASAS3CQ.js} +2 -2
  49. package/dist/{chunk-WQM326GS.js → chunk-2LY6GIIE.js} +2 -2
  50. package/dist/{chunk-JL43BVDE.js → chunk-2OIQDTDC.js} +2 -2
  51. package/dist/{chunk-33SV3E43.js → chunk-3OY7KXHM.js} +3 -3
  52. package/dist/{chunk-AIUBBHSF.js → chunk-5UZ6UCOZ.js} +3 -3
  53. package/dist/chunk-5WITETWU.js +591 -0
  54. package/dist/chunk-5WITETWU.js.map +1 -0
  55. package/dist/{chunk-UT5BV5OG.js → chunk-7HXZJAID.js} +2 -2
  56. package/dist/{chunk-M7BXDKPR.js → chunk-7M6NYQWB.js} +3 -3
  57. package/dist/{chunk-TPTECFWR.js → chunk-B6LZ4IBH.js} +3 -3
  58. package/dist/{chunk-J5LLX6IL.js → chunk-BF6SXNQJ.js} +10 -10
  59. package/dist/{chunk-4PC4PRJE.js → chunk-BKIFTXHR.js} +2 -2
  60. package/dist/{chunk-VVG2BOKA.js → chunk-BMEYMKWX.js} +2 -2
  61. package/dist/{chunk-DCZBSE4F.js → chunk-D5YOZ66N.js} +18 -18
  62. package/dist/{chunk-BHXYAVUM.js → chunk-DLG5V6ND.js} +2 -2
  63. package/dist/{chunk-52UKFTUK.js → chunk-F4EU6VUC.js} +2 -2
  64. package/dist/{chunk-M4A44LUA.js → chunk-GSTIBXBW.js} +2 -2
  65. package/dist/{chunk-W5XVQFLM.js → chunk-GXFSQ6SD.js} +2 -2
  66. package/dist/{chunk-XADV5IZ3.js → chunk-HDIUYMSB.js} +5 -5
  67. package/dist/{chunk-FXTYIA46.js → chunk-J272WKX2.js} +2 -2
  68. package/dist/{chunk-ENTCVTQR.js → chunk-JJRVPWFY.js} +11 -1
  69. package/dist/chunk-JJRVPWFY.js.map +1 -0
  70. package/dist/{chunk-JYL3BVVZ.js → chunk-JSEJH2YQ.js} +2 -2
  71. package/dist/{chunk-5UDMFE3Q.js → chunk-MLXZD4WM.js} +2 -2
  72. package/dist/{chunk-PUSLMZBQ.js → chunk-NOEMGE56.js} +2 -2
  73. package/dist/{chunk-C5QLI33R.js → chunk-QINJITDS.js} +2 -2
  74. package/dist/{chunk-45BRYON6.js → chunk-QPOHMO6M.js} +2 -2
  75. package/dist/{chunk-ZQOCRIGA.js → chunk-QYN5PXDZ.js} +3 -3
  76. package/dist/{chunk-PA45XCUD.js → chunk-RANKJI5T.js} +2 -2
  77. package/dist/{chunk-ZHY5TMJG.js → chunk-RMHMUUBW.js} +2392 -628
  78. package/dist/chunk-RMHMUUBW.js.map +1 -0
  79. package/dist/{chunk-37ZO6LLJ.js → chunk-RYLEDKQ2.js} +2 -2
  80. package/dist/{chunk-CV6BBVYV.js → chunk-TEMSWHQD.js} +2 -2
  81. package/dist/{chunk-QGR6OVGT.js → chunk-VFSAWRMZ.js} +2 -2
  82. package/dist/{chunk-NLK2VZYZ.js → chunk-VXCNQYTC.js} +2 -2
  83. package/dist/{chunk-AZ2QBGYB.js → chunk-W7Y5JDVB.js} +1 -1
  84. package/dist/{chunk-VBHPOWBJ.js → chunk-WD5B5AIE.js} +1051 -591
  85. package/dist/chunk-WD5B5AIE.js.map +1 -0
  86. package/dist/{chunk-OYESWJ43.js → chunk-WLRD2TXF.js} +15 -10
  87. package/dist/chunk-WLRD2TXF.js.map +1 -0
  88. package/dist/{chunk-4F6X3RXW.js → chunk-X57M2Q4I.js} +2 -2
  89. package/dist/{chunk-6MTSFX7A.js → chunk-X7XEDOSL.js} +8 -8
  90. package/dist/{chunk-UEVLYVNW.js → chunk-YXKVLYXU.js} +2 -2
  91. package/dist/{chunk-OQAL6SIR.js → chunk-ZMSZVISA.js} +2 -2
  92. package/dist/{cli-CnOkH9hA.d.ts → cli-DMAFI0qt.d.ts} +3 -3
  93. package/dist/cli.d.ts +7 -6
  94. package/dist/cli.js +33 -33
  95. package/dist/compounding/engine.d.ts +1 -1
  96. package/dist/compounding/engine.js +7 -7
  97. package/dist/connectors/codex-materialize-runner.js +7 -7
  98. package/dist/connectors/index.js +7 -7
  99. package/dist/consolidation-provenance-check.d.ts +1 -1
  100. package/dist/consolidation-provenance-check.js +4 -4
  101. package/dist/consolidation-undo.d.ts +1 -1
  102. package/dist/consolidation-undo.js +3 -3
  103. package/dist/contradiction/index.d.ts +1 -1
  104. package/dist/convergence-refresh.d.ts +1 -1
  105. package/dist/convergence-refresh.js +9 -9
  106. package/dist/corpus-watermark.js +9 -9
  107. package/dist/dependency-propagation-delivery-D63r24pH.d.ts +41 -0
  108. package/dist/entity-retrieval.d.ts +1 -1
  109. package/dist/entity-retrieval.js +7 -7
  110. package/dist/explicit-capture.d.ts +5 -4
  111. package/dist/explicit-capture.js +4 -4
  112. package/dist/external-wiki-access.d.ts +6 -5
  113. package/dist/external-wiki-access.js +17 -17
  114. package/dist/external-wiki-mcp-tools.d.ts +6 -5
  115. package/dist/extraction.js +7 -7
  116. package/dist/{forget-UJDJHG6R.js → forget-HDS4N6CG.js} +3 -3
  117. package/dist/harmonic-retrieval.js +1 -1
  118. package/dist/index.d.ts +687 -686
  119. package/dist/index.js +39 -39
  120. package/dist/maintenance/memory-governance.js +7 -7
  121. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +1 -1
  122. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -7
  123. package/dist/maintenance/rebuild-memory-projection.d.ts +1 -1
  124. package/dist/maintenance/rebuild-memory-projection.js +8 -8
  125. package/dist/{maintenance-CKwxpdRx.d.ts → maintenance-kBII2qUI.d.ts} +3 -2
  126. package/dist/mcp-memory-inspector-app.d.ts +6 -5
  127. package/dist/memory-worth-outcomes.d.ts +1 -1
  128. package/dist/namespaces/migrate.d.ts +1 -1
  129. package/dist/namespaces/migrate.js +8 -8
  130. package/dist/namespaces/storage.d.ts +1 -1
  131. package/dist/namespaces/storage.js +7 -7
  132. package/dist/operator-doctor-corpus.js +10 -10
  133. package/dist/operator-toolkit.d.ts +1 -1
  134. package/dist/operator-toolkit.js +15 -15
  135. package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
  136. package/dist/orchestration/maintenance.d.ts +2 -2
  137. package/dist/orchestration/maintenance.js +12 -12
  138. package/dist/{orchestrator-BshGam-o.d.ts → orchestrator-DHy5LtTy.d.ts} +20 -35
  139. package/dist/orchestrator.d.ts +5 -4
  140. package/dist/orchestrator.js +39 -39
  141. package/dist/page-versioning.js +3 -3
  142. package/dist/schemas.d.ts +138 -138
  143. package/dist/semantic-consolidation.js +8 -8
  144. package/dist/semantic-rule-promotion.js +7 -7
  145. package/dist/semantic-rule-verifier.js +7 -7
  146. package/dist/{service-BIgVM7fL.d.ts → service-PT2_z7xm.d.ts} +1 -1
  147. package/dist/shared-context/manager.d.ts +8 -8
  148. package/dist/source-agent-qualifier.js +7 -7
  149. package/dist/{storage-CVfGWqCI.d.ts → storage-BmVudhk4.d.ts} +46 -27
  150. package/dist/storage.d.ts +1 -1
  151. package/dist/storage.js +6 -6
  152. package/dist/temporal-supersession.d.ts +51 -26
  153. package/dist/temporal-supersession.js +3 -1
  154. package/dist/tier-migration.d.ts +1 -1
  155. package/dist/transfer/capsule-import.js +4 -4
  156. package/dist/transfer/types.d.ts +66 -66
  157. package/dist/verified-recall.js +7 -7
  158. package/package.json +2 -2
  159. package/src/lifecycle/tombstones.ts +30 -0
  160. package/src/orchestration/consolidation-run.ts +324 -106
  161. package/src/orchestration/contradiction-linking-coordinator.ts +237 -64
  162. package/src/orchestration/dependency-propagation-delivery.test.ts +2353 -0
  163. package/src/orchestration/dependency-propagation-delivery.ts +1143 -0
  164. package/src/orchestration/dependency-propagation-queue-state.ts +220 -0
  165. package/src/orchestration/dependency-propagation-recovery-replay.ts +237 -0
  166. package/src/orchestration/dependency-propagation-replay-reconciliation.ts +73 -0
  167. package/src/orchestration/dependency-propagation-triggers.test.ts +1069 -11
  168. package/src/orchestration/dependency-propagation.test.ts +82 -31
  169. package/src/orchestration/dependency-propagation.ts +55 -17
  170. package/src/orchestration/extraction-persist-deps.ts +2 -2
  171. package/src/orchestration/extraction-persist.ts +14 -15
  172. package/src/orchestration/extraction-queue-coordinator.ts +23 -1
  173. package/src/orchestration/extraction-shutdown.ts +29 -0
  174. package/src/orchestration/maintenance.ts +13 -7
  175. package/src/orchestration/turn-ingestion.ts +5 -1
  176. package/src/orchestrator-background-writes.test.ts +265 -1
  177. package/src/orchestrator-extraction-queue.test.ts +39 -0
  178. package/src/orchestrator.ts +59 -58
  179. package/src/storage/committed-invalidation.ts +34 -0
  180. package/src/storage/deletion-revision-store.ts +529 -0
  181. package/src/storage/supersession-audit.ts +41 -0
  182. package/src/storage/supersession-side-effects.ts +52 -25
  183. package/src/storage-contract/failure-semantics.test.ts +12 -0
  184. package/src/storage-contract/round-trip.test.ts +184 -2
  185. package/src/storage-deletion-revisions.test.ts +213 -1
  186. package/src/storage-frontmatter-cas.test.ts +141 -0
  187. package/src/storage-memory-lifecycle-ledger.test.ts +372 -0
  188. package/src/storage-replay.test.ts +149 -0
  189. package/src/storage.ts +345 -358
  190. package/src/temporal-supersession.test.ts +431 -2
  191. package/src/temporal-supersession.ts +567 -107
  192. package/src/testing/subjects/dependency-propagation.test.ts +179 -38
  193. package/dist/chunk-ENTCVTQR.js.map +0 -1
  194. package/dist/chunk-EWMTOVMY.js +0 -484
  195. package/dist/chunk-EWMTOVMY.js.map +0 -1
  196. package/dist/chunk-OYESWJ43.js.map +0 -1
  197. package/dist/chunk-VBHPOWBJ.js.map +0 -1
  198. package/dist/chunk-ZHY5TMJG.js.map +0 -1
  199. /package/dist/{capsule-merge-XMFBXVDP.js.map → capsule-merge-HCJJMLPS.js.map} +0 -0
  200. /package/dist/{chunk-PWN32TAG.js.map → chunk-2ASAS3CQ.js.map} +0 -0
  201. /package/dist/{chunk-WQM326GS.js.map → chunk-2LY6GIIE.js.map} +0 -0
  202. /package/dist/{chunk-JL43BVDE.js.map → chunk-2OIQDTDC.js.map} +0 -0
  203. /package/dist/{chunk-33SV3E43.js.map → chunk-3OY7KXHM.js.map} +0 -0
  204. /package/dist/{chunk-AIUBBHSF.js.map → chunk-5UZ6UCOZ.js.map} +0 -0
  205. /package/dist/{chunk-UT5BV5OG.js.map → chunk-7HXZJAID.js.map} +0 -0
  206. /package/dist/{chunk-M7BXDKPR.js.map → chunk-7M6NYQWB.js.map} +0 -0
  207. /package/dist/{chunk-TPTECFWR.js.map → chunk-B6LZ4IBH.js.map} +0 -0
  208. /package/dist/{chunk-J5LLX6IL.js.map → chunk-BF6SXNQJ.js.map} +0 -0
  209. /package/dist/{chunk-4PC4PRJE.js.map → chunk-BKIFTXHR.js.map} +0 -0
  210. /package/dist/{chunk-VVG2BOKA.js.map → chunk-BMEYMKWX.js.map} +0 -0
  211. /package/dist/{chunk-DCZBSE4F.js.map → chunk-D5YOZ66N.js.map} +0 -0
  212. /package/dist/{chunk-BHXYAVUM.js.map → chunk-DLG5V6ND.js.map} +0 -0
  213. /package/dist/{chunk-52UKFTUK.js.map → chunk-F4EU6VUC.js.map} +0 -0
  214. /package/dist/{chunk-M4A44LUA.js.map → chunk-GSTIBXBW.js.map} +0 -0
  215. /package/dist/{chunk-W5XVQFLM.js.map → chunk-GXFSQ6SD.js.map} +0 -0
  216. /package/dist/{chunk-XADV5IZ3.js.map → chunk-HDIUYMSB.js.map} +0 -0
  217. /package/dist/{chunk-FXTYIA46.js.map → chunk-J272WKX2.js.map} +0 -0
  218. /package/dist/{chunk-JYL3BVVZ.js.map → chunk-JSEJH2YQ.js.map} +0 -0
  219. /package/dist/{chunk-5UDMFE3Q.js.map → chunk-MLXZD4WM.js.map} +0 -0
  220. /package/dist/{chunk-PUSLMZBQ.js.map → chunk-NOEMGE56.js.map} +0 -0
  221. /package/dist/{chunk-C5QLI33R.js.map → chunk-QINJITDS.js.map} +0 -0
  222. /package/dist/{chunk-45BRYON6.js.map → chunk-QPOHMO6M.js.map} +0 -0
  223. /package/dist/{chunk-ZQOCRIGA.js.map → chunk-QYN5PXDZ.js.map} +0 -0
  224. /package/dist/{chunk-PA45XCUD.js.map → chunk-RANKJI5T.js.map} +0 -0
  225. /package/dist/{chunk-37ZO6LLJ.js.map → chunk-RYLEDKQ2.js.map} +0 -0
  226. /package/dist/{chunk-CV6BBVYV.js.map → chunk-TEMSWHQD.js.map} +0 -0
  227. /package/dist/{chunk-QGR6OVGT.js.map → chunk-VFSAWRMZ.js.map} +0 -0
  228. /package/dist/{chunk-NLK2VZYZ.js.map → chunk-VXCNQYTC.js.map} +0 -0
  229. /package/dist/{chunk-AZ2QBGYB.js.map → chunk-W7Y5JDVB.js.map} +0 -0
  230. /package/dist/{chunk-4F6X3RXW.js.map → chunk-X57M2Q4I.js.map} +0 -0
  231. /package/dist/{chunk-6MTSFX7A.js.map → chunk-X7XEDOSL.js.map} +0 -0
  232. /package/dist/{chunk-UEVLYVNW.js.map → chunk-YXKVLYXU.js.map} +0 -0
  233. /package/dist/{chunk-OQAL6SIR.js.map → chunk-ZMSZVISA.js.map} +0 -0
  234. /package/dist/{forget-UJDJHG6R.js.map → forget-HDS4N6CG.js.map} +0 -0
@@ -0,0 +1,591 @@
1
+ import {
2
+ effectiveValidAt
3
+ } from "./chunk-6CIAGZ6X.js";
4
+ import {
5
+ log
6
+ } from "./chunk-3WCASNQZ.js";
7
+
8
+ // src/temporal-supersession.ts
9
+ import { createHash } from "crypto";
10
+ function normalizeSupersessionKey(raw) {
11
+ return raw.trim().toLowerCase().replace(/[\s\-]+/g, "-").replace(/^-|-$/g, "");
12
+ }
13
+ function computeSupersessionKey(entityRef, attributeName) {
14
+ if (!entityRef || typeof entityRef !== "string") return null;
15
+ if (!attributeName || typeof attributeName !== "string") return null;
16
+ const entity = normalizeSupersessionKey(entityRef);
17
+ const attr = normalizeSupersessionKey(attributeName);
18
+ if (entity.length === 0 || attr.length === 0) return null;
19
+ return `${entity}::${attr}`;
20
+ }
21
+ function supersessionKeysForFact(spec) {
22
+ if (!spec.entityRef) return [];
23
+ if (!spec.structuredAttributes) return [];
24
+ const keys = [];
25
+ for (const attrName of Object.keys(spec.structuredAttributes)) {
26
+ const key = computeSupersessionKey(spec.entityRef, attrName);
27
+ if (key) keys.push(key);
28
+ }
29
+ return keys;
30
+ }
31
+ function lookupAttributeByNormalizedKey(attributes, rawKey) {
32
+ const normalizedTarget = normalizeSupersessionKey(rawKey);
33
+ for (const [k, v] of Object.entries(attributes)) {
34
+ if (normalizeSupersessionKey(k) === normalizedTarget) return v;
35
+ }
36
+ return void 0;
37
+ }
38
+ function shouldSupersedeExisting(args) {
39
+ const { candidate, newEntityRef, newAttributes, newCreatedAt, newMemoryId } = args;
40
+ if (candidate.id === newMemoryId) return null;
41
+ if (candidate.status && candidate.status !== "active") return null;
42
+ if (!candidate.entityRef) return null;
43
+ if (!candidate.structuredAttributes) return null;
44
+ const candidateEntityNorm = normalizeSupersessionKey(candidate.entityRef);
45
+ const newEntityNorm = normalizeSupersessionKey(newEntityRef);
46
+ if (candidateEntityNorm !== newEntityNorm) return null;
47
+ const candidateCreated = Date.parse(effectiveValidAt(candidate));
48
+ const newCreated = Date.parse(newCreatedAt);
49
+ if (!Number.isFinite(candidateCreated) || !Number.isFinite(newCreated)) return null;
50
+ if (candidateCreated >= newCreated) return null;
51
+ const matchedKeys = [];
52
+ for (const [attrName, newValue] of Object.entries(newAttributes)) {
53
+ const candidateValue = lookupAttributeByNormalizedKey(
54
+ candidate.structuredAttributes,
55
+ attrName
56
+ );
57
+ if (candidateValue === void 0) continue;
58
+ if (normalizeValue(String(candidateValue)) === normalizeValue(newValue)) continue;
59
+ const key = computeSupersessionKey(newEntityRef, attrName);
60
+ if (key) matchedKeys.push(key);
61
+ }
62
+ return matchedKeys.length > 0 ? { matchedKeys } : null;
63
+ }
64
+ function normalizeValue(v) {
65
+ return v.trim().toLowerCase();
66
+ }
67
+ function temporalSupersessionOperationKey(sourceMemoryId, replacementId, mutation) {
68
+ return createHash("sha256").update(
69
+ JSON.stringify({
70
+ sourceMemoryId,
71
+ replacementId,
72
+ cause: "temporal_supersession",
73
+ supersededAt: mutation.supersededAt,
74
+ invalidAt: mutation.invalidAt ?? null,
75
+ matchedKeys: [...mutation.matchedKeys].sort(compareByteStable)
76
+ })
77
+ ).digest("hex");
78
+ }
79
+ function compareByteStable(left, right) {
80
+ return Buffer.from(left, "utf8").compare(Buffer.from(right, "utf8"));
81
+ }
82
+ function canonicalTemporalValue(value) {
83
+ if (Array.isArray(value)) return value.map((entry) => canonicalTemporalValue(entry));
84
+ if (value && typeof value === "object") {
85
+ return Object.fromEntries(
86
+ Object.entries(value).sort(([left], [right]) => compareByteStable(left, right)).map(([key, entry]) => [key, canonicalTemporalValue(entry)])
87
+ );
88
+ }
89
+ return value;
90
+ }
91
+ function temporalSnapshotKey(memory) {
92
+ return JSON.stringify(
93
+ canonicalTemporalValue({
94
+ content: memory.content,
95
+ frontmatter: memory.frontmatter
96
+ })
97
+ );
98
+ }
99
+ function temporalMutationPatch(replacementId, mutation) {
100
+ return {
101
+ status: "superseded",
102
+ supersededBy: replacementId,
103
+ supersededAt: mutation.supersededAt,
104
+ updated: mutation.supersededAt,
105
+ ...mutation.invalidAt ? { invalid_at: mutation.invalidAt } : {}
106
+ };
107
+ }
108
+ async function classifyTemporalPrimaryMutation(args) {
109
+ let current;
110
+ try {
111
+ current = await args.storage.readMemoryByPath(args.path);
112
+ } catch {
113
+ return "unknown";
114
+ }
115
+ if (!current) return "unknown";
116
+ const beforeKey = temporalSnapshotKey(args.before);
117
+ const committedKey = temporalSnapshotKey({
118
+ content: args.before.content,
119
+ frontmatter: { ...args.before.frontmatter, ...args.patch }
120
+ });
121
+ const currentKey = temporalSnapshotKey(current);
122
+ if (currentKey === committedKey) return "committed";
123
+ if (currentKey === beforeKey) return "not-committed";
124
+ return "unknown";
125
+ }
126
+ async function settleTemporalPropagationAfterPrimaryFailure(pending, commitState, memoryId) {
127
+ let token = pending.token;
128
+ if (commitState === "not-committed") {
129
+ if (token !== null) {
130
+ try {
131
+ await pending.delivery.cancel(token);
132
+ } catch (error) {
133
+ log.warn(
134
+ `temporal-supersession: dependency propagation cancellation failed for ${memoryId}: ${error}`
135
+ );
136
+ }
137
+ }
138
+ return;
139
+ }
140
+ if (token === null && (commitState === "committed" || commitState === "unknown")) {
141
+ try {
142
+ token = await pending.delivery.prepare(pending.event);
143
+ } catch (error) {
144
+ log.warn(
145
+ `temporal-supersession: dependency propagation recovery preparation failed for ${memoryId}: ${error}`
146
+ );
147
+ }
148
+ }
149
+ if (token !== null) {
150
+ try {
151
+ await pending.delivery.deferPrepared(token);
152
+ } catch (error) {
153
+ log.warn(`temporal-supersession: dependency propagation defer failed for ${memoryId}: ${error}`);
154
+ }
155
+ return;
156
+ }
157
+ if (commitState === "committed") {
158
+ try {
159
+ await pending.delivery.afterMutation(null, pending.event);
160
+ } catch (error) {
161
+ log.warn(`temporal-supersession: dependency propagation fallback failed for ${memoryId}: ${error}`);
162
+ }
163
+ }
164
+ }
165
+ async function hasTemporalLifecycleEffect(args) {
166
+ const events = await args.storage.getMemoryTimeline(args.memoryId, 200);
167
+ return events.some((event) => {
168
+ if (event.memoryId !== args.memoryId || event.eventType !== "superseded" && event.eventType !== "updated" || event.timestamp !== args.timestamp || event.after?.status !== "superseded") {
169
+ return false;
170
+ }
171
+ if (event.correlationId !== void 0) return event.correlationId === args.operationKey;
172
+ return event.reasonCode === args.reasonCode && Array.isArray(event.relatedMemoryIds) && event.relatedMemoryIds.length === args.relatedMemoryIds.length && event.relatedMemoryIds.every((memoryId, index) => memoryId === args.relatedMemoryIds[index]);
173
+ });
174
+ }
175
+ async function hasTemporalTombstoneEffect(args) {
176
+ if (!args.storage.hasExactTombstone) return false;
177
+ return args.storage.hasExactTombstone({
178
+ sourceMemoryId: args.oldMemory.frontmatter.id,
179
+ ...args.oldMemory.frontmatter.contentHash ? { contentHash: args.oldMemory.frontmatter.contentHash } : {},
180
+ ...args.oldMemory.frontmatter.entityRef ? { entityRef: args.oldMemory.frontmatter.entityRef } : {},
181
+ ...args.supersessionKey ? { supersessionKey: args.supersessionKey } : {},
182
+ createdAt: args.createdAt,
183
+ operationKey: args.operationKey
184
+ });
185
+ }
186
+ async function ensureTemporalLifecycleEffect(args) {
187
+ const reasonCode = args.child ? "structured-attribute-update-child-chunk" : "structured-attribute-update";
188
+ const relatedMemoryIds = args.child ? [args.replacementId, args.memory.frontmatter.parentId ?? ""].filter(Boolean) : [args.replacementId];
189
+ const lifecycleEffect = await hasTemporalLifecycleEffect({
190
+ storage: args.storage,
191
+ memoryId: args.memory.frontmatter.id,
192
+ timestamp: args.mutation.supersededAt,
193
+ operationKey: args.operationKey,
194
+ reasonCode,
195
+ relatedMemoryIds
196
+ });
197
+ if (lifecycleEffect === void 0) return false;
198
+ if (lifecycleEffect === true) return true;
199
+ if (lifecycleEffect === false || args.memory.frontmatter.status !== "superseded") {
200
+ if (!args.storage.writeMemoryFrontmatterIfUnchanged) return false;
201
+ const wrote = await args.storage.writeMemoryFrontmatterIfUnchanged(
202
+ args.memory,
203
+ {
204
+ status: "superseded",
205
+ supersededBy: args.replacementId,
206
+ supersededAt: args.mutation.supersededAt,
207
+ updated: args.mutation.supersededAt,
208
+ ...args.mutation.invalidAt && !args.memory.frontmatter.invalid_at ? { invalid_at: args.mutation.invalidAt } : {}
209
+ },
210
+ {
211
+ actor: "temporal-supersession",
212
+ reasonCode: args.child ? "structured-attribute-update-child-chunk" : "structured-attribute-update",
213
+ relatedMemoryIds: args.child ? [args.replacementId, args.memory.frontmatter.parentId ?? ""].filter(Boolean) : [args.replacementId],
214
+ correlationId: args.operationKey
215
+ }
216
+ );
217
+ return wrote;
218
+ }
219
+ return true;
220
+ }
221
+ async function expireChildChunksForSupersededParent(args) {
222
+ const processedChunkIds = /* @__PURE__ */ new Set();
223
+ const chunks = args.allCandidates.filter(
224
+ (candidate) => candidate.frontmatter.parentId === args.parentId
225
+ );
226
+ for (const chunk of chunks) {
227
+ const chunkKey = chunk.frontmatter.id ?? chunk.path;
228
+ if (processedChunkIds.has(chunkKey)) continue;
229
+ try {
230
+ const freshChunk = await args.storage.readMemoryByPath(chunk.path);
231
+ if (!freshChunk) continue;
232
+ processedChunkIds.add(chunkKey);
233
+ const freshStatus = freshChunk.frontmatter.status ?? "active";
234
+ if (freshStatus !== "active" && !(freshStatus === "superseded" && freshChunk.frontmatter.supersededBy === args.newMemoryId)) {
235
+ continue;
236
+ }
237
+ const completed = await ensureTemporalLifecycleEffect({
238
+ storage: args.storage,
239
+ memory: freshChunk,
240
+ replacementId: args.newMemoryId,
241
+ mutation: {
242
+ supersededAt: args.supersededAt,
243
+ ...args.invalidAt ? { invalidAt: args.invalidAt } : {},
244
+ matchedKeys: []
245
+ },
246
+ operationKey: `${args.operationKey}:child:${freshChunk.frontmatter.id}`,
247
+ child: true
248
+ });
249
+ if (!completed) return false;
250
+ } catch (err) {
251
+ log.warn(
252
+ `temporal-supersession: failed to expire child chunk ${chunk.frontmatter.id} for parent ${args.parentId}: ${err}`
253
+ );
254
+ return false;
255
+ }
256
+ }
257
+ return true;
258
+ }
259
+ async function applyTemporalSupersessionPrimaryMutation(args) {
260
+ const { storage, oldMemory, replacementId, mutation } = args;
261
+ if (typeof storage.getMemoryTimeline !== "function") {
262
+ log.warn("temporal-supersession: required memory timeline adapter is missing");
263
+ return false;
264
+ }
265
+ const operationKey = temporalSupersessionOperationKey(
266
+ oldMemory.frontmatter.id,
267
+ replacementId,
268
+ mutation
269
+ );
270
+ const alreadyApplied = oldMemory.frontmatter.status === "superseded" && oldMemory.frontmatter.supersededBy === replacementId && oldMemory.frontmatter.supersededAt === mutation.supersededAt && (mutation.invalidAt === void 0 || oldMemory.frontmatter.invalid_at === mutation.invalidAt);
271
+ const lifecycleEffect = alreadyApplied ? await hasTemporalLifecycleEffect({
272
+ storage,
273
+ memoryId: oldMemory.frontmatter.id,
274
+ timestamp: mutation.supersededAt,
275
+ operationKey,
276
+ reasonCode: "structured-attribute-update",
277
+ relatedMemoryIds: [replacementId]
278
+ }) : void 0;
279
+ if (alreadyApplied && lifecycleEffect === void 0) return false;
280
+ if (!alreadyApplied || lifecycleEffect === false) {
281
+ if (!storage.writeMemoryFrontmatterIfUnchanged) return false;
282
+ const wrote = await storage.writeMemoryFrontmatterIfUnchanged(
283
+ oldMemory,
284
+ temporalMutationPatch(replacementId, mutation),
285
+ {
286
+ actor: "temporal-supersession",
287
+ reasonCode: "structured-attribute-update",
288
+ relatedMemoryIds: [replacementId],
289
+ correlationId: operationKey
290
+ }
291
+ );
292
+ if (!wrote) return false;
293
+ }
294
+ let allCandidates = args.allCandidates;
295
+ if (!allCandidates) {
296
+ let hotMemories;
297
+ let coldMemories;
298
+ try {
299
+ hotMemories = await storage.readAllMemories();
300
+ } catch (error) {
301
+ log.warn(`temporal-supersession: recovery hot-memory scan failed: ${error}`);
302
+ return false;
303
+ }
304
+ try {
305
+ coldMemories = await storage.readAllColdMemories();
306
+ } catch (error) {
307
+ log.warn(`temporal-supersession: recovery cold-memory scan failed: ${error}`);
308
+ return false;
309
+ }
310
+ allCandidates = [...hotMemories, ...coldMemories];
311
+ }
312
+ const childrenCompleted = await expireChildChunksForSupersededParent({
313
+ storage,
314
+ allCandidates,
315
+ parentId: oldMemory.frontmatter.id,
316
+ newMemoryId: replacementId,
317
+ supersededAt: mutation.supersededAt,
318
+ invalidAt: mutation.invalidAt ?? oldMemory.frontmatter.invalid_at,
319
+ operationKey
320
+ });
321
+ if (!childrenCompleted) return false;
322
+ const keysToTombstone = mutation.matchedKeys.length > 0 ? mutation.matchedKeys : [void 0];
323
+ for (const key of keysToTombstone) {
324
+ const tombstoneOperationKey = `${operationKey}:tombstone:${key ?? "content"}`;
325
+ if (await hasTemporalTombstoneEffect({
326
+ storage,
327
+ oldMemory,
328
+ supersessionKey: key,
329
+ operationKey: tombstoneOperationKey,
330
+ createdAt: mutation.supersededAt
331
+ })) {
332
+ continue;
333
+ }
334
+ try {
335
+ const tombstoneId = await storage.appendTombstone({
336
+ reason: "supersession",
337
+ createdBy: "supersession",
338
+ sourceMemoryId: oldMemory.frontmatter.id,
339
+ ...oldMemory.frontmatter.contentHash ? { contentHash: oldMemory.frontmatter.contentHash } : {},
340
+ rawContent: oldMemory.content,
341
+ ...oldMemory.frontmatter.entityRef ? { entityRef: oldMemory.frontmatter.entityRef } : {},
342
+ ...key ? { supersessionKey: key } : {},
343
+ createdAt: mutation.supersededAt,
344
+ operationKey: tombstoneOperationKey
345
+ });
346
+ if (tombstoneId === null && storage.isTombstonesEnabled?.() !== false) {
347
+ return false;
348
+ }
349
+ } catch (error) {
350
+ log.warn(
351
+ `temporal-supersession: tombstone emit failed for ${oldMemory.frontmatter.id}${key ? ` (key=${key})` : ""} : ${error}`
352
+ );
353
+ return false;
354
+ }
355
+ }
356
+ return true;
357
+ }
358
+ async function applyTemporalSupersession(args) {
359
+ const empty = { supersededIds: [], matchedKeys: [] };
360
+ const createdAtMs = typeof args.createdAt === "string" ? Date.parse(args.createdAt) : Number.NaN;
361
+ if (!Number.isFinite(createdAtMs)) {
362
+ log.warn(`temporal-supersession: refusing mutation with invalid createdAt: ${String(args.createdAt)}`);
363
+ return empty;
364
+ }
365
+ if (!args.enabled) return empty;
366
+ if (!args.entityRef) return empty;
367
+ if (!args.structuredAttributes) return empty;
368
+ if (Object.keys(args.structuredAttributes).length === 0) return empty;
369
+ if (typeof args.storage.getMemoryTimeline !== "function") {
370
+ log.warn("temporal-supersession: required memory timeline adapter is missing");
371
+ return empty;
372
+ }
373
+ const newKeys = supersessionKeysForFact({
374
+ entityRef: args.entityRef,
375
+ structuredAttributes: args.structuredAttributes
376
+ });
377
+ if (newKeys.length === 0) return empty;
378
+ let hotMemories;
379
+ try {
380
+ hotMemories = await args.storage.readAllMemories();
381
+ } catch (err) {
382
+ log.warn(`temporal-supersession: readAllMemories failed: ${err}`);
383
+ return empty;
384
+ }
385
+ const newMemoryFile = hotMemories.find((m) => m.frontmatter.id === args.newMemoryId);
386
+ const persistedCreatedAt = args.useCallerTimestamp ? args.createdAt : newMemoryFile ? effectiveValidAt(newMemoryFile.frontmatter) : args.createdAt;
387
+ const supersededIds = [];
388
+ const matchedKeys = /* @__PURE__ */ new Set();
389
+ const processedIds = /* @__PURE__ */ new Set();
390
+ let coldMemories;
391
+ try {
392
+ coldMemories = await args.storage.readAllColdMemories();
393
+ } catch (err) {
394
+ log.warn(`temporal-supersession: readAllColdMemories failed: ${err}`);
395
+ coldMemories = [];
396
+ }
397
+ const allCandidates = [...hotMemories, ...coldMemories];
398
+ const replacementMemory = allCandidates.find((memory) => memory.frontmatter.id === args.newMemoryId) ?? newMemoryFile;
399
+ for (const memory of allCandidates) {
400
+ if (memory.frontmatter.id === args.newMemoryId) continue;
401
+ const dedupeKey = memory.frontmatter.id ?? memory.path;
402
+ if (processedIds.has(dedupeKey)) continue;
403
+ const snapshotStatus = memory.frontmatter.status ?? "active";
404
+ if (snapshotStatus !== "active") {
405
+ continue;
406
+ }
407
+ const decision = shouldSupersedeExisting({
408
+ candidate: memory.frontmatter,
409
+ newEntityRef: args.entityRef,
410
+ newAttributes: args.structuredAttributes,
411
+ newCreatedAt: persistedCreatedAt,
412
+ newMemoryId: args.newMemoryId
413
+ });
414
+ if (!decision) {
415
+ processedIds.add(dedupeKey);
416
+ continue;
417
+ }
418
+ let preparedPropagation = null;
419
+ let primaryPath = null;
420
+ let primaryBefore = null;
421
+ let primaryPatch = null;
422
+ try {
423
+ const fresh = await args.storage.readMemoryByPath(memory.path);
424
+ if (!fresh) {
425
+ log.debug(
426
+ `[engram] temporal supersession skipped candidate ${memory.frontmatter.id}: no longer readable at ${memory.path} \u2014 leaving id available for alternate tier`
427
+ );
428
+ continue;
429
+ }
430
+ processedIds.add(dedupeKey);
431
+ const freshStatus = fresh.frontmatter.status ?? "active";
432
+ if (freshStatus !== "active" || fresh.frontmatter.supersededBy) {
433
+ log.debug(
434
+ `[engram] temporal supersession skipped candidate ${memory.frontmatter.id}: already superseded by concurrent writer`
435
+ );
436
+ continue;
437
+ }
438
+ primaryPath = fresh.path;
439
+ primaryBefore = {
440
+ content: fresh.content,
441
+ frontmatter: { ...fresh.frontmatter }
442
+ };
443
+ const oldCreatedMs = new Date(fresh.frontmatter.created).getTime();
444
+ const newCreatedMs = new Date(persistedCreatedAt).getTime();
445
+ const argCreatedMs = new Date(args.createdAt).getTime();
446
+ const maxMs = Math.max(
447
+ Number.isFinite(oldCreatedMs) ? oldCreatedMs : 0,
448
+ Number.isFinite(newCreatedMs) ? newCreatedMs : 0,
449
+ Number.isFinite(argCreatedMs) ? argCreatedMs : 0
450
+ );
451
+ const supersededAt = new Date(maxMs).toISOString();
452
+ let invalidAtPatch;
453
+ if (!fresh.frontmatter.invalid_at) {
454
+ if (args.useCallerTimestamp) {
455
+ invalidAtPatch = persistedCreatedAt;
456
+ } else {
457
+ const newValidAt = replacementMemory?.frontmatter.valid_at?.trim();
458
+ invalidAtPatch = newValidAt && newValidAt.length > 0 ? newValidAt : persistedCreatedAt;
459
+ }
460
+ }
461
+ const mutation = {
462
+ supersededAt,
463
+ ...invalidAtPatch ? { invalidAt: invalidAtPatch } : {},
464
+ matchedKeys: decision.matchedKeys
465
+ };
466
+ primaryPatch = temporalMutationPatch(args.newMemoryId, mutation);
467
+ const propagationEvent = args.dependencyPropagationDelivery && args.namespaceScope ? {
468
+ oldMemory: {
469
+ content: fresh.content,
470
+ frontmatter: {
471
+ ...fresh.frontmatter,
472
+ ...fresh.frontmatter.links ? { links: fresh.frontmatter.links.map((link) => ({ ...link })) } : {}
473
+ }
474
+ },
475
+ replacementId: args.newMemoryId,
476
+ replacementContent: replacementMemory?.content ?? null,
477
+ cause: "temporal_supersession",
478
+ namespaceScope: args.namespaceScope,
479
+ temporalMutation: mutation
480
+ } : null;
481
+ if (propagationEvent && args.dependencyPropagationDelivery) {
482
+ preparedPropagation = {
483
+ delivery: args.dependencyPropagationDelivery,
484
+ event: propagationEvent,
485
+ token: null
486
+ };
487
+ try {
488
+ preparedPropagation.token = await args.dependencyPropagationDelivery.prepare(propagationEvent);
489
+ } catch (prepareErr) {
490
+ log.warn(
491
+ `temporal-supersession: dependency propagation preparation failed for ${fresh.frontmatter.id}: ${prepareErr}`
492
+ );
493
+ }
494
+ }
495
+ const wrote = await applyTemporalSupersessionPrimaryMutation({
496
+ storage: args.storage,
497
+ oldMemory: fresh,
498
+ replacementId: args.newMemoryId,
499
+ mutation,
500
+ allCandidates
501
+ });
502
+ if (!wrote) {
503
+ const commitState = await classifyTemporalPrimaryMutation({
504
+ storage: args.storage,
505
+ path: fresh.path,
506
+ before: primaryBefore,
507
+ patch: primaryPatch
508
+ });
509
+ if (preparedPropagation) {
510
+ await settleTemporalPropagationAfterPrimaryFailure(
511
+ preparedPropagation,
512
+ commitState,
513
+ fresh.frontmatter.id
514
+ );
515
+ if (commitState !== "not-committed") {
516
+ log.warn(
517
+ `temporal-supersession: retaining dependency propagation recovery for ${fresh.frontmatter.id} after ${commitState} primary mutation`
518
+ );
519
+ }
520
+ }
521
+ preparedPropagation = null;
522
+ continue;
523
+ }
524
+ if (preparedPropagation) {
525
+ const completedPropagation = preparedPropagation;
526
+ preparedPropagation = null;
527
+ try {
528
+ await completedPropagation.delivery.afterMutation(
529
+ completedPropagation.token,
530
+ completedPropagation.event
531
+ );
532
+ } catch (afterMutationErr) {
533
+ log.warn(
534
+ `temporal-supersession: dependency propagation delivery failed for ${memory.frontmatter.id}: ${afterMutationErr}`
535
+ );
536
+ }
537
+ }
538
+ supersededIds.push(memory.frontmatter.id);
539
+ for (const key of decision.matchedKeys) matchedKeys.add(key);
540
+ } catch (err) {
541
+ let commitState = "unknown";
542
+ if (primaryPath && primaryBefore && primaryPatch) {
543
+ commitState = await classifyTemporalPrimaryMutation({
544
+ storage: args.storage,
545
+ path: primaryPath,
546
+ before: primaryBefore,
547
+ patch: primaryPatch
548
+ });
549
+ }
550
+ if (preparedPropagation) {
551
+ await settleTemporalPropagationAfterPrimaryFailure(
552
+ preparedPropagation,
553
+ commitState,
554
+ memory.frontmatter.id
555
+ );
556
+ if (commitState !== "not-committed") {
557
+ log.warn(
558
+ `temporal-supersession: retaining dependency propagation recovery for ${memory.frontmatter.id} after ${commitState} primary mutation`
559
+ );
560
+ }
561
+ }
562
+ preparedPropagation = null;
563
+ log.warn(
564
+ `temporal-supersession: failed to mark ${memory.frontmatter.id} superseded: ${err}`
565
+ );
566
+ }
567
+ }
568
+ if (supersededIds.length > 0) {
569
+ log.debug(
570
+ `temporal-supersession: marked ${supersededIds.length} memories superseded by ${args.newMemoryId} (keys=${Array.from(matchedKeys).join(",")})`
571
+ );
572
+ }
573
+ return { supersededIds, matchedKeys: Array.from(matchedKeys) };
574
+ }
575
+ function shouldFilterSupersededFromRecall(frontmatter, options) {
576
+ if (!options.enabled) return false;
577
+ if (options.includeInRecall) return false;
578
+ return frontmatter.status === "superseded";
579
+ }
580
+
581
+ export {
582
+ normalizeSupersessionKey,
583
+ computeSupersessionKey,
584
+ supersessionKeysForFact,
585
+ lookupAttributeByNormalizedKey,
586
+ shouldSupersedeExisting,
587
+ applyTemporalSupersessionPrimaryMutation,
588
+ applyTemporalSupersession,
589
+ shouldFilterSupersededFromRecall
590
+ };
591
+ //# sourceMappingURL=chunk-5WITETWU.js.map