@remnic/core 9.54.4 → 9.54.5

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 (526) hide show
  1. package/dist/access-admin-ops-surface.d.ts +12 -11
  2. package/dist/access-admin-ops-surface.js +46 -44
  3. package/dist/access-authorization-probe.d.ts +12 -11
  4. package/dist/access-authorization-probe.js +47 -45
  5. package/dist/access-boundary.d.ts +12 -11
  6. package/dist/access-boundary.js +46 -44
  7. package/dist/access-cli.js +92 -90
  8. package/dist/access-cli.js.map +1 -1
  9. package/dist/access-coding-context-resolution.d.ts +1 -1
  10. package/dist/access-extraction-force-flush.d.ts +12 -11
  11. package/dist/access-extraction-force-flush.js +46 -44
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-lcm-compaction.d.ts +12 -11
  14. package/dist/access-http-lifecycle-flush.d.ts +12 -11
  15. package/dist/access-http-offline-stream.d.ts +12 -11
  16. package/dist/access-http-query.js +46 -44
  17. package/dist/access-http.d.ts +12 -11
  18. package/dist/access-http.js +56 -54
  19. package/dist/access-identity-continuity-surface.d.ts +9 -9
  20. package/dist/access-identity-continuity-surface.js +46 -44
  21. package/dist/access-lcm-surface.d.ts +12 -11
  22. package/dist/access-lcm-surface.js +46 -44
  23. package/dist/access-mcp.d.ts +12 -11
  24. package/dist/access-mcp.js +52 -50
  25. package/dist/access-memory-search-fanout.d.ts +22 -2
  26. package/dist/access-memory-search-fanout.js +1 -1
  27. package/dist/{access-namespace-preflight-C7n4tgWC.d.ts → access-namespace-preflight-BdHlGd_T.d.ts} +1 -1
  28. package/dist/access-namespace-preflight.d.ts +3 -3
  29. package/dist/access-namespace-preflight.js +46 -44
  30. package/dist/access-observe-write-surface.d.ts +12 -11
  31. package/dist/access-observe-write-surface.js +46 -44
  32. package/dist/access-offline-manifest.d.ts +10 -9
  33. package/dist/access-offline-manifest.js +12 -10
  34. package/dist/access-operations-batch.js +48 -46
  35. package/dist/access-operations.d.ts +15 -14
  36. package/dist/access-operations.js +51 -49
  37. package/dist/access-recall-concurrency.d.ts +12 -11
  38. package/dist/access-recall-concurrency.js +46 -44
  39. package/dist/access-recall-response.d.ts +12 -11
  40. package/dist/access-recall-response.js +46 -44
  41. package/dist/access-recall-surface.d.ts +12 -11
  42. package/dist/access-recall-surface.js +46 -44
  43. package/dist/access-schema.d.ts +90 -90
  44. package/dist/access-schema.js +3 -2
  45. package/dist/{access-service-CXvbxLK-.d.ts → access-service-DL7X9hrg.d.ts} +7 -7
  46. package/dist/access-service-helpers.d.ts +12 -11
  47. package/dist/access-service.d.ts +12 -11
  48. package/dist/access-service.js +46 -44
  49. package/dist/access-surface-catalog.d.ts +12 -11
  50. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  51. package/dist/action-confidence.d.ts +1 -1
  52. package/dist/active-memory-bridge.d.ts +13 -1
  53. package/dist/active-memory-bridge.js +6 -1
  54. package/dist/active-recall.d.ts +1 -1
  55. package/dist/active-recall.js +3 -2
  56. package/dist/active-recall.js.map +1 -1
  57. package/dist/adapters/index.js +4 -4
  58. package/dist/adapters/registry.js +2 -2
  59. package/dist/ambient-provenance.d.ts +1 -1
  60. package/dist/artifact-search.d.ts +1 -1
  61. package/dist/behavior-learner.d.ts +1 -1
  62. package/dist/behavior-signals.d.ts +1 -1
  63. package/dist/bootstrap.d.ts +9 -9
  64. package/dist/briefing.d.ts +2 -2
  65. package/dist/briefing.js +30 -9
  66. package/dist/buffer-surprise-report.d.ts +1 -1
  67. package/dist/buffer-turn-helpers.d.ts +1 -1
  68. package/dist/buffer.d.ts +2 -2
  69. package/dist/buffer.js +3 -3
  70. package/dist/bulk-import/index.d.ts +3 -3
  71. package/dist/calibration.d.ts +1 -1
  72. package/dist/capabilities.d.ts +1 -1
  73. package/dist/{catalog-BOOxl-I2.d.ts → catalog-B90is4d8.d.ts} +1 -1
  74. package/dist/causal-behavior.d.ts +1 -1
  75. package/dist/causal-consolidation.d.ts +1 -1
  76. package/dist/causal-consolidation.js +31 -10
  77. package/dist/causal-consolidation.js.map +1 -1
  78. package/dist/causal-trajectory-graph.d.ts +1 -1
  79. package/dist/{chunk-6LAPLZOS.js → chunk-2DD6ZHOM.js} +8 -3
  80. package/dist/chunk-2DD6ZHOM.js.map +1 -0
  81. package/dist/{chunk-47P3RYZP.js → chunk-2INWPC6E.js} +2 -2
  82. package/dist/{chunk-3CSX3ETE.js → chunk-2LWQSV6A.js} +23 -11
  83. package/dist/chunk-2LWQSV6A.js.map +1 -0
  84. package/dist/{chunk-7BZOBA5J.js → chunk-2PNXOQ4P.js} +69 -11
  85. package/dist/chunk-2PNXOQ4P.js.map +1 -0
  86. package/dist/{chunk-WOPA3SGI.js → chunk-3OTSVCPK.js} +8 -8
  87. package/dist/{chunk-PX2LSHYM.js → chunk-3SXLD5T3.js} +3 -3
  88. package/dist/{chunk-T2JHZWH6.js → chunk-3WGI7F4V.js} +237 -93
  89. package/dist/chunk-3WGI7F4V.js.map +1 -0
  90. package/dist/{chunk-C4ZNGVK3.js → chunk-5JKUSBMX.js} +2 -2
  91. package/dist/{chunk-S75M5ZRK.js → chunk-6LEIWWAF.js} +16 -1
  92. package/dist/chunk-6LEIWWAF.js.map +1 -0
  93. package/dist/{chunk-MAXVH44E.js → chunk-6NNNURLK.js} +4 -4
  94. package/dist/{chunk-LJS7KUPV.js → chunk-6PZGKGAO.js} +2 -2
  95. package/dist/{chunk-YN6ASZUG.js → chunk-6QPI2ITJ.js} +5 -5
  96. package/dist/{chunk-CYF6WVE7.js → chunk-7HG7MGAP.js} +2688 -496
  97. package/dist/chunk-7HG7MGAP.js.map +1 -0
  98. package/dist/{chunk-CGVHPCP2.js → chunk-7Q7JWLQ4.js} +2 -2
  99. package/dist/{chunk-227UFSEQ.js → chunk-7RZJWZ46.js} +5 -5
  100. package/dist/{chunk-JBPKEARU.js → chunk-AU7Q3LSC.js} +4 -4
  101. package/dist/{chunk-PDDTI7IC.js → chunk-B4T3FQMT.js} +1 -1
  102. package/dist/{chunk-UU3G6GUP.js → chunk-BIF4SHMD.js} +1 -1
  103. package/dist/{chunk-UU3G6GUP.js.map → chunk-BIF4SHMD.js.map} +1 -1
  104. package/dist/{chunk-APPFNGX6.js → chunk-BSXGTDVJ.js} +2 -2
  105. package/dist/{chunk-4IIFL7GC.js → chunk-CLKBV3Z3.js} +10 -10
  106. package/dist/{chunk-ZYLC7NFO.js → chunk-CSY44OKU.js} +4 -4
  107. package/dist/{chunk-HLYR2TQL.js → chunk-CUTFSLSD.js} +2 -2
  108. package/dist/{chunk-RDJRFDJY.js → chunk-DBY26JJJ.js} +2 -2
  109. package/dist/{chunk-QWGE2PUH.js → chunk-DDA55IVB.js} +10 -10
  110. package/dist/{chunk-VMMQDEN5.js → chunk-DN2IDKI5.js} +2 -2
  111. package/dist/{chunk-2GFK22OZ.js → chunk-DOOWFDWN.js} +2 -2
  112. package/dist/{chunk-7FGL6CGA.js → chunk-DVYRD4HY.js} +2 -2
  113. package/dist/{chunk-YGLY6QFV.js → chunk-F2Y6I74C.js} +2 -2
  114. package/dist/{chunk-UU7TRFNE.js → chunk-FFEBSFVT.js} +2 -2
  115. package/dist/chunk-HNDIND7P.js +331 -0
  116. package/dist/chunk-HNDIND7P.js.map +1 -0
  117. package/dist/{chunk-NIS256NW.js → chunk-JKW663ZN.js} +2 -2
  118. package/dist/{chunk-G7A5HLUS.js → chunk-KJH6W2I7.js} +2 -2
  119. package/dist/{chunk-IXEBUYO4.js → chunk-KM55SMLG.js} +11 -2
  120. package/dist/{chunk-IXEBUYO4.js.map → chunk-KM55SMLG.js.map} +1 -1
  121. package/dist/{chunk-G2LUMAUF.js → chunk-L7RTUEDG.js} +12 -5
  122. package/dist/chunk-L7RTUEDG.js.map +1 -0
  123. package/dist/chunk-LC2BDILZ.js +57 -0
  124. package/dist/chunk-LC2BDILZ.js.map +1 -0
  125. package/dist/{chunk-JV5YUBIZ.js → chunk-LC3FD4BV.js} +52 -46
  126. package/dist/chunk-LC3FD4BV.js.map +1 -0
  127. package/dist/{chunk-HWRD23DW.js → chunk-LVKYLMSM.js} +3 -3
  128. package/dist/{chunk-RUMNY5DT.js → chunk-MRGJZ75M.js} +6 -2
  129. package/dist/chunk-MRGJZ75M.js.map +1 -0
  130. package/dist/{chunk-ZMYDYNI4.js → chunk-N7CXQ5TA.js} +4 -4
  131. package/dist/{chunk-3JLPGJ43.js → chunk-NGT35IGQ.js} +5 -5
  132. package/dist/{chunk-GUKBW4HL.js → chunk-NQMSEB5D.js} +6 -6
  133. package/dist/{chunk-WRJVB3C2.js → chunk-PO7NXBG2.js} +2 -2
  134. package/dist/{chunk-WM65LU67.js → chunk-QOQQMVR2.js} +2 -2
  135. package/dist/{chunk-QHFV6VNU.js → chunk-QPAQSG3F.js} +2 -2
  136. package/dist/{chunk-UTRO5UJU.js → chunk-QPW3PAIH.js} +5 -1
  137. package/dist/chunk-QPW3PAIH.js.map +1 -0
  138. package/dist/{chunk-6R4G7N4S.js → chunk-QQXWFDRD.js} +128 -74
  139. package/dist/chunk-QQXWFDRD.js.map +1 -0
  140. package/dist/{chunk-UES4BHA2.js → chunk-QTO6BMQZ.js} +2 -2
  141. package/dist/{chunk-THPPCISA.js → chunk-RBII7637.js} +5 -5
  142. package/dist/{chunk-QT2FRYI4.js → chunk-RG426DJO.js} +2 -2
  143. package/dist/{chunk-XUAMCLY4.js → chunk-TKFGFDPJ.js} +17 -13
  144. package/dist/chunk-TKFGFDPJ.js.map +1 -0
  145. package/dist/{chunk-VKXWK44Q.js → chunk-TY6MKIWP.js} +3 -3
  146. package/dist/{chunk-AZM4CCAC.js → chunk-UWJNKGBA.js} +5 -5
  147. package/dist/{chunk-JDZPNCMA.js → chunk-UYOXFFEY.js} +6 -3
  148. package/dist/chunk-UYOXFFEY.js.map +1 -0
  149. package/dist/{chunk-ZPJ4QSGP.js → chunk-VTU5IEKY.js} +2 -2
  150. package/dist/{chunk-RZ4XGKOJ.js → chunk-VYQ4URQB.js} +8 -8
  151. package/dist/{chunk-WDBX6VER.js → chunk-VZRFGJCH.js} +5 -5
  152. package/dist/{chunk-IBKR2TFR.js → chunk-WM5LD6AT.js} +2 -2
  153. package/dist/{chunk-K4QS7LXU.js → chunk-WZWZRZ2V.js} +2 -2
  154. package/dist/{chunk-G4T7L557.js → chunk-XKAR4RF6.js} +2 -2
  155. package/dist/{chunk-DZD576ZU.js → chunk-XSV2YDCJ.js} +2 -2
  156. package/dist/{chunk-G7Z6EENO.js → chunk-YDWPYDML.js} +4 -4
  157. package/dist/{chunk-6HPHEFXT.js → chunk-YKZLOPTC.js} +2 -2
  158. package/dist/{chunk-NH5IR2WM.js → chunk-YR65W7BV.js} +6 -2
  159. package/dist/chunk-YR65W7BV.js.map +1 -0
  160. package/dist/{chunk-GYPQL6XN.js → chunk-Z4N7SVVF.js} +35 -47
  161. package/dist/chunk-Z4N7SVVF.js.map +1 -0
  162. package/dist/{cli-DVUFIa5E.d.ts → cli-jfuZXixq.d.ts} +5 -5
  163. package/dist/cli.d.ts +14 -13
  164. package/dist/cli.js +74 -72
  165. package/dist/coding/pre-action-gate.d.ts +1 -1
  166. package/dist/compounding/engine.d.ts +2 -2
  167. package/dist/compounding/engine.js +30 -9
  168. package/dist/compounding/preference-consolidator.d.ts +1 -1
  169. package/dist/compression-optimizer.d.ts +1 -1
  170. package/dist/config.d.ts +1 -1
  171. package/dist/config.js +3 -2
  172. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  173. package/dist/connectors/codex-materialize-runner.js +30 -9
  174. package/dist/connectors/codex-materialize.d.ts +1 -1
  175. package/dist/connectors/index.d.ts +1 -1
  176. package/dist/connectors/index.js +29 -9
  177. package/dist/consolidation-provenance-check.d.ts +2 -2
  178. package/dist/consolidation-undo.d.ts +2 -2
  179. package/dist/contradiction/index.d.ts +2 -2
  180. package/dist/contradiction/index.js +3 -1
  181. package/dist/contradiction-scan-KCADHXPE.js +20 -0
  182. package/dist/converge-config.d.ts +1 -1
  183. package/dist/convergence-refresh.d.ts +2 -2
  184. package/dist/convergence-refresh.js +32 -11
  185. package/dist/conversation-index/backend.d.ts +1 -1
  186. package/dist/conversation-index/backend.js +2 -2
  187. package/dist/conversation-index/chunker.d.ts +1 -1
  188. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  189. package/dist/conversation-index/indexer.d.ts +1 -1
  190. package/dist/conversation-index/search.d.ts +1 -1
  191. package/dist/corpus-watermark.d.ts +1 -1
  192. package/dist/corpus-watermark.js +21 -20
  193. package/dist/day-summary.d.ts +1 -1
  194. package/dist/delinearize.d.ts +1 -1
  195. package/dist/dependency-propagation-config.d.ts +1 -1
  196. package/dist/{dependency-propagation-delivery-XzF76C9n.d.ts → dependency-propagation-delivery-CTDuAVJc.d.ts} +1 -1
  197. package/dist/direct-answer-wiring.d.ts +1 -1
  198. package/dist/direct-answer.d.ts +1 -1
  199. package/dist/embedding-fallback.d.ts +1 -1
  200. package/dist/enrichment/index.d.ts +1 -1
  201. package/dist/entity-retrieval.d.ts +2 -2
  202. package/dist/entity-retrieval.js +30 -9
  203. package/dist/entity-schema.d.ts +1 -1
  204. package/dist/explicit-capture.d.ts +9 -9
  205. package/dist/explicit-capture.js +6 -4
  206. package/dist/external-wiki-access.d.ts +12 -11
  207. package/dist/external-wiki-access.js +47 -45
  208. package/dist/external-wiki-collection-registration.d.ts +1 -1
  209. package/dist/external-wiki-collection.d.ts +1 -1
  210. package/dist/external-wiki-mcp-tools.d.ts +12 -11
  211. package/dist/extraction-error-classification.d.ts +1 -1
  212. package/dist/extraction-faithfulness.d.ts +1 -1
  213. package/dist/extraction-judge-telemetry.d.ts +1 -1
  214. package/dist/extraction-judge-training.d.ts +1 -1
  215. package/dist/extraction-judge.d.ts +1 -1
  216. package/dist/extraction-liveness.d.ts +1 -1
  217. package/dist/extraction-normalization.d.ts +1 -1
  218. package/dist/extraction-prompt.d.ts +1 -1
  219. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  220. package/dist/extraction-source-grounding.d.ts +1 -1
  221. package/dist/extraction.d.ts +1 -1
  222. package/dist/extraction.js +29 -13
  223. package/dist/fallback-llm.d.ts +1 -1
  224. package/dist/{first-start-migration-626C5554.js → first-start-migration-LMMZFLKK.js} +13 -5
  225. package/dist/first-start-migration-LMMZFLKK.js.map +1 -0
  226. package/dist/graph-dashboard-diff.d.ts +1 -1
  227. package/dist/graph-dashboard-key.d.ts +1 -1
  228. package/dist/graph-dashboard-parser.d.ts +1 -1
  229. package/dist/graph-edge-reinforcement.d.ts +1 -1
  230. package/dist/graph-path-reconstruction.d.ts +1 -1
  231. package/dist/graph-path-scoring.d.ts +1 -1
  232. package/dist/graph-snapshot.d.ts +1 -1
  233. package/dist/graph.d.ts +1 -1
  234. package/dist/harmonic-retrieval.js +1 -1
  235. package/dist/importance.d.ts +1 -1
  236. package/dist/importers/index.d.ts +1 -1
  237. package/dist/in-flight-reads.d.ts +1 -1
  238. package/dist/index.d.ts +1439 -716
  239. package/dist/index.js +207 -121
  240. package/dist/intent.d.ts +1 -1
  241. package/dist/lcm/engine.d.ts +1 -1
  242. package/dist/lcm/engine.js +2 -2
  243. package/dist/lcm/index.d.ts +1 -1
  244. package/dist/lcm/index.js +5 -5
  245. package/dist/lcm/tools.d.ts +1 -1
  246. package/dist/lifecycle.d.ts +1 -1
  247. package/dist/live-connectors-runner.d.ts +1 -1
  248. package/dist/local-llm.d.ts +1 -1
  249. package/dist/local-model-endpoint.d.ts +1 -1
  250. package/dist/maintenance/memory-governance.d.ts +1 -1
  251. package/dist/maintenance/memory-governance.js +30 -9
  252. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  253. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +30 -9
  254. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  255. package/dist/maintenance/rebuild-memory-projection.js +31 -10
  256. package/dist/{maintenance-BJzNIKBE.d.ts → maintenance-heMZSq7G.d.ts} +3 -3
  257. package/dist/mcp-memory-inspector-app.d.ts +12 -11
  258. package/dist/memory-action-policy.d.ts +1 -1
  259. package/dist/memory-cache.d.ts +1 -1
  260. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  261. package/dist/memory-projection-mutations.js +2 -2
  262. package/dist/memory-projection-store.d.ts +6 -2
  263. package/dist/memory-projection-store.js +1 -1
  264. package/dist/memory-provenance.d.ts +1 -1
  265. package/dist/memory-snapshot.d.ts +1 -1
  266. package/dist/memory-worth-outcomes.d.ts +2 -2
  267. package/dist/models-json.d.ts +1 -1
  268. package/dist/namespaces/migrate.d.ts +3 -3
  269. package/dist/namespaces/migrate.js +20 -19
  270. package/dist/namespaces/principal.d.ts +1 -1
  271. package/dist/namespaces/search.d.ts +1 -1
  272. package/dist/namespaces/search.js +6 -6
  273. package/dist/namespaces/storage.d.ts +3 -3
  274. package/dist/namespaces/storage.js +30 -9
  275. package/dist/native-knowledge.d.ts +1 -1
  276. package/dist/offline-sync-file-io.d.ts +20 -0
  277. package/dist/offline-sync-file-io.js +18 -0
  278. package/dist/offline-sync-file-io.js.map +1 -0
  279. package/dist/offline-sync-impression-drain.d.ts +1 -1
  280. package/dist/offline-sync-impression-drain.js +5 -5
  281. package/dist/offline-sync.d.ts +8 -6
  282. package/dist/offline-sync.js +2 -1
  283. package/dist/operator-doctor-corpus.d.ts +1 -1
  284. package/dist/operator-doctor-corpus.js +22 -21
  285. package/dist/operator-doctor-replica.d.ts +1 -1
  286. package/dist/operator-toolkit.d.ts +3 -3
  287. package/dist/operator-toolkit.js +34 -32
  288. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  289. package/dist/orchestration/maintenance.d.ts +4 -4
  290. package/dist/orchestration/maintenance.js +35 -15
  291. package/dist/{orchestrator-BiXgBJBQ.d.ts → orchestrator-BQQPsSjs.d.ts} +11 -8
  292. package/dist/orchestrator.d.ts +9 -9
  293. package/dist/orchestrator.js +93 -91
  294. package/dist/patterns-cli.d.ts +1 -1
  295. package/dist/{pipeline-sz_dcuLg.d.ts → pipeline-DFfmsnGk.d.ts} +1 -1
  296. package/dist/policy-runtime.d.ts +1 -1
  297. package/dist/proactive-contention.d.ts +1 -1
  298. package/dist/provenance.d.ts +1 -1
  299. package/dist/{purge-533FZLS4.js → purge-GB7PZHT2.js} +2 -2
  300. package/dist/{qmd-eAWObK4M.d.ts → qmd-BF5bcVRs.d.ts} +1 -1
  301. package/dist/qmd-preflight.d.ts +2 -2
  302. package/dist/qmd-recall-cache.d.ts +1 -1
  303. package/dist/qmd.d.ts +2 -2
  304. package/dist/recall-concurrency-config.d.ts +1 -1
  305. package/dist/recall-disclosure-escalation.d.ts +1 -1
  306. package/dist/recall-explain-renderer.d.ts +1 -1
  307. package/dist/recall-explain-renderer.js +3 -3
  308. package/dist/recall-memory-map.d.ts +1 -1
  309. package/dist/recall-planner-llm.d.ts +1 -1
  310. package/dist/recall-state.d.ts +1 -1
  311. package/dist/recall-tag-filter.d.ts +1 -1
  312. package/dist/recall-timings.d.ts +1 -1
  313. package/dist/recall-xray-cli.d.ts +1 -1
  314. package/dist/recall-xray-cli.js +4 -4
  315. package/dist/recall-xray-renderer.d.ts +1 -1
  316. package/dist/recall-xray-renderer.js +3 -3
  317. package/dist/recall-xray.d.ts +1 -1
  318. package/dist/recall-xray.js +2 -2
  319. package/dist/reconcile/cursor.d.ts +2 -1
  320. package/dist/reconcile/manifest.d.ts +2 -1
  321. package/dist/reconcile/manifest.js +6 -5
  322. package/dist/reconcile/plan.d.ts +2 -1
  323. package/dist/reconcile/plan.js +3 -2
  324. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  325. package/dist/replay/normalizers/claude.d.ts +1 -1
  326. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  327. package/dist/replay/normalizers/shared.d.ts +1 -1
  328. package/dist/replay/runner.d.ts +1 -1
  329. package/dist/replay/types.d.ts +1 -1
  330. package/dist/replica-divergence.d.ts +1 -1
  331. package/dist/replica-peers-config.d.ts +1 -1
  332. package/dist/resolve-auth-token.d.ts +1 -1
  333. package/dist/resume-bundles.js +4 -3
  334. package/dist/retrieval-agents.d.ts +2 -2
  335. package/dist/retrieval-tiers.d.ts +1 -1
  336. package/dist/routing/engine.d.ts +1 -1
  337. package/dist/routing/store.d.ts +1 -1
  338. package/dist/salvage-envelope.d.ts +1 -1
  339. package/dist/schemas.d.ts +138 -138
  340. package/dist/{scope-profiles-BBQsXuyj.d.ts → scope-profiles-CbUOsE_E.d.ts} +1 -1
  341. package/dist/search/embed-helper.d.ts +1 -1
  342. package/dist/search/factory.d.ts +1 -1
  343. package/dist/search/factory.js +4 -4
  344. package/dist/search/index.d.ts +1 -1
  345. package/dist/search/index.js +6 -6
  346. package/dist/search/lancedb-backend.d.ts +1 -1
  347. package/dist/search/meilisearch-backend.d.ts +1 -1
  348. package/dist/search/noop-backend.d.ts +1 -1
  349. package/dist/search/orama-backend.d.ts +1 -1
  350. package/dist/search/port.d.ts +1 -1
  351. package/dist/search/remote-backend.d.ts +1 -1
  352. package/dist/{semantic-consolidation-HD8RkzVA.d.ts → semantic-consolidation-DAB3xdKM.d.ts} +1 -1
  353. package/dist/semantic-consolidation.d.ts +2 -2
  354. package/dist/semantic-consolidation.js +31 -10
  355. package/dist/semantic-rule-promotion.js +30 -9
  356. package/dist/semantic-rule-verifier.d.ts +1 -1
  357. package/dist/semantic-rule-verifier.js +30 -9
  358. package/dist/{service-DIrtHHEg.d.ts → service-DGKg2O6r.d.ts} +2 -2
  359. package/dist/session-observer-bands.d.ts +1 -1
  360. package/dist/session-observer-state.d.ts +1 -1
  361. package/dist/shared-context/manager.d.ts +9 -9
  362. package/dist/signal.d.ts +1 -1
  363. package/dist/source-agent-qualifier.d.ts +1 -1
  364. package/dist/source-agent-qualifier.js +28 -12
  365. package/dist/{storage-DqCzXi56.d.ts → storage-CC1jKcWg.d.ts} +46 -13
  366. package/dist/storage.d.ts +2 -2
  367. package/dist/storage.js +30 -9
  368. package/dist/summarizer.d.ts +1 -1
  369. package/dist/summary-snapshot.d.ts +1 -1
  370. package/dist/temporal-supersession.d.ts +2 -2
  371. package/dist/temporal-timeline-recall.d.ts +1 -1
  372. package/dist/temporal-validity.d.ts +1 -1
  373. package/dist/threading.d.ts +1 -1
  374. package/dist/tier-migration.d.ts +2 -2
  375. package/dist/tier-routing.d.ts +2 -2
  376. package/dist/tier-routing.js +7 -1
  377. package/dist/{tier-stats-2JCZYEF7.js → tier-stats-JDN6HRNT.js} +8 -2
  378. package/dist/{tier-stats-2JCZYEF7.js.map → tier-stats-JDN6HRNT.js.map} +1 -1
  379. package/dist/topics.d.ts +1 -1
  380. package/dist/transcript.d.ts +1 -1
  381. package/dist/transfer/types.d.ts +66 -66
  382. package/dist/trust-score-stage.d.ts +1 -1
  383. package/dist/trust-score.d.ts +1 -1
  384. package/dist/{types-d_j4vC6N.d.ts → types-BnQza1y8.d.ts} +2 -1
  385. package/dist/types.d.ts +1 -1
  386. package/dist/types.js +1 -1
  387. package/dist/utility-runtime.d.ts +2 -2
  388. package/dist/verified-recall.js +30 -9
  389. package/dist/write-envelope.d.ts +1 -1
  390. package/package.json +2 -2
  391. package/src/access-http.test.ts +31 -0
  392. package/src/access-memory-search-fanout.ts +24 -1
  393. package/src/access-offline-manifest.ts +5 -0
  394. package/src/access-service-namespace.test.ts +14 -0
  395. package/src/access-service-observe-scope.test.ts +2 -0
  396. package/src/access-service-offline-file-content.test.ts +211 -0
  397. package/src/access-service.ts +20 -43
  398. package/src/active-memory-bridge.test.ts +151 -0
  399. package/src/active-memory-bridge.ts +87 -11
  400. package/src/briefing.test.ts +38 -0
  401. package/src/briefing.ts +3 -3
  402. package/src/cli.ts +6 -1
  403. package/src/connectors/codex-materialize-runner.ts +2 -0
  404. package/src/contradiction/contradiction-scan.ts +2 -0
  405. package/src/contradiction/contradiction.test.ts +42 -0
  406. package/src/correction/correction-access-wiring.ts +8 -2
  407. package/src/correction/correction-storage-integration.test.ts +7 -0
  408. package/src/explicit-capture.test.ts +24 -0
  409. package/src/explicit-capture.ts +2 -0
  410. package/src/index.ts +3 -0
  411. package/src/maintenance/first-start-migration.ts +2 -1
  412. package/src/maintenance/memory-governance.test.ts +25 -0
  413. package/src/maintenance/memory-governance.ts +4 -1
  414. package/src/maintenance/pattern-reinforcement.test.ts +20 -0
  415. package/src/maintenance/pattern-reinforcement.ts +2 -1
  416. package/src/maintenance/rebuild-memory-projection.ts +8 -8
  417. package/src/memory-projection-store.ts +25 -27
  418. package/src/offline-sync-file-io.ts +68 -0
  419. package/src/offline-sync.ts +43 -57
  420. package/src/orchestration/consolidation-run.ts +5 -4
  421. package/src/orchestration/contradiction-linking-coordinator.ts +7 -0
  422. package/src/orchestration/contradiction-localization.integration.test.ts +115 -0
  423. package/src/orchestration/lifecycle-policy-coordinator.ts +2 -1
  424. package/src/orchestration/qmd-result-resolver.test.ts +215 -14
  425. package/src/orchestration/qmd-result-resolver.ts +142 -82
  426. package/src/orchestration/recall-search-pipeline.test.ts +41 -0
  427. package/src/orchestration/recall-search-pipeline.ts +12 -0
  428. package/src/orchestration/semantic-consolidation-coordinator.ts +2 -1
  429. package/src/orchestration/tier-migration-coordinator.ts +23 -56
  430. package/src/orchestration/workspace-ops.test.ts +37 -0
  431. package/src/orchestration/workspace-ops.ts +5 -29
  432. package/src/orchestrator.ts +7 -8
  433. package/src/storage/supersession-audit.ts +7 -1
  434. package/src/storage/supersession-side-effects.ts +17 -5
  435. package/src/storage.ts +18 -19
  436. package/src/support-passport/card-projection.test.ts +129 -0
  437. package/src/support-passport/card-projection.ts +287 -0
  438. package/src/support-passport/card-service.test.ts +2462 -0
  439. package/src/support-passport/card-service.ts +1042 -0
  440. package/src/support-passport/contracts.test.ts +143 -0
  441. package/src/support-passport/contracts.ts +136 -0
  442. package/src/support-passport/errors.ts +24 -0
  443. package/src/support-passport/grant-contracts.ts +139 -0
  444. package/src/support-passport/grant-service-cache.test.ts +148 -0
  445. package/src/support-passport/grant-service-cancellation.test.ts +81 -0
  446. package/src/support-passport/grant-service.test.ts +2882 -0
  447. package/src/support-passport/grant-service.ts +364 -0
  448. package/src/support-passport/grant-store-commit-hook.test.ts +123 -0
  449. package/src/support-passport/grant-store-order.test.ts +60 -0
  450. package/src/support-passport/grant-store-path-safety.test.ts +30 -0
  451. package/src/support-passport/grant-store-recovery.test.ts +448 -0
  452. package/src/support-passport/grant-store.ts +902 -0
  453. package/src/support-passport/index.ts +7 -0
  454. package/src/support-passport/offline-sync-guard.ts +230 -0
  455. package/src/support-passport/owner-lock.ts +53 -0
  456. package/src/support-passport/private-file.ts +371 -0
  457. package/src/tier-routing.ts +28 -17
  458. package/src/training-export/converter.test.ts +24 -0
  459. package/src/training-export/converter.ts +2 -0
  460. package/src/types.ts +1 -1
  461. package/src/wearables/service.test.ts +13 -0
  462. package/src/wearables/service.ts +2 -0
  463. package/dist/chunk-3CSX3ETE.js.map +0 -1
  464. package/dist/chunk-6LAPLZOS.js.map +0 -1
  465. package/dist/chunk-6R4G7N4S.js.map +0 -1
  466. package/dist/chunk-7BZOBA5J.js.map +0 -1
  467. package/dist/chunk-CYF6WVE7.js.map +0 -1
  468. package/dist/chunk-G2LUMAUF.js.map +0 -1
  469. package/dist/chunk-GYPQL6XN.js.map +0 -1
  470. package/dist/chunk-JDZPNCMA.js.map +0 -1
  471. package/dist/chunk-JV5YUBIZ.js.map +0 -1
  472. package/dist/chunk-NH5IR2WM.js.map +0 -1
  473. package/dist/chunk-RUMNY5DT.js.map +0 -1
  474. package/dist/chunk-S75M5ZRK.js.map +0 -1
  475. package/dist/chunk-T2JHZWH6.js.map +0 -1
  476. package/dist/chunk-UTRO5UJU.js.map +0 -1
  477. package/dist/chunk-XUAMCLY4.js.map +0 -1
  478. package/dist/contradiction-scan-HYLIRMJ2.js +0 -14
  479. package/dist/first-start-migration-626C5554.js.map +0 -1
  480. /package/dist/{chunk-47P3RYZP.js.map → chunk-2INWPC6E.js.map} +0 -0
  481. /package/dist/{chunk-WOPA3SGI.js.map → chunk-3OTSVCPK.js.map} +0 -0
  482. /package/dist/{chunk-PX2LSHYM.js.map → chunk-3SXLD5T3.js.map} +0 -0
  483. /package/dist/{chunk-C4ZNGVK3.js.map → chunk-5JKUSBMX.js.map} +0 -0
  484. /package/dist/{chunk-MAXVH44E.js.map → chunk-6NNNURLK.js.map} +0 -0
  485. /package/dist/{chunk-LJS7KUPV.js.map → chunk-6PZGKGAO.js.map} +0 -0
  486. /package/dist/{chunk-YN6ASZUG.js.map → chunk-6QPI2ITJ.js.map} +0 -0
  487. /package/dist/{chunk-CGVHPCP2.js.map → chunk-7Q7JWLQ4.js.map} +0 -0
  488. /package/dist/{chunk-227UFSEQ.js.map → chunk-7RZJWZ46.js.map} +0 -0
  489. /package/dist/{chunk-JBPKEARU.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  490. /package/dist/{chunk-PDDTI7IC.js.map → chunk-B4T3FQMT.js.map} +0 -0
  491. /package/dist/{chunk-APPFNGX6.js.map → chunk-BSXGTDVJ.js.map} +0 -0
  492. /package/dist/{chunk-4IIFL7GC.js.map → chunk-CLKBV3Z3.js.map} +0 -0
  493. /package/dist/{chunk-ZYLC7NFO.js.map → chunk-CSY44OKU.js.map} +0 -0
  494. /package/dist/{chunk-HLYR2TQL.js.map → chunk-CUTFSLSD.js.map} +0 -0
  495. /package/dist/{chunk-RDJRFDJY.js.map → chunk-DBY26JJJ.js.map} +0 -0
  496. /package/dist/{chunk-QWGE2PUH.js.map → chunk-DDA55IVB.js.map} +0 -0
  497. /package/dist/{chunk-VMMQDEN5.js.map → chunk-DN2IDKI5.js.map} +0 -0
  498. /package/dist/{chunk-2GFK22OZ.js.map → chunk-DOOWFDWN.js.map} +0 -0
  499. /package/dist/{chunk-7FGL6CGA.js.map → chunk-DVYRD4HY.js.map} +0 -0
  500. /package/dist/{chunk-YGLY6QFV.js.map → chunk-F2Y6I74C.js.map} +0 -0
  501. /package/dist/{chunk-UU7TRFNE.js.map → chunk-FFEBSFVT.js.map} +0 -0
  502. /package/dist/{chunk-NIS256NW.js.map → chunk-JKW663ZN.js.map} +0 -0
  503. /package/dist/{chunk-G7A5HLUS.js.map → chunk-KJH6W2I7.js.map} +0 -0
  504. /package/dist/{chunk-HWRD23DW.js.map → chunk-LVKYLMSM.js.map} +0 -0
  505. /package/dist/{chunk-ZMYDYNI4.js.map → chunk-N7CXQ5TA.js.map} +0 -0
  506. /package/dist/{chunk-3JLPGJ43.js.map → chunk-NGT35IGQ.js.map} +0 -0
  507. /package/dist/{chunk-GUKBW4HL.js.map → chunk-NQMSEB5D.js.map} +0 -0
  508. /package/dist/{chunk-WRJVB3C2.js.map → chunk-PO7NXBG2.js.map} +0 -0
  509. /package/dist/{chunk-WM65LU67.js.map → chunk-QOQQMVR2.js.map} +0 -0
  510. /package/dist/{chunk-QHFV6VNU.js.map → chunk-QPAQSG3F.js.map} +0 -0
  511. /package/dist/{chunk-UES4BHA2.js.map → chunk-QTO6BMQZ.js.map} +0 -0
  512. /package/dist/{chunk-THPPCISA.js.map → chunk-RBII7637.js.map} +0 -0
  513. /package/dist/{chunk-QT2FRYI4.js.map → chunk-RG426DJO.js.map} +0 -0
  514. /package/dist/{chunk-VKXWK44Q.js.map → chunk-TY6MKIWP.js.map} +0 -0
  515. /package/dist/{chunk-AZM4CCAC.js.map → chunk-UWJNKGBA.js.map} +0 -0
  516. /package/dist/{chunk-ZPJ4QSGP.js.map → chunk-VTU5IEKY.js.map} +0 -0
  517. /package/dist/{chunk-RZ4XGKOJ.js.map → chunk-VYQ4URQB.js.map} +0 -0
  518. /package/dist/{chunk-WDBX6VER.js.map → chunk-VZRFGJCH.js.map} +0 -0
  519. /package/dist/{chunk-IBKR2TFR.js.map → chunk-WM5LD6AT.js.map} +0 -0
  520. /package/dist/{chunk-K4QS7LXU.js.map → chunk-WZWZRZ2V.js.map} +0 -0
  521. /package/dist/{chunk-G4T7L557.js.map → chunk-XKAR4RF6.js.map} +0 -0
  522. /package/dist/{chunk-DZD576ZU.js.map → chunk-XSV2YDCJ.js.map} +0 -0
  523. /package/dist/{chunk-G7Z6EENO.js.map → chunk-YDWPYDML.js.map} +0 -0
  524. /package/dist/{chunk-6HPHEFXT.js.map → chunk-YKZLOPTC.js.map} +0 -0
  525. /package/dist/{contradiction-scan-HYLIRMJ2.js.map → contradiction-scan-KCADHXPE.js.map} +0 -0
  526. /package/dist/{purge-533FZLS4.js.map → purge-GB7PZHT2.js.map} +0 -0
@@ -0,0 +1,448 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, readFile, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+
7
+ import { SupportPassportError } from "./errors.js";
8
+ import { SupportPassportGrantStore } from "./grant-store.js";
9
+
10
+ test("a final stale owner-index write cannot hide a peer grant", async () => {
11
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-final-recovery-"));
12
+ try {
13
+ const grantIds = ["00000000-0000-4000-8000-000000000001", "00000000-0000-4000-8000-000000000002"];
14
+ const peerGrantId = "00000000-0000-4000-8000-000000000003";
15
+ const now = new Date("2026-08-11T12:00:00.000Z");
16
+ const store = new SupportPassportGrantStore({
17
+ memoryDir: root,
18
+ makeGrantId: () => grantIds.shift() ?? "00000000-0000-4000-8000-000000000004",
19
+ now: () => now,
20
+ });
21
+ const input = {
22
+ namespace: "alice",
23
+ principal: "owner:alice",
24
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
25
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
26
+ };
27
+ const first = await store.create(input);
28
+ const peerState = {
29
+ ...first.state,
30
+ grantId: peerGrantId,
31
+ secretHash: "b".repeat(64),
32
+ };
33
+ const inspected = store as unknown as {
34
+ withOwnerIndexLock<T>(ownerHash: string, task: (lock: { refresh(): Promise<boolean> }) => Promise<T>): Promise<T>;
35
+ writeOwnerIndex(ownerHash: string, indexedGrantIds: string[]): Promise<void>;
36
+ writeState(state: typeof peerState, requireAbsent: boolean): Promise<void>;
37
+ writeOwnerMembership(state: typeof peerState): Promise<void>;
38
+ };
39
+ const writeOwnerIndex = inspected.writeOwnerIndex.bind(store);
40
+ let ownerIndexWrites = 0;
41
+ inspected.writeOwnerIndex = async (ownerHash, indexedGrantIds) => {
42
+ ownerIndexWrites += 1;
43
+ if (ownerIndexWrites === 3) {
44
+ await inspected.writeState(peerState, true);
45
+ await inspected.writeOwnerMembership(peerState);
46
+ await writeOwnerIndex(ownerHash, [...indexedGrantIds, peerGrantId]);
47
+ }
48
+ await writeOwnerIndex(ownerHash, indexedGrantIds);
49
+ };
50
+ let ownerLockRuns = 0;
51
+ inspected.withOwnerIndexLock = async (_ownerHash, task) => {
52
+ ownerLockRuns += 1;
53
+ let refreshes = 0;
54
+ return await task({
55
+ refresh: async () => {
56
+ refreshes += 1;
57
+ return refreshes === 1;
58
+ },
59
+ });
60
+ };
61
+
62
+ await assert.rejects(
63
+ store.create(input),
64
+ (error: unknown) => error instanceof SupportPassportError && error.code === "storage_conflict"
65
+ );
66
+
67
+ assert.equal(ownerLockRuns, 4);
68
+ assert.equal(ownerIndexWrites, 4);
69
+ assert.deepEqual(
70
+ new Set((await store.listForOwner(input.namespace, input.principal)).map((state) => state.grantId)),
71
+ new Set([first.state.grantId, peerGrantId])
72
+ );
73
+ } finally {
74
+ await rm(root, { recursive: true, force: true });
75
+ }
76
+ });
77
+
78
+ test("owner membership enforces capacity when the derived index is stale", async () => {
79
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-cap-recovery-"));
80
+ try {
81
+ const now = new Date("2026-08-11T12:00:00.000Z");
82
+ let nextGrantId = 1;
83
+ const grantId = (value: number) => `00000000-0000-4000-8000-${String(value).padStart(12, "0")}`;
84
+ const store = new SupportPassportGrantStore({
85
+ memoryDir: root,
86
+ makeGrantId: () => grantId(nextGrantId++),
87
+ now: () => now,
88
+ });
89
+ const input = {
90
+ namespace: "alice",
91
+ principal: "owner:alice",
92
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
93
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
94
+ };
95
+ const first = await store.create(input);
96
+ const inspected = store as unknown as {
97
+ ownerHash(namespace: string, principalHash: string): string;
98
+ writeState(state: typeof first.state, requireAbsent: boolean): Promise<void>;
99
+ writeOwnerMembership(state: typeof first.state): Promise<void>;
100
+ writeOwnerIndex(ownerHash: string, indexedGrantIds: string[]): Promise<void>;
101
+ };
102
+ const states = [first.state];
103
+ for (let index = 2; index <= 100; index += 1) {
104
+ const state = { ...first.state, grantId: grantId(index) };
105
+ await inspected.writeState(state, true);
106
+ await inspected.writeOwnerMembership(state);
107
+ states.push(state);
108
+ }
109
+ nextGrantId = 101;
110
+ const ownerHash = inspected.ownerHash(first.state.namespace, first.state.principalHash);
111
+ await inspected.writeOwnerIndex(
112
+ ownerHash,
113
+ states.slice(0, 99).map((state) => state.grantId)
114
+ );
115
+
116
+ await assert.rejects(
117
+ store.create(input),
118
+ (error: unknown) => error instanceof SupportPassportError && error.code === "invalid_input"
119
+ );
120
+ const listed = await store.listForOwner(input.namespace, input.principal);
121
+ assert.equal(listed.length, 100);
122
+ assert.equal(
123
+ listed.some((state) => state.grantId === grantId(101)),
124
+ false
125
+ );
126
+ } finally {
127
+ await rm(root, { recursive: true, force: true });
128
+ }
129
+ });
130
+
131
+ test("an owner can list every active grant while repairing an overflow", async () => {
132
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-list-overflow-"));
133
+ try {
134
+ const now = new Date("2026-08-11T12:00:00.000Z");
135
+ const store = new SupportPassportGrantStore({ memoryDir: root, now: () => now });
136
+ const created = await store.create({
137
+ namespace: "alice",
138
+ principal: "owner:alice",
139
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
140
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
141
+ });
142
+ const states = Array.from({ length: 101 }, (_, index) => ({
143
+ ...created.state,
144
+ grantId: `00000000-0000-4000-8000-${String(index + 1).padStart(12, "0")}`,
145
+ }));
146
+ const inspected = store as unknown as {
147
+ readOwnerMembershipStates(namespace: string, principalHash: string): Promise<typeof states>;
148
+ };
149
+ inspected.readOwnerMembershipStates = async () => states;
150
+
151
+ const listed = await store.listForOwner("alice", "owner:alice");
152
+
153
+ assert.equal(listed.length, 101);
154
+ assert.equal(listed.every((state) => !state.revokedAt), true);
155
+ } finally {
156
+ await rm(root, { recursive: true, force: true });
157
+ }
158
+ });
159
+
160
+ test("overflow recovery locks a committed grant before removing it", async () => {
161
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-locked-overflow-"));
162
+ try {
163
+ const now = new Date("2026-08-11T12:00:00.000Z");
164
+ const store = new SupportPassportGrantStore({ memoryDir: root, now: () => now });
165
+ const committed = await store.create({
166
+ namespace: "alice",
167
+ principal: "owner:alice",
168
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
169
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
170
+ });
171
+ const states = Array.from({ length: 101 }, (_, index) => ({
172
+ ...committed.state,
173
+ grantId: index === 0
174
+ ? committed.state.grantId
175
+ : `00000000-0000-4000-8000-${String(index + 1).padStart(12, "0")}`,
176
+ }));
177
+ const lockedGrantIds: string[] = [];
178
+ const removedGrantIds: string[] = [];
179
+ const inspected = store as unknown as {
180
+ reconcileCommittedGrant(
181
+ value: typeof committed,
182
+ ownerHash: string,
183
+ lock: { refresh(): Promise<boolean> },
184
+ ): Promise<typeof committed>;
185
+ readState(grantId: string): Promise<typeof committed.state>;
186
+ readOwnerMembershipStates(namespace: string, principalHash: string): Promise<typeof states>;
187
+ withGrantLock<T>(
188
+ grantId: string,
189
+ task: (lock: { refresh(): Promise<boolean> }) => Promise<T>,
190
+ ): Promise<T>;
191
+ removeStoredGrant(state: typeof committed.state): Promise<void>;
192
+ writeOwnerIndexWhileLocked(): Promise<void>;
193
+ };
194
+ inspected.readState = async () => committed.state;
195
+ inspected.readOwnerMembershipStates = async () => states;
196
+ inspected.withGrantLock = async (grantId, task) => {
197
+ lockedGrantIds.push(grantId);
198
+ return await task({ refresh: async () => true });
199
+ };
200
+ inspected.removeStoredGrant = async (state) => {
201
+ removedGrantIds.push(state.grantId);
202
+ };
203
+ inspected.writeOwnerIndexWhileLocked = async () => undefined;
204
+
205
+ await assert.rejects(
206
+ inspected.reconcileCommittedGrant(committed, "a".repeat(64), { refresh: async () => true }),
207
+ (error: unknown) => error instanceof SupportPassportError && error.code === "storage_conflict",
208
+ );
209
+
210
+ assert.deepEqual(lockedGrantIds, [committed.state.grantId]);
211
+ assert.deepEqual(removedGrantIds, [committed.state.grantId]);
212
+ } finally {
213
+ await rm(root, { recursive: true, force: true });
214
+ }
215
+ });
216
+
217
+ test("recovery keeps a committed grant when stale history cleanup fails", async () => {
218
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-cleanup-isolation-"));
219
+ try {
220
+ const now = new Date("2026-08-11T12:00:00.000Z");
221
+ const store = new SupportPassportGrantStore({ memoryDir: root, now: () => now });
222
+ const committed = await store.create({
223
+ namespace: "alice",
224
+ principal: "owner:alice",
225
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
226
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
227
+ });
228
+ const inactiveStates = Array.from({ length: 100 }, (_, index) => ({
229
+ ...committed.state,
230
+ grantId: `00000000-0000-4000-8000-${String(index + 2).padStart(12, "0")}`,
231
+ stateVersion: 2,
232
+ revokedAt: now.toISOString(),
233
+ }));
234
+ const cleanupAttempts: string[] = [];
235
+ const inspected = store as unknown as {
236
+ reconcileCommittedGrant(
237
+ value: typeof committed,
238
+ ownerHash: string,
239
+ lock: { refresh(): Promise<boolean> },
240
+ ): Promise<typeof committed>;
241
+ readState(grantId: string): Promise<typeof committed.state>;
242
+ readOwnerMembershipStates(
243
+ namespace: string,
244
+ principalHash: string,
245
+ ): Promise<Array<typeof committed.state>>;
246
+ withGrantLock<T>(
247
+ grantId: string,
248
+ task: (lock: { refresh(): Promise<boolean> }) => Promise<T>,
249
+ ): Promise<T>;
250
+ removeStoredGrant(state: typeof committed.state): Promise<void>;
251
+ writeOwnerIndexWhileLocked(): Promise<void>;
252
+ };
253
+ inspected.readState = async () => committed.state;
254
+ inspected.readOwnerMembershipStates = async () => [committed.state, ...inactiveStates];
255
+ inspected.withGrantLock = async (grantId, task) => {
256
+ cleanupAttempts.push(grantId);
257
+ return await task({ refresh: async () => true });
258
+ };
259
+ inspected.removeStoredGrant = async () => {
260
+ throw new Error("simulated stale history cleanup failure");
261
+ };
262
+ inspected.writeOwnerIndexWhileLocked = async () => undefined;
263
+
264
+ const result = await inspected.reconcileCommittedGrant(
265
+ committed,
266
+ "a".repeat(64),
267
+ { refresh: async () => true },
268
+ );
269
+
270
+ assert.equal(result.state.grantId, committed.state.grantId);
271
+ assert.equal(cleanupAttempts.length, 1);
272
+ } finally {
273
+ await rm(root, { recursive: true, force: true });
274
+ }
275
+ });
276
+
277
+ test("an owner list ignores a stale derived index", async () => {
278
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-list-recovery-"));
279
+ try {
280
+ const grantIds = ["00000000-0000-4000-8000-000000000001", "00000000-0000-4000-8000-000000000002"];
281
+ const now = new Date("2026-08-11T12:00:00.000Z");
282
+ const store = new SupportPassportGrantStore({
283
+ memoryDir: root,
284
+ makeGrantId: () => grantIds.shift() ?? "00000000-0000-4000-8000-000000000003",
285
+ now: () => now,
286
+ });
287
+ const input = {
288
+ namespace: "alice",
289
+ principal: "owner:alice",
290
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
291
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
292
+ };
293
+ const first = await store.create(input);
294
+ const second = await store.create(input);
295
+ const inspected = store as unknown as {
296
+ ownerHash(namespace: string, principalHash: string): string;
297
+ writeOwnerIndex(ownerHash: string, indexedGrantIds: string[]): Promise<void>;
298
+ };
299
+ const ownerHash = inspected.ownerHash(first.state.namespace, first.state.principalHash);
300
+ await inspected.writeOwnerIndex(ownerHash, [first.state.grantId]);
301
+
302
+ assert.deepEqual(
303
+ new Set((await store.listForOwner(input.namespace, input.principal)).map((state) => state.grantId)),
304
+ new Set([first.state.grantId, second.state.grantId])
305
+ );
306
+ } finally {
307
+ await rm(root, { recursive: true, force: true });
308
+ }
309
+ });
310
+
311
+ test("a later create rebuilds the derived index from owner membership", async () => {
312
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-index-rebuild-"));
313
+ try {
314
+ const grantIds = ["00000000-0000-4000-8000-000000000001", "00000000-0000-4000-8000-000000000002"];
315
+ const peerGrantId = "00000000-0000-4000-8000-000000000003";
316
+ const now = new Date("2026-08-11T12:00:00.000Z");
317
+ const store = new SupportPassportGrantStore({
318
+ memoryDir: root,
319
+ makeGrantId: () => grantIds.shift() ?? "00000000-0000-4000-8000-000000000004",
320
+ now: () => now,
321
+ });
322
+ const input = {
323
+ namespace: "alice",
324
+ principal: "owner:alice",
325
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
326
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
327
+ };
328
+ const first = await store.create(input);
329
+ const peerState = {
330
+ ...first.state,
331
+ grantId: peerGrantId,
332
+ secretHash: "b".repeat(64),
333
+ };
334
+ const inspected = store as unknown as {
335
+ ownerHash(namespace: string, principalHash: string): string;
336
+ writeState(state: typeof peerState, requireAbsent: boolean): Promise<void>;
337
+ writeOwnerMembership(state: typeof peerState): Promise<void>;
338
+ writeOwnerIndex(ownerHash: string, indexedGrantIds: string[]): Promise<void>;
339
+ };
340
+ await inspected.writeState(peerState, true);
341
+ await inspected.writeOwnerMembership(peerState);
342
+ const ownerHash = inspected.ownerHash(first.state.namespace, first.state.principalHash);
343
+ await inspected.writeOwnerIndex(ownerHash, [first.state.grantId]);
344
+
345
+ const second = await store.create(input);
346
+ const indexPath = path.join(root, "state", "support-passport", "grants", "owners", `${ownerHash}.json`);
347
+ const derivedIndex = JSON.parse(await readFile(indexPath, "utf8")) as { grantIds: string[] };
348
+
349
+ assert.deepEqual(new Set(derivedIndex.grantIds), new Set([first.state.grantId, second.state.grantId, peerGrantId]));
350
+ } finally {
351
+ await rm(root, { recursive: true, force: true });
352
+ }
353
+ });
354
+
355
+ test("concurrent owner creates reserve capacity before writing membership", async () => {
356
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-concurrent-cap-"));
357
+ try {
358
+ const now = new Date("2026-08-11T12:00:00.000Z");
359
+ let nextGrantId = 1;
360
+ const store = new SupportPassportGrantStore({
361
+ memoryDir: root,
362
+ makeGrantId: () => `00000000-0000-4000-8000-${String(nextGrantId++).padStart(12, "0")}`,
363
+ now: () => now,
364
+ });
365
+ const input = {
366
+ namespace: "alice",
367
+ principal: "owner:alice",
368
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
369
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
370
+ };
371
+
372
+ const first = await store.create(input);
373
+ const inspected = store as unknown as {
374
+ writeState(state: typeof first.state, requireAbsent: boolean): Promise<void>;
375
+ writeOwnerMembership(state: typeof first.state): Promise<void>;
376
+ };
377
+ for (let index = 2; index <= 99; index += 1) {
378
+ const state = {
379
+ ...first.state,
380
+ grantId: `00000000-0000-4000-8000-${String(index).padStart(12, "0")}`,
381
+ };
382
+ await inspected.writeState(state, true);
383
+ await inspected.writeOwnerMembership(state);
384
+ }
385
+ nextGrantId = 100;
386
+
387
+ const results = await Promise.allSettled([store.create(input), store.create(input)]);
388
+ const fulfilled = results.filter((result) => result.status === "fulfilled");
389
+ const rejected = results.filter((result) => result.status === "rejected");
390
+
391
+ assert.equal(fulfilled.length, 1);
392
+ assert.equal(rejected.length, 1);
393
+ assert.ok(
394
+ rejected.every(
395
+ (result) => result.reason instanceof SupportPassportError && result.reason.code === "invalid_input",
396
+ ),
397
+ );
398
+ assert.equal((await store.listForOwner(input.namespace, input.principal)).length, 100);
399
+ } finally {
400
+ await rm(root, { recursive: true, force: true });
401
+ }
402
+ });
403
+
404
+ test("owner-index recovery removes history entries beyond the retained set", async () => {
405
+ const root = await mkdtemp(path.join(tmpdir(), "remnic-support-grant-overflow-recovery-"));
406
+ try {
407
+ const now = new Date("2026-08-11T12:00:00.000Z");
408
+ const store = new SupportPassportGrantStore({
409
+ memoryDir: root,
410
+ makeGrantId: () => "00000000-0000-4000-8000-000000000001",
411
+ now: () => now,
412
+ });
413
+ const input = {
414
+ namespace: "alice",
415
+ principal: "owner:alice",
416
+ cards: [{ cardId: "card-1", revision: "a".repeat(64) }],
417
+ expiresAt: new Date(now.getTime() + 3_600_000).toISOString(),
418
+ };
419
+ const committed = await store.create(input);
420
+ const inspected = store as unknown as {
421
+ ownerHash(namespace: string, principalHash: string): string;
422
+ writeState(state: typeof committed.state, requireAbsent: boolean): Promise<void>;
423
+ writeOwnerMembership(state: typeof committed.state): Promise<void>;
424
+ reconcileCommittedGrant(
425
+ value: typeof committed,
426
+ ownerHash: string,
427
+ lock: { refresh(): Promise<boolean> },
428
+ ): Promise<typeof committed>;
429
+ };
430
+ for (let index = 2; index <= 101; index += 1) {
431
+ const state = {
432
+ ...committed.state,
433
+ grantId: `00000000-0000-4000-8000-${String(index).padStart(12, "0")}`,
434
+ stateVersion: 2,
435
+ revokedAt: now.toISOString(),
436
+ };
437
+ await inspected.writeState(state, true);
438
+ await inspected.writeOwnerMembership(state);
439
+ }
440
+ const ownerHash = inspected.ownerHash(committed.state.namespace, committed.state.principalHash);
441
+
442
+ await inspected.reconcileCommittedGrant(committed, ownerHash, { refresh: async () => true });
443
+
444
+ assert.equal((await store.listForOwner(input.namespace, input.principal)).length, 100);
445
+ } finally {
446
+ await rm(root, { recursive: true, force: true });
447
+ }
448
+ });