@remnic/core 9.66.2 → 9.66.4

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 (547) hide show
  1. package/dist/access-admin-ops-surface.js +31 -31
  2. package/dist/access-audit.js +2 -2
  3. package/dist/access-authorization-probe.js +32 -32
  4. package/dist/access-boundary.js +31 -31
  5. package/dist/access-cli.js +97 -97
  6. package/dist/access-extraction-force-flush.js +31 -31
  7. package/dist/access-http-query.js +33 -33
  8. package/dist/access-http.js +49 -49
  9. package/dist/access-identity-continuity-surface.js +31 -31
  10. package/dist/access-lcm-surface.js +31 -31
  11. package/dist/access-mcp.js +39 -39
  12. package/dist/access-namespace-preflight.js +31 -31
  13. package/dist/access-observe-write-surface.js +31 -31
  14. package/dist/access-offline-manifest.js +3 -3
  15. package/dist/access-operations-batch.js +34 -34
  16. package/dist/access-operations.js +38 -38
  17. package/dist/access-recall-concurrency.js +31 -31
  18. package/dist/access-recall-response.js +31 -31
  19. package/dist/access-recall-surface.js +31 -31
  20. package/dist/access-schema.js +5 -5
  21. package/dist/access-service.js +31 -31
  22. package/dist/access-surface-catalog.js +33 -33
  23. package/dist/active-recall.js +5 -5
  24. package/dist/adapters/index.js +7 -7
  25. package/dist/adapters/registry.js +3 -3
  26. package/dist/briefing.js +8 -8
  27. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-GWVG7LGC.js} +2 -2
  28. package/dist/causal-behavior.js +2 -2
  29. package/dist/causal-chain.js +2 -2
  30. package/dist/causal-consolidation.js +11 -11
  31. package/dist/causal-retrieval.js +2 -2
  32. package/dist/causal-trajectory-graph.js +2 -2
  33. package/dist/causal-trajectory.js +1 -1
  34. package/dist/{chunk-36HJ36FK.js → chunk-27JH2KKM.js} +3 -3
  35. package/dist/{chunk-NZPFCP5A.js → chunk-2PSX5BJU.js} +2 -2
  36. package/dist/{chunk-RCPKBW7K.js → chunk-322MSJYS.js} +5 -5
  37. package/dist/{chunk-C3ZYZKDJ.js → chunk-3E4REX7E.js} +2 -2
  38. package/dist/{chunk-Y2YM4C75.js → chunk-4BRBSON5.js} +2 -2
  39. package/dist/{chunk-B4B3QDV3.js → chunk-4EX26ZS3.js} +24 -24
  40. package/dist/{chunk-ER2UPUMG.js → chunk-562Q236T.js} +2 -2
  41. package/dist/{chunk-F2JXJABQ.js → chunk-5BIOXQGN.js} +2 -2
  42. package/dist/{chunk-DSEHPUID.js → chunk-5C3OQ253.js} +2 -2
  43. package/dist/{chunk-LSR5LQXN.js → chunk-5VLXQFOS.js} +2 -2
  44. package/dist/{chunk-2QSGJTDG.js → chunk-636UUVOZ.js} +10 -10
  45. package/dist/{chunk-AI5M4FVQ.js → chunk-6DTQSLER.js} +2 -2
  46. package/dist/{chunk-CDLPF3PX.js → chunk-6IL5FFHH.js} +2 -2
  47. package/dist/{chunk-VKDBDJIX.js → chunk-6L6V2OIX.js} +3 -3
  48. package/dist/{chunk-ZXROBS53.js → chunk-6NA527W2.js} +48 -48
  49. package/dist/{chunk-R2Q6FTOX.js → chunk-7IEFFOIC.js} +2 -2
  50. package/dist/{chunk-4PG2CKI6.js → chunk-AQHDMA4A.js} +2 -2
  51. package/dist/{chunk-RKNJBZ55.js → chunk-AU7Q3LSC.js} +7 -7
  52. package/dist/{chunk-6BYJQ3L2.js → chunk-BE4Y6GK6.js} +8 -8
  53. package/dist/{chunk-PW3GKWH3.js → chunk-BQVWC67C.js} +4 -4
  54. package/dist/{chunk-KQAFEZQX.js → chunk-BUKK5SWA.js} +2 -2
  55. package/dist/{chunk-UVYL5G7A.js → chunk-C3LUYZLX.js} +3 -3
  56. package/dist/{chunk-JMXHVJ2V.js → chunk-DFWO37KT.js} +14 -14
  57. package/dist/{chunk-WKWY7YF3.js → chunk-F5FHDDOV.js} +2 -2
  58. package/dist/{chunk-U4HZEW2B.js → chunk-FH4BB7F4.js} +7 -7
  59. package/dist/{chunk-UHQE37NI.js → chunk-G5TYMG7R.js} +2 -2
  60. package/dist/{chunk-PP7R754B.js → chunk-GPFZFCRN.js} +1 -1
  61. package/dist/{chunk-EH7BNIUN.js → chunk-HAF3PUMO.js} +3 -3
  62. package/dist/{chunk-J2R275FN.js → chunk-HQJM3BKH.js} +2 -2
  63. package/dist/{chunk-O7ERGZDA.js → chunk-I7NBTRLR.js} +2 -2
  64. package/dist/{chunk-6545JDIM.js → chunk-IHK5KTOC.js} +2 -2
  65. package/dist/{chunk-25OLNWYG.js → chunk-IP7KIW7W.js} +2 -2
  66. package/dist/{chunk-XJJYSX6F.js → chunk-JCUG7AXZ.js} +4 -4
  67. package/dist/{chunk-OERZXNSK.js → chunk-JGXMA6HL.js} +2 -2
  68. package/dist/{chunk-CQ6IWZDI.js → chunk-JVDAIASW.js} +2 -2
  69. package/dist/{chunk-F4W5HTED.js → chunk-K3CQQNMX.js} +2 -2
  70. package/dist/{chunk-D2YNNDML.js → chunk-KWIGDKM2.js} +2 -2
  71. package/dist/{chunk-227UFSEQ.js → chunk-LEPOP46W.js} +4 -4
  72. package/dist/{chunk-OLBZ2WGG.js → chunk-LTBKKSCX.js} +2 -2
  73. package/dist/{chunk-VSMSYDIH.js → chunk-MARZW7DB.js} +2 -2
  74. package/dist/chunk-MKD3OMPS.js +20 -0
  75. package/dist/chunk-MKD3OMPS.js.map +1 -0
  76. package/dist/{chunk-W5IYHQA5.js → chunk-MS2I7JVN.js} +3 -3
  77. package/dist/{chunk-BLHKR4GJ.js → chunk-NHACZAM3.js} +2 -2
  78. package/dist/{chunk-2VZHB5US.js → chunk-NTZ3452G.js} +2 -2
  79. package/dist/{chunk-65HXVEVG.js → chunk-OT3GGOFW.js} +2 -2
  80. package/dist/{chunk-2NLLXCJG.js → chunk-OWHERGF2.js} +2 -2
  81. package/dist/{chunk-OUKBMQ2O.js → chunk-PD66CVSD.js} +2 -2
  82. package/dist/{chunk-EQRD4NMH.js → chunk-PMMNP5GZ.js} +2 -2
  83. package/dist/{chunk-47WWTCJY.js → chunk-RNRDH4ZO.js} +308 -94
  84. package/dist/chunk-RNRDH4ZO.js.map +1 -0
  85. package/dist/{chunk-PRRUK2ZH.js → chunk-RNVXKTIA.js} +2 -2
  86. package/dist/{chunk-ZBIEX4XN.js → chunk-SACAOBDB.js} +1 -1
  87. package/dist/{chunk-JJ6ZEFXC.js → chunk-SNFWXG5G.js} +2 -2
  88. package/dist/{chunk-NTFXBILO.js → chunk-SY7ASLC6.js} +5 -5
  89. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  90. package/dist/{chunk-X7Y7WX73.js → chunk-UVYI6VIX.js} +1 -1
  91. package/dist/{chunk-YZ5VC2JJ.js → chunk-VVWPY5U7.js} +2 -2
  92. package/dist/{chunk-OIDICRH7.js → chunk-W7O7PH5E.js} +2 -2
  93. package/dist/{chunk-RH3XLQG4.js → chunk-WTRFM4SF.js} +2 -2
  94. package/dist/{chunk-6PUF7LUO.js → chunk-Y5U72X3D.js} +2 -2
  95. package/dist/{chunk-FFWONAAW.js → chunk-Y7LFWOX6.js} +3 -3
  96. package/dist/{chunk-D3DUA64S.js → chunk-YJDKSDIU.js} +2 -2
  97. package/dist/{chunk-BIJAWZYW.js → chunk-YMOPYG3K.js} +6 -6
  98. package/dist/{chunk-ZMVW2HJJ.js → chunk-YUYARGKM.js} +2 -2
  99. package/dist/{chunk-UMZUKOJU.js → chunk-Z3YEGSR4.js} +4 -4
  100. package/dist/{chunk-D6Q5EPOV.js → chunk-ZYKNDRUJ.js} +3 -3
  101. package/dist/cli.js +73 -73
  102. package/dist/coding/export-okf-codegraph.js +8 -8
  103. package/dist/coding/pre-action-gate.js +2 -2
  104. package/dist/compounding/engine.js +8 -8
  105. package/dist/config.js +5 -5
  106. package/dist/connectors/codex-materialize-runner.js +8 -8
  107. package/dist/connectors/index.js +8 -8
  108. package/dist/convergence-refresh.js +10 -10
  109. package/dist/conversation-index/backend.js +2 -2
  110. package/dist/corpus-watermark.js +10 -10
  111. package/dist/entity-retrieval.js +8 -8
  112. package/dist/external-wiki-access.js +32 -32
  113. package/dist/extraction-span-bench.d.ts +14 -0
  114. package/dist/extraction-span-bench.js +17 -0
  115. package/dist/extraction-span-bench.js.map +1 -0
  116. package/dist/extraction-span-clip.d.ts +22 -0
  117. package/dist/extraction-span-clip.js +19 -0
  118. package/dist/extraction-span-clip.js.map +1 -0
  119. package/dist/extraction-span-contains.d.ts +12 -0
  120. package/dist/extraction-span-contains.js +17 -0
  121. package/dist/extraction-span-contains.js.map +1 -0
  122. package/dist/extraction-span-gap.d.ts +14 -0
  123. package/dist/extraction-span-gap.js +18 -0
  124. package/dist/extraction-span-gap.js.map +1 -0
  125. package/dist/extraction-span-join.d.ts +23 -0
  126. package/dist/extraction-span-join.js +19 -0
  127. package/dist/extraction-span-join.js.map +1 -0
  128. package/dist/extraction-span-length.d.ts +11 -0
  129. package/dist/extraction-span-length.js +17 -0
  130. package/dist/extraction-span-length.js.map +1 -0
  131. package/dist/extraction-span-overlap.d.ts +14 -0
  132. package/dist/extraction-span-overlap.js +16 -0
  133. package/dist/extraction-span-overlap.js.map +1 -0
  134. package/dist/extraction-span-shift.d.ts +15 -0
  135. package/dist/extraction-span-shift.js +17 -0
  136. package/dist/extraction-span-shift.js.map +1 -0
  137. package/dist/extraction-span-slice.d.ts +12 -0
  138. package/dist/extraction-span-slice.js +17 -0
  139. package/dist/extraction-span-slice.js.map +1 -0
  140. package/dist/extraction-span-validate.d.ts +20 -0
  141. package/dist/extraction-span-validate.js +20 -0
  142. package/dist/extraction-span-validate.js.map +1 -0
  143. package/dist/extraction.js +8 -8
  144. package/dist/{graph-edge-decay-FXGELBFA.js → graph-edge-decay-A4SDFMMS.js} +4 -4
  145. package/dist/graph-snapshot.js +3 -3
  146. package/dist/graph.js +3 -3
  147. package/dist/harmonic-retrieval.js +1 -1
  148. package/dist/index.d.ts +181 -1
  149. package/dist/index.js +140 -112
  150. package/dist/lcm/engine.js +2 -2
  151. package/dist/lcm/index.js +7 -7
  152. package/dist/location/index.js +10 -10
  153. package/dist/maintenance/memory-governance.js +8 -8
  154. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -8
  155. package/dist/maintenance/rebuild-memory-projection.js +9 -9
  156. package/dist/namespaces/migrate.js +9 -9
  157. package/dist/namespaces/search.js +6 -6
  158. package/dist/namespaces/storage.js +8 -8
  159. package/dist/offline-sync.js +2 -2
  160. package/dist/operator-doctor-corpus.js +11 -11
  161. package/dist/operator-toolkit.js +23 -23
  162. package/dist/orchestration/maintenance.js +16 -16
  163. package/dist/orchestrator.js +97 -97
  164. package/dist/recall-deep-budget-left.d.ts +8 -0
  165. package/dist/recall-deep-budget-left.js +15 -0
  166. package/dist/recall-deep-budget-left.js.map +1 -0
  167. package/dist/recall-deep-budget.d.ts +9 -0
  168. package/dist/recall-deep-budget.js +15 -0
  169. package/dist/recall-deep-budget.js.map +1 -0
  170. package/dist/recall-deep-expand.d.ts +12 -0
  171. package/dist/recall-deep-expand.js +17 -0
  172. package/dist/recall-deep-expand.js.map +1 -0
  173. package/dist/recall-deep-policy.d.ts +17 -0
  174. package/dist/recall-deep-policy.js +18 -0
  175. package/dist/recall-deep-policy.js.map +1 -0
  176. package/dist/recall-deep-query.d.ts +15 -0
  177. package/dist/recall-deep-query.js +12 -0
  178. package/dist/recall-deep-query.js.map +1 -0
  179. package/dist/recall-deep-refine.d.ts +12 -0
  180. package/dist/recall-deep-refine.js +17 -0
  181. package/dist/recall-deep-refine.js.map +1 -0
  182. package/dist/recall-deep-step-count.d.ts +8 -0
  183. package/dist/recall-deep-step-count.js +15 -0
  184. package/dist/recall-deep-step-count.js.map +1 -0
  185. package/dist/recall-deep-stop-reason.d.ts +17 -0
  186. package/dist/recall-deep-stop-reason.js +23 -0
  187. package/dist/recall-deep-stop-reason.js.map +1 -0
  188. package/dist/recall-deep-stop.d.ts +17 -0
  189. package/dist/recall-deep-stop.js +23 -0
  190. package/dist/recall-deep-stop.js.map +1 -0
  191. package/dist/recall-deep-working-set.d.ts +9 -0
  192. package/dist/recall-deep-working-set.js +14 -0
  193. package/dist/recall-deep-working-set.js.map +1 -0
  194. package/dist/recall-navigate-access.d.ts +39 -0
  195. package/dist/recall-navigate-access.js +31 -0
  196. package/dist/recall-navigate-access.js.map +1 -0
  197. package/dist/recall-navigate-action.d.ts +17 -0
  198. package/dist/recall-navigate-action.js +14 -0
  199. package/dist/recall-navigate-action.js.map +1 -0
  200. package/dist/recall-navigate-budget.d.ts +16 -0
  201. package/dist/recall-navigate-budget.js +18 -0
  202. package/dist/recall-navigate-budget.js.map +1 -0
  203. package/dist/recall-navigate-cost.d.ts +8 -0
  204. package/dist/recall-navigate-cost.js +15 -0
  205. package/dist/recall-navigate-cost.js.map +1 -0
  206. package/dist/recall-navigate-depth.d.ts +8 -0
  207. package/dist/recall-navigate-depth.js +15 -0
  208. package/dist/recall-navigate-depth.js.map +1 -0
  209. package/dist/recall-navigate-link.d.ts +17 -0
  210. package/dist/recall-navigate-link.js +20 -0
  211. package/dist/recall-navigate-link.js.map +1 -0
  212. package/dist/recall-navigate-max-children.d.ts +8 -0
  213. package/dist/recall-navigate-max-children.js +15 -0
  214. package/dist/recall-navigate-max-children.js.map +1 -0
  215. package/dist/recall-navigate-node.d.ts +15 -0
  216. package/dist/recall-navigate-node.js +13 -0
  217. package/dist/recall-navigate-node.js.map +1 -0
  218. package/dist/recall-navigate-path.d.ts +9 -0
  219. package/dist/recall-navigate-path.js +14 -0
  220. package/dist/recall-navigate-path.js.map +1 -0
  221. package/dist/recall-navigate-render.d.ts +15 -0
  222. package/dist/recall-navigate-render.js +23 -0
  223. package/dist/recall-navigate-render.js.map +1 -0
  224. package/dist/recall-state-view-current.d.ts +18 -0
  225. package/dist/recall-state-view-current.js +14 -0
  226. package/dist/recall-state-view-current.js.map +1 -0
  227. package/dist/recall-state-view-inject.d.ts +15 -0
  228. package/dist/recall-state-view-inject.js +16 -0
  229. package/dist/recall-state-view-inject.js.map +1 -0
  230. package/dist/recall-state-view-kind.d.ts +17 -0
  231. package/dist/recall-state-view-kind.js +14 -0
  232. package/dist/recall-state-view-kind.js.map +1 -0
  233. package/dist/recall-state-view-label.d.ts +17 -0
  234. package/dist/recall-state-view-label.js +16 -0
  235. package/dist/recall-state-view-label.js.map +1 -0
  236. package/dist/recall-state-view-render.js +3 -14
  237. package/dist/recall-state-view-render.js.map +1 -1
  238. package/dist/recall-state-view-successor.d.ts +15 -0
  239. package/dist/recall-state-view-successor.js +13 -0
  240. package/dist/recall-state-view-successor.js.map +1 -0
  241. package/dist/recall-state-view-superseded.d.ts +15 -0
  242. package/dist/recall-state-view-superseded.js +14 -0
  243. package/dist/recall-state-view-superseded.js.map +1 -0
  244. package/dist/recall-state-view-transition.d.ts +18 -0
  245. package/dist/recall-state-view-transition.js +14 -0
  246. package/dist/recall-state-view-transition.js.map +1 -0
  247. package/dist/resume-bundles.js +6 -6
  248. package/dist/search/factory.js +5 -5
  249. package/dist/search/index.js +9 -9
  250. package/dist/semantic-consolidation.js +9 -9
  251. package/dist/semantic-rule-promotion.js +8 -8
  252. package/dist/semantic-rule-verifier.js +8 -8
  253. package/dist/source-agent-qualifier.js +8 -8
  254. package/dist/storage.js +7 -7
  255. package/dist/support-passport/index.js +34 -34
  256. package/dist/transfer/backup.js +2 -2
  257. package/dist/transfer/capsule-export.js +2 -2
  258. package/dist/transfer/capsule-import.js +2 -2
  259. package/dist/transfer/export-okf.js +9 -9
  260. package/dist/verified-recall.js +8 -8
  261. package/dist/who-knows-cli.js +9 -9
  262. package/dist/who-knows.js +8 -8
  263. package/package.json +2 -2
  264. package/src/activity/dwell.test.ts +28 -0
  265. package/src/activity/dwell.ts +22 -0
  266. package/src/activity/from-ms.test.ts +25 -0
  267. package/src/activity/from-ms.ts +13 -0
  268. package/src/activity/heading-level.test.ts +23 -0
  269. package/src/activity/heading-level.ts +21 -0
  270. package/src/activity/heading-title.test.ts +21 -0
  271. package/src/activity/heading-title.ts +26 -0
  272. package/src/activity/index.ts +6 -0
  273. package/src/activity/journal-heading.test.ts +22 -0
  274. package/src/activity/journal-heading.ts +18 -0
  275. package/src/activity/journal-mode.test.ts +32 -0
  276. package/src/activity/journal-mode.ts +20 -0
  277. package/src/activity/journal-path.test.ts +25 -0
  278. package/src/activity/journal-path.ts +27 -0
  279. package/src/activity/journal-section.test.ts +37 -0
  280. package/src/activity/journal-section.ts +75 -0
  281. package/src/activity/journal-source.test.ts +37 -0
  282. package/src/activity/journal-source.ts +23 -0
  283. package/src/activity/privacy-enabled.test.ts +30 -0
  284. package/src/activity/privacy-enabled.ts +33 -0
  285. package/src/activity/privacy-keys.test.ts +22 -0
  286. package/src/activity/privacy-keys.ts +12 -0
  287. package/src/activity/privacy-redact.test.ts +25 -0
  288. package/src/activity/privacy-redact.ts +23 -0
  289. package/src/activity/privacy-window.test.ts +49 -0
  290. package/src/activity/privacy-window.ts +32 -0
  291. package/src/activity/retain-days.test.ts +20 -0
  292. package/src/activity/retain-days.ts +14 -0
  293. package/src/activity/timeline/analysis-claim.test.ts +33 -0
  294. package/src/activity/timeline/analysis-claim.ts +16 -0
  295. package/src/activity/timeline/analysis-dup.test.ts +28 -0
  296. package/src/activity/timeline/analysis-dup.ts +10 -0
  297. package/src/activity/timeline/analysis-empty.test.ts +21 -0
  298. package/src/activity/timeline/analysis-empty.ts +14 -0
  299. package/src/activity/timeline/analysis-evidence.test.ts +32 -0
  300. package/src/activity/timeline/analysis-evidence.ts +20 -0
  301. package/src/activity/timeline/analysis-max.test.ts +26 -0
  302. package/src/activity/timeline/analysis-max.ts +14 -0
  303. package/src/activity/timeline/analysis-order.test.ts +28 -0
  304. package/src/activity/timeline/analysis-order.ts +10 -0
  305. package/src/activity/timeline/analysis-overlap.test.ts +26 -0
  306. package/src/activity/timeline/analysis-overlap.ts +17 -0
  307. package/src/activity/timeline/analysis-prompt.test.ts +50 -0
  308. package/src/activity/timeline/analysis-prompt.ts +24 -0
  309. package/src/activity/timeline/index.ts +8 -0
  310. package/src/activity/timeline/recap-card-count.test.ts +19 -0
  311. package/src/activity/timeline/recap-card-count.ts +13 -0
  312. package/src/activity/timeline/recap-card-id.test.ts +21 -0
  313. package/src/activity/timeline/recap-card-id.ts +16 -0
  314. package/src/activity/timeline/recap-date.test.ts +21 -0
  315. package/src/activity/timeline/recap-date.ts +19 -0
  316. package/src/activity/timeline/recap-empty.test.ts +21 -0
  317. package/src/activity/timeline/recap-empty.ts +14 -0
  318. package/src/activity/timeline/recap-export.test.ts +78 -0
  319. package/src/activity/timeline/recap-export.ts +41 -0
  320. package/src/activity/timeline/recap-id.test.ts +28 -0
  321. package/src/activity/timeline/recap-id.ts +10 -0
  322. package/src/activity/timeline/recap-markdown.test.ts +56 -0
  323. package/src/activity/timeline/recap-markdown.ts +26 -0
  324. package/src/activity/timeline/recap-sort-key.test.ts +18 -0
  325. package/src/activity/timeline/recap-sort-key.ts +14 -0
  326. package/src/activity/timeline/recap-tz.test.ts +35 -0
  327. package/src/activity/timeline/recap-tz.ts +19 -0
  328. package/src/activity/timeline/week-count.test.ts +19 -0
  329. package/src/activity/timeline/week-count.ts +13 -0
  330. package/src/activity/timeline/week-days.test.ts +26 -0
  331. package/src/activity/timeline/week-days.ts +23 -0
  332. package/src/activity/timeline/week-export.test.ts +59 -0
  333. package/src/activity/timeline/week-export.ts +44 -0
  334. package/src/activity/timeline/week-iso.test.ts +29 -0
  335. package/src/activity/timeline/week-iso.ts +20 -0
  336. package/src/activity/timeline/week-monday.test.ts +17 -0
  337. package/src/activity/timeline/week-monday.ts +12 -0
  338. package/src/activity/timeline/week-range.test.ts +23 -0
  339. package/src/activity/timeline/week-range.ts +26 -0
  340. package/src/activity/timeline/week-snapshot.test.ts +66 -0
  341. package/src/activity/timeline/week-snapshot.ts +40 -0
  342. package/src/activity/timeline/week-span.test.ts +21 -0
  343. package/src/activity/timeline/week-span.ts +18 -0
  344. package/src/activity/timeline/week-sunday.test.ts +17 -0
  345. package/src/activity/timeline/week-sunday.ts +12 -0
  346. package/src/activity/to-ms.test.ts +25 -0
  347. package/src/activity/to-ms.ts +13 -0
  348. package/src/activity/vault-begin.test.ts +20 -0
  349. package/src/activity/vault-begin.ts +13 -0
  350. package/src/activity/vault-end.test.ts +20 -0
  351. package/src/activity/vault-end.ts +13 -0
  352. package/src/activity/vault-frontmatter.test.ts +28 -0
  353. package/src/activity/vault-frontmatter.ts +39 -0
  354. package/src/activity/vault-join.test.ts +21 -0
  355. package/src/activity/vault-join.ts +31 -0
  356. package/src/activity/vault-marker.test.ts +23 -0
  357. package/src/activity/vault-marker.ts +27 -0
  358. package/src/activity/vault-name-trim.test.ts +22 -0
  359. package/src/activity/vault-name-trim.ts +16 -0
  360. package/src/activity/vault-region-pair.test.ts +26 -0
  361. package/src/activity/vault-region-pair.ts +24 -0
  362. package/src/activity/vault-region.test.ts +24 -0
  363. package/src/activity/vault-region.ts +24 -0
  364. package/src/activity/vault-suffix.test.ts +20 -0
  365. package/src/activity/vault-suffix.ts +12 -0
  366. package/src/activity/vault-wikilink.test.ts +27 -0
  367. package/src/activity/vault-wikilink.ts +28 -0
  368. package/src/activity/window-order.test.ts +27 -0
  369. package/src/activity/window-order.ts +24 -0
  370. package/src/dedup/merge-count.test.ts +19 -0
  371. package/src/dedup/merge-count.ts +13 -0
  372. package/src/dedup/merge-dup.test.ts +21 -0
  373. package/src/dedup/merge-dup.ts +16 -0
  374. package/src/dedup/merge-empty.test.ts +22 -0
  375. package/src/dedup/merge-empty.ts +18 -0
  376. package/src/dedup/merge-id.test.ts +18 -0
  377. package/src/dedup/merge-id.ts +14 -0
  378. package/src/dedup/merge-min-score.test.ts +37 -0
  379. package/src/dedup/merge-min-score.ts +22 -0
  380. package/src/dedup/merge-pair.test.ts +19 -0
  381. package/src/dedup/merge-pair.ts +13 -0
  382. package/src/dedup/merge-score.test.ts +20 -0
  383. package/src/dedup/merge-score.ts +14 -0
  384. package/src/dedup/merge-self.test.ts +19 -0
  385. package/src/dedup/merge-self.ts +17 -0
  386. package/src/dedup/merge-threshold.test.ts +46 -0
  387. package/src/dedup/merge-threshold.ts +26 -0
  388. package/src/dedup/merge-tie.test.ts +22 -0
  389. package/src/dedup/merge-tie.ts +13 -0
  390. package/src/extraction-span-bench.test.ts +27 -0
  391. package/src/extraction-span-bench.ts +28 -0
  392. package/src/extraction-span-clip.test.ts +71 -0
  393. package/src/extraction-span-clip.ts +26 -0
  394. package/src/extraction-span-contains.test.ts +30 -0
  395. package/src/extraction-span-contains.ts +20 -0
  396. package/src/extraction-span-gap.test.ts +29 -0
  397. package/src/extraction-span-gap.ts +25 -0
  398. package/src/extraction-span-join.test.ts +50 -0
  399. package/src/extraction-span-join.ts +30 -0
  400. package/src/extraction-span-length.test.ts +25 -0
  401. package/src/extraction-span-length.ts +16 -0
  402. package/src/extraction-span-overlap.test.ts +34 -0
  403. package/src/extraction-span-overlap.ts +23 -0
  404. package/src/extraction-span-shift.test.ts +25 -0
  405. package/src/extraction-span-shift.ts +20 -0
  406. package/src/extraction-span-slice.test.ts +32 -0
  407. package/src/extraction-span-slice.ts +20 -0
  408. package/src/extraction-span-validate.test.ts +42 -0
  409. package/src/extraction-span-validate.ts +27 -0
  410. package/src/recall-deep-budget-left.test.ts +20 -0
  411. package/src/recall-deep-budget-left.ts +13 -0
  412. package/src/recall-deep-budget.test.ts +19 -0
  413. package/src/recall-deep-budget.ts +14 -0
  414. package/src/recall-deep-expand.test.ts +23 -0
  415. package/src/recall-deep-expand.ts +19 -0
  416. package/src/recall-deep-policy.test.ts +32 -0
  417. package/src/recall-deep-policy.ts +22 -0
  418. package/src/recall-deep-query.test.ts +23 -0
  419. package/src/recall-deep-query.ts +15 -0
  420. package/src/recall-deep-refine.test.ts +23 -0
  421. package/src/recall-deep-refine.ts +19 -0
  422. package/src/recall-deep-step-count.test.ts +20 -0
  423. package/src/recall-deep-step-count.ts +13 -0
  424. package/src/recall-deep-stop-reason.test.ts +46 -0
  425. package/src/recall-deep-stop-reason.ts +27 -0
  426. package/src/recall-deep-stop.test.ts +34 -0
  427. package/src/recall-deep-stop.ts +31 -0
  428. package/src/recall-deep-working-set.test.ts +21 -0
  429. package/src/recall-deep-working-set.ts +14 -0
  430. package/src/recall-navigate-access.test.ts +73 -0
  431. package/src/recall-navigate-access.ts +48 -0
  432. package/src/recall-navigate-action.test.ts +32 -0
  433. package/src/recall-navigate-action.ts +20 -0
  434. package/src/recall-navigate-budget.test.ts +23 -0
  435. package/src/recall-navigate-budget.ts +22 -0
  436. package/src/recall-navigate-cost.test.ts +20 -0
  437. package/src/recall-navigate-cost.ts +13 -0
  438. package/src/recall-navigate-depth.test.ts +20 -0
  439. package/src/recall-navigate-depth.ts +13 -0
  440. package/src/recall-navigate-link.test.ts +19 -0
  441. package/src/recall-navigate-link.ts +26 -0
  442. package/src/recall-navigate-max-children.test.ts +20 -0
  443. package/src/recall-navigate-max-children.ts +13 -0
  444. package/src/recall-navigate-node.test.ts +21 -0
  445. package/src/recall-navigate-node.ts +16 -0
  446. package/src/recall-navigate-path.test.ts +21 -0
  447. package/src/recall-navigate-path.ts +14 -0
  448. package/src/recall-navigate-render.test.ts +63 -0
  449. package/src/recall-navigate-render.ts +31 -0
  450. package/src/recall-state-view-current.test.ts +23 -0
  451. package/src/recall-state-view-current.ts +24 -0
  452. package/src/recall-state-view-inject.test.ts +32 -0
  453. package/src/recall-state-view-inject.ts +14 -0
  454. package/src/recall-state-view-kind.test.ts +19 -0
  455. package/src/recall-state-view-kind.ts +20 -0
  456. package/src/recall-state-view-label.test.ts +36 -0
  457. package/src/recall-state-view-label.ts +22 -0
  458. package/src/recall-state-view-successor.test.ts +21 -0
  459. package/src/recall-state-view-successor.ts +16 -0
  460. package/src/recall-state-view-superseded.test.ts +20 -0
  461. package/src/recall-state-view-superseded.ts +17 -0
  462. package/src/recall-state-view-transition.test.ts +30 -0
  463. package/src/recall-state-view-transition.ts +24 -0
  464. package/src/shared-context/authority.test.ts +35 -0
  465. package/src/shared-context/authority.ts +25 -0
  466. package/src/shared-context/claim-key.test.ts +21 -0
  467. package/src/shared-context/claim-key.ts +16 -0
  468. package/src/shared-context/contradictions.test.ts +39 -0
  469. package/src/shared-context/contradictions.ts +32 -0
  470. package/src/shared-context/envelope-actor.test.ts +21 -0
  471. package/src/shared-context/envelope-actor.ts +16 -0
  472. package/src/shared-context/envelope-at.test.ts +19 -0
  473. package/src/shared-context/envelope-at.ts +17 -0
  474. package/src/shared-context/envelope-id.test.ts +21 -0
  475. package/src/shared-context/envelope-id.ts +16 -0
  476. package/src/shared-context/envelope-required.test.ts +24 -0
  477. package/src/shared-context/envelope-required.ts +15 -0
  478. package/src/shared-context/envelope-ttl.test.ts +29 -0
  479. package/src/shared-context/envelope-ttl.ts +35 -0
  480. package/src/shared-context/provenance.test.ts +35 -0
  481. package/src/shared-context/provenance.ts +68 -0
  482. package/dist/chunk-47WWTCJY.js.map +0 -1
  483. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
  484. /package/dist/{chunk-36HJ36FK.js.map → chunk-27JH2KKM.js.map} +0 -0
  485. /package/dist/{chunk-NZPFCP5A.js.map → chunk-2PSX5BJU.js.map} +0 -0
  486. /package/dist/{chunk-RCPKBW7K.js.map → chunk-322MSJYS.js.map} +0 -0
  487. /package/dist/{chunk-C3ZYZKDJ.js.map → chunk-3E4REX7E.js.map} +0 -0
  488. /package/dist/{chunk-Y2YM4C75.js.map → chunk-4BRBSON5.js.map} +0 -0
  489. /package/dist/{chunk-B4B3QDV3.js.map → chunk-4EX26ZS3.js.map} +0 -0
  490. /package/dist/{chunk-ER2UPUMG.js.map → chunk-562Q236T.js.map} +0 -0
  491. /package/dist/{chunk-F2JXJABQ.js.map → chunk-5BIOXQGN.js.map} +0 -0
  492. /package/dist/{chunk-DSEHPUID.js.map → chunk-5C3OQ253.js.map} +0 -0
  493. /package/dist/{chunk-LSR5LQXN.js.map → chunk-5VLXQFOS.js.map} +0 -0
  494. /package/dist/{chunk-2QSGJTDG.js.map → chunk-636UUVOZ.js.map} +0 -0
  495. /package/dist/{chunk-AI5M4FVQ.js.map → chunk-6DTQSLER.js.map} +0 -0
  496. /package/dist/{chunk-CDLPF3PX.js.map → chunk-6IL5FFHH.js.map} +0 -0
  497. /package/dist/{chunk-VKDBDJIX.js.map → chunk-6L6V2OIX.js.map} +0 -0
  498. /package/dist/{chunk-ZXROBS53.js.map → chunk-6NA527W2.js.map} +0 -0
  499. /package/dist/{chunk-R2Q6FTOX.js.map → chunk-7IEFFOIC.js.map} +0 -0
  500. /package/dist/{chunk-4PG2CKI6.js.map → chunk-AQHDMA4A.js.map} +0 -0
  501. /package/dist/{chunk-RKNJBZ55.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  502. /package/dist/{chunk-6BYJQ3L2.js.map → chunk-BE4Y6GK6.js.map} +0 -0
  503. /package/dist/{chunk-PW3GKWH3.js.map → chunk-BQVWC67C.js.map} +0 -0
  504. /package/dist/{chunk-KQAFEZQX.js.map → chunk-BUKK5SWA.js.map} +0 -0
  505. /package/dist/{chunk-UVYL5G7A.js.map → chunk-C3LUYZLX.js.map} +0 -0
  506. /package/dist/{chunk-JMXHVJ2V.js.map → chunk-DFWO37KT.js.map} +0 -0
  507. /package/dist/{chunk-WKWY7YF3.js.map → chunk-F5FHDDOV.js.map} +0 -0
  508. /package/dist/{chunk-U4HZEW2B.js.map → chunk-FH4BB7F4.js.map} +0 -0
  509. /package/dist/{chunk-UHQE37NI.js.map → chunk-G5TYMG7R.js.map} +0 -0
  510. /package/dist/{chunk-PP7R754B.js.map → chunk-GPFZFCRN.js.map} +0 -0
  511. /package/dist/{chunk-EH7BNIUN.js.map → chunk-HAF3PUMO.js.map} +0 -0
  512. /package/dist/{chunk-J2R275FN.js.map → chunk-HQJM3BKH.js.map} +0 -0
  513. /package/dist/{chunk-O7ERGZDA.js.map → chunk-I7NBTRLR.js.map} +0 -0
  514. /package/dist/{chunk-6545JDIM.js.map → chunk-IHK5KTOC.js.map} +0 -0
  515. /package/dist/{chunk-25OLNWYG.js.map → chunk-IP7KIW7W.js.map} +0 -0
  516. /package/dist/{chunk-XJJYSX6F.js.map → chunk-JCUG7AXZ.js.map} +0 -0
  517. /package/dist/{chunk-OERZXNSK.js.map → chunk-JGXMA6HL.js.map} +0 -0
  518. /package/dist/{chunk-CQ6IWZDI.js.map → chunk-JVDAIASW.js.map} +0 -0
  519. /package/dist/{chunk-F4W5HTED.js.map → chunk-K3CQQNMX.js.map} +0 -0
  520. /package/dist/{chunk-D2YNNDML.js.map → chunk-KWIGDKM2.js.map} +0 -0
  521. /package/dist/{chunk-227UFSEQ.js.map → chunk-LEPOP46W.js.map} +0 -0
  522. /package/dist/{chunk-OLBZ2WGG.js.map → chunk-LTBKKSCX.js.map} +0 -0
  523. /package/dist/{chunk-VSMSYDIH.js.map → chunk-MARZW7DB.js.map} +0 -0
  524. /package/dist/{chunk-W5IYHQA5.js.map → chunk-MS2I7JVN.js.map} +0 -0
  525. /package/dist/{chunk-BLHKR4GJ.js.map → chunk-NHACZAM3.js.map} +0 -0
  526. /package/dist/{chunk-2VZHB5US.js.map → chunk-NTZ3452G.js.map} +0 -0
  527. /package/dist/{chunk-65HXVEVG.js.map → chunk-OT3GGOFW.js.map} +0 -0
  528. /package/dist/{chunk-2NLLXCJG.js.map → chunk-OWHERGF2.js.map} +0 -0
  529. /package/dist/{chunk-OUKBMQ2O.js.map → chunk-PD66CVSD.js.map} +0 -0
  530. /package/dist/{chunk-EQRD4NMH.js.map → chunk-PMMNP5GZ.js.map} +0 -0
  531. /package/dist/{chunk-PRRUK2ZH.js.map → chunk-RNVXKTIA.js.map} +0 -0
  532. /package/dist/{chunk-ZBIEX4XN.js.map → chunk-SACAOBDB.js.map} +0 -0
  533. /package/dist/{chunk-JJ6ZEFXC.js.map → chunk-SNFWXG5G.js.map} +0 -0
  534. /package/dist/{chunk-NTFXBILO.js.map → chunk-SY7ASLC6.js.map} +0 -0
  535. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  536. /package/dist/{chunk-X7Y7WX73.js.map → chunk-UVYI6VIX.js.map} +0 -0
  537. /package/dist/{chunk-YZ5VC2JJ.js.map → chunk-VVWPY5U7.js.map} +0 -0
  538. /package/dist/{chunk-OIDICRH7.js.map → chunk-W7O7PH5E.js.map} +0 -0
  539. /package/dist/{chunk-RH3XLQG4.js.map → chunk-WTRFM4SF.js.map} +0 -0
  540. /package/dist/{chunk-6PUF7LUO.js.map → chunk-Y5U72X3D.js.map} +0 -0
  541. /package/dist/{chunk-FFWONAAW.js.map → chunk-Y7LFWOX6.js.map} +0 -0
  542. /package/dist/{chunk-D3DUA64S.js.map → chunk-YJDKSDIU.js.map} +0 -0
  543. /package/dist/{chunk-BIJAWZYW.js.map → chunk-YMOPYG3K.js.map} +0 -0
  544. /package/dist/{chunk-ZMVW2HJJ.js.map → chunk-YUYARGKM.js.map} +0 -0
  545. /package/dist/{chunk-UMZUKOJU.js.map → chunk-Z3YEGSR4.js.map} +0 -0
  546. /package/dist/{chunk-D6Q5EPOV.js.map → chunk-ZYKNDRUJ.js.map} +0 -0
  547. /package/dist/{graph-edge-decay-FXGELBFA.js.map → graph-edge-decay-A4SDFMMS.js.map} +0 -0
@@ -0,0 +1,23 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { assertCurrentHasNoSuccessor } from "./recall-state-view-current.js";
5
+
6
+ test("current plus successor id is current_has_successor", () => {
7
+ assert.deepEqual(assertCurrentHasNoSuccessor({ kind: "current", successorId: "mem-2" }), {
8
+ ok: false,
9
+ error: "current_has_successor",
10
+ });
11
+ });
12
+
13
+ test("current plus empty successor id is ok", () => {
14
+ assert.deepEqual(assertCurrentHasNoSuccessor({ kind: "current", successorId: "" }), { ok: true });
15
+ assert.deepEqual(assertCurrentHasNoSuccessor({ kind: "current", successorId: " " }), { ok: true });
16
+ assert.deepEqual(assertCurrentHasNoSuccessor({ kind: "current" }), { ok: true });
17
+ });
18
+
19
+ test("historical plus successor id is ok", () => {
20
+ assert.deepEqual(assertCurrentHasNoSuccessor({ kind: "historical", successorId: "mem-2" }), {
21
+ ok: true,
22
+ });
23
+ });
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Recall state-view current-has-no-successor guard (issue #1952 leftover).
3
+ *
4
+ * Pure. Surfaces wait. Current plus a successor is current_has_successor.
5
+ */
6
+
7
+ export type AssertCurrentHasNoSuccessorInput = {
8
+ kind: string;
9
+ successorId?: string;
10
+ };
11
+
12
+ export type AssertCurrentHasNoSuccessorResult =
13
+ | { ok: true }
14
+ | { ok: false; error: "current_has_successor" };
15
+
16
+ export function assertCurrentHasNoSuccessor(
17
+ input: AssertCurrentHasNoSuccessorInput,
18
+ ): AssertCurrentHasNoSuccessorResult {
19
+ const successorId = input.successorId?.trim() ?? "";
20
+ if (input.kind === "current" && successorId.length > 0) {
21
+ return { ok: false, error: "current_has_successor" };
22
+ }
23
+ return { ok: true };
24
+ }
@@ -0,0 +1,32 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { injectStateViewLines } from "./recall-state-view-inject.js";
5
+
6
+ const TEXT = "Was a baker";
7
+ const DATE = "2026-03-01";
8
+ const SUCCESSOR = "new-job";
9
+
10
+ const historical = {
11
+ id: "old-job",
12
+ text: TEXT,
13
+ stateLabel: "historical" as const,
14
+ supersededAt: DATE,
15
+ supersededBy: SUCCESSOR,
16
+ };
17
+
18
+ test("enabled false keeps original text per item", () => {
19
+ assert.deepEqual(injectStateViewLines([historical]), [TEXT]);
20
+ assert.deepEqual(injectStateViewLines([historical], { enabled: false }), [TEXT]);
21
+ });
22
+
23
+ test("empty list stays empty", () => {
24
+ assert.deepEqual(injectStateViewLines([]), []);
25
+ assert.deepEqual(injectStateViewLines([], { enabled: true }), []);
26
+ });
27
+
28
+ test("enabled prefix maps historical text", () => {
29
+ assert.deepEqual(injectStateViewLines([historical], { enabled: true }), [
30
+ `[superseded ${DATE} by ${SUCCESSOR}] ${TEXT}`,
31
+ ]);
32
+ });
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Recall inject-line mapper for state views (issue #1952).
3
+ *
4
+ * Maps each result through renderStateViewLine. A disabled flag keeps
5
+ * original text per item. An empty list stays empty.
6
+ */
7
+ import { renderStateViewLine, type StateViewLineResult } from "./recall-state-view-render.js";
8
+
9
+ export function injectStateViewLines(
10
+ results: readonly StateViewLineResult[],
11
+ options: { enabled?: boolean } = {},
12
+ ): string[] {
13
+ return results.map((result) => renderStateViewLine(result, options));
14
+ }
@@ -0,0 +1,19 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseStateViewKind } from "./recall-state-view-kind.js";
5
+
6
+ test("parses each allowed kind", () => {
7
+ for (const kind of ["current", "historical", "transition"] as const) {
8
+ assert.deepEqual(parseStateViewKind(kind), { ok: true, kind });
9
+ }
10
+ });
11
+
12
+ test("unknown kind is unknown_kind", () => {
13
+ assert.deepEqual(parseStateViewKind("ghost"), { ok: false, error: "unknown_kind" });
14
+ assert.deepEqual(parseStateViewKind("superseded"), { ok: false, error: "unknown_kind" });
15
+ });
16
+
17
+ test("empty kind is unknown_kind", () => {
18
+ assert.deepEqual(parseStateViewKind(""), { ok: false, error: "unknown_kind" });
19
+ });
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Recall state-view kind parse (issue #1952 leftover).
3
+ *
4
+ * Pure. Surfaces wait. Unknown or empty is unknown_kind.
5
+ */
6
+
7
+ const STATE_VIEW_KINDS = ["current", "historical", "transition"] as const;
8
+
9
+ export type StateViewKind = (typeof STATE_VIEW_KINDS)[number];
10
+
11
+ export type ParseStateViewKindResult =
12
+ | { ok: true; kind: StateViewKind }
13
+ | { ok: false; error: "unknown_kind" };
14
+
15
+ export function parseStateViewKind(value: string): ParseStateViewKindResult {
16
+ if ((STATE_VIEW_KINDS as readonly string[]).includes(value)) {
17
+ return { ok: true, kind: value as StateViewKind };
18
+ }
19
+ return { ok: false, error: "unknown_kind" };
20
+ }
@@ -0,0 +1,36 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { labelStateView } from "./recall-state-view-label.js";
5
+
6
+ const DATE = "2026-03-01";
7
+ const SUCCESSOR = "new-job";
8
+
9
+ test("kind current is current", () => {
10
+ assert.equal(
11
+ labelStateView({ kind: "current", supersededAt: DATE, successorId: SUCCESSOR }),
12
+ "current",
13
+ );
14
+ });
15
+
16
+ test("kind historical with both fields is historical", () => {
17
+ assert.equal(
18
+ labelStateView({ kind: "historical", supersededAt: DATE, successorId: SUCCESSOR }),
19
+ "historical",
20
+ );
21
+ });
22
+
23
+ test("missing supersededAt or successorId is current", () => {
24
+ assert.equal(
25
+ labelStateView({ kind: "historical", successorId: SUCCESSOR }),
26
+ "current",
27
+ );
28
+ assert.equal(
29
+ labelStateView({ kind: "transition", supersededAt: DATE }),
30
+ "current",
31
+ );
32
+ });
33
+
34
+ test("unknown kind throws", () => {
35
+ assert.throws(() => labelStateView({ kind: "ghost" }), /unknown state view kind/);
36
+ });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Pure state-view labeler (issue #1952 leftover).
3
+ *
4
+ * Surfaces wait. `current` stays current. `historical` and `transition`
5
+ * keep their kind only when both supersededAt and successorId are set.
6
+ * Missing either field is current. Unknown kind throws.
7
+ */
8
+ import type { StateLabel } from "./recall-state-view.js";
9
+
10
+ export function labelStateView(input: {
11
+ kind: string;
12
+ supersededAt?: string;
13
+ successorId?: string;
14
+ }): StateLabel {
15
+ const { kind, supersededAt, successorId } = input;
16
+ if (kind === "current") return "current";
17
+ if (kind === "historical" || kind === "transition") {
18
+ if (!supersededAt || !successorId) return "current";
19
+ return kind;
20
+ }
21
+ throw new Error(`unknown state view kind: ${JSON.stringify(kind)}`);
22
+ }
@@ -0,0 +1,21 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseSuccessorId } from "./recall-state-view-successor.js";
5
+
6
+ test("ok successor id returns trimmed successorId", () => {
7
+ assert.deepEqual(parseSuccessorId("mem-2"), { ok: true, successorId: "mem-2" });
8
+ });
9
+
10
+ test("empty successor id is missing_successor", () => {
11
+ assert.deepEqual(parseSuccessorId(""), { ok: false, error: "missing_successor" });
12
+ assert.deepEqual(parseSuccessorId(" "), { ok: false, error: "missing_successor" });
13
+ });
14
+
15
+ test("newline in successor id is invalid_successor", () => {
16
+ assert.deepEqual(parseSuccessorId("mem-1\nmem-2"), { ok: false, error: "invalid_successor" });
17
+ });
18
+
19
+ test("trims surrounding whitespace", () => {
20
+ assert.deepEqual(parseSuccessorId(" mem-2 "), { ok: true, successorId: "mem-2" });
21
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Recall state-view successor-id parse (issue #1952 leftover).
3
+ *
4
+ * Pure. Surfaces wait. Empty is missing_successor. Newline is invalid_successor.
5
+ */
6
+
7
+ export type ParseSuccessorIdResult =
8
+ | { ok: true; successorId: string }
9
+ | { ok: false; error: "missing_successor" | "invalid_successor" };
10
+
11
+ export function parseSuccessorId(value: string): ParseSuccessorIdResult {
12
+ const successorId = value.trim();
13
+ if (successorId.length === 0) return { ok: false, error: "missing_successor" };
14
+ if (successorId.includes("\n")) return { ok: false, error: "invalid_successor" };
15
+ return { ok: true, successorId };
16
+ }
@@ -0,0 +1,20 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseSupersededAt } from "./recall-state-view-superseded.js";
5
+
6
+ test("ok date returns canonical ISO supersededAt", () => {
7
+ assert.deepEqual(parseSupersededAt("2026-08-19T12:34:56.000Z"), {
8
+ ok: true,
9
+ supersededAt: "2026-08-19T12:34:56.000Z",
10
+ });
11
+ });
12
+
13
+ test("empty date is missing_date", () => {
14
+ assert.deepEqual(parseSupersededAt(""), { ok: false, error: "missing_date" });
15
+ assert.deepEqual(parseSupersededAt(" "), { ok: false, error: "missing_date" });
16
+ });
17
+
18
+ test("invalid date is invalid_date", () => {
19
+ assert.deepEqual(parseSupersededAt("not-a-date"), { ok: false, error: "invalid_date" });
20
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Recall state-view superseded-at parse (issue #1952 leftover).
3
+ *
4
+ * Pure. Surfaces wait. Empty is missing_date. Unparseable is invalid_date.
5
+ */
6
+
7
+ export type ParseSupersededAtResult =
8
+ | { ok: true; supersededAt: string }
9
+ | { ok: false; error: "missing_date" | "invalid_date" };
10
+
11
+ export function parseSupersededAt(value: string): ParseSupersededAtResult {
12
+ const trimmed = value.trim();
13
+ if (trimmed.length === 0) return { ok: false, error: "missing_date" };
14
+ const parsed = Date.parse(trimmed);
15
+ if (!Number.isFinite(parsed)) return { ok: false, error: "invalid_date" };
16
+ return { ok: true, supersededAt: new Date(parsed).toISOString() };
17
+ }
@@ -0,0 +1,30 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { assertTransitionHasSuccessor } from "./recall-state-view-transition.js";
5
+
6
+ test("transition plus empty successor id is transition_missing_successor", () => {
7
+ assert.deepEqual(assertTransitionHasSuccessor({ kind: "transition", successorId: "" }), {
8
+ ok: false,
9
+ error: "transition_missing_successor",
10
+ });
11
+ assert.deepEqual(assertTransitionHasSuccessor({ kind: "transition", successorId: " " }), {
12
+ ok: false,
13
+ error: "transition_missing_successor",
14
+ });
15
+ assert.deepEqual(assertTransitionHasSuccessor({ kind: "transition" }), {
16
+ ok: false,
17
+ error: "transition_missing_successor",
18
+ });
19
+ });
20
+
21
+ test("transition plus successor id is ok", () => {
22
+ assert.deepEqual(assertTransitionHasSuccessor({ kind: "transition", successorId: "mem-2" }), {
23
+ ok: true,
24
+ });
25
+ });
26
+
27
+ test("current plus empty successor id is ok", () => {
28
+ assert.deepEqual(assertTransitionHasSuccessor({ kind: "current", successorId: "" }), { ok: true });
29
+ assert.deepEqual(assertTransitionHasSuccessor({ kind: "current" }), { ok: true });
30
+ });
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Recall state-view transition-has-successor guard (issue #1952 leftover).
3
+ *
4
+ * Pure. Surfaces wait. Transition without a successor is transition_missing_successor.
5
+ */
6
+
7
+ export type AssertTransitionHasSuccessorInput = {
8
+ kind: string;
9
+ successorId?: string;
10
+ };
11
+
12
+ export type AssertTransitionHasSuccessorResult =
13
+ | { ok: true }
14
+ | { ok: false; error: "transition_missing_successor" };
15
+
16
+ export function assertTransitionHasSuccessor(
17
+ input: AssertTransitionHasSuccessorInput,
18
+ ): AssertTransitionHasSuccessorResult {
19
+ const successorId = input.successorId?.trim() ?? "";
20
+ if (input.kind === "transition" && successorId.length === 0) {
21
+ return { ok: false, error: "transition_missing_successor" };
22
+ }
23
+ return { ok: true };
24
+ }
@@ -0,0 +1,35 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import { checkAuthority } from "./authority.js";
5
+
6
+ test("checkAuthority rejects a missing actor", () => {
7
+ assert.deepEqual(checkAuthority({ actor: "", required: "agent-a" }), {
8
+ ok: false,
9
+ error: "missing_actor",
10
+ });
11
+ assert.deepEqual(checkAuthority({ required: "agent-a" }), {
12
+ ok: false,
13
+ error: "missing_actor",
14
+ });
15
+ assert.deepEqual(checkAuthority({ actor: " ", required: "agent-a" }), {
16
+ ok: false,
17
+ error: "missing_actor",
18
+ });
19
+ });
20
+
21
+ test("checkAuthority allows an empty required role", () => {
22
+ assert.deepEqual(checkAuthority({ actor: "agent-a", required: "" }), { ok: true });
23
+ assert.deepEqual(checkAuthority({ actor: "agent-a" }), { ok: true });
24
+ });
25
+
26
+ test("checkAuthority allows a matching actor", () => {
27
+ assert.deepEqual(checkAuthority({ actor: "agent-a", required: "agent-a" }), { ok: true });
28
+ });
29
+
30
+ test("checkAuthority rejects a mismatched actor", () => {
31
+ assert.deepEqual(checkAuthority({ actor: "agent-a", required: "agent-b" }), {
32
+ ok: false,
33
+ error: "forbidden",
34
+ });
35
+ });
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared-item actor authority (issue #1957).
3
+ *
4
+ * Pure helper. Empty required means no gate. Missing actor always fails.
5
+ */
6
+
7
+ export type AuthorityCheckError = "missing_actor" | "forbidden";
8
+
9
+ export type AuthorityCheck =
10
+ | { ok: true }
11
+ | { ok: false; error: AuthorityCheckError };
12
+
13
+ export interface CheckAuthorityInput {
14
+ actor?: string;
15
+ required?: string;
16
+ }
17
+
18
+ export function checkAuthority(input: CheckAuthorityInput): AuthorityCheck {
19
+ const actor = input.actor?.trim() ?? "";
20
+ if (actor.length === 0) return { ok: false, error: "missing_actor" };
21
+ const required = input.required?.trim() ?? "";
22
+ if (required.length === 0) return { ok: true };
23
+ if (actor !== required) return { ok: false, error: "forbidden" };
24
+ return { ok: true };
25
+ }
@@ -0,0 +1,21 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseClaimKey } from "./claim-key.js";
5
+
6
+ test("ok key returns trimmed key", () => {
7
+ assert.deepEqual(parseClaimKey("claim-a"), { ok: true, key: "claim-a" });
8
+ });
9
+
10
+ test("empty key is missing_key", () => {
11
+ assert.deepEqual(parseClaimKey(""), { ok: false, error: "missing_key" });
12
+ assert.deepEqual(parseClaimKey(" "), { ok: false, error: "missing_key" });
13
+ });
14
+
15
+ test("newline in key is invalid_key", () => {
16
+ assert.deepEqual(parseClaimKey("claim-a\nclaim-b"), { ok: false, error: "invalid_key" });
17
+ });
18
+
19
+ test("trims surrounding whitespace", () => {
20
+ assert.deepEqual(parseClaimKey(" claim-a "), { ok: true, key: "claim-a" });
21
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared-context claim key parse (issue #1957 leftover).
3
+ *
4
+ * Pure. Empty is missing_key. Newline is invalid_key.
5
+ */
6
+
7
+ export type ParseClaimKeyResult =
8
+ | { ok: true; key: string }
9
+ | { ok: false; error: "missing_key" | "invalid_key" };
10
+
11
+ export function parseClaimKey(value: string): ParseClaimKeyResult {
12
+ const key = value.trim();
13
+ if (key.length === 0) return { ok: false, error: "missing_key" };
14
+ if (key.includes("\n")) return { ok: false, error: "invalid_key" };
15
+ return { ok: true, key };
16
+ }
@@ -0,0 +1,39 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import {
5
+ detectContradictionPair,
6
+ type SharedClaimItem,
7
+ } from "./contradictions.js";
8
+
9
+ test("detectContradictionPair returns same for identical ids", () => {
10
+ const a: SharedClaimItem = { id: "item-1", claims: { host: "alpha" } };
11
+ const b: SharedClaimItem = { id: "item-1", claims: { host: "beta" } };
12
+
13
+ assert.deepEqual(detectContradictionPair(a, b), { kind: "same" });
14
+ });
15
+
16
+ test("detectContradictionPair returns conflict with the unequal overlapping keys", () => {
17
+ const a: SharedClaimItem = {
18
+ id: "item-1",
19
+ claims: { tier: "high", host: "alpha", region: "us" },
20
+ };
21
+ const b: SharedClaimItem = {
22
+ id: "item-2",
23
+ claims: { tier: "high", host: "beta", owner: "ops" },
24
+ };
25
+
26
+ assert.deepEqual(detectContradictionPair(a, b), {
27
+ kind: "conflict",
28
+ keys: ["host"],
29
+ });
30
+ });
31
+
32
+ test("detectContradictionPair returns none when overlap is absent or equal", () => {
33
+ const disjoint: SharedClaimItem = { id: "item-1", claims: { host: "alpha" } };
34
+ const other: SharedClaimItem = { id: "item-2", claims: { owner: "ops" } };
35
+ const agreeing: SharedClaimItem = { id: "item-3", claims: { host: "alpha" } };
36
+
37
+ assert.deepEqual(detectContradictionPair(disjoint, other), { kind: "none" });
38
+ assert.deepEqual(detectContradictionPair(disjoint, agreeing), { kind: "none" });
39
+ });
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Shared-item contradiction detection (issue #1957).
3
+ *
4
+ * Pure helper. Same-id items are one item; overlapping claim keys with
5
+ * unequal values are a conflict. No deletes, no persistence.
6
+ */
7
+
8
+ export interface SharedClaimItem {
9
+ id: string;
10
+ claims: Record<string, string>;
11
+ }
12
+
13
+ export type ContradictionPairResult =
14
+ | { kind: "same" }
15
+ | { kind: "conflict"; keys: string[] }
16
+ | { kind: "none" };
17
+
18
+ export function detectContradictionPair(
19
+ a: SharedClaimItem,
20
+ b: SharedClaimItem,
21
+ ): ContradictionPairResult {
22
+ if (a.id === b.id) {
23
+ return { kind: "same" };
24
+ }
25
+ const keys: string[] = [];
26
+ for (const key of Object.keys(a.claims)) {
27
+ if (key in b.claims && a.claims[key] !== b.claims[key]) {
28
+ keys.push(key);
29
+ }
30
+ }
31
+ return keys.length > 0 ? { kind: "conflict", keys: keys.sort() } : { kind: "none" };
32
+ }
@@ -0,0 +1,21 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseEnvelopeActor } from "./envelope-actor.js";
5
+
6
+ test("ok actor returns trimmed actor", () => {
7
+ assert.deepEqual(parseEnvelopeActor("agent-a"), { ok: true, actor: "agent-a" });
8
+ });
9
+
10
+ test("empty actor is missing_actor", () => {
11
+ assert.deepEqual(parseEnvelopeActor(""), { ok: false, error: "missing_actor" });
12
+ assert.deepEqual(parseEnvelopeActor(" "), { ok: false, error: "missing_actor" });
13
+ });
14
+
15
+ test("newline in actor is invalid_actor", () => {
16
+ assert.deepEqual(parseEnvelopeActor("agent-a\nagent-b"), { ok: false, error: "invalid_actor" });
17
+ });
18
+
19
+ test("trims surrounding whitespace", () => {
20
+ assert.deepEqual(parseEnvelopeActor(" agent-a "), { ok: true, actor: "agent-a" });
21
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared-item envelope actor parse (issue #1957 leftover).
3
+ *
4
+ * Pure. Empty is missing_actor. Newline is invalid_actor.
5
+ */
6
+
7
+ export type ParseEnvelopeActorResult =
8
+ | { ok: true; actor: string }
9
+ | { ok: false; error: "missing_actor" | "invalid_actor" };
10
+
11
+ export function parseEnvelopeActor(value: string): ParseEnvelopeActorResult {
12
+ const actor = value.trim();
13
+ if (actor.length === 0) return { ok: false, error: "missing_actor" };
14
+ if (actor.includes("\n")) return { ok: false, error: "invalid_actor" };
15
+ return { ok: true, actor };
16
+ }
@@ -0,0 +1,19 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseEnvelopeAt } from "./envelope-at.js";
5
+
6
+ const AT = "2026-08-18T12:00:00.000Z";
7
+
8
+ test("ok at returns ISO string", () => {
9
+ assert.deepEqual(parseEnvelopeAt(AT), { ok: true, at: AT });
10
+ });
11
+
12
+ test("empty at is missing_at", () => {
13
+ assert.deepEqual(parseEnvelopeAt(""), { ok: false, error: "missing_at" });
14
+ assert.deepEqual(parseEnvelopeAt(" "), { ok: false, error: "missing_at" });
15
+ });
16
+
17
+ test("invalid at is invalid_at", () => {
18
+ assert.deepEqual(parseEnvelopeAt("not-a-date"), { ok: false, error: "invalid_at" });
19
+ });
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Shared-item envelope at parse (issue #1957 leftover).
3
+ *
4
+ * Pure. Empty is missing_at. Invalid Date.parse is invalid_at.
5
+ */
6
+
7
+ export type ParseEnvelopeAtResult =
8
+ | { ok: true; at: string }
9
+ | { ok: false; error: "missing_at" | "invalid_at" };
10
+
11
+ export function parseEnvelopeAt(value: string): ParseEnvelopeAtResult {
12
+ const raw = value.trim();
13
+ if (raw.length === 0) return { ok: false, error: "missing_at" };
14
+ const ms = Date.parse(raw);
15
+ if (!Number.isFinite(ms)) return { ok: false, error: "invalid_at" };
16
+ return { ok: true, at: new Date(ms).toISOString() };
17
+ }
@@ -0,0 +1,21 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseEnvelopeId } from "./envelope-id.js";
5
+
6
+ test("ok id returns trimmed id", () => {
7
+ assert.deepEqual(parseEnvelopeId("item-a"), { ok: true, id: "item-a" });
8
+ });
9
+
10
+ test("empty id is missing_id", () => {
11
+ assert.deepEqual(parseEnvelopeId(""), { ok: false, error: "missing_id" });
12
+ assert.deepEqual(parseEnvelopeId(" "), { ok: false, error: "missing_id" });
13
+ });
14
+
15
+ test("newline in id is invalid_id", () => {
16
+ assert.deepEqual(parseEnvelopeId("item-a\nitem-b"), { ok: false, error: "invalid_id" });
17
+ });
18
+
19
+ test("trims surrounding whitespace", () => {
20
+ assert.deepEqual(parseEnvelopeId(" item-a "), { ok: true, id: "item-a" });
21
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared-item envelope id parse (issue #1957 leftover).
3
+ *
4
+ * Pure. Empty is missing_id. Newline is invalid_id.
5
+ */
6
+
7
+ export type ParseEnvelopeIdResult =
8
+ | { ok: true; id: string }
9
+ | { ok: false; error: "missing_id" | "invalid_id" };
10
+
11
+ export function parseEnvelopeId(value: string): ParseEnvelopeIdResult {
12
+ const id = value.trim();
13
+ if (id.length === 0) return { ok: false, error: "missing_id" };
14
+ if (id.includes("\n")) return { ok: false, error: "invalid_id" };
15
+ return { ok: true, id };
16
+ }
@@ -0,0 +1,24 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { parseRequiredActor } from "./envelope-required.js";
5
+
6
+ test("empty required actor is allowed", () => {
7
+ assert.deepEqual(parseRequiredActor(""), { ok: true, required: "" });
8
+ assert.deepEqual(parseRequiredActor(" "), { ok: true, required: "" });
9
+ });
10
+
11
+ test("ok required actor returns trimmed value", () => {
12
+ assert.deepEqual(parseRequiredActor("agent-a"), { ok: true, required: "agent-a" });
13
+ });
14
+
15
+ test("newline in required actor is invalid_required", () => {
16
+ assert.deepEqual(parseRequiredActor("agent-a\nagent-b"), {
17
+ ok: false,
18
+ error: "invalid_required",
19
+ });
20
+ });
21
+
22
+ test("trims surrounding whitespace", () => {
23
+ assert.deepEqual(parseRequiredActor(" agent-a "), { ok: true, required: "agent-a" });
24
+ });