@remnic/core 9.69.44 → 9.69.46

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 (533) hide show
  1. package/dist/access-admin-ops-surface.d.ts +14 -14
  2. package/dist/access-admin-ops-surface.js +36 -36
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +14 -14
  5. package/dist/access-authorization-probe.js +37 -37
  6. package/dist/access-boundary.d.ts +14 -14
  7. package/dist/access-boundary.js +36 -36
  8. package/dist/access-cli.js +90 -87
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-coding-context-resolution.d.ts +1 -1
  11. package/dist/access-extraction-force-flush.d.ts +14 -14
  12. package/dist/access-extraction-force-flush.js +36 -36
  13. package/dist/access-health-types.d.ts +1 -1
  14. package/dist/access-http-briefing.d.ts +14 -14
  15. package/dist/access-http-briefing.js +37 -37
  16. package/dist/access-http-lcm-compaction.d.ts +14 -14
  17. package/dist/access-http-lifecycle-flush.d.ts +14 -14
  18. package/dist/access-http-offline-stream.d.ts +14 -14
  19. package/dist/access-http-query.d.ts +2 -2
  20. package/dist/access-http-query.js +38 -38
  21. package/dist/access-http.d.ts +15 -15
  22. package/dist/access-http.js +52 -52
  23. package/dist/access-identity-continuity-surface.d.ts +11 -11
  24. package/dist/access-identity-continuity-surface.js +36 -36
  25. package/dist/access-lcm-surface.d.ts +14 -14
  26. package/dist/access-lcm-surface.js +36 -36
  27. package/dist/access-mcp-shared-context-tools.d.ts +14 -14
  28. package/dist/access-mcp.d.ts +14 -14
  29. package/dist/access-mcp.js +44 -44
  30. package/dist/access-memory-search-fanout.d.ts +2 -2
  31. package/dist/{access-namespace-preflight-CE-RrXKu.d.ts → access-namespace-preflight-DDnsN22V.d.ts} +1 -1
  32. package/dist/access-namespace-preflight.d.ts +3 -3
  33. package/dist/access-namespace-preflight.js +36 -36
  34. package/dist/access-observe-transcript.d.ts +11 -11
  35. package/dist/access-observe-write-category.d.ts +3 -3
  36. package/dist/access-observe-write-category.js +4 -4
  37. package/dist/access-observe-write-surface.d.ts +14 -14
  38. package/dist/access-observe-write-surface.js +36 -36
  39. package/dist/access-offline-manifest.d.ts +11 -11
  40. package/dist/access-offline-manifest.js +3 -3
  41. package/dist/access-operations-batch.js +37 -37
  42. package/dist/access-operations.d.ts +14 -14
  43. package/dist/access-operations.js +43 -43
  44. package/dist/access-recall-concurrency.d.ts +14 -14
  45. package/dist/access-recall-concurrency.js +36 -36
  46. package/dist/access-recall-response.d.ts +14 -14
  47. package/dist/access-recall-response.js +36 -36
  48. package/dist/access-recall-surface.d.ts +14 -14
  49. package/dist/access-recall-surface.js +36 -36
  50. package/dist/access-schema.d.ts +114 -114
  51. package/dist/access-schema.js +3 -3
  52. package/dist/{access-service-Cww3xAAy.d.ts → access-service-DGynYlbE.d.ts} +73 -73
  53. package/dist/access-service-helpers.d.ts +14 -14
  54. package/dist/access-service.d.ts +14 -14
  55. package/dist/access-service.js +36 -36
  56. package/dist/access-surface-catalog.d.ts +14 -14
  57. package/dist/access-surface-catalog.js +38 -38
  58. package/dist/access-wearables-meetings-surface.d.ts +4 -4
  59. package/dist/action-confidence.d.ts +1 -1
  60. package/dist/active-memory-bridge.d.ts +1 -1
  61. package/dist/active-recall.d.ts +1 -1
  62. package/dist/activity/digest.d.ts +1 -1
  63. package/dist/ambient-provenance.d.ts +1 -1
  64. package/dist/artifact-search.d.ts +1 -1
  65. package/dist/{auto-sync-QZD4RD6H.js → auto-sync-DG5KEOF5.js} +5 -5
  66. package/dist/background-generation.d.ts +1 -1
  67. package/dist/behavior-learner.d.ts +1 -1
  68. package/dist/behavior-signals.d.ts +1 -1
  69. package/dist/bootstrap.d.ts +11 -11
  70. package/dist/briefing-window.d.ts +2 -2
  71. package/dist/briefing.d.ts +2 -2
  72. package/dist/briefing.js +12 -12
  73. package/dist/buffer-surprise-report.d.ts +1 -1
  74. package/dist/buffer-turn-helpers.d.ts +1 -1
  75. package/dist/buffer.d.ts +2 -2
  76. package/dist/buffer.js +3 -3
  77. package/dist/bulk-import/index.d.ts +3 -3
  78. package/dist/calibration.d.ts +1 -1
  79. package/dist/calibration.js +2 -2
  80. package/dist/capabilities.d.ts +1 -1
  81. package/dist/{catalog-Ya3DDn_T.d.ts → catalog-Dl2hYqpS.d.ts} +1 -1
  82. package/dist/causal-behavior.d.ts +1 -1
  83. package/dist/causal-consolidation.d.ts +1 -1
  84. package/dist/causal-consolidation.js +13 -13
  85. package/dist/causal-trajectory-graph.d.ts +1 -1
  86. package/dist/{chunk-MOL7JK4F.js → chunk-3NYM6JA4.js} +2 -2
  87. package/dist/{chunk-WNMVUWI7.js → chunk-3UQIS2GC.js} +2 -2
  88. package/dist/{chunk-JDL5BYYF.js → chunk-47C6DF43.js} +3 -3
  89. package/dist/{chunk-ZBSP4BSN.js → chunk-4ECS33D4.js} +2 -2
  90. package/dist/{chunk-6EGIQEKC.js → chunk-4HTQ76O4.js} +2 -2
  91. package/dist/{chunk-7L54ARML.js → chunk-4XTSKGLX.js} +2 -2
  92. package/dist/{chunk-SUS64JER.js → chunk-5EHPB6RL.js} +2 -2
  93. package/dist/{chunk-J2MGTGKC.js → chunk-5ZXGH2ZL.js} +20 -3
  94. package/dist/chunk-5ZXGH2ZL.js.map +1 -0
  95. package/dist/{chunk-VDLNQVYW.js → chunk-62NYUFNH.js} +7 -7
  96. package/dist/{chunk-Y77UTH7F.js → chunk-66QOUYNS.js} +83 -64
  97. package/dist/chunk-66QOUYNS.js.map +1 -0
  98. package/dist/{chunk-SZV2L2IG.js → chunk-7BNB7KHB.js} +4 -4
  99. package/dist/chunk-AAQA6ZUP.js +41 -0
  100. package/dist/chunk-AAQA6ZUP.js.map +1 -0
  101. package/dist/{chunk-RJ7Z7YXK.js → chunk-AG6PANBG.js} +14 -20
  102. package/dist/chunk-AG6PANBG.js.map +1 -0
  103. package/dist/{chunk-IAGEEVQL.js → chunk-AN2O4KZY.js} +2 -2
  104. package/dist/{chunk-JUOJGZPV.js → chunk-AYP2FZFA.js} +2 -2
  105. package/dist/{chunk-XK76RJBN.js → chunk-AYZHHMTK.js} +2 -2
  106. package/dist/{chunk-LQVXSRAJ.js → chunk-B4EGAHHS.js} +2 -2
  107. package/dist/{chunk-HKQAI6XI.js → chunk-CFIHVWYZ.js} +2 -2
  108. package/dist/{chunk-DABSYX7V.js → chunk-CWMMKFO7.js} +3 -3
  109. package/dist/{chunk-WLHPCAVD.js → chunk-D5DTZBTV.js} +6 -6
  110. package/dist/{chunk-2HDLDBJW.js → chunk-DDBLZJRV.js} +2 -2
  111. package/dist/{chunk-F2FJTOV6.js → chunk-DO6R3LIE.js} +2 -2
  112. package/dist/{chunk-SHEHQBCG.js → chunk-DUJYRVUD.js} +638 -45
  113. package/dist/chunk-DUJYRVUD.js.map +1 -0
  114. package/dist/{chunk-LD22AAJI.js → chunk-EAZ3YZKN.js} +2 -2
  115. package/dist/{chunk-46FVFU7S.js → chunk-EC5SVM6H.js} +2 -2
  116. package/dist/{chunk-GKKLI23D.js → chunk-EEHQY7ER.js} +2 -2
  117. package/dist/{chunk-UHSOPTNB.js → chunk-EP6BA7VV.js} +50 -15
  118. package/dist/chunk-EP6BA7VV.js.map +1 -0
  119. package/dist/{chunk-BPXJINHW.js → chunk-EUP4AXIW.js} +2 -2
  120. package/dist/{chunk-2WMXZYMS.js → chunk-F5V7KRQS.js} +2 -2
  121. package/dist/{chunk-4AX5OYKC.js → chunk-FDDCZDBI.js} +2 -2
  122. package/dist/{chunk-XLPZN3A5.js → chunk-FMEP2RB5.js} +2 -2
  123. package/dist/{chunk-D7UUB33A.js → chunk-FSH6KRKO.js} +2 -2
  124. package/dist/{chunk-3254BYQV.js → chunk-GGY7WKMB.js} +1 -1
  125. package/dist/{chunk-ROXDOKLM.js → chunk-GYYLZOSO.js} +4 -4
  126. package/dist/{chunk-3K64PLY3.js → chunk-HXDXR2FH.js} +23 -23
  127. package/dist/{chunk-XOCGC3FJ.js → chunk-HYWPUYLO.js} +2 -2
  128. package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
  129. package/dist/{chunk-M6FKXOYV.js → chunk-IXMWTNNY.js} +2 -2
  130. package/dist/{chunk-ZYSOT6HD.js → chunk-J3IWHCMF.js} +2 -2
  131. package/dist/{chunk-3YQ7VLP3.js → chunk-J5OXWG66.js} +2 -2
  132. package/dist/{chunk-H2N6SLTR.js → chunk-JIWZVOQM.js} +2 -2
  133. package/dist/{chunk-C3YEB7CR.js → chunk-JOP7W24J.js} +4 -4
  134. package/dist/{chunk-F6PTJLEM.js → chunk-K4KE5MYE.js} +1 -1
  135. package/dist/{chunk-IOTYIECA.js → chunk-KF57IQFX.js} +13 -13
  136. package/dist/{chunk-JL4TQYM5.js → chunk-L272A5QW.js} +33 -2
  137. package/dist/{chunk-JL4TQYM5.js.map → chunk-L272A5QW.js.map} +1 -1
  138. package/dist/chunk-M4DB6ZNN.js +87 -0
  139. package/dist/chunk-M4DB6ZNN.js.map +1 -0
  140. package/dist/{chunk-ZVQ5HF77.js → chunk-N46SNYMC.js} +2 -2
  141. package/dist/{chunk-YR5QT4SR.js → chunk-NAFPHFDM.js} +2 -2
  142. package/dist/{chunk-VHANUT45.js → chunk-ORQ7AZMU.js} +7 -7
  143. package/dist/{chunk-EOXCOZ6L.js → chunk-OV7GJ4KW.js} +2 -2
  144. package/dist/{chunk-VJXMFBVR.js → chunk-P7S7BVBJ.js} +2 -2
  145. package/dist/{chunk-GMU7MAHS.js → chunk-QUFJ3NJE.js} +260 -796
  146. package/dist/chunk-QUFJ3NJE.js.map +1 -0
  147. package/dist/{chunk-7F47R4H4.js → chunk-S3SND7SO.js} +2 -2
  148. package/dist/{chunk-5AJZ7EUW.js → chunk-S7KDHFF2.js} +2 -2
  149. package/dist/{chunk-4WMGRLTV.js → chunk-SRRZZHA5.js} +2 -2
  150. package/dist/{chunk-KDLOKVX7.js → chunk-SW42MMAH.js} +2 -2
  151. package/dist/{chunk-2YIUUXNK.js → chunk-T5NI5K46.js} +2 -2
  152. package/dist/{chunk-QCTXQ2HW.js → chunk-TE6B2UU6.js} +2 -2
  153. package/dist/{chunk-JDOBQPJY.js → chunk-TNQR7N52.js} +2 -2
  154. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  155. package/dist/{chunk-T3F2HWIG.js → chunk-TZ44E732.js} +2 -2
  156. package/dist/{chunk-PF7LQ22G.js → chunk-U4ESGVZ2.js} +3 -3
  157. package/dist/{chunk-WJPR2XUN.js → chunk-UEJY6ZTQ.js} +2 -2
  158. package/dist/{chunk-K3IVJ5ML.js → chunk-UGGOQKO6.js} +26 -26
  159. package/dist/{chunk-OCX7OWOC.js → chunk-UOREPQ3C.js} +2 -2
  160. package/dist/{chunk-R3H2AXO2.js → chunk-VGRVJ6Z6.js} +2 -2
  161. package/dist/{chunk-IWHNT35B.js → chunk-WOBMSMUK.js} +3 -3
  162. package/dist/{chunk-DDGQDNQW.js → chunk-XLZZLUWL.js} +2 -2
  163. package/dist/{chunk-KORQWGUA.js → chunk-Y3XHIWVP.js} +2 -2
  164. package/dist/{chunk-BZDK5EOD.js → chunk-YFVIA5A6.js} +2 -2
  165. package/dist/{chunk-GR76OKET.js → chunk-YSBYNCCN.js} +2 -2
  166. package/dist/{chunk-OGAKUA7I.js → chunk-YUQPUK6H.js} +2 -2
  167. package/dist/{chunk-TRTLWUDD.js → chunk-ZTHGFTMW.js} +2 -2
  168. package/dist/{cli-Cl7bKIWJ.d.ts → cli-Cik3H7q1.d.ts} +5 -5
  169. package/dist/cli.d.ts +16 -16
  170. package/dist/cli.js +67 -67
  171. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  172. package/dist/coding/export-okf-codegraph.js +11 -11
  173. package/dist/coding/pre-action-gate.d.ts +1 -1
  174. package/dist/compounding/engine.d.ts +2 -2
  175. package/dist/compounding/engine.js +12 -12
  176. package/dist/compounding/preference-consolidator.d.ts +1 -1
  177. package/dist/compression-optimizer.d.ts +1 -1
  178. package/dist/config.d.ts +1 -1
  179. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  180. package/dist/connectors/codex-materialize-runner.js +12 -12
  181. package/dist/connectors/codex-materialize.d.ts +1 -1
  182. package/dist/connectors/index.d.ts +1 -1
  183. package/dist/connectors/index.js +12 -12
  184. package/dist/consolidation-provenance-check.d.ts +2 -2
  185. package/dist/consolidation-undo.d.ts +2 -2
  186. package/dist/contradiction/index.d.ts +4 -4
  187. package/dist/converge-config.d.ts +1 -1
  188. package/dist/convergence-refresh.d.ts +2 -2
  189. package/dist/convergence-refresh.js +14 -14
  190. package/dist/conversation-index/backend.d.ts +1 -1
  191. package/dist/conversation-index/chunker.d.ts +1 -1
  192. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  193. package/dist/conversation-index/indexer.d.ts +1 -1
  194. package/dist/conversation-index/search.d.ts +1 -1
  195. package/dist/corpus-watermark.d.ts +1 -1
  196. package/dist/corpus-watermark.js +14 -14
  197. package/dist/cross-lingual-recall.d.ts +1 -1
  198. package/dist/day-summary.d.ts +1 -1
  199. package/dist/deep-recall-http-glue.d.ts +14 -14
  200. package/dist/deep-recall-http-glue.js +4 -4
  201. package/dist/deep-recall-mcp-tools.d.ts +14 -14
  202. package/dist/deep-recall-policy-llm.d.ts +2 -2
  203. package/dist/deep-recall-policy-llm.js +3 -3
  204. package/dist/deep-recall-seeds.d.ts +1 -1
  205. package/dist/delinearize.d.ts +1 -1
  206. package/dist/dependency-propagation-config.d.ts +1 -1
  207. package/dist/{dependency-propagation-delivery-CggS9BFT.d.ts → dependency-propagation-delivery-BXaUoVUf.d.ts} +1 -1
  208. package/dist/direct-answer-wiring.d.ts +1 -1
  209. package/dist/direct-answer.d.ts +1 -1
  210. package/dist/embedding-fallback.d.ts +1 -1
  211. package/dist/enrichment/index.d.ts +1 -1
  212. package/dist/entity-origin-fields.d.ts +1 -1
  213. package/dist/entity-retrieval.d.ts +2 -2
  214. package/dist/entity-retrieval.js +12 -12
  215. package/dist/entity-schema.d.ts +1 -1
  216. package/dist/episodic-context.d.ts +1 -1
  217. package/dist/eval-trajectory-contracts.d.ts +1 -1
  218. package/dist/eval-trajectory-store.d.ts +1 -1
  219. package/dist/eval-trajectory.d.ts +1 -1
  220. package/dist/explicit-capture.d.ts +11 -11
  221. package/dist/explicit-capture.js +2 -2
  222. package/dist/external-wiki-access.d.ts +14 -14
  223. package/dist/external-wiki-access.js +37 -37
  224. package/dist/external-wiki-collection-registration.d.ts +1 -1
  225. package/dist/external-wiki-collection.d.ts +1 -1
  226. package/dist/external-wiki-mcp-tools.d.ts +14 -14
  227. package/dist/extraction-error-classification.d.ts +1 -1
  228. package/dist/extraction-faithfulness.d.ts +2 -2
  229. package/dist/extraction-faithfulness.js +3 -3
  230. package/dist/extraction-judge-telemetry.d.ts +2 -2
  231. package/dist/extraction-judge-training.d.ts +2 -2
  232. package/dist/extraction-judge.d.ts +2 -2
  233. package/dist/extraction-judge.js +3 -3
  234. package/dist/extraction-liveness.d.ts +1 -1
  235. package/dist/extraction-normalization.d.ts +1 -1
  236. package/dist/extraction-prompt.d.ts +1 -1
  237. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  238. package/dist/extraction-source-grounding.d.ts +1 -1
  239. package/dist/extraction-span-config.d.ts +1 -1
  240. package/dist/extraction-span-materialize.d.ts +1 -1
  241. package/dist/extraction-span-wire.d.ts +23 -4
  242. package/dist/extraction-span-wire.js +7 -8
  243. package/dist/extraction-span-wire.js.map +1 -1
  244. package/dist/extraction.d.ts +2 -2
  245. package/dist/extraction.js +19 -17
  246. package/dist/fallback-llm-codex-subscription.d.ts +1 -1
  247. package/dist/fallback-llm-codex-subscription.js +1 -1
  248. package/dist/fallback-llm.d.ts +1 -1
  249. package/dist/fallback-llm.js +2 -2
  250. package/dist/{generic-recall-paths-CoXPSnCw.d.ts → generic-recall-paths-BkVVEoeO.d.ts} +1 -1
  251. package/dist/graph-append-error.d.ts +1 -1
  252. package/dist/graph-dashboard-diff.d.ts +1 -1
  253. package/dist/graph-dashboard-key.d.ts +1 -1
  254. package/dist/graph-dashboard-parser.d.ts +1 -1
  255. package/dist/graph-edge-reinforcement.d.ts +1 -1
  256. package/dist/graph-jsonl.d.ts +1 -1
  257. package/dist/graph-path-reconstruction.d.ts +1 -1
  258. package/dist/graph-path-scoring.d.ts +1 -1
  259. package/dist/graph-snapshot.d.ts +1 -1
  260. package/dist/graph.d.ts +1 -1
  261. package/dist/harmonic-retrieval.js +1 -1
  262. package/dist/importance.d.ts +1 -1
  263. package/dist/importers/index.d.ts +1 -1
  264. package/dist/importers/test-utils.d.ts +1 -1
  265. package/dist/in-flight-reads.d.ts +1 -1
  266. package/dist/{index-fdw_oK5a.d.ts → index-Zb6SUV4R.d.ts} +3 -3
  267. package/dist/index.d.ts +703 -703
  268. package/dist/index.js +90 -87
  269. package/dist/intent.d.ts +1 -1
  270. package/dist/lcm/engine.d.ts +1 -1
  271. package/dist/lcm/index.d.ts +1 -1
  272. package/dist/lcm/index.js +3 -3
  273. package/dist/lcm/tools.d.ts +1 -1
  274. package/dist/lifecycle.d.ts +1 -1
  275. package/dist/live-connectors-runner.d.ts +1 -1
  276. package/dist/{local-llm-3-jtw52a.d.ts → local-llm-DdrhmecM.d.ts} +1 -1
  277. package/dist/local-llm-helpers.d.ts +2 -2
  278. package/dist/local-llm.d.ts +2 -2
  279. package/dist/local-model-endpoint.d.ts +1 -1
  280. package/dist/location/index.d.ts +5 -5
  281. package/dist/location/index.js +14 -14
  282. package/dist/maintenance/memory-governance.d.ts +1 -1
  283. package/dist/maintenance/memory-governance.js +12 -12
  284. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  285. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +12 -12
  286. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  287. package/dist/maintenance/rebuild-memory-projection.js +13 -13
  288. package/dist/{maintenance-DgeeH0a1.d.ts → maintenance-Du_VRvVg.d.ts} +3 -3
  289. package/dist/mcp-memory-inspector-app.d.ts +14 -14
  290. package/dist/memory-action-policy.d.ts +1 -1
  291. package/dist/memory-age.d.ts +100 -0
  292. package/dist/memory-age.js +22 -0
  293. package/dist/memory-age.js.map +1 -0
  294. package/dist/memory-cache.d.ts +1 -1
  295. package/dist/memory-controller.d.ts +1 -1
  296. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  297. package/dist/memory-projection-store.d.ts +1 -1
  298. package/dist/memory-provenance.d.ts +1 -1
  299. package/dist/memory-snapshot.d.ts +1 -1
  300. package/dist/memory-subject-cli.d.ts +14 -14
  301. package/dist/memory-subject.d.ts +14 -14
  302. package/dist/memory-worth-outcomes.d.ts +2 -2
  303. package/dist/models-json.d.ts +1 -1
  304. package/dist/namespaces/migrate.d.ts +3 -3
  305. package/dist/namespaces/migrate.js +13 -13
  306. package/dist/namespaces/principal.d.ts +1 -1
  307. package/dist/namespaces/search.d.ts +1 -1
  308. package/dist/namespaces/search.js +3 -3
  309. package/dist/namespaces/storage.d.ts +3 -3
  310. package/dist/namespaces/storage.js +12 -12
  311. package/dist/native-knowledge.d.ts +1 -1
  312. package/dist/offline-sync-impression-drain.d.ts +1 -1
  313. package/dist/operator-doctor-corpus.d.ts +1 -1
  314. package/dist/operator-doctor-corpus.js +15 -15
  315. package/dist/operator-doctor-replica.d.ts +1 -1
  316. package/dist/operator-toolkit.d.ts +3 -3
  317. package/dist/operator-toolkit.js +20 -20
  318. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  319. package/dist/orchestration/maintenance.d.ts +4 -4
  320. package/dist/orchestration/maintenance.js +20 -20
  321. package/dist/{orchestrator-VXWKdatm.d.ts → orchestrator-D9U3Zgjp.d.ts} +10 -10
  322. package/dist/orchestrator.d.ts +11 -11
  323. package/dist/orchestrator.js +90 -87
  324. package/dist/patterns-cli.d.ts +1 -1
  325. package/dist/{pipeline-CwXZBKR5.d.ts → pipeline-4lqKJZ_0.d.ts} +1 -1
  326. package/dist/policy-runtime.d.ts +1 -1
  327. package/dist/proactive-contention.d.ts +2 -2
  328. package/dist/provenance.d.ts +1 -1
  329. package/dist/{public-http-DdmM4scJ.d.ts → public-http-AabioFLh.d.ts} +1 -1
  330. package/dist/{qmd-DOLTPIQg.d.ts → qmd-DnoWaXKb.d.ts} +1 -1
  331. package/dist/qmd-preflight.d.ts +2 -2
  332. package/dist/qmd-recall-cache.d.ts +1 -1
  333. package/dist/qmd.d.ts +2 -2
  334. package/dist/recall-concurrency-config.d.ts +1 -1
  335. package/dist/recall-disclosure-escalation.d.ts +1 -1
  336. package/dist/recall-explain-renderer.d.ts +1 -1
  337. package/dist/recall-memory-map.d.ts +1 -1
  338. package/dist/recall-navigate-access.d.ts +1 -1
  339. package/dist/recall-navigate-disclosure.d.ts +1 -1
  340. package/dist/recall-navigate.d.ts +1 -1
  341. package/dist/recall-navigation-http-glue.d.ts +14 -14
  342. package/dist/recall-navigation-mcp-tools.d.ts +14 -14
  343. package/dist/recall-navigation-operations.js +37 -37
  344. package/dist/recall-navigation-renderer.d.ts +1 -1
  345. package/dist/recall-navigation.d.ts +1 -1
  346. package/dist/recall-navigation.js +36 -36
  347. package/dist/recall-planner-llm.d.ts +1 -1
  348. package/dist/recall-planner-llm.js +2 -2
  349. package/dist/recall-state-view-admission.d.ts +2 -2
  350. package/dist/recall-state-view-admission.js +3 -3
  351. package/dist/recall-state-view-anchors.d.ts +1 -1
  352. package/dist/recall-state.d.ts +1 -1
  353. package/dist/recall-tag-filter.d.ts +1 -1
  354. package/dist/recall-timings.d.ts +1 -1
  355. package/dist/recall-xray-cli.d.ts +1 -1
  356. package/dist/recall-xray-renderer.d.ts +1 -1
  357. package/dist/recall-xray.d.ts +1 -1
  358. package/dist/reconcile/cursor.d.ts +1 -1
  359. package/dist/reconcile/manifest.d.ts +1 -1
  360. package/dist/reconcile/manifest.js +2 -2
  361. package/dist/reconcile/plan.d.ts +1 -1
  362. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  363. package/dist/replay/normalizers/claude.d.ts +1 -1
  364. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  365. package/dist/replay/normalizers/shared.d.ts +1 -1
  366. package/dist/replay/runner.d.ts +1 -1
  367. package/dist/replay/types.d.ts +1 -1
  368. package/dist/replica-divergence.d.ts +1 -1
  369. package/dist/replica-peers-config.d.ts +1 -1
  370. package/dist/resolve-auth-token.d.ts +1 -1
  371. package/dist/retrieval-agents.d.ts +2 -2
  372. package/dist/retrieval-tiers.d.ts +1 -1
  373. package/dist/routing/engine.d.ts +1 -1
  374. package/dist/routing/store.d.ts +1 -1
  375. package/dist/salvage-envelope.d.ts +1 -1
  376. package/dist/schemas.d.ts +160 -160
  377. package/dist/{scope-profiles-C564-hrv.d.ts → scope-profiles-crazXegZ.d.ts} +1 -1
  378. package/dist/search/embed-helper.d.ts +1 -1
  379. package/dist/search/factory.d.ts +1 -1
  380. package/dist/search/factory.js +2 -2
  381. package/dist/search/index.d.ts +1 -1
  382. package/dist/search/index.js +4 -4
  383. package/dist/search/lancedb-backend.d.ts +1 -1
  384. package/dist/search/meilisearch-backend.d.ts +1 -1
  385. package/dist/search/noop-backend.d.ts +1 -1
  386. package/dist/search/orama-backend.d.ts +1 -1
  387. package/dist/search/port.d.ts +1 -1
  388. package/dist/search/remote-backend.d.ts +1 -1
  389. package/dist/{semantic-consolidation-g6x-ShY8.d.ts → semantic-consolidation-B09JI9WM.d.ts} +1 -1
  390. package/dist/semantic-consolidation.d.ts +2 -2
  391. package/dist/semantic-consolidation.js +13 -13
  392. package/dist/semantic-rule-promotion.js +12 -12
  393. package/dist/semantic-rule-verifier.d.ts +1 -1
  394. package/dist/semantic-rule-verifier.js +12 -12
  395. package/dist/{service-CaCOk0rd.d.ts → service-ByjbCuj7.d.ts} +2 -2
  396. package/dist/session-observer-bands.d.ts +1 -1
  397. package/dist/session-observer-state.d.ts +1 -1
  398. package/dist/shared-context/manager.d.ts +7 -7
  399. package/dist/signal.d.ts +1 -1
  400. package/dist/source-agent-qualifier.d.ts +1 -1
  401. package/dist/source-agent-qualifier.js +15 -15
  402. package/dist/source-attribution.d.ts +7 -4
  403. package/dist/source-attribution.js +1 -1
  404. package/dist/standup/build.js +12 -12
  405. package/dist/{storage-C9nsZX5Q.d.ts → storage-CbdF077z.d.ts} +17 -3
  406. package/dist/storage.d.ts +2 -2
  407. package/dist/storage.js +11 -11
  408. package/dist/subject-config.d.ts +1 -1
  409. package/dist/summarizer.d.ts +1 -1
  410. package/dist/summarizer.js +3 -3
  411. package/dist/summary-snapshot.d.ts +1 -1
  412. package/dist/support-passport/index.d.ts +17 -17
  413. package/dist/support-passport/index.js +39 -39
  414. package/dist/{tagging-BA4RFdH3.d.ts → tagging-CF7DNV7_.d.ts} +2 -2
  415. package/dist/temporal-supersession.d.ts +2 -2
  416. package/dist/temporal-timeline-recall.d.ts +1 -1
  417. package/dist/temporal-validity.d.ts +1 -1
  418. package/dist/threading.d.ts +1 -1
  419. package/dist/tier-migration.d.ts +2 -2
  420. package/dist/tier-routing.d.ts +1 -1
  421. package/dist/topics.d.ts +1 -1
  422. package/dist/transcript.d.ts +1 -1
  423. package/dist/transfer/autodetect.js +1 -1
  424. package/dist/transfer/backup.js +1 -1
  425. package/dist/transfer/capsule-export.js +2 -2
  426. package/dist/transfer/export-okf.d.ts +1 -1
  427. package/dist/transfer/export-okf.js +12 -12
  428. package/dist/transfer/types.d.ts +78 -78
  429. package/dist/trust-score-stage.d.ts +1 -1
  430. package/dist/trust-score.d.ts +1 -1
  431. package/dist/{types-Sps-lg5I.d.ts → types-nmhnJpxx.d.ts} +1 -1
  432. package/dist/types.d.ts +1 -1
  433. package/dist/utility-runtime.d.ts +1 -1
  434. package/dist/verified-recall.js +12 -12
  435. package/dist/who-knows-cli.d.ts +14 -14
  436. package/dist/who-knows-cli.js +13 -13
  437. package/dist/who-knows.d.ts +14 -14
  438. package/dist/who-knows.js +12 -12
  439. package/dist/write-envelope.d.ts +1 -1
  440. package/package.json +2 -2
  441. package/src/background-generation.test.ts +77 -0
  442. package/src/dedup/merge.test.ts +185 -8
  443. package/src/extraction-span-wire.test.ts +17 -1
  444. package/src/extraction-span-wire.ts +46 -3
  445. package/src/extraction.ts +2 -11
  446. package/src/memory-age.test.ts +106 -0
  447. package/src/memory-age.ts +196 -0
  448. package/src/orchestration/recall-search-pipeline.test.ts +207 -1
  449. package/src/orchestration/recall-search-pipeline.ts +13 -9
  450. package/src/orchestration/semantic-merge-commit-effects.ts +31 -9
  451. package/src/orchestration/semantic-merge-persist.ts +16 -5
  452. package/src/providers/codex-subscription.test.ts +109 -3
  453. package/src/providers/codex-subscription.ts +57 -17
  454. package/src/source-attribution.test.ts +27 -0
  455. package/src/source-attribution.ts +41 -5
  456. package/src/storage/cas-revision-host.ts +22 -0
  457. package/src/storage/cas-revision-store.test.ts +44 -1
  458. package/src/storage/cas-revision-store.ts +23 -0
  459. package/src/storage/tombstone-blocked-capture-sync.ts +26 -1
  460. package/src/storage-frontmatter-cas.test.ts +49 -1
  461. package/src/storage.ts +1 -1
  462. package/src/summarizer.ts +18 -0
  463. package/dist/chunk-GMU7MAHS.js.map +0 -1
  464. package/dist/chunk-J2MGTGKC.js.map +0 -1
  465. package/dist/chunk-RJ7Z7YXK.js.map +0 -1
  466. package/dist/chunk-SHEHQBCG.js.map +0 -1
  467. package/dist/chunk-UHSOPTNB.js.map +0 -1
  468. package/dist/chunk-Y77UTH7F.js.map +0 -1
  469. /package/dist/{auto-sync-QZD4RD6H.js.map → auto-sync-DG5KEOF5.js.map} +0 -0
  470. /package/dist/{chunk-MOL7JK4F.js.map → chunk-3NYM6JA4.js.map} +0 -0
  471. /package/dist/{chunk-WNMVUWI7.js.map → chunk-3UQIS2GC.js.map} +0 -0
  472. /package/dist/{chunk-JDL5BYYF.js.map → chunk-47C6DF43.js.map} +0 -0
  473. /package/dist/{chunk-ZBSP4BSN.js.map → chunk-4ECS33D4.js.map} +0 -0
  474. /package/dist/{chunk-6EGIQEKC.js.map → chunk-4HTQ76O4.js.map} +0 -0
  475. /package/dist/{chunk-7L54ARML.js.map → chunk-4XTSKGLX.js.map} +0 -0
  476. /package/dist/{chunk-SUS64JER.js.map → chunk-5EHPB6RL.js.map} +0 -0
  477. /package/dist/{chunk-VDLNQVYW.js.map → chunk-62NYUFNH.js.map} +0 -0
  478. /package/dist/{chunk-SZV2L2IG.js.map → chunk-7BNB7KHB.js.map} +0 -0
  479. /package/dist/{chunk-IAGEEVQL.js.map → chunk-AN2O4KZY.js.map} +0 -0
  480. /package/dist/{chunk-JUOJGZPV.js.map → chunk-AYP2FZFA.js.map} +0 -0
  481. /package/dist/{chunk-XK76RJBN.js.map → chunk-AYZHHMTK.js.map} +0 -0
  482. /package/dist/{chunk-LQVXSRAJ.js.map → chunk-B4EGAHHS.js.map} +0 -0
  483. /package/dist/{chunk-HKQAI6XI.js.map → chunk-CFIHVWYZ.js.map} +0 -0
  484. /package/dist/{chunk-DABSYX7V.js.map → chunk-CWMMKFO7.js.map} +0 -0
  485. /package/dist/{chunk-WLHPCAVD.js.map → chunk-D5DTZBTV.js.map} +0 -0
  486. /package/dist/{chunk-2HDLDBJW.js.map → chunk-DDBLZJRV.js.map} +0 -0
  487. /package/dist/{chunk-F2FJTOV6.js.map → chunk-DO6R3LIE.js.map} +0 -0
  488. /package/dist/{chunk-LD22AAJI.js.map → chunk-EAZ3YZKN.js.map} +0 -0
  489. /package/dist/{chunk-46FVFU7S.js.map → chunk-EC5SVM6H.js.map} +0 -0
  490. /package/dist/{chunk-GKKLI23D.js.map → chunk-EEHQY7ER.js.map} +0 -0
  491. /package/dist/{chunk-BPXJINHW.js.map → chunk-EUP4AXIW.js.map} +0 -0
  492. /package/dist/{chunk-2WMXZYMS.js.map → chunk-F5V7KRQS.js.map} +0 -0
  493. /package/dist/{chunk-4AX5OYKC.js.map → chunk-FDDCZDBI.js.map} +0 -0
  494. /package/dist/{chunk-XLPZN3A5.js.map → chunk-FMEP2RB5.js.map} +0 -0
  495. /package/dist/{chunk-D7UUB33A.js.map → chunk-FSH6KRKO.js.map} +0 -0
  496. /package/dist/{chunk-3254BYQV.js.map → chunk-GGY7WKMB.js.map} +0 -0
  497. /package/dist/{chunk-ROXDOKLM.js.map → chunk-GYYLZOSO.js.map} +0 -0
  498. /package/dist/{chunk-3K64PLY3.js.map → chunk-HXDXR2FH.js.map} +0 -0
  499. /package/dist/{chunk-XOCGC3FJ.js.map → chunk-HYWPUYLO.js.map} +0 -0
  500. /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  501. /package/dist/{chunk-M6FKXOYV.js.map → chunk-IXMWTNNY.js.map} +0 -0
  502. /package/dist/{chunk-ZYSOT6HD.js.map → chunk-J3IWHCMF.js.map} +0 -0
  503. /package/dist/{chunk-3YQ7VLP3.js.map → chunk-J5OXWG66.js.map} +0 -0
  504. /package/dist/{chunk-H2N6SLTR.js.map → chunk-JIWZVOQM.js.map} +0 -0
  505. /package/dist/{chunk-C3YEB7CR.js.map → chunk-JOP7W24J.js.map} +0 -0
  506. /package/dist/{chunk-F6PTJLEM.js.map → chunk-K4KE5MYE.js.map} +0 -0
  507. /package/dist/{chunk-IOTYIECA.js.map → chunk-KF57IQFX.js.map} +0 -0
  508. /package/dist/{chunk-ZVQ5HF77.js.map → chunk-N46SNYMC.js.map} +0 -0
  509. /package/dist/{chunk-YR5QT4SR.js.map → chunk-NAFPHFDM.js.map} +0 -0
  510. /package/dist/{chunk-VHANUT45.js.map → chunk-ORQ7AZMU.js.map} +0 -0
  511. /package/dist/{chunk-EOXCOZ6L.js.map → chunk-OV7GJ4KW.js.map} +0 -0
  512. /package/dist/{chunk-VJXMFBVR.js.map → chunk-P7S7BVBJ.js.map} +0 -0
  513. /package/dist/{chunk-7F47R4H4.js.map → chunk-S3SND7SO.js.map} +0 -0
  514. /package/dist/{chunk-5AJZ7EUW.js.map → chunk-S7KDHFF2.js.map} +0 -0
  515. /package/dist/{chunk-4WMGRLTV.js.map → chunk-SRRZZHA5.js.map} +0 -0
  516. /package/dist/{chunk-KDLOKVX7.js.map → chunk-SW42MMAH.js.map} +0 -0
  517. /package/dist/{chunk-2YIUUXNK.js.map → chunk-T5NI5K46.js.map} +0 -0
  518. /package/dist/{chunk-QCTXQ2HW.js.map → chunk-TE6B2UU6.js.map} +0 -0
  519. /package/dist/{chunk-JDOBQPJY.js.map → chunk-TNQR7N52.js.map} +0 -0
  520. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  521. /package/dist/{chunk-T3F2HWIG.js.map → chunk-TZ44E732.js.map} +0 -0
  522. /package/dist/{chunk-PF7LQ22G.js.map → chunk-U4ESGVZ2.js.map} +0 -0
  523. /package/dist/{chunk-WJPR2XUN.js.map → chunk-UEJY6ZTQ.js.map} +0 -0
  524. /package/dist/{chunk-K3IVJ5ML.js.map → chunk-UGGOQKO6.js.map} +0 -0
  525. /package/dist/{chunk-OCX7OWOC.js.map → chunk-UOREPQ3C.js.map} +0 -0
  526. /package/dist/{chunk-R3H2AXO2.js.map → chunk-VGRVJ6Z6.js.map} +0 -0
  527. /package/dist/{chunk-IWHNT35B.js.map → chunk-WOBMSMUK.js.map} +0 -0
  528. /package/dist/{chunk-DDGQDNQW.js.map → chunk-XLZZLUWL.js.map} +0 -0
  529. /package/dist/{chunk-KORQWGUA.js.map → chunk-Y3XHIWVP.js.map} +0 -0
  530. /package/dist/{chunk-BZDK5EOD.js.map → chunk-YFVIA5A6.js.map} +0 -0
  531. /package/dist/{chunk-GR76OKET.js.map → chunk-YSBYNCCN.js.map} +0 -0
  532. /package/dist/{chunk-OGAKUA7I.js.map → chunk-YUQPUK6H.js.map} +0 -0
  533. /package/dist/{chunk-TRTLWUDD.js.map → chunk-ZTHGFTMW.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import assert from "node:assert/strict";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- import { mkdtemp, rm } from "node:fs/promises";
4
+ import { mkdir, mkdtemp, rm, utimes, writeFile } from "node:fs/promises";
5
5
  import test from "node:test";
6
6
 
7
7
  import { parseConfig } from "../config.js";
@@ -565,3 +565,209 @@ test("QMD stops after an underfilled archive-only page", async () => {
565
565
  assert.deepEqual(out, []);
566
566
  assert.equal(searchCalls, 1, "an underfilled raw page must not trigger widening");
567
567
  });
568
+
569
+ // ─── #2976: memory age from content dates; bulk-touch mtime distrust ─────────
570
+
571
+ const AGE_DAY_MS = 86_400_000;
572
+
573
+ function scoredResult(namespace: string, p: string, score: number): QmdSearchResult {
574
+ return { docid: `${namespace}:${p}`, namespace, path: p, score, snippet: p };
575
+ }
576
+
577
+ function ageMemory(absPath: string, frontmatter: Record<string, unknown>): MemoryFile {
578
+ return {
579
+ path: absPath,
580
+ content: absPath,
581
+ frontmatter: { status: "active", memoryKind: "fact", ...frontmatter } as unknown as MemoryFile["frontmatter"],
582
+ };
583
+ }
584
+
585
+ function boostCoordinator(
586
+ memoryDir: string,
587
+ recencyWeight: number,
588
+ ): RecallSearchPipelineCoordinator {
589
+ const config = parseConfig({
590
+ openaiApiKey: "sk-test",
591
+ memoryDir,
592
+ workspaceDir: path.join(memoryDir, "workspace"),
593
+ });
594
+ const deps = {
595
+ config,
596
+ effectiveRecencyWeight: () => recencyWeight,
597
+ filterSearchResultsForRecall: async (
598
+ results: QmdSearchResult[],
599
+ preloaded?: Map<string, MemoryFile>,
600
+ ) => ({ results, memoryByPath: preloaded ?? new Map() }),
601
+ } as unknown as RecallSearchPipelineDeps;
602
+ return new RecallSearchPipelineCoordinator(deps);
603
+ }
604
+
605
+ async function writeDatedFile(filePath: string, mtimeMs: number): Promise<void> {
606
+ await mkdir(path.dirname(filePath), { recursive: true });
607
+ await writeFile(filePath, "fixture\n");
608
+ await utimes(filePath, mtimeMs / 1000, mtimeMs / 1000);
609
+ }
610
+
611
+ function isoAgo(now: number, days: number): string {
612
+ return new Date(now - days * AGE_DAY_MS).toISOString();
613
+ }
614
+
615
+ test("#2976 content dates age a memory even when its mtime is fresh (updated backs a missing created)", async () => {
616
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-age-content-"));
617
+ try {
618
+ const now = Date.now();
619
+ const fileA = path.join(memoryDir, "facts", "a.md");
620
+ const fileB = path.join(memoryDir, "facts", "b.md");
621
+ // Both files carry today's mtime — the bulk import / cp -r shape. A has
622
+ // no created, only a 40-day-old updated; B carries a 40-day-old created.
623
+ await writeDatedFile(fileA, now);
624
+ await writeDatedFile(fileB, now);
625
+ const memoryByPath = new Map<string, MemoryFile>([
626
+ ["default\0facts/a.md", ageMemory(fileA, { updated: isoAgo(now, 40) })],
627
+ ["default\0facts/b.md", ageMemory(fileB, { created: isoAgo(now, 40), updated: isoAgo(now, 40) })],
628
+ ]);
629
+
630
+ const boosted = await boostCoordinator(memoryDir, 0.5).boostSearchResults(
631
+ [scoredResult("default", "facts/a.md", 1), scoredResult("default", "facts/b.md", 1)],
632
+ ["default"],
633
+ undefined,
634
+ memoryByPath,
635
+ );
636
+
637
+ const [a, b] = boosted;
638
+ const expected = 1 * 0.5 + Math.pow(0.5, 40 / 7) * 0.5;
639
+ assert.ok(a && Number.isFinite(a.score), "a memory without created must not score NaN");
640
+ assert.ok(b && Number.isFinite(b.score));
641
+ assert.ok(Math.abs(a.score - expected) < 1e-9, `ages by the 40-day-old content date (${a?.score}), not the fresh mtime (1.0)`);
642
+ assert.equal(a.score, b.score, "updated and created of the same age produce the same score");
643
+ } finally {
644
+ await rm(memoryDir, { recursive: true, force: true });
645
+ }
646
+ });
647
+
648
+ test("#2976 a bulk-touch mtime cluster never inflates freshness (ranking unchanged vs pre-touch base order)", async () => {
649
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-age-bulk-"));
650
+ try {
651
+ const now = Date.now();
652
+ const files = ["facts/x.md", "facts/y.md", "facts/z.md"];
653
+ const baseScores = [0.9, 0.8, 0.7];
654
+ const mtimes = [now - 10 * AGE_DAY_MS, now - 30 * AGE_DAY_MS, now - 90 * AGE_DAY_MS];
655
+ // Undated memories: only mtime can say how old they are.
656
+ const buildMap = () =>
657
+ new Map<string, MemoryFile>(
658
+ files.map((rel) => ["default\0" + rel, ageMemory(path.join(memoryDir, rel), {})]),
659
+ );
660
+ for (let i = 0; i < files.length; i += 1) {
661
+ await writeDatedFile(path.join(memoryDir, files[i]!), mtimes[i]!);
662
+ }
663
+ const results = () => files.map((rel, i) => scoredResult("default", rel, baseScores[i]!));
664
+
665
+ // Pre-touch: mtimes are scattered, so each trusted mtime ages its memory.
666
+ const preTouch = await boostCoordinator(memoryDir, 0.5).boostSearchResults(
667
+ results(),
668
+ ["default"],
669
+ undefined,
670
+ buildMap(),
671
+ );
672
+ for (const r of preTouch) {
673
+ assert.ok(Number.isFinite(r.score), "an undated memory with a trusted mtime must not score NaN");
674
+ }
675
+ assert.deepEqual(
676
+ preTouch.map((r) => r.path),
677
+ ["facts/x.md", "facts/y.md", "facts/z.md"],
678
+ "pre-touch, the scattered trusted mtimes preserve the base ranking",
679
+ );
680
+
681
+ // Bulk touch: every mtime reset to one calendar day (cp -r / restore).
682
+ const bulkDay = now - 1 * AGE_DAY_MS;
683
+ for (const rel of files) {
684
+ await writeDatedFile(path.join(memoryDir, rel), bulkDay);
685
+ }
686
+ const postTouch = await boostCoordinator(memoryDir, 0.5).boostSearchResults(
687
+ results(),
688
+ ["default"],
689
+ undefined,
690
+ buildMap(),
691
+ );
692
+ assert.deepEqual(
693
+ postTouch.map((r) => r.score),
694
+ baseScores,
695
+ "a same-day mtime cluster is distrusted: no recency boost, scores stay at base",
696
+ );
697
+ assert.deepEqual(
698
+ postTouch.map((r) => r.path),
699
+ ["facts/x.md", "facts/y.md", "facts/z.md"],
700
+ "ranking is unchanged versus the pre-touch base order",
701
+ );
702
+ } finally {
703
+ await rm(memoryDir, { recursive: true, force: true });
704
+ }
705
+ });
706
+
707
+ test("#2976 an undated memory falls back to a trusted scattered mtime; a dated sibling keeps its content age", async () => {
708
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-age-fallback-"));
709
+ try {
710
+ const now = Date.now();
711
+ const fileA = path.join(memoryDir, "facts", "undated.md");
712
+ const fileB = path.join(memoryDir, "facts", "dated.md");
713
+ // A: no dates, mtime 2 days ago. B: created 2 days ago, mtime 5 days ago
714
+ // (different days, one file each — no cluster, mtime stays trusted).
715
+ await writeDatedFile(fileA, now - 2 * AGE_DAY_MS);
716
+ await writeDatedFile(fileB, now - 5 * AGE_DAY_MS);
717
+ const memoryByPath = new Map<string, MemoryFile>([
718
+ ["default\0facts/undated.md", ageMemory(fileA, {})],
719
+ ["default\0facts/dated.md", ageMemory(fileB, { created: isoAgo(now, 2), updated: isoAgo(now, 2) })],
720
+ ]);
721
+
722
+ const boosted = await boostCoordinator(memoryDir, 0.5).boostSearchResults(
723
+ [scoredResult("default", "facts/undated.md", 1), scoredResult("default", "facts/dated.md", 1)],
724
+ ["default"],
725
+ undefined,
726
+ memoryByPath,
727
+ );
728
+
729
+ const [undated, dated] = boosted;
730
+ // 1e-6 (not 1e-9): the pipeline stamps its own Date.now() after this
731
+ // test's fixture writes, so a few ms of clock drift shifts the 2-day
732
+ // blend in the 8th decimal.
733
+ const expected = 1 * 0.5 + Math.pow(0.5, 2 / 7) * 0.5;
734
+ assert.ok(undated && Number.isFinite(undated.score), "the undated memory must not score NaN");
735
+ assert.ok(
736
+ undated && Math.abs(undated.score - expected) < 1e-6,
737
+ `an undated memory ages by its trusted mtime (2 days): got ${undated?.score}, want ~${expected}`,
738
+ );
739
+ assert.ok(
740
+ undated && dated && Math.abs(undated.score - dated.score) < 1e-6,
741
+ "mtime fallback and a same-aged content date score identically",
742
+ );
743
+ } finally {
744
+ await rm(memoryDir, { recursive: true, force: true });
745
+ }
746
+ });
747
+
748
+ test("#2976 guard: a memory whose content date is older than its fresh mtime ages by the content date", async () => {
749
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-age-guard-"));
750
+ try {
751
+ const now = Date.now();
752
+ const filePath = path.join(memoryDir, "facts", "old.md");
753
+ await writeDatedFile(filePath, now); // fresh mtime, 90-day-old content
754
+ const memoryByPath = new Map<string, MemoryFile>([
755
+ ["default\0facts/old.md", ageMemory(filePath, { created: isoAgo(now, 90), updated: isoAgo(now, 90) })],
756
+ ]);
757
+
758
+ const boosted = await boostCoordinator(memoryDir, 0.5).boostSearchResults(
759
+ [scoredResult("default", "facts/old.md", 1)],
760
+ ["default"],
761
+ undefined,
762
+ memoryByPath,
763
+ );
764
+
765
+ const expected = 1 * 0.5 + Math.pow(0.5, 90 / 7) * 0.5;
766
+ assert.ok(
767
+ boosted[0] && Math.abs(boosted[0].score - expected) < 1e-9,
768
+ "ages by the 90-day-old created date, not the fresh mtime",
769
+ );
770
+ } finally {
771
+ await rm(memoryDir, { recursive: true, force: true });
772
+ }
773
+ });
@@ -34,6 +34,7 @@ import { RerankCache, rerankLocalOrNoop, reorderByRankedKeys } from "../rerank.j
34
34
  import type { SearchBackend, SearchDegradation, SearchExecutionOptions, SearchQueryOptions } from "../search/port.js";
35
35
  import { SecureStoreLockedError } from "../secure-store/index.js";
36
36
  import { isPathInsideStorageRoot } from "../storage-paths.js";
37
+ import { applyRecencyBoost, collectMtimeFallbackContext } from "../memory-age.js";
37
38
  import type { CorpusReadOptions } from "../corpus-read-cancellation.js";
38
39
  import { extractTagsFromPrompt, isTemporalQuery, queryByDateRangeAsync, queryByTagsAsync, readIndexSnapshotAsync, recencyWindowFromPrompt } from "../temporal-index.js";
39
40
  import {
@@ -1558,20 +1559,23 @@ export class RecallSearchPipelineCoordinator {
1558
1559
 
1559
1560
  const boosted: QmdSearchResult[] = [];
1560
1561
  const recencyWeight = this.deps.effectiveRecencyWeight();
1562
+ // #2976: mtime backs age only for memories without content dates, and a
1563
+ // same-day mtime cluster (bulk import / restore / cp -r) is distrusted.
1564
+ const mtimeFallback =
1565
+ recencyWeight > 0
1566
+ ? await collectMtimeFallbackContext(
1567
+ safeResults.flatMap((r) => { const m = memoryForResult(memoryByPath, r); return m ? [m] : []; }),
1568
+ )
1569
+ : null;
1561
1570
  for (const r of safeResults) {
1562
1571
  const memory = memoryForResult(memoryByPath, r);
1563
1572
  let score = r.score;
1564
1573
 
1565
1574
  if (memory) {
1566
- // Recency boost: exponential decay over 7 days
1567
- if (recencyWeight > 0) {
1568
- const createdAt = new Date(memory.frontmatter.created).getTime();
1569
- const ageMs = now - createdAt;
1570
- const ageDays = ageMs / (1000 * 60 * 60 * 24);
1571
- const halfLifeDays = 7;
1572
- const recencyScore = Math.pow(0.5, ageDays / halfLifeDays);
1573
- score = score * (1 - recencyWeight) + recencyScore * recencyWeight;
1574
- }
1575
+ // Recency boost: 7-day exponential decay over the shared age resolver
1576
+ // (#2976): content dates first, trusted mtime as fallback, unknown
1577
+ // age never fresh. See memory-age.ts.
1578
+ score = applyRecencyBoost(score, memory, recencyWeight, now, mtimeFallback);
1575
1579
 
1576
1580
  // Access count boost: log scale, capped
1577
1581
  if (this.deps.config.boostAccessCount && memory.frontmatter.accessCount) {
@@ -13,6 +13,7 @@
13
13
  */
14
14
 
15
15
  import { GraphEdgeAppendError } from "../graph-append-error.js";
16
+ import type { CasRevisionReadStatus } from "../storage/cas-revision-store.js";
16
17
  import type { GraphEdge, GraphType } from "../graph.js";
17
18
  import { readFile } from "node:fs/promises";
18
19
  import { removeNodeEdgesForRewrite, rollbackNodeEdgeRewrite } from "../graph-jsonl.js";
@@ -259,8 +260,8 @@ export async function persistMergedTargetThreadEpisode(
259
260
  }
260
261
 
261
262
  /**
262
- * Round N+12 (C) + N+14: replace a merged target's generated graph edges
263
- * with the rebuild's rows, revision-guarded end to end. The caller's
263
+ * Round N+12 (C) + N+14 + #2837: replace a merged target's generated graph
264
+ * edges with the rebuild's rows, revision-guarded end to end. The caller's
264
265
  * committed-body check can pass, writer B can then commit a NEWER merge and
265
266
  * finish rebuilding edges for it, and writer A would resume to remove B's
266
267
  * edges and install edges derived from A's older body. The revision observed
@@ -271,6 +272,15 @@ export async function persistMergedTargetThreadEpisode(
271
272
  * chain only then). A build failure rolls back the same way (round N+10 C)
272
273
  * and rethrows — fail-open stays the caller's decision.
273
274
  *
275
+ * #2837: the post-build guard reads the truthful receipt STATUS, never the
276
+ * fail-open token. The old guard collapsed an unreadable sidecar into
277
+ * undefined on both reads, so an unavailable-vs-unavailable rewrite compared
278
+ * undefined against undefined, passed, and installed replacement edges no
279
+ * receipt ever verified. An `unavailable` post-build status now aborts the
280
+ * install (rollback, false) so the next merge retries; only a PROVEN match —
281
+ * present-and-equal, or absent-against-absent for a pre-sidecar target —
282
+ * may install.
283
+ *
274
284
  * Round N+14 makes the ROLLBACK surgical: `build` returns the exact rows it
275
285
  * appended (by identity), and the rollback removes only those — never a
276
286
  * node-wide sweep — so rows a newer writer appended after this writer's
@@ -283,13 +293,14 @@ export async function rewriteMergedTargetGraphEdges(
283
293
  storage: {
284
294
  dir: string;
285
295
  getMemoryByIdIncludingArchived: (id: string) => Promise<MemoryFile | null>;
286
- readCasRevision: (filePath: string) => Promise<string | undefined>;
296
+ readCasRevisionStatus: (filePath: string) => Promise<CasRevisionReadStatus>;
287
297
  },
288
298
  input: {
289
299
  targetId: string;
290
300
  memoryRelPath: string;
291
301
  mergedContent: string;
292
- /** The CAS revision token the committed-body check observed. */
302
+ /** The CAS revision token the committed-body check observed (undefined
303
+ * only when the check PROVED the receipt absent — #2837). */
293
304
  revisionChecked: string | undefined;
294
305
  rewriteTypes: readonly GraphType[];
295
306
  build: () => Promise<GraphEdge[] | void>;
@@ -306,15 +317,26 @@ export async function rewriteMergedTargetGraphEdges(
306
317
  try {
307
318
  appended = (await input.build()) ?? undefined;
308
319
  const committedNow = await storage.getMemoryByIdIncludingArchived(input.targetId);
309
- const committedRevision = committedNow === null ? undefined : await storage.readCasRevision(committedNow.path).catch((err) => {
310
- log.warn(`rewriteMergedTargetGraphEdges: failed to read CAS revision for ${committedNow.path}: ${err}`);
311
- return undefined;
312
- });
320
+ let standing: CasRevisionReadStatus;
321
+ if (committedNow === null) {
322
+ standing = { status: "absent" };
323
+ } else {
324
+ standing = await storage.readCasRevisionStatus(committedNow.path).catch((err: unknown) => ({
325
+ status: "unavailable" as const,
326
+ reason: err instanceof Error ? err.message : String(err),
327
+ }));
328
+ }
313
329
  if (
314
330
  !committedNow ||
315
331
  committedNow.content !== input.mergedContent ||
316
- committedRevision !== input.revisionChecked
332
+ standing.status === "unavailable" ||
333
+ (standing.status === "present" ? standing.revision : undefined) !== input.revisionChecked
317
334
  ) {
335
+ if (standing.status === "unavailable") {
336
+ log.warn(
337
+ `rewriteMergedTargetGraphEdges: CAS revision status for ${input.memoryRelPath} is unavailable (${standing.reason}); aborting the install — an unverified replacement must not install (#2837)`,
338
+ );
339
+ }
318
340
  await rollbackNodeEdgeRewrite(storage.dir, input.memoryRelPath, input.rewriteTypes, removedEdges, input.targetId, appended);
319
341
  return false;
320
342
  }
@@ -1144,15 +1144,26 @@ export async function runMergedTargetPostEffects(
1144
1144
  if (input.graphCaps.entityGraph) rewriteTypes.push("entity");
1145
1145
  if (input.graphCaps.timeGraph) rewriteTypes.push("time");
1146
1146
  if (input.graphCaps.causalGraph) rewriteTypes.push("causal");
1147
- // Round N+12 (C): the remove-and-rebuild is revision-guarded end to end
1148
- // (see rewriteMergedTargetGraphEdges) — a writer committing a newer body
1149
- // mid-rebuild aborts this install instead of clobbering its edges.
1147
+ // Round N+12 (C) + #2837: the remove-and-rebuild is revision-guarded
1148
+ // end to end (see rewriteMergedTargetGraphEdges) — a writer committing
1149
+ // a newer body mid-rebuild aborts this install instead of clobbering
1150
+ // its edges. The guard compares the truthful receipt STATUS (#2807:
1151
+ // the dedicated CAS revision token, never public `updated`), and an
1152
+ // UNAVAILABLE sidecar SKIPS the effect entirely: passing a fail-open
1153
+ // undefined into the install is what let an unchecked replacement
1154
+ // install when both sidecar reads failed.
1155
+ const receiptStatus = await storage.readCasRevisionStatus(committed.path);
1156
+ if (receiptStatus.status === "unavailable") {
1157
+ log.warn(
1158
+ `runMergedTargetPostEffects: CAS revision status for ${committed.path} is unavailable (${receiptStatus.reason}); skipping the graph rewrite — the next merge retries it (#2837)`,
1159
+ );
1160
+ return signals;
1161
+ }
1150
1162
  rewriteInstalled = await rewriteMergedTargetGraphEdges(storage, {
1151
1163
  targetId: merge.targetId,
1152
1164
  memoryRelPath,
1153
1165
  mergedContent: merge.mergedContent,
1154
- // #2807: the dedicated CAS revision token, not public `updated`.
1155
- revisionChecked: await storage.readCasRevision(committed.path),
1166
+ revisionChecked: receiptStatus.status === "present" ? receiptStatus.revision : undefined,
1156
1167
  rewriteTypes,
1157
1168
  build: () =>
1158
1169
  deps.buildGraphEdge(
@@ -452,10 +452,10 @@ test("request deadline starts before login and login consumes the same budget",
452
452
  options: { timeoutMs },
453
453
  });
454
454
 
455
- // Login shares the 5s budget (capped at the 10s login-status ceiling) and
456
- // exec only gets what login left: 5s - 2s.
455
+ // The shared login subprocess uses the 10s ceiling; this caller still
456
+ // spends its 5s budget and exec only gets what login left: 5s - 2s.
457
457
  await call(5_000);
458
- assert.deepEqual(loginTimeouts, [5_000]);
458
+ assert.deepEqual(loginTimeouts, [10_000]);
459
459
  assert.equal(execCalls.length, 1);
460
460
  assert.equal(execCalls[0]?.timeoutMs, 3_000);
461
461
 
@@ -731,6 +731,112 @@ test("shared login check: each caller times out on its own budget, without cance
731
731
  assert.equal(loginCalls, 1);
732
732
  });
733
733
 
734
+ test("shared login check does not inherit the first waiter's shorter deadline", async () => {
735
+ __codexSubscriptionTestHooks.resetLoginStatusCache();
736
+ const loginTimeouts: number[] = [];
737
+ const loginPending = Promise.withResolvers<{ status: number | null; stdout: string; stderr: string }>();
738
+ const runner = createCodexSubscriptionRunner({
739
+ env: { HOME: "/home/alice", PATH: "/usr/bin:/bin" },
740
+ now: () => 0,
741
+ runLoginStatus: (_executable, _env, timeoutMs) => {
742
+ loginTimeouts.push(timeoutMs);
743
+ return loginPending.promise;
744
+ },
745
+ runCodexExec: async () => ({ status: 0, stdout: "", stderr: "", outputText: "ok" }),
746
+ });
747
+ const call = (timeoutMs: number) =>
748
+ runner({
749
+ config: { executable: "codex-fake" },
750
+ modelId: "gpt-5.6-luna",
751
+ messages: [{ role: "user", content: "hi" }],
752
+ options: { timeoutMs },
753
+ });
754
+
755
+ const short = call(120);
756
+ await flushLoop();
757
+ assert.deepEqual(loginTimeouts, [10_000], "shared check uses the login-status ceiling, not the first waiter's 120ms");
758
+
759
+ const long = call(10_000);
760
+ await flushLoop();
761
+ assert.equal(loginTimeouts.length, 1, "the longer waiter must reuse the in-flight check");
762
+
763
+ const startedAt = Date.now();
764
+ await assert.rejects(short, (error: unknown) => {
765
+ assert.ok(error instanceof CodexSubscriptionTimeoutError);
766
+ assert.equal(error.name, "TimeoutError");
767
+ return true;
768
+ });
769
+ assert.ok(Date.now() - startedAt < 5_000, "short waiter must not wait for the 10s ceiling");
770
+
771
+ loginPending.resolve({ status: 0, stdout: "Logged in using ChatGPT\n", stderr: "" });
772
+ assert.equal((await long).content, "ok");
773
+ });
774
+
775
+ test("in-flight login checks are scoped to the owning runner", async () => {
776
+ __codexSubscriptionTestHooks.resetLoginStatusCache();
777
+ let loginCallsA = 0;
778
+ let loginCallsB = 0;
779
+ const pendingA = Promise.withResolvers<{ status: number | null; stdout: string; stderr: string }>();
780
+ const pendingB = Promise.withResolvers<{ status: number | null; stdout: string; stderr: string }>();
781
+ const env = { HOME: "/home/alice", PATH: "/usr/bin:/bin" };
782
+ const makeRunner = (
783
+ bump: () => void,
784
+ pending: Promise<{ status: number | null; stdout: string; stderr: string }>,
785
+ ) =>
786
+ createCodexSubscriptionRunner({
787
+ env,
788
+ now: () => 0,
789
+ runLoginStatus: () => {
790
+ bump();
791
+ return pending;
792
+ },
793
+ runCodexExec: async () => ({ status: 0, stdout: "", stderr: "", outputText: "ok" }),
794
+ });
795
+ const runnerA = makeRunner(() => {
796
+ loginCallsA++;
797
+ }, pendingA.promise);
798
+ const runnerB = makeRunner(() => {
799
+ loginCallsB++;
800
+ }, pendingB.promise);
801
+ const call = (target: typeof runnerA, signal?: AbortSignal) =>
802
+ target({
803
+ config: { executable: "codex-fake" },
804
+ modelId: "gpt-5.6-luna",
805
+ messages: [{ role: "user", content: "hi" }],
806
+ options: { timeoutMs: 60_000, ...(signal ? { signal } : {}) },
807
+ });
808
+
809
+ const abortA = new AbortController();
810
+ const first = call(runnerA, abortA.signal);
811
+ await flushLoop();
812
+ assert.equal(loginCallsA, 1);
813
+
814
+ const second = call(runnerB);
815
+ await flushLoop();
816
+ assert.equal(loginCallsB, 1, "unrelated runner must not share the in-flight login");
817
+ assert.equal(loginCallsA, 1);
818
+
819
+ abortA.abort(new Error("A cancelled"));
820
+ await assert.rejects(first, (error: unknown) => error instanceof Error && error.message === "A cancelled");
821
+
822
+ pendingB.resolve({ status: 0, stdout: "Logged in using ChatGPT\n", stderr: "" });
823
+ assert.equal((await second).content, "ok");
824
+ assert.equal(loginCallsB, 1);
825
+
826
+ let loginCallsC = 0;
827
+ const runnerC = createCodexSubscriptionRunner({
828
+ env,
829
+ now: () => 0,
830
+ runLoginStatus: () => {
831
+ loginCallsC++;
832
+ return Promise.resolve({ status: 0, stdout: "Logged in using ChatGPT\n", stderr: "" });
833
+ },
834
+ runCodexExec: async () => ({ status: 0, stdout: "", stderr: "", outputText: "ok" }),
835
+ });
836
+ assert.equal((await call(runnerC)).content, "ok");
837
+ assert.equal(loginCallsC, 0, "settled login success remains reusable across runners");
838
+ });
839
+
734
840
  test("caller abort reaches the cold login check: no spawn when pre-aborted, wait aborts in flight", async () => {
735
841
  __codexSubscriptionTestHooks.resetLoginStatusCache();
736
842
  const loginSignals: (AbortSignal | undefined)[] = [];