@remnic/core 9.54.5 → 9.54.7

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 (548) hide show
  1. package/dist/access-admin-ops-surface.d.ts +24 -24
  2. package/dist/access-admin-ops-surface.js +32 -29
  3. package/dist/access-authorization-probe.d.ts +25 -23
  4. package/dist/access-authorization-probe.js +35 -30
  5. package/dist/access-boundary.d.ts +26 -24
  6. package/dist/access-boundary.js +36 -31
  7. package/dist/access-cli.js +86 -80
  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 +19 -19
  11. package/dist/access-extraction-force-flush.js +32 -29
  12. package/dist/access-health-types.d.ts +1 -1
  13. package/dist/access-http-lcm-compaction.d.ts +22 -22
  14. package/dist/access-http-lifecycle-flush.d.ts +22 -22
  15. package/dist/access-http-offline-stream.d.ts +18 -18
  16. package/dist/access-http-query.js +32 -29
  17. package/dist/access-http.d.ts +55 -37
  18. package/dist/access-http.js +52 -43
  19. package/dist/access-identity-continuity-surface.d.ts +9 -9
  20. package/dist/access-identity-continuity-surface.js +32 -29
  21. package/dist/access-lcm-surface.d.ts +21 -21
  22. package/dist/access-lcm-surface.js +32 -29
  23. package/dist/access-mcp.d.ts +22 -22
  24. package/dist/access-mcp.js +40 -36
  25. package/dist/access-memory-search-fanout.d.ts +2 -2
  26. package/dist/{access-namespace-preflight-BdHlGd_T.d.ts → access-namespace-preflight-CCNn_6NE.d.ts} +1 -1
  27. package/dist/access-namespace-preflight.d.ts +3 -3
  28. package/dist/access-namespace-preflight.js +32 -29
  29. package/dist/access-observe-write-surface.d.ts +22 -22
  30. package/dist/access-observe-write-surface.js +32 -29
  31. package/dist/access-offline-manifest.d.ts +9 -9
  32. package/dist/access-offline-manifest.js +2 -2
  33. package/dist/access-operations-batch.js +34 -31
  34. package/dist/access-operations.d.ts +23 -23
  35. package/dist/access-operations.js +38 -34
  36. package/dist/access-recall-concurrency.d.ts +21 -21
  37. package/dist/access-recall-concurrency.js +32 -29
  38. package/dist/access-recall-response.d.ts +19 -19
  39. package/dist/access-recall-response.js +32 -29
  40. package/dist/access-recall-surface.d.ts +19 -19
  41. package/dist/access-recall-surface.js +32 -29
  42. package/dist/access-schema.js +3 -3
  43. package/dist/{access-service-DL7X9hrg.d.ts → access-service-DK82xdNi.d.ts} +1314 -83
  44. package/dist/access-service-helpers.d.ts +22 -22
  45. package/dist/access-service.d.ts +31 -31
  46. package/dist/access-service.js +32 -29
  47. package/dist/access-surface-catalog.d.ts +22 -22
  48. package/dist/access-surface-catalog.js +209 -2
  49. package/dist/access-surface-catalog.js.map +1 -1
  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 +6 -5
  53. package/dist/active-memory-bridge.js +2 -2
  54. package/dist/active-recall.d.ts +1 -1
  55. package/dist/active-recall.js +2 -1
  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/admin-console/public/what-helps-me/app.js +1594 -0
  60. package/dist/admin-console/public/what-helps-me/index.html +339 -0
  61. package/dist/admin-console/public/what-helps-me/model.js +685 -0
  62. package/dist/admin-console/public/what-helps-me/what-helps-me.css +1296 -0
  63. package/dist/ambient-provenance.d.ts +1 -1
  64. package/dist/artifact-search.d.ts +1 -1
  65. package/dist/{auto-sync-TDHLZPVP.js → auto-sync-NR3GPCOA.js} +4 -4
  66. package/dist/behavior-learner.d.ts +1 -1
  67. package/dist/behavior-signals.d.ts +1 -1
  68. package/dist/bootstrap.d.ts +9 -9
  69. package/dist/briefing.d.ts +2 -2
  70. package/dist/briefing.js +14 -14
  71. package/dist/buffer-surprise-report.d.ts +1 -1
  72. package/dist/buffer-turn-helpers.d.ts +1 -1
  73. package/dist/buffer.d.ts +2 -2
  74. package/dist/buffer.js +2 -2
  75. package/dist/bulk-import/index.d.ts +3 -3
  76. package/dist/calibration.d.ts +1 -1
  77. package/dist/calibration.js +1 -1
  78. package/dist/capabilities.d.ts +1 -1
  79. package/dist/{catalog-B90is4d8.d.ts → catalog-DGFf8mD9.d.ts} +1 -1
  80. package/dist/causal-behavior.d.ts +1 -1
  81. package/dist/causal-consolidation.d.ts +1 -1
  82. package/dist/causal-consolidation.js +15 -15
  83. package/dist/causal-trajectory-graph.d.ts +1 -1
  84. package/dist/{chunk-CSY44OKU.js → chunk-26ZXBTYN.js} +4 -4
  85. package/dist/chunk-26ZXBTYN.js.map +1 -0
  86. package/dist/{chunk-LLJMAULE.js → chunk-2FKEIPIT.js} +5 -5
  87. package/dist/{chunk-AU7Q3LSC.js → chunk-2QSZNTDO.js} +4 -4
  88. package/dist/chunk-37DZZFFM.js +502 -0
  89. package/dist/chunk-37DZZFFM.js.map +1 -0
  90. package/dist/chunk-3HSRWJTC.js +9 -0
  91. package/dist/chunk-3HSRWJTC.js.map +1 -0
  92. package/dist/{chunk-TKFGFDPJ.js → chunk-3TIZPSJC.js} +4 -4
  93. package/dist/{chunk-B4T3FQMT.js → chunk-43SEBY2M.js} +1 -1
  94. package/dist/{chunk-LVKYLMSM.js → chunk-46SZBVDS.js} +2 -2
  95. package/dist/{chunk-YKZLOPTC.js → chunk-5FD7JMTX.js} +2 -2
  96. package/dist/{chunk-2PNXOQ4P.js → chunk-5NB726GV.js} +3 -7
  97. package/dist/chunk-5NB726GV.js.map +1 -0
  98. package/dist/chunk-62OKGIJA.js +39 -0
  99. package/dist/chunk-62OKGIJA.js.map +1 -0
  100. package/dist/{chunk-WM5LD6AT.js → chunk-6CYHUWCO.js} +2 -2
  101. package/dist/{chunk-BIF4SHMD.js → chunk-76JJSXK7.js} +1 -1
  102. package/dist/chunk-76JJSXK7.js.map +1 -0
  103. package/dist/{chunk-3SXLD5T3.js → chunk-7BD6O7ZV.js} +189 -4
  104. package/dist/chunk-7BD6O7ZV.js.map +1 -0
  105. package/dist/chunk-7TBXNYLO.js +346 -0
  106. package/dist/chunk-7TBXNYLO.js.map +1 -0
  107. package/dist/{chunk-YR65W7BV.js → chunk-BRR5EUTF.js} +3 -3
  108. package/dist/{chunk-JKW663ZN.js → chunk-CIAI24TQ.js} +2 -2
  109. package/dist/{chunk-3WGI7F4V.js → chunk-D3LBIUWV.js} +9219 -5233
  110. package/dist/chunk-D3LBIUWV.js.map +1 -0
  111. package/dist/{chunk-YDWPYDML.js → chunk-EKTP7MNS.js} +4 -4
  112. package/dist/{chunk-6LEIWWAF.js → chunk-F2JRDPON.js} +2 -2
  113. package/dist/{chunk-VYQ4URQB.js → chunk-FFRTNF3L.js} +2 -2
  114. package/dist/{chunk-TY6MKIWP.js → chunk-FONWBCVY.js} +3 -3
  115. package/dist/{chunk-XSV2YDCJ.js → chunk-FPLM2TKD.js} +2 -2
  116. package/dist/{chunk-VTU5IEKY.js → chunk-FTPONF6B.js} +2 -2
  117. package/dist/{chunk-6PZGKGAO.js → chunk-FWX7W5PM.js} +2 -2
  118. package/dist/{chunk-QPW3PAIH.js → chunk-G6DFSS6A.js} +2 -2
  119. package/dist/{chunk-2DD6ZHOM.js → chunk-GJ776BC2.js} +3 -3
  120. package/dist/{chunk-XKAR4RF6.js → chunk-GN3WRFJY.js} +6 -6
  121. package/dist/{chunk-RG426DJO.js → chunk-H7NAZ3UB.js} +2 -2
  122. package/dist/{chunk-BSXGTDVJ.js → chunk-HBUFQRIM.js} +2 -2
  123. package/dist/{chunk-FFEBSFVT.js → chunk-HGJ6NJ4E.js} +2 -2
  124. package/dist/{chunk-WB7JSQCP.js → chunk-HIEWDJ2O.js} +5 -2
  125. package/dist/{chunk-WB7JSQCP.js.map → chunk-HIEWDJ2O.js.map} +1 -1
  126. package/dist/{chunk-QTO6BMQZ.js → chunk-I3MSGFGD.js} +17 -6
  127. package/dist/chunk-I3MSGFGD.js.map +1 -0
  128. package/dist/{chunk-5JKUSBMX.js → chunk-IKP5OYQQ.js} +2 -2
  129. package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
  130. package/dist/{chunk-DBY26JJJ.js → chunk-IQ4NVWEF.js} +2 -2
  131. package/dist/{chunk-7Q7JWLQ4.js → chunk-JYG4OLWH.js} +2 -2
  132. package/dist/{chunk-3OTSVCPK.js → chunk-K26NWEOC.js} +4 -4
  133. package/dist/{chunk-WZWZRZ2V.js → chunk-K2UGPTYY.js} +484 -43
  134. package/dist/chunk-K2UGPTYY.js.map +1 -0
  135. package/dist/{chunk-L6CQ7WIW.js → chunk-KFBOPMF6.js} +11 -11
  136. package/dist/chunk-KFBOPMF6.js.map +1 -0
  137. package/dist/{chunk-HOIRB77A.js → chunk-L6Z5OAS4.js} +2 -2
  138. package/dist/{chunk-7RZJWZ46.js → chunk-LEPOP46W.js} +5 -5
  139. package/dist/{chunk-QQXWFDRD.js → chunk-M4YHAODQ.js} +270 -684
  140. package/dist/chunk-M4YHAODQ.js.map +1 -0
  141. package/dist/{chunk-NGT35IGQ.js → chunk-MIH3CJPN.js} +3 -3
  142. package/dist/{chunk-QPAQSG3F.js → chunk-MK5VEWCR.js} +2 -2
  143. package/dist/chunk-NISZQW72.js +140 -0
  144. package/dist/chunk-NISZQW72.js.map +1 -0
  145. package/dist/{chunk-L7RTUEDG.js → chunk-OCIP6YMD.js} +2 -2
  146. package/dist/{chunk-2INWPC6E.js → chunk-PG4QBPVG.js} +20 -10
  147. package/dist/chunk-PG4QBPVG.js.map +1 -0
  148. package/dist/{chunk-DDA55IVB.js → chunk-PT54WISF.js} +189 -55
  149. package/dist/chunk-PT54WISF.js.map +1 -0
  150. package/dist/{chunk-UWJNKGBA.js → chunk-QZLDRQ4I.js} +5 -5
  151. package/dist/{chunk-UYOXFFEY.js → chunk-RUNORG2P.js} +3 -3
  152. package/dist/{chunk-LC3FD4BV.js → chunk-RZQ6W2W4.js} +39 -39
  153. package/dist/{chunk-MRGJZ75M.js → chunk-SMNYAMJD.js} +3 -3
  154. package/dist/{chunk-MKQBXQKU.js → chunk-TB6CBZ5V.js} +22 -15
  155. package/dist/chunk-TB6CBZ5V.js.map +1 -0
  156. package/dist/{chunk-DN2IDKI5.js → chunk-TO7ZTWJW.js} +2 -2
  157. package/dist/{chunk-K2TDK7GG.js → chunk-TWTUGCTY.js} +2 -2
  158. package/dist/{chunk-CUTFSLSD.js → chunk-UCTS3DDH.js} +2 -2
  159. package/dist/{chunk-JYIJNNN3.js → chunk-UG6VXIOK.js} +2 -2
  160. package/dist/{chunk-QOQQMVR2.js → chunk-UKYS3NU5.js} +2 -2
  161. package/dist/{chunk-VZRFGJCH.js → chunk-UPLZNJKN.js} +2 -2
  162. package/dist/{chunk-C23BYTJV.js → chunk-UW5NPZJ2.js} +40 -12
  163. package/dist/chunk-UW5NPZJ2.js.map +1 -0
  164. package/dist/{chunk-DOOWFDWN.js → chunk-V6ERBR7U.js} +2 -2
  165. package/dist/{chunk-7HG7MGAP.js → chunk-W5ZKPI34.js} +462 -2673
  166. package/dist/chunk-W5ZKPI34.js.map +1 -0
  167. package/dist/{chunk-HNDIND7P.js → chunk-XX4HPFFM.js} +54 -15
  168. package/dist/chunk-XX4HPFFM.js.map +1 -0
  169. package/dist/{chunk-N7CXQ5TA.js → chunk-XZHE2DEN.js} +1 -1
  170. package/dist/chunk-YXQEKCZM.js +223 -0
  171. package/dist/chunk-YXQEKCZM.js.map +1 -0
  172. package/dist/{chunk-6NNNURLK.js → chunk-Z54EM5YZ.js} +4 -4
  173. package/dist/{chunk-F2Y6I74C.js → chunk-ZRZVLB7O.js} +2 -2
  174. package/dist/{chunk-CLKBV3Z3.js → chunk-ZUKIUXHQ.js} +9 -9
  175. package/dist/{cli-jfuZXixq.d.ts → cli-BPDUXnAl.d.ts} +5 -5
  176. package/dist/cli.d.ts +22 -22
  177. package/dist/cli.js +66 -58
  178. package/dist/coding/pre-action-gate.d.ts +1 -1
  179. package/dist/compounding/engine.d.ts +2 -2
  180. package/dist/compounding/engine.js +14 -14
  181. package/dist/compounding/preference-consolidator.d.ts +1 -1
  182. package/dist/compression-optimizer.d.ts +1 -1
  183. package/dist/config.d.ts +1 -1
  184. package/dist/config.js +2 -1
  185. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  186. package/dist/connectors/codex-materialize-runner.js +14 -14
  187. package/dist/connectors/codex-materialize.d.ts +1 -1
  188. package/dist/connectors/index.d.ts +1 -1
  189. package/dist/connectors/index.js +14 -14
  190. package/dist/consolidation-provenance-check.d.ts +2 -2
  191. package/dist/consolidation-undo.d.ts +2 -2
  192. package/dist/contradiction/index.d.ts +2 -2
  193. package/dist/contradiction/index.js +2 -2
  194. package/dist/{contradiction-scan-KCADHXPE.js → contradiction-scan-JDTBXRGW.js} +3 -3
  195. package/dist/converge-config.d.ts +1 -1
  196. package/dist/convergence-refresh.d.ts +2 -2
  197. package/dist/convergence-refresh.js +16 -16
  198. package/dist/conversation-index/backend.d.ts +1 -1
  199. package/dist/conversation-index/backend.js +2 -2
  200. package/dist/conversation-index/chunker.d.ts +1 -1
  201. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  202. package/dist/conversation-index/indexer.d.ts +1 -1
  203. package/dist/conversation-index/search.d.ts +1 -1
  204. package/dist/corpus-watermark.d.ts +1 -1
  205. package/dist/corpus-watermark.js +16 -16
  206. package/dist/day-summary.d.ts +1 -1
  207. package/dist/delinearize.d.ts +1 -1
  208. package/dist/dependency-propagation-config.d.ts +1 -1
  209. package/dist/{dependency-propagation-delivery-CTDuAVJc.d.ts → dependency-propagation-delivery-CzEfB31P.d.ts} +1 -1
  210. package/dist/direct-answer-wiring.d.ts +1 -1
  211. package/dist/direct-answer.d.ts +1 -1
  212. package/dist/embedding-fallback.d.ts +1 -1
  213. package/dist/enrichment/index.d.ts +1 -1
  214. package/dist/entity-retrieval.d.ts +2 -2
  215. package/dist/entity-retrieval.js +14 -14
  216. package/dist/entity-schema.d.ts +1 -1
  217. package/dist/explicit-capture.d.ts +9 -9
  218. package/dist/explicit-capture.js +4 -3
  219. package/dist/external-wiki-access.d.ts +22 -22
  220. package/dist/external-wiki-access.js +33 -30
  221. package/dist/external-wiki-collection-registration.d.ts +1 -1
  222. package/dist/external-wiki-collection.d.ts +1 -1
  223. package/dist/external-wiki-mcp-tools.d.ts +22 -22
  224. package/dist/extraction-error-classification.d.ts +1 -1
  225. package/dist/extraction-faithfulness.d.ts +1 -1
  226. package/dist/extraction-faithfulness.js +2 -2
  227. package/dist/extraction-judge-telemetry.d.ts +1 -1
  228. package/dist/extraction-judge-training.d.ts +1 -1
  229. package/dist/extraction-judge.d.ts +1 -1
  230. package/dist/extraction-judge.js +2 -2
  231. package/dist/extraction-liveness.d.ts +1 -1
  232. package/dist/extraction-normalization.d.ts +1 -1
  233. package/dist/extraction-prompt.d.ts +1 -1
  234. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  235. package/dist/extraction-source-grounding.d.ts +1 -1
  236. package/dist/extraction.d.ts +1 -1
  237. package/dist/extraction.js +20 -20
  238. package/dist/fallback-llm.d.ts +14 -1
  239. package/dist/fallback-llm.js +1 -1
  240. package/dist/{first-start-migration-LMMZFLKK.js → first-start-migration-CRZCZAJN.js} +5 -5
  241. package/dist/graph-dashboard-diff.d.ts +1 -1
  242. package/dist/graph-dashboard-key.d.ts +1 -1
  243. package/dist/graph-dashboard-parser.d.ts +1 -1
  244. package/dist/graph-edge-reinforcement.d.ts +1 -1
  245. package/dist/graph-path-reconstruction.d.ts +1 -1
  246. package/dist/graph-path-scoring.d.ts +1 -1
  247. package/dist/graph-snapshot.d.ts +1 -1
  248. package/dist/graph.d.ts +1 -1
  249. package/dist/harmonic-retrieval.js +1 -1
  250. package/dist/importance.d.ts +1 -1
  251. package/dist/importers/index.d.ts +1 -1
  252. package/dist/in-flight-reads.d.ts +1 -1
  253. package/dist/index.d.ts +30 -747
  254. package/dist/index.js +203 -118
  255. package/dist/inline-script.d.ts +3 -0
  256. package/dist/inline-script.js +8 -0
  257. package/dist/inline-script.js.map +1 -0
  258. package/dist/intent.d.ts +1 -1
  259. package/dist/lcm/engine.d.ts +1 -1
  260. package/dist/lcm/engine.js +2 -2
  261. package/dist/lcm/index.d.ts +1 -1
  262. package/dist/lcm/index.js +2 -2
  263. package/dist/lcm/tools.d.ts +1 -1
  264. package/dist/lifecycle.d.ts +1 -1
  265. package/dist/live-connectors-runner.d.ts +1 -1
  266. package/dist/local-llm.d.ts +2 -1
  267. package/dist/local-llm.js +2 -2
  268. package/dist/local-model-endpoint.d.ts +1 -1
  269. package/dist/maintenance/memory-governance.d.ts +1 -1
  270. package/dist/maintenance/memory-governance.js +14 -14
  271. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  272. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
  273. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  274. package/dist/maintenance/rebuild-memory-projection.js +15 -15
  275. package/dist/{maintenance-heMZSq7G.d.ts → maintenance-C8aRWfhq.d.ts} +3 -3
  276. package/dist/mcp-memory-inspector-app.d.ts +22 -22
  277. package/dist/mcp-read-only-tools.js +1 -1
  278. package/dist/memory-action-policy.d.ts +1 -1
  279. package/dist/memory-cache.d.ts +1 -1
  280. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  281. package/dist/memory-projection-store.d.ts +1 -1
  282. package/dist/memory-provenance.d.ts +1 -1
  283. package/dist/memory-snapshot.d.ts +1 -1
  284. package/dist/memory-worth-outcomes.d.ts +2 -2
  285. package/dist/models-json.d.ts +1 -1
  286. package/dist/namespaces/migrate.d.ts +3 -3
  287. package/dist/namespaces/migrate.js +15 -15
  288. package/dist/namespaces/principal.d.ts +1 -1
  289. package/dist/namespaces/search.d.ts +1 -1
  290. package/dist/namespaces/search.js +6 -6
  291. package/dist/namespaces/storage.d.ts +3 -3
  292. package/dist/namespaces/storage.js +14 -14
  293. package/dist/native-knowledge.d.ts +1 -1
  294. package/dist/offline-sync-impression-drain.d.ts +1 -1
  295. package/dist/operator-doctor-corpus.d.ts +1 -1
  296. package/dist/operator-doctor-corpus.js +17 -17
  297. package/dist/operator-doctor-replica.d.ts +1 -1
  298. package/dist/operator-toolkit.d.ts +3 -3
  299. package/dist/operator-toolkit.js +23 -22
  300. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  301. package/dist/orchestration/maintenance.d.ts +4 -4
  302. package/dist/orchestration/maintenance.js +19 -19
  303. package/dist/{orchestrator-BQQPsSjs.d.ts → orchestrator-D85CzDDY.d.ts} +8 -8
  304. package/dist/orchestrator.d.ts +9 -9
  305. package/dist/orchestrator.js +86 -80
  306. package/dist/patterns-cli.d.ts +1 -1
  307. package/dist/{pipeline-DFfmsnGk.d.ts → pipeline-DPcUifCO.d.ts} +1 -1
  308. package/dist/policy-runtime.d.ts +1 -1
  309. package/dist/proactive-contention.d.ts +1 -1
  310. package/dist/provenance.d.ts +1 -1
  311. package/dist/public-http-D3GBeII4.d.ts +25 -0
  312. package/dist/{qmd-BF5bcVRs.d.ts → qmd-dFCHp1r0.d.ts} +1 -1
  313. package/dist/qmd-preflight.d.ts +2 -2
  314. package/dist/qmd-recall-cache.d.ts +1 -1
  315. package/dist/qmd.d.ts +2 -2
  316. package/dist/recall-concurrency-config.d.ts +1 -1
  317. package/dist/recall-disclosure-escalation.d.ts +1 -1
  318. package/dist/recall-explain-renderer.d.ts +1 -1
  319. package/dist/recall-explain-renderer.js +3 -3
  320. package/dist/recall-memory-map.d.ts +1 -1
  321. package/dist/recall-planner-llm.d.ts +1 -1
  322. package/dist/recall-planner-llm.js +1 -1
  323. package/dist/recall-state.d.ts +1 -1
  324. package/dist/recall-tag-filter.d.ts +1 -1
  325. package/dist/recall-timings.d.ts +1 -1
  326. package/dist/recall-xray-cli.d.ts +1 -1
  327. package/dist/recall-xray-cli.js +4 -4
  328. package/dist/recall-xray-renderer.d.ts +1 -1
  329. package/dist/recall-xray-renderer.js +3 -3
  330. package/dist/recall-xray.d.ts +1 -1
  331. package/dist/recall-xray.js +2 -2
  332. package/dist/reconcile/cursor.d.ts +1 -1
  333. package/dist/reconcile/manifest.d.ts +1 -1
  334. package/dist/reconcile/plan.d.ts +1 -1
  335. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  336. package/dist/replay/normalizers/claude.d.ts +1 -1
  337. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  338. package/dist/replay/normalizers/shared.d.ts +1 -1
  339. package/dist/replay/runner.d.ts +1 -1
  340. package/dist/replay/types.d.ts +1 -1
  341. package/dist/replica-divergence.d.ts +1 -1
  342. package/dist/replica-peers-config.d.ts +1 -1
  343. package/dist/resolve-auth-token.d.ts +1 -1
  344. package/dist/resume-bundles.js +3 -2
  345. package/dist/retrieval-agents.d.ts +2 -2
  346. package/dist/retrieval-tiers.d.ts +1 -1
  347. package/dist/routing/engine.d.ts +1 -1
  348. package/dist/routing/store.d.ts +1 -1
  349. package/dist/salvage-envelope.d.ts +1 -1
  350. package/dist/{scope-profiles-CbUOsE_E.d.ts → scope-profiles-DICK7GtN.d.ts} +1 -1
  351. package/dist/search/embed-helper.d.ts +1 -1
  352. package/dist/search/factory.d.ts +1 -1
  353. package/dist/search/factory.js +5 -5
  354. package/dist/search/index.d.ts +1 -1
  355. package/dist/search/index.js +9 -9
  356. package/dist/search/lancedb-backend.d.ts +1 -1
  357. package/dist/search/meilisearch-backend.d.ts +1 -1
  358. package/dist/search/noop-backend.d.ts +1 -1
  359. package/dist/search/orama-backend.d.ts +1 -1
  360. package/dist/search/port.d.ts +1 -1
  361. package/dist/search/remote-backend.d.ts +1 -1
  362. package/dist/{semantic-consolidation-DAB3xdKM.d.ts → semantic-consolidation-BP7NAX0N.d.ts} +1 -1
  363. package/dist/semantic-consolidation.d.ts +2 -2
  364. package/dist/semantic-consolidation.js +15 -15
  365. package/dist/semantic-rule-promotion.js +14 -14
  366. package/dist/semantic-rule-verifier.d.ts +1 -1
  367. package/dist/semantic-rule-verifier.js +14 -14
  368. package/dist/{service-DGKg2O6r.d.ts → service-DT-pJyda.d.ts} +660 -660
  369. package/dist/session-observer-bands.d.ts +1 -1
  370. package/dist/session-observer-state.d.ts +1 -1
  371. package/dist/shared-context/manager.d.ts +1 -1
  372. package/dist/signal.d.ts +1 -1
  373. package/dist/source-agent-qualifier.d.ts +1 -1
  374. package/dist/source-agent-qualifier.js +16 -16
  375. package/dist/{storage-CC1jKcWg.d.ts → storage-qOnaJ1Lw.d.ts} +4 -1
  376. package/dist/storage.d.ts +2 -2
  377. package/dist/storage.js +13 -13
  378. package/dist/summarizer.d.ts +1 -1
  379. package/dist/summarizer.js +5 -5
  380. package/dist/summary-snapshot.d.ts +1 -1
  381. package/dist/support-passport/index.d.ts +518 -0
  382. package/dist/support-passport/index.js +357 -0
  383. package/dist/support-passport/index.js.map +1 -0
  384. package/dist/temporal-supersession.d.ts +2 -2
  385. package/dist/temporal-timeline-recall.d.ts +1 -1
  386. package/dist/temporal-validity.d.ts +1 -1
  387. package/dist/threading.d.ts +1 -1
  388. package/dist/tier-migration.d.ts +2 -2
  389. package/dist/tier-routing.d.ts +1 -1
  390. package/dist/tier-routing.js +2 -2
  391. package/dist/{tier-stats-JDN6HRNT.js → tier-stats-EXYSKSVN.js} +3 -3
  392. package/dist/topics.d.ts +1 -1
  393. package/dist/transcript.d.ts +1 -1
  394. package/dist/transfer/autodetect.js +1 -1
  395. package/dist/transfer/backup.js +1 -1
  396. package/dist/transfer/capsule-export.js +2 -2
  397. package/dist/transfer/types.d.ts +24 -24
  398. package/dist/trust-score-stage.d.ts +1 -1
  399. package/dist/trust-score.d.ts +1 -1
  400. package/dist/{types-BnQza1y8.d.ts → types-ed-SvS2t.d.ts} +7 -1
  401. package/dist/types.d.ts +1 -1
  402. package/dist/types.js +1 -1
  403. package/dist/utility-runtime.d.ts +1 -1
  404. package/dist/verified-recall.js +14 -14
  405. package/dist/write-envelope.d.ts +1 -1
  406. package/dist/write-rate-limiter.d.ts +11 -5
  407. package/dist/write-rate-limiter.js +1 -1
  408. package/package.json +12 -2
  409. package/scripts/build-with-heap.mjs +11 -1
  410. package/src/access-authorization-probe.ts +20 -2
  411. package/src/access-boundary.ts +32 -0
  412. package/src/access-http.test.ts +1940 -643
  413. package/src/access-http.ts +81 -74
  414. package/src/access-mcp.ts +3 -1
  415. package/src/access-operations.ts +2 -0
  416. package/src/access-service.ts +612 -845
  417. package/src/access-surface-catalog.test.ts +40 -10
  418. package/src/access-surface-catalog.ts +15 -0
  419. package/src/active-memory-bridge.ts +17 -19
  420. package/src/config.ts +18 -9
  421. package/src/fallback-llm.test.ts +54 -0
  422. package/src/fallback-llm.ts +54 -9
  423. package/src/inline-script.ts +6 -0
  424. package/src/local-llm-headers-timeout.test.ts +42 -0
  425. package/src/local-llm.ts +8 -8
  426. package/src/mcp-read-only-tools.ts +3 -0
  427. package/src/relay/mission-access.test.ts +11 -11
  428. package/src/relay/mission-ui.test.ts +3 -1
  429. package/src/storage/tombstone-blocked-capture-sync.ts +31 -0
  430. package/src/storage-contract/failure-semantics.test.ts +102 -0
  431. package/src/support-passport/access-http-base.ts +143 -0
  432. package/src/support-passport/access-http.ts +172 -0
  433. package/src/support-passport/access-operations.ts +272 -0
  434. package/src/support-passport/access-service-base.test.ts +193 -0
  435. package/src/support-passport/access-service-base.ts +176 -0
  436. package/src/support-passport/access-surface.test.ts +283 -0
  437. package/src/support-passport/access-surface.ts +286 -0
  438. package/src/support-passport/card-projection.test.ts +8 -0
  439. package/src/support-passport/card-projection.ts +77 -16
  440. package/src/support-passport/card-replacement.ts +126 -0
  441. package/src/support-passport/card-service-commit-forwarding.test.ts +160 -0
  442. package/src/support-passport/card-service.test.ts +533 -31
  443. package/src/support-passport/card-service.ts +506 -364
  444. package/src/support-passport/card-state.ts +158 -0
  445. package/src/support-passport/config-model-routing.test.ts +37 -0
  446. package/src/support-passport/config.test.ts +34 -0
  447. package/src/support-passport/config.ts +41 -0
  448. package/src/support-passport/contracts.test.ts +15 -2
  449. package/src/support-passport/contracts.ts +13 -0
  450. package/src/support-passport/errors.ts +6 -0
  451. package/src/support-passport/generated-batch.test.ts +185 -0
  452. package/src/support-passport/generated-batch.ts +338 -0
  453. package/src/support-passport/grant-contracts.ts +45 -1
  454. package/src/support-passport/grant-generated-batch-scope.test.ts +201 -0
  455. package/src/support-passport/grant-service-cache.test.ts +2 -2
  456. package/src/support-passport/grant-service-cancellation.test.ts +2 -0
  457. package/src/support-passport/grant-service-marker-cache.test.ts +62 -0
  458. package/src/support-passport/grant-service.test.ts +853 -239
  459. package/src/support-passport/grant-service.ts +206 -57
  460. package/src/support-passport/grant-store.ts +7 -3
  461. package/src/support-passport/index.ts +10 -0
  462. package/src/support-passport/mcp-tools.test.ts +222 -0
  463. package/src/support-passport/mcp-tools.ts +187 -0
  464. package/src/support-passport/model-adapter.test.ts +840 -0
  465. package/src/support-passport/model-adapter.ts +602 -0
  466. package/src/support-passport/model-audit-pinned-write.test.ts +59 -0
  467. package/src/support-passport/model-audit.ts +152 -0
  468. package/src/support-passport/model-bridge.test.ts +456 -0
  469. package/src/support-passport/model-bridge.ts +439 -0
  470. package/src/support-passport/model-contracts.ts +124 -0
  471. package/src/support-passport/model-service.test.ts +1731 -0
  472. package/src/support-passport/model-service.ts +399 -0
  473. package/src/support-passport/owner-http.test.ts +671 -0
  474. package/src/support-passport/owner-lock.ts +26 -9
  475. package/src/support-passport/private-file.test.ts +99 -0
  476. package/src/support-passport/private-file.ts +139 -12
  477. package/src/support-passport/public-http.test.ts +476 -0
  478. package/src/support-passport/public-http.ts +601 -0
  479. package/src/support-passport/ui.test.ts +181 -0
  480. package/src/types.ts +7 -0
  481. package/src/write-rate-limiter.test.ts +30 -6
  482. package/src/write-rate-limiter.ts +29 -18
  483. package/dist/chunk-2INWPC6E.js.map +0 -1
  484. package/dist/chunk-2PNXOQ4P.js.map +0 -1
  485. package/dist/chunk-3SXLD5T3.js.map +0 -1
  486. package/dist/chunk-3WGI7F4V.js.map +0 -1
  487. package/dist/chunk-7HG7MGAP.js.map +0 -1
  488. package/dist/chunk-BIF4SHMD.js.map +0 -1
  489. package/dist/chunk-C23BYTJV.js.map +0 -1
  490. package/dist/chunk-CSY44OKU.js.map +0 -1
  491. package/dist/chunk-DDA55IVB.js.map +0 -1
  492. package/dist/chunk-HNDIND7P.js.map +0 -1
  493. package/dist/chunk-L6CQ7WIW.js.map +0 -1
  494. package/dist/chunk-MKQBXQKU.js.map +0 -1
  495. package/dist/chunk-QQXWFDRD.js.map +0 -1
  496. package/dist/chunk-QTO6BMQZ.js.map +0 -1
  497. package/dist/chunk-WZWZRZ2V.js.map +0 -1
  498. /package/dist/{auto-sync-TDHLZPVP.js.map → auto-sync-NR3GPCOA.js.map} +0 -0
  499. /package/dist/{chunk-LLJMAULE.js.map → chunk-2FKEIPIT.js.map} +0 -0
  500. /package/dist/{chunk-AU7Q3LSC.js.map → chunk-2QSZNTDO.js.map} +0 -0
  501. /package/dist/{chunk-TKFGFDPJ.js.map → chunk-3TIZPSJC.js.map} +0 -0
  502. /package/dist/{chunk-B4T3FQMT.js.map → chunk-43SEBY2M.js.map} +0 -0
  503. /package/dist/{chunk-LVKYLMSM.js.map → chunk-46SZBVDS.js.map} +0 -0
  504. /package/dist/{chunk-YKZLOPTC.js.map → chunk-5FD7JMTX.js.map} +0 -0
  505. /package/dist/{chunk-WM5LD6AT.js.map → chunk-6CYHUWCO.js.map} +0 -0
  506. /package/dist/{chunk-YR65W7BV.js.map → chunk-BRR5EUTF.js.map} +0 -0
  507. /package/dist/{chunk-JKW663ZN.js.map → chunk-CIAI24TQ.js.map} +0 -0
  508. /package/dist/{chunk-YDWPYDML.js.map → chunk-EKTP7MNS.js.map} +0 -0
  509. /package/dist/{chunk-6LEIWWAF.js.map → chunk-F2JRDPON.js.map} +0 -0
  510. /package/dist/{chunk-VYQ4URQB.js.map → chunk-FFRTNF3L.js.map} +0 -0
  511. /package/dist/{chunk-TY6MKIWP.js.map → chunk-FONWBCVY.js.map} +0 -0
  512. /package/dist/{chunk-XSV2YDCJ.js.map → chunk-FPLM2TKD.js.map} +0 -0
  513. /package/dist/{chunk-VTU5IEKY.js.map → chunk-FTPONF6B.js.map} +0 -0
  514. /package/dist/{chunk-6PZGKGAO.js.map → chunk-FWX7W5PM.js.map} +0 -0
  515. /package/dist/{chunk-QPW3PAIH.js.map → chunk-G6DFSS6A.js.map} +0 -0
  516. /package/dist/{chunk-2DD6ZHOM.js.map → chunk-GJ776BC2.js.map} +0 -0
  517. /package/dist/{chunk-XKAR4RF6.js.map → chunk-GN3WRFJY.js.map} +0 -0
  518. /package/dist/{chunk-RG426DJO.js.map → chunk-H7NAZ3UB.js.map} +0 -0
  519. /package/dist/{chunk-BSXGTDVJ.js.map → chunk-HBUFQRIM.js.map} +0 -0
  520. /package/dist/{chunk-FFEBSFVT.js.map → chunk-HGJ6NJ4E.js.map} +0 -0
  521. /package/dist/{chunk-5JKUSBMX.js.map → chunk-IKP5OYQQ.js.map} +0 -0
  522. /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  523. /package/dist/{chunk-DBY26JJJ.js.map → chunk-IQ4NVWEF.js.map} +0 -0
  524. /package/dist/{chunk-7Q7JWLQ4.js.map → chunk-JYG4OLWH.js.map} +0 -0
  525. /package/dist/{chunk-3OTSVCPK.js.map → chunk-K26NWEOC.js.map} +0 -0
  526. /package/dist/{chunk-HOIRB77A.js.map → chunk-L6Z5OAS4.js.map} +0 -0
  527. /package/dist/{chunk-7RZJWZ46.js.map → chunk-LEPOP46W.js.map} +0 -0
  528. /package/dist/{chunk-NGT35IGQ.js.map → chunk-MIH3CJPN.js.map} +0 -0
  529. /package/dist/{chunk-QPAQSG3F.js.map → chunk-MK5VEWCR.js.map} +0 -0
  530. /package/dist/{chunk-L7RTUEDG.js.map → chunk-OCIP6YMD.js.map} +0 -0
  531. /package/dist/{chunk-UWJNKGBA.js.map → chunk-QZLDRQ4I.js.map} +0 -0
  532. /package/dist/{chunk-UYOXFFEY.js.map → chunk-RUNORG2P.js.map} +0 -0
  533. /package/dist/{chunk-LC3FD4BV.js.map → chunk-RZQ6W2W4.js.map} +0 -0
  534. /package/dist/{chunk-MRGJZ75M.js.map → chunk-SMNYAMJD.js.map} +0 -0
  535. /package/dist/{chunk-DN2IDKI5.js.map → chunk-TO7ZTWJW.js.map} +0 -0
  536. /package/dist/{chunk-K2TDK7GG.js.map → chunk-TWTUGCTY.js.map} +0 -0
  537. /package/dist/{chunk-CUTFSLSD.js.map → chunk-UCTS3DDH.js.map} +0 -0
  538. /package/dist/{chunk-JYIJNNN3.js.map → chunk-UG6VXIOK.js.map} +0 -0
  539. /package/dist/{chunk-QOQQMVR2.js.map → chunk-UKYS3NU5.js.map} +0 -0
  540. /package/dist/{chunk-VZRFGJCH.js.map → chunk-UPLZNJKN.js.map} +0 -0
  541. /package/dist/{chunk-DOOWFDWN.js.map → chunk-V6ERBR7U.js.map} +0 -0
  542. /package/dist/{chunk-N7CXQ5TA.js.map → chunk-XZHE2DEN.js.map} +0 -0
  543. /package/dist/{chunk-6NNNURLK.js.map → chunk-Z54EM5YZ.js.map} +0 -0
  544. /package/dist/{chunk-F2Y6I74C.js.map → chunk-ZRZVLB7O.js.map} +0 -0
  545. /package/dist/{chunk-CLKBV3Z3.js.map → chunk-ZUKIUXHQ.js.map} +0 -0
  546. /package/dist/{contradiction-scan-KCADHXPE.js.map → contradiction-scan-JDTBXRGW.js.map} +0 -0
  547. /package/dist/{first-start-migration-LMMZFLKK.js.map → first-start-migration-CRZCZAJN.js.map} +0 -0
  548. /package/dist/{tier-stats-JDN6HRNT.js.map → tier-stats-EXYSKSVN.js.map} +0 -0
@@ -6,23 +6,23 @@ import {
6
6
  loadSyncState,
7
7
  syncWearableSource,
8
8
  wearableSourceLabel
9
- } from "./chunk-HOIRB77A.js";
10
- import {
11
- runPeerProfileReasoner
12
- } from "./chunk-I74SUMNI.js";
13
- import {
14
- CompressionGuidelineCoordinator
15
- } from "./chunk-6LKEUCEM.js";
9
+ } from "./chunk-L6Z5OAS4.js";
16
10
  import {
17
11
  ActivityStore,
18
12
  MaintenanceScheduler
19
- } from "./chunk-3OTSVCPK.js";
13
+ } from "./chunk-K26NWEOC.js";
14
+ import {
15
+ runPeerProfileReasoner
16
+ } from "./chunk-I74SUMNI.js";
20
17
  import {
21
18
  migrateFromEngram
22
19
  } from "./chunk-7HYPN2GC.js";
20
+ import {
21
+ CompressionGuidelineCoordinator
22
+ } from "./chunk-6LKEUCEM.js";
23
23
  import {
24
24
  LcmEngine
25
- } from "./chunk-6NNNURLK.js";
25
+ } from "./chunk-Z54EM5YZ.js";
26
26
  import {
27
27
  chunkTranscriptEntries
28
28
  } from "./chunk-TECVW3JP.js";
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  CompoundingEngine,
34
34
  defaultTierMigrationCycleBudget
35
- } from "./chunk-F2Y6I74C.js";
35
+ } from "./chunk-ZRZVLB7O.js";
36
36
  import {
37
37
  SharedContextManager
38
38
  } from "./chunk-M23RF3LJ.js";
@@ -41,9 +41,12 @@ import {
41
41
  applyUtilityRankingRuntimeDelta,
42
42
  loadUtilityRuntimeValues
43
43
  } from "./chunk-SEF4IOFE.js";
44
+ import {
45
+ TierMigrationExecutor
46
+ } from "./chunk-YRFAYOFQ.js";
44
47
  import {
45
48
  decideTierTransition
46
- } from "./chunk-6LEIWWAF.js";
49
+ } from "./chunk-F2JRDPON.js";
47
50
  import {
48
51
  TmtBuilder
49
52
  } from "./chunk-ECZU5BJH.js";
@@ -56,12 +59,9 @@ import {
56
59
  import {
57
60
  CODEX_THREAD_KEY_PREFIX
58
61
  } from "./chunk-4EX5WZ4M.js";
59
- import {
60
- TierMigrationExecutor
61
- } from "./chunk-YRFAYOFQ.js";
62
62
  import {
63
63
  HourlySummarizer
64
- } from "./chunk-LLJMAULE.js";
64
+ } from "./chunk-2FKEIPIT.js";
65
65
  import {
66
66
  buildTargetedFactRecallSection,
67
67
  shouldRecallTargetedFactEvidence
@@ -105,6 +105,12 @@ import {
105
105
  buildResponseGuidanceRecallSection,
106
106
  shouldRecallResponseGuidance
107
107
  } from "./chunk-6TCXIRP5.js";
108
+ import {
109
+ LastRecallStore,
110
+ RecallHandleHistoryStore,
111
+ TierMigrationStatusStore,
112
+ clampGraphRecallExpandedEntries
113
+ } from "./chunk-PRDJMOST.js";
108
114
  import {
109
115
  findUnresolvedEntityRefs
110
116
  } from "./chunk-X7XN6YU4.js";
@@ -119,12 +125,6 @@ import {
119
125
  import {
120
126
  reorderRecallResultsWithMmr
121
127
  } from "./chunk-YDBIWGNI.js";
122
- import {
123
- LastRecallStore,
124
- RecallHandleHistoryStore,
125
- TierMigrationStatusStore,
126
- clampGraphRecallExpandedEntries
127
- } from "./chunk-PRDJMOST.js";
128
128
  import {
129
129
  applyReasoningTraceBoost
130
130
  } from "./chunk-ZZTOURJI.js";
@@ -163,16 +163,13 @@ import {
163
163
  } from "./chunk-OH7QLI6W.js";
164
164
  import {
165
165
  ExtractionEngine
166
- } from "./chunk-XKAR4RF6.js";
166
+ } from "./chunk-GN3WRFJY.js";
167
167
  import {
168
168
  parseMemoryActionEligibilityContext
169
169
  } from "./chunk-WFLBP5GC.js";
170
170
  import {
171
171
  ModelRegistry
172
172
  } from "./chunk-WLZYGLJ4.js";
173
- import {
174
- LocalLlmClient
175
- } from "./chunk-L6CQ7WIW.js";
176
173
  import {
177
174
  recordJudgeTrainingPair
178
175
  } from "./chunk-PWFCHOB3.js";
@@ -182,7 +179,7 @@ import {
182
179
  getVerdictKind,
183
180
  judgeFactDurability,
184
181
  validateProcedureExtraction
185
- } from "./chunk-K2TDK7GG.js";
182
+ } from "./chunk-TWTUGCTY.js";
186
183
  import {
187
184
  buildExplicitCueRecallSection
188
185
  } from "./chunk-TVIVY7KU.js";
@@ -190,7 +187,7 @@ import {
190
187
  buildEntityRecallSection,
191
188
  entityRecentTranscriptLookbackHours,
192
189
  readRecentEntityTranscriptEntries
193
- } from "./chunk-XSV2YDCJ.js";
190
+ } from "./chunk-FPLM2TKD.js";
194
191
  import {
195
192
  buildEventOrderRecallSection,
196
193
  shouldRecallEventOrderEvidence
@@ -207,7 +204,7 @@ import {
207
204
  } from "./chunk-YK6BDDHP.js";
208
205
  import {
209
206
  refreshConvergedNamespaces
210
- } from "./chunk-5JKUSBMX.js";
207
+ } from "./chunk-IKP5OYQQ.js";
211
208
  import {
212
209
  formatDaySummaryMemories
213
210
  } from "./chunk-RPSYDM6C.js";
@@ -216,44 +213,44 @@ import {
216
213
  ensureBuiltInWearableConnectors,
217
214
  getWearableConnector,
218
215
  listWearableConnectors
219
- } from "./chunk-LC3FD4BV.js";
220
- import {
221
- normalizeReplaySessionKey
222
- } from "./chunk-AJVLDJU6.js";
216
+ } from "./chunk-RZQ6W2W4.js";
223
217
  import {
224
218
  RoutingRulesStore
225
219
  } from "./chunk-XL24QQ63.js";
220
+ import {
221
+ normalizeReplaySessionKey
222
+ } from "./chunk-AJVLDJU6.js";
226
223
  import {
227
224
  compareVerifiedEpisodeResults,
228
225
  searchVerifiedEpisodes
229
- } from "./chunk-YKZLOPTC.js";
226
+ } from "./chunk-5FD7JMTX.js";
230
227
  import {
231
228
  ThreadingManager
232
229
  } from "./chunk-OJP3N7UK.js";
233
230
  import {
234
231
  compareVerifiedSemanticRuleResults,
235
232
  searchVerifiedSemanticRules
236
- } from "./chunk-6PZGKGAO.js";
233
+ } from "./chunk-FWX7W5PM.js";
237
234
  import {
238
235
  searchWorkProductLedgerEntries
239
236
  } from "./chunk-WT6UL3UA.js";
240
237
  import {
241
238
  TranscriptManager
242
239
  } from "./chunk-HYQJQGD3.js";
240
+ import {
241
+ PolicyRuntimeManager
242
+ } from "./chunk-33JBK2XP.js";
243
243
  import {
244
244
  runNamespaceMaintenanceFanout,
245
245
  summarizeNamespaceMaintenanceHealth
246
- } from "./chunk-CLKBV3Z3.js";
246
+ } from "./chunk-ZUKIUXHQ.js";
247
247
  import {
248
248
  NamespaceCatalog,
249
249
  planNamespaceMaintenance
250
- } from "./chunk-VYQ4URQB.js";
251
- import {
252
- PolicyRuntimeManager
253
- } from "./chunk-33JBK2XP.js";
250
+ } from "./chunk-FFRTNF3L.js";
254
251
  import {
255
252
  searchHarmonicRetrieval
256
- } from "./chunk-B4T3FQMT.js";
253
+ } from "./chunk-43SEBY2M.js";
257
254
  import {
258
255
  isAboveImportanceThreshold,
259
256
  scoreImportance
@@ -285,7 +282,7 @@ import {
285
282
  materializeAfterSemanticConsolidation,
286
283
  parseConsolidationResponse,
287
284
  parseOperatorAwareConsolidationResponse
288
- } from "./chunk-QOQQMVR2.js";
285
+ } from "./chunk-UKYS3NU5.js";
289
286
  import {
290
287
  BootstrapEngine
291
288
  } from "./chunk-MYVPLJOO.js";
@@ -300,13 +297,13 @@ import {
300
297
  } from "./chunk-UQ7RN5HK.js";
301
298
  import {
302
299
  SmartBuffer
303
- } from "./chunk-CUTFSLSD.js";
300
+ } from "./chunk-UCTS3DDH.js";
304
301
  import {
305
302
  isDisagreementPrompt
306
303
  } from "./chunk-H3FZVNRN.js";
307
304
  import {
308
305
  detectMeetings
309
- } from "./chunk-2INWPC6E.js";
306
+ } from "./chunk-PG4QBPVG.js";
310
307
  import {
311
308
  compileCorrectionRule,
312
309
  correctionsFilePath,
@@ -331,7 +328,7 @@ import {
331
328
  } from "./chunk-KD3QD3A5.js";
332
329
  import {
333
330
  MeetingsInputError
334
- } from "./chunk-DDA55IVB.js";
331
+ } from "./chunk-PT54WISF.js";
335
332
  import {
336
333
  WearablesInputError,
337
334
  describeErrorForOperator
@@ -352,7 +349,7 @@ import {
352
349
  filterRecallCandidates,
353
350
  isGenericRecallExcludedPath,
354
351
  isTopLevelArchivePath
355
- } from "./chunk-3WGI7F4V.js";
352
+ } from "./chunk-D3LBIUWV.js";
356
353
  import {
357
354
  importCapsule
358
355
  } from "./chunk-QYN5PXDZ.js";
@@ -370,6 +367,9 @@ import {
370
367
  trustResultFor,
371
368
  trustResultKey
372
369
  } from "./chunk-GNVZQ5JN.js";
370
+ import {
371
+ buildXraySnapshot
372
+ } from "./chunk-MK5VEWCR.js";
373
373
  import {
374
374
  boundRecallContextComposition,
375
375
  composeRecallContext,
@@ -377,9 +377,6 @@ import {
377
377
  formatCuriosityFooter,
378
378
  selectCuriosityQuestion
379
379
  } from "./chunk-AHVEHR6K.js";
380
- import {
381
- buildXraySnapshot
382
- } from "./chunk-QPAQSG3F.js";
383
380
  import {
384
381
  objectiveStateStoreOverrideForNamespace,
385
382
  searchObjectiveStateSnapshots
@@ -391,15 +388,18 @@ import {
391
388
  import {
392
389
  ProfilingCollector
393
390
  } from "./chunk-NLE6TSLG.js";
391
+ import {
392
+ LocalLlmClient
393
+ } from "./chunk-KFBOPMF6.js";
394
394
  import {
395
395
  buildProcedurePersistBody
396
396
  } from "./chunk-QDW3E4RD.js";
397
397
  import {
398
398
  shouldSkipImplicitExtraction
399
- } from "./chunk-MRGJZ75M.js";
399
+ } from "./chunk-SMNYAMJD.js";
400
400
  import {
401
401
  NamespaceStorageRouter
402
- } from "./chunk-VZRFGJCH.js";
402
+ } from "./chunk-UPLZNJKN.js";
403
403
  import {
404
404
  searchCausalTrajectories
405
405
  } from "./chunk-AHZOMHWN.js";
@@ -408,7 +408,7 @@ import {
408
408
  } from "./chunk-BIJAWZYW.js";
409
409
  import {
410
410
  buildChainFollowupGenerator
411
- } from "./chunk-UYOXFFEY.js";
411
+ } from "./chunk-RUNORG2P.js";
412
412
  import {
413
413
  QmdResultResolver,
414
414
  StorageManager,
@@ -427,7 +427,10 @@ import {
427
427
  reconstructFusionInputs,
428
428
  selfDeps,
429
429
  serializeFusionDay
430
- } from "./chunk-QQXWFDRD.js";
430
+ } from "./chunk-M4YHAODQ.js";
431
+ import {
432
+ buildRetiredFactTombstoneInputs
433
+ } from "./chunk-MLPTFODV.js";
431
434
  import {
432
435
  bodyIsEscaped,
433
436
  decodeTranscriptBody,
@@ -438,18 +441,15 @@ import {
438
441
  saveSpeakerRegistry,
439
442
  speakerRegistryKey
440
443
  } from "./chunk-UHVXE24Y.js";
441
- import {
442
- buildRetiredFactTombstoneInputs
443
- } from "./chunk-MLPTFODV.js";
444
444
  import {
445
445
  NamespaceSearchRouter,
446
446
  namespaceCollectionName
447
- } from "./chunk-DN2IDKI5.js";
447
+ } from "./chunk-TO7ZTWJW.js";
448
448
  import {
449
449
  createConversationIndexRuntime,
450
450
  createSearchBackend,
451
451
  isSearchBackendEnabled
452
- } from "./chunk-UWJNKGBA.js";
452
+ } from "./chunk-QZLDRQ4I.js";
453
453
  import {
454
454
  NoopSearchBackend
455
455
  } from "./chunk-CYEPCZN5.js";
@@ -463,7 +463,7 @@ import {
463
463
  } from "./chunk-S2V7RUCL.js";
464
464
  import {
465
465
  confidenceTier
466
- } from "./chunk-BIF4SHMD.js";
466
+ } from "./chunk-76JJSXK7.js";
467
467
  import {
468
468
  lintWorkspaceFiles,
469
469
  rotateMarkdownFileToArchive
@@ -472,7 +472,7 @@ import {
472
472
  applyFaithfulnessVerdict,
473
473
  createFaithfulnessCounters,
474
474
  runFaithfulnessGateBatch
475
- } from "./chunk-JYIJNNN3.js";
475
+ } from "./chunk-UG6VXIOK.js";
476
476
  import {
477
477
  TAG_LIMITS,
478
478
  composeMemoryEnvelope,
@@ -514,7 +514,7 @@ import {
514
514
  FallbackLlmClient,
515
515
  fallbackLlmRuntimeContextFromConfig,
516
516
  gatewayTaskChainOptions
517
- } from "./chunk-C23BYTJV.js";
517
+ } from "./chunk-UW5NPZJ2.js";
518
518
  import {
519
519
  BulkImportBatchPartialFailureError,
520
520
  COMPACTION_SIGNAL_MAX_AGE_MS,
@@ -554,7 +554,7 @@ import {
554
554
  throwIfRecallAborted,
555
555
  tokenizeRecallQuery,
556
556
  utcDateKeysForLocalDay
557
- } from "./chunk-N7CXQ5TA.js";
557
+ } from "./chunk-XZHE2DEN.js";
558
558
  import {
559
559
  inferIntentFromText,
560
560
  intentCompatibilityScore,
@@ -615,28 +615,9 @@ import {
615
615
  ContentHashIndex
616
616
  } from "./chunk-CX5SW2EW.js";
617
617
  import {
618
- serializeMutations,
619
- withHeldFileLock
620
- } from "./chunk-FFAZ2XFU.js";
621
- import {
622
- SUPPORT_PASSPORT_ATTRIBUTE_KEYS,
623
- SUPPORT_PASSPORT_CARD_TAG,
624
- SupportPassportCardCategorySchema,
625
- SupportPassportCardListSchema,
626
- SupportPassportCardMutationInputSchema,
627
- SupportPassportListCardsInputSchema,
628
- SupportPassportManualDraftInputSchema,
629
- SupportPassportMemoryIdSchema,
630
- SupportPassportNamespaceSchema,
631
- SupportPassportReplaceCardInputSchema,
632
- computeSupportPassportCardRevision,
633
- computeSupportPassportOwnerKey,
634
- decodeSupportPassportNamespaceAttributes,
635
- encodeSupportPassportNamespaceAttributes,
636
618
  excludeSupportPassportPrivateMemories,
637
- isSupportPassportPrivateMemory,
638
- projectSupportPassportCard
639
- } from "./chunk-HNDIND7P.js";
619
+ isSupportPassportPrivateMemory
620
+ } from "./chunk-XX4HPFFM.js";
640
621
  import {
641
622
  namespaceIdentityFromToken,
642
623
  namespaceIdentityToken,
@@ -659,9 +640,6 @@ import {
659
640
  assertIsDirectoryNotSymlink,
660
641
  assertRealpathInsideRoot
661
642
  } from "./chunk-GCGJW34D.js";
662
- import {
663
- parseIsoOffsetTimestamp
664
- } from "./chunk-P7FMDTKL.js";
665
643
  import {
666
644
  canReadNamespace,
667
645
  defaultNamespaceForPrincipal,
@@ -2236,7 +2214,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2236
2214
  namespaces,
2237
2215
  {
2238
2216
  readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
2239
- readMemoryFrontmatter: async (path38, preferredNamespace) => {
2217
+ readMemoryFrontmatter: async (path35, preferredNamespace) => {
2240
2218
  if (!fallbackReader) {
2241
2219
  for (const ns of namespaces) {
2242
2220
  try {
@@ -2248,7 +2226,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2248
2226
  }
2249
2227
  if (!fallbackReader) return null;
2250
2228
  const memory = await this.readQmdResultMemory(
2251
- path38,
2229
+ path35,
2252
2230
  fallbackReader,
2253
2231
  namespaces,
2254
2232
  preferredNamespace
@@ -15043,7 +15021,7 @@ var OrchestratorInitCoordinator = class {
15043
15021
  if (signal.aborted) return;
15044
15022
  if (lifecycleCaps.lifecyclePolicy && resolveQmdCapabilities(this.deps.config).qmdTierMigration) {
15045
15023
  try {
15046
- const { runFirstStartMigration } = await import("./first-start-migration-LMMZFLKK.js");
15024
+ const { runFirstStartMigration } = await import("./first-start-migration-CRZCZAJN.js");
15047
15025
  const result = await runFirstStartMigration({
15048
15026
  storage: this.deps.storage,
15049
15027
  config: this.deps.config,
@@ -15066,7 +15044,7 @@ var OrchestratorInitCoordinator = class {
15066
15044
  if (signal.aborted) return;
15067
15045
  if (!this.deps.wearablesAutoSyncHandle && this.deps.config.wearables.enabled && this.deps.config.wearables.autoSyncEnabled && Object.values(this.deps.config.wearables.sources).some((source) => source.enabled)) {
15068
15046
  try {
15069
- const { startWearablesAutoSync } = await import("./auto-sync-TDHLZPVP.js");
15047
+ const { startWearablesAutoSync } = await import("./auto-sync-NR3GPCOA.js");
15070
15048
  if (signal.aborted) return;
15071
15049
  this.deps.wearablesAutoSyncHandle = startWearablesAutoSync(
15072
15050
  {
@@ -20970,2340 +20948,166 @@ ${doc.content}` : doc.content,
20970
20948
  }
20971
20949
  };
20972
20950
 
20973
- // src/support-passport/errors.ts
20974
- var SupportPassportError = class extends Error {
20975
- code;
20976
- status;
20977
- constructor(code, message, status) {
20978
- super(message);
20979
- this.name = "SupportPassportError";
20980
- this.code = code;
20981
- this.status = status;
20982
- }
20951
+ // src/relay/mission-fixture.ts
20952
+ var RELAY_DEMO_MISSION_ID = "checkout-token-recovery";
20953
+ var RELAY_DEMO_NAMESPACE = "relay-build-week";
20954
+ var sourceEvidence = {
20955
+ kind: "source",
20956
+ id: "source-checkout-contract",
20957
+ label: "Checkout token contract",
20958
+ locator: "fixture://checkout-service/src/token-policy.ts",
20959
+ capture: "fixture"
20983
20960
  };
20984
-
20985
- // src/support-passport/owner-lock.ts
20986
- import { createHash as createHash9 } from "crypto";
20987
- import path21 from "path";
20988
- var CARD_MUTATION_LOCK_STALE_MS = 6e4;
20989
- var CARD_MUTATION_LOCK_MAX_WAIT_MS = 3e4;
20990
- function computeSupportPassportOwnerLockKey(namespace, principal) {
20991
- return createHash9("sha256").update(JSON.stringify([namespace, principal])).digest("hex");
20992
- }
20993
- function supportPassportOwnerLockPath(storage, scope) {
20994
- const ownerLockKey = scope.ownerKey ?? computeSupportPassportOwnerLockKey(scope.namespace, scope.principal);
20995
- if (!/^[a-f0-9]{64}$/.test(ownerLockKey)) {
20996
- throw new SupportPassportError("card_data_invalid", "The support passport owner scope is invalid.", 500);
20997
- }
20998
- return path21.join(storage.dir, "state", `support-passport-cards-${ownerLockKey}.lock`);
20999
- }
21000
- async function withSupportPassportOwnerLock(storage, scope, task) {
21001
- const lockPath = supportPassportOwnerLockPath(storage, scope);
21002
- return await serializeMutations(
21003
- lockPath,
21004
- () => withHeldFileLock(
21005
- lockPath,
21006
- { staleMs: CARD_MUTATION_LOCK_STALE_MS, maxWaitMs: CARD_MUTATION_LOCK_MAX_WAIT_MS },
21007
- async (acquired, lock) => {
21008
- if (!acquired) {
21009
- throw new SupportPassportError("storage_conflict", "The support passport is busy. Try again.", 409);
21010
- }
21011
- return await task(lock);
21012
- }
21013
- )
21014
- );
21015
- }
21016
- async function requireSupportPassportOwnerLock(lock) {
21017
- if (await lock.refresh()) return;
21018
- throw new SupportPassportError("storage_conflict", "The support passport changed during the request.", 409);
20961
+ var testEvidence = {
20962
+ kind: "test",
20963
+ id: "test-checkout-contract",
20964
+ label: "Checkout integration contract",
20965
+ locator: "fixture://checkout-service/test/token-policy.test.ts",
20966
+ capture: "fixture"
20967
+ };
20968
+ var approvalEvidence = {
20969
+ kind: "approval",
20970
+ id: "approval-build-week-operator",
20971
+ label: "Human approval receipt",
20972
+ locator: "fixture://relay/approvals/correction-token-refresh.json",
20973
+ capture: "fixture"
20974
+ };
20975
+ var correctionEvidence = {
20976
+ kind: "correction",
20977
+ id: "correction-token-refresh",
20978
+ label: "Applied Remnic correction",
20979
+ locator: "fixture://remnic/corrections/correction-token-refresh.json",
20980
+ capture: "fixture"
20981
+ };
20982
+ function at(second) {
20983
+ return `2026-07-17T18:00:${String(second).padStart(2, "0")}.000Z`;
21019
20984
  }
21020
-
21021
- // src/support-passport/card-service.ts
21022
- var OWNER_VISIBLE_STATUSES = /* @__PURE__ */ new Set(["pending_review", "active"]);
21023
- var MAX_OWNER_VISIBLE_CARDS = 100;
21024
- function invalidInput() {
21025
- return new SupportPassportError("invalid_input", "The support card request is invalid.", 400);
21026
- }
21027
- function isStorageConflict(error) {
21028
- return error instanceof SupportPassportError && error.code === "storage_conflict";
21029
- }
21030
- var SupportPassportCardService = class {
21031
- resolveOwner;
21032
- now;
21033
- constructor(dependencies) {
21034
- this.resolveOwner = dependencies.resolveOwner;
21035
- this.now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
21036
- }
21037
- async listCards(input) {
21038
- const parsed = SupportPassportListCardsInputSchema.safeParse(input);
21039
- if (!parsed.success) throw invalidInput();
21040
- const { principal, namespace, storage } = await this.resolveOwnerScope(parsed.data.principal);
21041
- return await withSupportPassportOwnerLock(storage, { namespace, principal }, async (lock) => {
21042
- const stored = await this.readStoredCards(storage, lock, principal, namespace);
21043
- const cards = this.ownerVisibleCards(stored).sort((a, b) => a.order - b.order || a.card.cardId.localeCompare(b.card.cardId)).map((item) => item.card);
21044
- const output = SupportPassportCardListSchema.safeParse(cards);
21045
- if (!output.success) {
21046
- throw new SupportPassportError("card_data_invalid", "The support card data is invalid.", 500);
21047
- }
21048
- return output.data;
21049
- });
21050
- }
21051
- async createManualDraft(input) {
21052
- const parsed = SupportPassportManualDraftInputSchema.safeParse(input);
21053
- if (!parsed.success) throw invalidInput();
21054
- const { principal, namespace, storage } = await this.resolveOwnerScope(parsed.data.principal);
21055
- return await withSupportPassportOwnerLock(
21056
- storage,
21057
- { namespace, principal },
21058
- (lock) => this.createDraft(
21059
- storage,
21060
- {
21061
- title: parsed.data.title,
21062
- statement: parsed.data.statement,
21063
- category: parsed.data.category,
21064
- reviewBy: parsed.data.reviewBy,
21065
- sourceMemoryIds: []
21066
- },
21067
- lock,
21068
- principal,
21069
- namespace
21070
- )
21071
- );
21072
- }
21073
- async replaceCard(input) {
21074
- const parsed = SupportPassportReplaceCardInputSchema.safeParse(input);
21075
- if (!parsed.success) throw invalidInput();
21076
- const { principal, namespace, storage } = await this.resolveOwnerScope(parsed.data.principal);
21077
- return await withSupportPassportOwnerLock(storage, { namespace, principal }, async (lock) => {
21078
- const loadedPrior = await this.requireCard(storage, parsed.data.cardId, namespace, principal);
21079
- const storedCards = await this.readProjectedCards(storage, namespace, principal);
21080
- const interruptedReplacements = storedCards.filter(
21081
- (item) => item.card.status === "pending_review" && (item.replacesDraftId === loadedPrior.card.cardId || item.memory.frontmatter.supersedes === loadedPrior.card.cardId)
21082
- );
21083
- if (interruptedReplacements.length > 1) {
21084
- throw new SupportPassportError(
21085
- "storage_conflict",
21086
- "Multiple support card edits already completed. Reload the support passport.",
21087
- 409
21088
- );
20985
+ function createRelayMissionFixture() {
20986
+ return [
20987
+ {
20988
+ occurredAt: at(0),
20989
+ idempotencyKey: "fixture-001",
20990
+ payload: {
20991
+ kind: "mission_started",
20992
+ title: "The checkout token split",
20993
+ objective: "Resolve a conflicting token refresh policy and prove a cold agent acts on it.",
20994
+ runMode: "fixture",
20995
+ evidence: [sourceEvidence]
21089
20996
  }
21090
- const [interruptedReplacement] = interruptedReplacements;
21091
- if (interruptedReplacement) {
21092
- if (interruptedReplacement.replacedRevision !== parsed.data.expectedRevision) {
21093
- throw new SupportPassportError("revision_conflict", "The support card changed after it was loaded.", 409);
21094
- }
21095
- const matchesRetry = interruptedReplacement.card.title === parsed.data.title && interruptedReplacement.card.statement === parsed.data.statement && interruptedReplacement.card.category === parsed.data.category && interruptedReplacement.card.reviewBy === parsed.data.reviewBy;
21096
- if (!matchesRetry) {
21097
- throw new SupportPassportError(
21098
- "storage_conflict",
21099
- "A different support card edit already completed. Reload the support passport.",
21100
- 409
21101
- );
21102
- }
21103
- if (!interruptedReplacement.draftReplacementPrepared) return interruptedReplacement.card;
21104
- const recovered = await this.recoverReplacementTransition(
21105
- storage,
21106
- interruptedReplacement.memory,
21107
- lock,
21108
- principal,
21109
- namespace
21110
- );
21111
- return this.projectRequiredCard(recovered, namespace, principal).card;
20997
+ },
20998
+ {
20999
+ occurredAt: at(2),
21000
+ idempotencyKey: "fixture-002",
21001
+ payload: {
21002
+ kind: "agent_status",
21003
+ agentId: "agent-atlas",
21004
+ sessionId: "session-atlas",
21005
+ label: "Atlas",
21006
+ role: "Checkout implementation",
21007
+ status: "working",
21008
+ evidence: [sourceEvidence]
21112
21009
  }
21113
- this.requireRevision(loadedPrior, parsed.data.expectedRevision);
21114
- await this.readStoredCards(storage, lock, principal, namespace);
21115
- const refreshedPrior = await this.requireCard(storage, parsed.data.cardId, namespace, principal);
21116
- this.requireRevision(refreshedPrior, parsed.data.expectedRevision);
21117
- const recoveredMemory = await this.recoverReplacementTransition(
21118
- storage,
21119
- refreshedPrior.memory,
21120
- lock,
21121
- principal,
21122
- namespace
21123
- );
21124
- const prior = this.projectRequiredCard(recoveredMemory, namespace, principal);
21125
- if (prior.card.status !== "active" && prior.card.status !== "pending_review") {
21126
- throw new SupportPassportError(
21127
- "invalid_card_status",
21128
- "Only a draft or approved support card can be edited.",
21129
- 409
21130
- );
21010
+ },
21011
+ {
21012
+ occurredAt: at(3),
21013
+ idempotencyKey: "fixture-003",
21014
+ payload: {
21015
+ kind: "agent_status",
21016
+ agentId: "agent-nova",
21017
+ sessionId: "session-nova",
21018
+ label: "Nova",
21019
+ role: "Integration verification",
21020
+ status: "working",
21021
+ evidence: [testEvidence]
21131
21022
  }
21132
- const replacement = await this.createDraft(
21133
- storage,
21134
- {
21135
- title: parsed.data.title,
21136
- statement: parsed.data.statement,
21137
- category: parsed.data.category,
21138
- reviewBy: parsed.data.reviewBy,
21139
- sourceMemoryIds: prior.sourceMemoryIds,
21140
- supersedes: prior.card.status === "active" ? prior.card.cardId : prior.memory.frontmatter.supersedes,
21141
- replacesDraftId: prior.card.status === "pending_review" ? prior.card.cardId : void 0,
21142
- replacedRevision: prior.card.revision,
21143
- order: prior.order,
21144
- draftReplacementPrepared: prior.card.status === "pending_review"
21145
- },
21146
- lock,
21147
- principal,
21148
- namespace
21149
- );
21150
- if (prior.card.status === "active") return replacement;
21151
- const replacedAt = this.now().toISOString();
21152
- await this.requireOwnerLock(lock);
21153
- const rejected = await storage.writeMemoryFrontmatterIfUnchanged(
21154
- prior.memory,
21155
- { status: "rejected", updated: replacedAt },
21156
- { actor: principal, reasonCode: "owner-replaced-draft" }
21157
- );
21158
- if (rejected) {
21159
- return await this.finishPreparedDraftReplacement(storage, replacement.cardId, lock, principal, namespace);
21023
+ },
21024
+ {
21025
+ occurredAt: at(6),
21026
+ idempotencyKey: "fixture-004",
21027
+ payload: {
21028
+ kind: "agent_output",
21029
+ agentId: "agent-atlas",
21030
+ sessionId: "session-atlas",
21031
+ outputId: "output-atlas-policy",
21032
+ summary: "Implemented a new token for every checkout retry.",
21033
+ evidence: [
21034
+ {
21035
+ kind: "agent_output",
21036
+ id: "output-atlas-policy",
21037
+ label: "Atlas one-shot output",
21038
+ locator: "fixture://codex/atlas/final-output.txt",
21039
+ capture: "fixture"
21040
+ }
21041
+ ]
21160
21042
  }
21161
- const currentPrior = await storage.getMemoryById(prior.card.cardId);
21162
- const currentPriorCard = currentPrior ? this.projectOwnedCard(currentPrior, namespace, principal) : null;
21163
- if (currentPriorCard?.card.status === "rejected") {
21164
- return await this.finishPreparedDraftReplacement(storage, replacement.cardId, lock, principal, namespace);
21043
+ },
21044
+ {
21045
+ occurredAt: at(7),
21046
+ idempotencyKey: "fixture-005",
21047
+ payload: {
21048
+ kind: "belief_observed",
21049
+ agentId: "agent-atlas",
21050
+ sessionId: "session-atlas",
21051
+ beliefId: "belief-new-token-every-request",
21052
+ decisionId: "decision-new-token-every-request",
21053
+ statement: "Mint a new checkout token for every request and retry.",
21054
+ confidence: 0.91,
21055
+ evidence: [
21056
+ {
21057
+ kind: "memory",
21058
+ id: "memory-stale-token-policy",
21059
+ label: "Stale project decision",
21060
+ locator: "fixture://remnic/memories/memory-stale-token-policy.md",
21061
+ capture: "fixture"
21062
+ }
21063
+ ]
21165
21064
  }
21166
- await this.rejectCreatedDraft(
21167
- storage,
21168
- replacement.cardId,
21169
- "draft-replacement-failed",
21170
- lock,
21171
- principal,
21172
- namespace
21173
- );
21174
- throw new SupportPassportError("storage_conflict", "The support card changed before it was edited.", 409);
21175
- });
21176
- }
21177
- async approveCard(input) {
21178
- const parsed = SupportPassportCardMutationInputSchema.safeParse(input);
21179
- if (!parsed.success) throw invalidInput();
21180
- const { principal, namespace, storage } = await this.resolveOwnerScope(parsed.data.principal);
21181
- return await withSupportPassportOwnerLock(storage, { namespace, principal }, async (lock) => {
21182
- const loadedCard = await this.requireCard(storage, parsed.data.cardId, namespace, principal);
21183
- this.requireRevision(loadedCard, parsed.data.expectedRevision);
21184
- this.requireStatus(loadedCard, "pending_review");
21185
- const recoveredMemory = await this.recoverReplacementTransition(
21186
- storage,
21187
- loadedCard.memory,
21188
- lock,
21189
- principal,
21190
- namespace
21191
- );
21192
- const card = this.projectRequiredCard(recoveredMemory, namespace, principal);
21193
- if (card.card.status === "active") return card.card;
21194
- if (card.card.status === "rejected") {
21195
- throw new SupportPassportError(
21196
- "storage_conflict",
21197
- "The support card was rejected while its replacement state was recovered.",
21198
- 409
21199
- );
21065
+ },
21066
+ {
21067
+ occurredAt: at(9),
21068
+ idempotencyKey: "fixture-006",
21069
+ payload: {
21070
+ kind: "agent_output",
21071
+ agentId: "agent-nova",
21072
+ sessionId: "session-nova",
21073
+ outputId: "output-nova-policy",
21074
+ summary: "The contract requires one token per checkout session, refreshed only after expiry.",
21075
+ evidence: [
21076
+ {
21077
+ kind: "agent_output",
21078
+ id: "output-nova-policy",
21079
+ label: "Nova one-shot output",
21080
+ locator: "fixture://codex/nova/final-output.txt",
21081
+ capture: "fixture"
21082
+ },
21083
+ sourceEvidence
21084
+ ]
21200
21085
  }
21201
- this.requireStatus(card, "pending_review");
21202
- await this.validatePriorForReplacement(storage, card, namespace, principal);
21203
- const updatedAt = this.now().toISOString();
21204
- await this.requireOwnerLock(lock);
21205
- let approved;
21206
- try {
21207
- approved = await storage.writeMemoryFrontmatterIfUnchanged(
21208
- card.memory,
21209
- { status: "active", updated: updatedAt },
21210
- { actor: principal, reasonCode: "owner-approved" }
21211
- );
21212
- } catch (error) {
21213
- const current = await storage.getMemoryById(card.card.cardId);
21214
- const currentCard = current ? this.projectOwnedCard(current, namespace, principal) : null;
21215
- if (currentCard?.card.status === "active") {
21216
- return await this.finishCommittedApproval(storage, currentCard, lock, principal, namespace);
21217
- }
21218
- throw error;
21086
+ },
21087
+ {
21088
+ occurredAt: at(10),
21089
+ idempotencyKey: "fixture-007",
21090
+ payload: {
21091
+ kind: "belief_observed",
21092
+ agentId: "agent-nova",
21093
+ sessionId: "session-nova",
21094
+ beliefId: "belief-refresh-after-expiry",
21095
+ decisionId: "decision-refresh-after-expiry",
21096
+ statement: "Reuse the checkout-session token and refresh it only after expiry.",
21097
+ confidence: 0.98,
21098
+ evidence: [sourceEvidence]
21219
21099
  }
21220
- if (!approved) {
21221
- const current = await storage.getMemoryById(card.card.cardId);
21222
- const currentCard = current ? this.projectOwnedCard(current, namespace, principal) : null;
21223
- if (currentCard?.card.status === "active") {
21224
- return await this.finishCommittedApproval(storage, currentCard, lock, principal, namespace);
21225
- }
21226
- throw new SupportPassportError("storage_conflict", "The support card changed before approval.", 409);
21227
- }
21228
- const committedCard = {
21229
- ...card.card,
21230
- status: "active",
21231
- updatedAt,
21232
- revision: this.revisionFor(card.card, "active", updatedAt)
21233
- };
21234
- try {
21235
- const current = await this.requireCard(storage, card.card.cardId, namespace, principal);
21236
- return await this.finishCommittedApproval(storage, current, lock, principal, namespace);
21237
- } catch (error) {
21238
- if (isStorageConflict(error)) throw error;
21239
- log.warn(
21240
- `support passport could not finish replacement approval side effects: ${error instanceof Error ? error.message : String(error)}`
21241
- );
21242
- return committedCard;
21243
- }
21244
- });
21245
- }
21246
- async rejectCard(input) {
21247
- return await this.changeStatus(input, "pending_review", "rejected");
21248
- }
21249
- async withdrawCard(input) {
21250
- return await this.changeStatus(input, "active", "archived");
21251
- }
21252
- async createDraft(storage, input, lock, principal, namespace) {
21253
- const now = this.now();
21254
- const reviewBy = input.reviewBy ?? now.toISOString();
21255
- const storedCards = await this.readStoredCards(storage, lock, principal, namespace);
21256
- const visibleCards = this.ownerVisibleCards(storedCards);
21257
- const replacesVisibleCard = visibleCards.some(
21258
- (item) => input.replacesDraftId === item.card.cardId && item.card.status === "pending_review" || input.supersedes === item.card.cardId && item.card.status === "active"
21259
- );
21260
- if (visibleCards.length - (replacesVisibleCard ? 1 : 0) >= MAX_OWNER_VISIBLE_CARDS) {
21261
- throw new SupportPassportError("invalid_input", "A support passport can contain at most 100 visible cards.", 400);
21262
- }
21263
- const maximumOrder = storedCards.reduce((maximum, card) => Math.max(maximum, card.order), -1);
21264
- const order = input.order ?? maximumOrder + 1;
21265
- if (!Number.isSafeInteger(order)) {
21266
- throw new SupportPassportError("storage_conflict", "The support card order range is exhausted.", 409);
21267
- }
21268
- const envelope = composeMemoryEnvelope(
21269
- {
21270
- content: input.statement,
21271
- category: "preference",
21272
- tags: [SUPPORT_PASSPORT_CARD_TAG],
21273
- structuredAttributes: {
21274
- ...encodeSupportPassportNamespaceAttributes(namespace),
21275
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.owner]: computeSupportPassportOwnerKey(principal),
21276
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.title]: input.title,
21277
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.category]: input.category,
21278
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.order]: String(order),
21279
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.reviewBy]: reviewBy,
21280
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.sourceMemoryIds]: input.sourceMemoryIds.join(","),
21281
- ...input.replacesDraftId ? { [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.replacesDraftId]: input.replacesDraftId } : {},
21282
- ...input.replacedRevision ? { [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.replacedRevision]: input.replacedRevision } : {},
21283
- ...input.draftReplacementPrepared ? { [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.draftReplacementPrepared]: "true" } : {}
21284
- },
21285
- sourceReason: "support-passport"
21286
- },
21287
- { source: "support-passport", now: this.now }
21288
- );
21289
- if (envelope.sanitizeViolations.length > 0) throw invalidInput();
21290
- await this.requireOwnerLock(lock);
21291
- const written = await storage.writeSealedMemory(envelope, {
21292
- actor: principal,
21293
- status: "pending_review",
21294
- lineage: input.sourceMemoryIds.length > 0 ? input.sourceMemoryIds : void 0,
21295
- supersedes: input.supersedes
21296
- });
21297
- if (written.tombstoneBlocked) {
21298
- throw new SupportPassportError("storage_conflict", "The support card needs memory review before use.", 409);
21299
- }
21300
- return this.projectRequiredCard(written.memory, namespace, principal).card;
21301
- }
21302
- async changeStatus(input, expectedStatus, nextStatus) {
21303
- const parsed = SupportPassportCardMutationInputSchema.safeParse(input);
21304
- if (!parsed.success) throw invalidInput();
21305
- const { principal, namespace, storage } = await this.resolveOwnerScope(parsed.data.principal);
21306
- return await withSupportPassportOwnerLock(storage, { namespace, principal }, async (lock) => {
21307
- let card = await this.requireCard(storage, parsed.data.cardId, namespace, principal);
21308
- this.requireRevision(card, parsed.data.expectedRevision);
21309
- this.requireStatus(card, expectedStatus);
21310
- if (expectedStatus === "pending_review" && nextStatus === "rejected") {
21311
- await this.rejectPendingReplacementForPredecessor(storage, card, lock, principal, namespace);
21312
- card = await this.requireCard(storage, card.card.cardId, namespace, principal);
21313
- this.requireRevision(card, parsed.data.expectedRevision);
21314
- this.requireStatus(card, expectedStatus);
21315
- }
21316
- if (expectedStatus === "pending_review" || expectedStatus === "active" && (card.replacesDraftId || card.memory.frontmatter.supersedes)) {
21317
- card = this.projectRequiredCard(
21318
- await this.recoverReplacementTransition(storage, card.memory, lock, principal, namespace, {
21319
- rollbackConflictedApproval: expectedStatus !== "active"
21320
- }),
21321
- namespace,
21322
- principal
21323
- );
21324
- }
21325
- if (card.card.status === nextStatus) return card.card;
21326
- this.requireStatus(card, expectedStatus);
21327
- if (expectedStatus === "active" && nextStatus === "archived") {
21328
- await this.rejectPendingReplacementForPredecessor(storage, card, lock, principal, namespace);
21329
- card = await this.requireCard(storage, card.card.cardId, namespace, principal);
21330
- this.requireRevision(card, parsed.data.expectedRevision);
21331
- this.requireStatus(card, expectedStatus);
21332
- }
21333
- const updatedAt = this.now().toISOString();
21334
- await this.requireOwnerLock(lock);
21335
- const changed = await storage.writeMemoryFrontmatterIfUnchanged(
21336
- card.memory,
21337
- {
21338
- status: nextStatus,
21339
- updated: updatedAt,
21340
- ...nextStatus === "archived" ? { archivedAt: updatedAt } : {}
21341
- },
21342
- { actor: principal, reasonCode: nextStatus === "archived" ? "owner-withdrew" : "owner-rejected" }
21343
- );
21344
- if (!changed)
21345
- throw new SupportPassportError(
21346
- "storage_conflict",
21347
- "The support card changed before the request completed.",
21348
- 409
21349
- );
21350
- return {
21351
- ...card.card,
21352
- status: nextStatus,
21353
- updatedAt,
21354
- revision: this.revisionFor(card.card, nextStatus, updatedAt)
21355
- };
21356
- });
21357
- }
21358
- revisionFor(card, status, updatedAt) {
21359
- return computeSupportPassportCardRevision({
21360
- cardId: card.cardId,
21361
- title: card.title,
21362
- statement: card.statement,
21363
- category: card.category,
21364
- status,
21365
- updatedAt,
21366
- reviewBy: card.reviewBy
21367
- });
21368
- }
21369
- async resolveOwnerScope(principal) {
21370
- const requestedPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal });
21371
- const owner = await this.resolveOwner(principal);
21372
- const namespace = SupportPassportNamespaceSchema.safeParse(owner.namespace);
21373
- const ownerPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal: owner.principal });
21374
- if (!requestedPrincipal.success || !namespace.success || !ownerPrincipal.success || ownerPrincipal.data.principal !== requestedPrincipal.data.principal) {
21375
- throw new SupportPassportError("card_data_invalid", "The support passport owner scope is invalid.", 500);
21376
- }
21377
- return { ...owner, principal: ownerPrincipal.data.principal, namespace: namespace.data };
21378
- }
21379
- async rejectCreatedDraft(storage, cardId, reasonCode, lock, principal, namespace) {
21380
- try {
21381
- const current = await this.requireCard(storage, cardId, namespace, principal);
21382
- await this.requireOwnerLock(lock);
21383
- const rejected = await storage.writeMemoryFrontmatterIfUnchanged(
21384
- current.memory,
21385
- { status: "rejected", updated: this.now().toISOString() },
21386
- { actor: principal, reasonCode }
21387
- );
21388
- if (!rejected) log.warn("support passport could not roll back a replacement draft");
21389
- } catch (error) {
21390
- log.warn(
21391
- `support passport could not roll back a replacement draft: ${error instanceof Error ? error.message : String(error)}`
21392
- );
21393
- }
21394
- }
21395
- async requireCard(storage, cardId, namespace, principal) {
21396
- const stored = await storage.getMemoryById(cardId);
21397
- const card = stored ? this.projectOwnedCard(stored, namespace, principal) : null;
21398
- if (!card) throw new SupportPassportError("card_not_found", "The support card was not found.", 404);
21399
- return card;
21400
- }
21401
- projectRequiredCard(memory, namespace, principal) {
21402
- const card = projectSupportPassportCard(memory);
21403
- if (!card) throw new SupportPassportError("card_data_invalid", "The support card data is invalid.", 500);
21404
- if (card.namespace !== namespace || card.owner !== computeSupportPassportOwnerKey(principal)) {
21405
- throw new SupportPassportError("card_not_found", "The support card was not found.", 404);
21406
- }
21407
- return card;
21408
- }
21409
- projectOwnedCard(memory, namespace, principal) {
21410
- const card = projectSupportPassportCard(memory);
21411
- return card?.namespace === namespace && card.owner === computeSupportPassportOwnerKey(principal) ? card : null;
21412
- }
21413
- ownsMemory(memory, namespace, principal) {
21414
- const attributes = memory.frontmatter.structuredAttributes;
21415
- return attributes !== void 0 && decodeSupportPassportNamespaceAttributes(attributes) === namespace && attributes[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.owner] === computeSupportPassportOwnerKey(principal);
21416
- }
21417
- async readProjectedCards(storage, namespace, principal) {
21418
- const owner = computeSupportPassportOwnerKey(principal);
21419
- const projected = (await storage.readAllMemories()).map(projectSupportPassportCard).filter((card) => card?.namespace === namespace && card.owner === owner);
21420
- const ids = /* @__PURE__ */ new Set();
21421
- for (const item of projected) {
21422
- if (ids.has(item.card.cardId)) {
21423
- throw new SupportPassportError("card_data_invalid", "Support card IDs must be unique.", 500);
21424
- }
21425
- ids.add(item.card.cardId);
21426
- }
21427
- return projected;
21428
- }
21429
- requireRevision(card, expectedRevision) {
21430
- if (card.card.revision !== expectedRevision) {
21431
- throw new SupportPassportError("revision_conflict", "The support card changed after it was loaded.", 409);
21432
- }
21433
- }
21434
- requireStatus(card, status) {
21435
- if (card.card.status !== status) {
21436
- throw new SupportPassportError("invalid_card_status", `The support card must have status ${status}.`, 409);
21437
- }
21438
- }
21439
- async readStoredCards(storage, lock, principal, namespace) {
21440
- const initialVersion = storage.getCorpusScanVersion();
21441
- const initial = await storage.readAllMemories();
21442
- for (const memory of initial) {
21443
- const card = this.projectOwnedCard(memory, namespace, principal);
21444
- if (card) await this.recoverReplacementTransition(storage, memory, lock, principal, namespace);
21445
- }
21446
- const memories = storage.getCorpusScanVersion() === initialVersion ? initial : await storage.readAllMemories();
21447
- const owner = computeSupportPassportOwnerKey(principal);
21448
- const projected = memories.map(projectSupportPassportCard).filter((card) => card?.namespace === namespace && card.owner === owner);
21449
- const ids = /* @__PURE__ */ new Set();
21450
- for (const item of projected) {
21451
- if (ids.has(item.card.cardId)) {
21452
- throw new SupportPassportError("card_data_invalid", "Support card IDs must be unique.", 500);
21453
- }
21454
- ids.add(item.card.cardId);
21455
- }
21456
- return projected;
21457
- }
21458
- ownerVisibleCards(storedCards) {
21459
- const visibleCards = storedCards.filter(
21460
- (item) => OWNER_VISIBLE_STATUSES.has(item.card.status) && !item.draftReplacementPrepared
21461
- );
21462
- if (visibleCards.length <= MAX_OWNER_VISIBLE_CARDS) return visibleCards;
21463
- const activeCardsWithPendingReplacements = new Set(
21464
- visibleCards.filter((item) => item.card.status === "pending_review").map((item) => item.memory.frontmatter.supersedes).filter((cardId) => typeof cardId === "string")
21465
- );
21466
- return visibleCards.filter(
21467
- (item) => item.card.status !== "active" || !activeCardsWithPendingReplacements.has(item.card.cardId)
21468
- );
21469
- }
21470
- async preparePriorForReplacement(storage, replacement, lock, principal, namespace) {
21471
- const priorId = replacement.memory.frontmatter.supersedes;
21472
- if (!priorId) return null;
21473
- const priorMemory = await storage.getMemoryById(priorId);
21474
- const priorIsOwned = priorMemory ? this.ownsMemory(priorMemory, namespace, principal) : false;
21475
- const alreadyRetired = priorIsOwned && priorMemory?.frontmatter.status === "superseded" && priorMemory.frontmatter.supersededBy === replacement.card.cardId;
21476
- const prior = priorMemory && priorIsOwned && !alreadyRetired ? projectSupportPassportCard(priorMemory) : null;
21477
- if (prior?.card.status === "rejected") return null;
21478
- if (!priorMemory || !alreadyRetired && prior?.card.status !== "active") {
21479
- throw new SupportPassportError("storage_conflict", "The prior support card changed before replacement.", 409);
21480
- }
21481
- if (alreadyRetired) return priorId;
21482
- const retiredAt = this.now().toISOString();
21483
- await this.requireOwnerLock(lock);
21484
- const retired = await storage.writeMemoryFrontmatterIfUnchanged(
21485
- priorMemory,
21486
- {
21487
- status: "superseded",
21488
- supersededBy: replacement.card.cardId,
21489
- supersededAt: retiredAt,
21490
- supersessionCause: "direct",
21491
- updated: retiredAt
21492
- },
21493
- {
21494
- actor: principal,
21495
- reasonCode: "support-passport-replacement-pending",
21496
- relatedMemoryIds: [replacement.card.cardId]
21497
- }
21498
- );
21499
- if (!retired) {
21500
- throw new SupportPassportError("storage_conflict", "The prior support card changed before replacement.", 409);
21501
- }
21502
- return priorId;
21503
- }
21504
- async rejectPendingReplacementForPredecessor(storage, predecessor, lock, principal, namespace) {
21505
- const storedCards = predecessor.card.status === "active" ? await this.readStoredCards(storage, lock, principal, namespace) : await this.readProjectedCards(storage, namespace, principal);
21506
- const replacements = storedCards.filter((item) => {
21507
- if (item.card.status !== "pending_review") return false;
21508
- return predecessor.card.status === "pending_review" ? item.replacesDraftId === predecessor.card.cardId : item.memory.frontmatter.supersedes === predecessor.card.cardId;
21509
- });
21510
- if (replacements.length > 1) {
21511
- throw new SupportPassportError(
21512
- "storage_conflict",
21513
- "Multiple support card edits target the card being withdrawn.",
21514
- 409
21515
- );
21516
- }
21517
- const [replacement] = replacements;
21518
- if (!replacement) return;
21519
- await this.requireOwnerLock(lock);
21520
- const rejected = await storage.writeMemoryFrontmatterIfUnchanged(
21521
- replacement.memory,
21522
- { status: "rejected", updated: this.now().toISOString() },
21523
- {
21524
- actor: principal,
21525
- reasonCode: predecessor.card.status === "pending_review" ? "source-draft-rejected" : "predecessor-withdrawn"
21526
- }
21527
- );
21528
- if (rejected) return;
21529
- const current = await storage.getMemoryById(replacement.card.cardId);
21530
- const currentCard = current ? this.projectOwnedCard(current, namespace, principal) : null;
21531
- if (currentCard?.card.status !== "rejected") {
21532
- throw new SupportPassportError("storage_conflict", "The pending support card edit could not be cancelled.", 409);
21533
- }
21534
- }
21535
- async validatePriorForReplacement(storage, replacement, namespace, principal) {
21536
- const priorId = replacement.memory.frontmatter.supersedes;
21537
- if (!priorId) return;
21538
- const priorMemory = await storage.getMemoryById(priorId);
21539
- const priorIsOwned = priorMemory ? this.ownsMemory(priorMemory, namespace, principal) : false;
21540
- const alreadyRetired = priorIsOwned && priorMemory?.frontmatter.status === "superseded" && priorMemory.frontmatter.supersededBy === replacement.card.cardId;
21541
- const prior = priorMemory && priorIsOwned && !alreadyRetired ? projectSupportPassportCard(priorMemory) : null;
21542
- if (prior?.card.status === "rejected" || alreadyRetired) return;
21543
- if (!priorMemory || prior?.card.status !== "active") {
21544
- throw new SupportPassportError("storage_conflict", "The prior support card changed before replacement.", 409);
21545
- }
21546
- }
21547
- async recoverReplacementTransition(storage, memory, lock, principal, namespace, options = {}) {
21548
- const replacement = this.projectOwnedCard(memory, namespace, principal);
21549
- if (replacement?.card.status !== "pending_review" && replacement?.card.status !== "active") return memory;
21550
- if (!replacement.replacesDraftId && !memory.frontmatter.supersedes) return memory;
21551
- if (replacement.card.status === "active" && memory.frontmatter.structuredAttributes?.[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.replacementComplete] === "true") {
21552
- return memory;
21553
- }
21554
- await this.recoverReplacedDraft(storage, replacement, lock, principal, namespace);
21555
- const currentMemory = await storage.getMemoryById(replacement.card.cardId) ?? memory;
21556
- const currentCard = this.projectOwnedCard(currentMemory, namespace, principal);
21557
- if (currentCard?.card.status !== "pending_review" && currentCard?.card.status !== "active") {
21558
- return currentMemory;
21559
- }
21560
- if (currentCard.card.status === "pending_review") {
21561
- const priorId = currentMemory.frontmatter.supersedes;
21562
- if (!priorId) return currentMemory;
21563
- const prior = await storage.getMemoryById(priorId);
21564
- if (prior && this.ownsMemory(prior, namespace, principal) && prior.frontmatter.status === "superseded" && prior.frontmatter.supersededBy === replacement.card.cardId) {
21565
- await this.restorePriorAfterApprovalFailure(
21566
- storage,
21567
- priorId,
21568
- replacement.card.cardId,
21569
- lock,
21570
- principal,
21571
- namespace
21572
- );
21573
- }
21574
- return await storage.getMemoryById(replacement.card.cardId) ?? currentMemory;
21575
- }
21576
- try {
21577
- await this.completeReplacementAfterActivation(storage, currentCard, lock, principal, namespace);
21578
- } catch (error) {
21579
- if (!isStorageConflict(error)) throw error;
21580
- if (options.rollbackConflictedApproval === false) throw error;
21581
- await this.rollbackConflictedApproval(storage, currentCard.card.cardId, lock, principal, namespace);
21582
- }
21583
- return await storage.getMemoryById(replacement.card.cardId) ?? currentMemory;
21584
- }
21585
- async completeReplacementAfterActivation(storage, replacement, lock, principal, namespace) {
21586
- const priorId = await this.preparePriorForReplacement(storage, replacement, lock, principal, namespace);
21587
- if (priorId && !await this.completePriorRetirement(storage, priorId, replacement, lock, principal, namespace)) {
21588
- throw new SupportPassportError("storage_conflict", "The prior support card changed before replacement.", 409);
21589
- }
21590
- await this.markReplacementComplete(storage, replacement.card.cardId, lock, principal, namespace);
21591
- }
21592
- async finishCommittedApproval(storage, replacement, lock, principal, namespace) {
21593
- try {
21594
- if (replacement.replacesDraftId || replacement.memory.frontmatter.supersedes) {
21595
- await this.completeReplacementAfterActivation(storage, replacement, lock, principal, namespace);
21596
- }
21597
- } catch (error) {
21598
- if (isStorageConflict(error)) {
21599
- await this.rollbackConflictedApproval(storage, replacement.card.cardId, lock, principal, namespace);
21600
- throw error;
21601
- }
21602
- log.warn(
21603
- `support passport could not finish replacement approval side effects: ${error instanceof Error ? error.message : String(error)}`
21604
- );
21605
- }
21606
- return replacement.card;
21607
- }
21608
- async rollbackConflictedApproval(storage, replacementId, lock, principal, namespace) {
21609
- const replacement = await this.requireCard(storage, replacementId, namespace, principal);
21610
- if (replacement.card.status !== "active") return;
21611
- await this.requireOwnerLock(lock);
21612
- const rolledBack = await storage.writeMemoryFrontmatterIfUnchanged(
21613
- replacement.memory,
21614
- { status: "pending_review", updated: this.now().toISOString() },
21615
- { actor: principal, reasonCode: "replacement-predecessor-conflict" }
21616
- );
21617
- if (!rolledBack) {
21618
- throw new SupportPassportError(
21619
- "storage_conflict",
21620
- "The replacement changed while its approval was rolled back.",
21621
- 409
21622
- );
21623
- }
21624
- const priorId = replacement.memory.frontmatter.supersedes;
21625
- if (priorId) {
21626
- await this.restorePriorAfterApprovalFailure(storage, priorId, replacementId, lock, principal, namespace);
21627
- }
21628
- }
21629
- async completePriorRetirement(storage, priorId, replacement, lock, principal, namespace) {
21630
- const replacementId = replacement.card.cardId;
21631
- const prior = await storage.getMemoryById(priorId);
21632
- if (!prior || !this.ownsMemory(prior, namespace, principal) || prior.frontmatter.status !== "superseded" || prior.frontmatter.supersededBy !== replacementId) {
21633
- return false;
21634
- }
21635
- await this.requireOwnerLock(lock);
21636
- const completed = await storage.supersedeMemory(
21637
- priorId,
21638
- replacementId,
21639
- "support-passport-replacement",
21640
- { supersessionCause: "direct" },
21641
- {
21642
- actor: principal,
21643
- requireActive: true,
21644
- acceptExactReplay: true,
21645
- expectedSnapshot: prior,
21646
- audit: {
21647
- content: stripAttributesSuffix(prior.content),
21648
- tags: ["supersession", "auto-resolved", "support-passport-audit"],
21649
- structuredAttributes: {
21650
- ...encodeSupportPassportNamespaceAttributes(namespace),
21651
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.owner]: computeSupportPassportOwnerKey(principal)
21652
- },
21653
- source: "support-passport"
21654
- }
21655
- }
21656
- );
21657
- if (!completed) log.warn("support passport could not complete replacement retirement side effects");
21658
- return completed;
21659
- }
21660
- async recoverReplacedDraft(storage, replacement, lock, principal, namespace) {
21661
- if (!replacement.replacesDraftId) return;
21662
- const replacedDraft = await storage.getMemoryById(replacement.replacesDraftId);
21663
- const projectedDraft = replacedDraft ? this.projectOwnedCard(replacedDraft, namespace, principal) : null;
21664
- if (replacedDraft && projectedDraft?.card.status === "pending_review" && projectedDraft.card.revision === replacement.replacedRevision) {
21665
- await this.requireOwnerLock(lock);
21666
- const rejected = await storage.writeMemoryFrontmatterIfUnchanged(
21667
- replacedDraft,
21668
- { status: "rejected", updated: this.now().toISOString() },
21669
- { actor: principal, reasonCode: "complete-draft-replacement" }
21670
- );
21671
- if (rejected) {
21672
- await this.finishPreparedDraftReplacement(storage, replacement.card.cardId, lock, principal, namespace);
21673
- return;
21674
- }
21675
- }
21676
- const currentDraft = await storage.getMemoryById(replacement.replacesDraftId);
21677
- if (currentDraft && this.ownsMemory(currentDraft, namespace, principal) && currentDraft.frontmatter.status === "rejected") {
21678
- await this.finishPreparedDraftReplacement(storage, replacement.card.cardId, lock, principal, namespace);
21679
- return;
21680
- }
21681
- if (currentDraft && this.ownsMemory(currentDraft, namespace, principal) && currentDraft.frontmatter.status === "pending_review") {
21682
- throw new SupportPassportError("storage_conflict", "The replaced draft changed during recovery.", 409);
21683
- }
21684
- await this.rejectOrphanedReplacement(storage, replacement.card.cardId, lock, principal, namespace);
21685
- }
21686
- async finishPreparedDraftReplacement(storage, replacementId, lock, principal, namespace) {
21687
- const replacement = await this.requireCard(storage, replacementId, namespace, principal);
21688
- if (!replacement.draftReplacementPrepared) return replacement.card;
21689
- const structuredAttributes = { ...replacement.memory.frontmatter.structuredAttributes };
21690
- delete structuredAttributes[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.draftReplacementPrepared];
21691
- await this.requireOwnerLock(lock);
21692
- const finished = await storage.writeMemoryFrontmatterIfUnchanged(
21693
- replacement.memory,
21694
- { structuredAttributes },
21695
- { actor: principal, reasonCode: "draft-replacement-complete" }
21696
- );
21697
- if (finished) {
21698
- return this.projectRequiredCard(
21699
- { ...replacement.memory, frontmatter: { ...replacement.memory.frontmatter, structuredAttributes } },
21700
- namespace,
21701
- principal
21702
- ).card;
21703
- }
21704
- const current = await this.requireCard(storage, replacementId, namespace, principal);
21705
- if (!current.draftReplacementPrepared) return current.card;
21706
- throw new SupportPassportError("storage_conflict", "The support card edit could not be completed.", 409);
21707
- }
21708
- async rejectOrphanedReplacement(storage, replacementId, lock, principal, namespace) {
21709
- const currentReplacement = await this.requireCard(storage, replacementId, namespace, principal);
21710
- if (currentReplacement.card.status === "rejected") return;
21711
- this.requireStatus(currentReplacement, "pending_review");
21712
- await this.requireOwnerLock(lock);
21713
- const rejected = await storage.writeMemoryFrontmatterIfUnchanged(
21714
- currentReplacement.memory,
21715
- { status: "rejected", updated: this.now().toISOString() },
21716
- { actor: principal, reasonCode: "replaced-draft-approved" }
21717
- );
21718
- if (rejected) return;
21719
- const latest = await storage.getMemoryById(replacementId);
21720
- if (latest?.frontmatter.status !== "rejected") {
21721
- throw new SupportPassportError("storage_conflict", "The orphaned replacement could not be rejected.", 409);
21722
- }
21723
- }
21724
- async restorePriorAfterApprovalFailure(storage, priorId, replacementId, lock, principal, namespace) {
21725
- const replacement = await storage.getMemoryById(replacementId);
21726
- if (replacement && !this.ownsMemory(replacement, namespace, principal)) {
21727
- throw new SupportPassportError("storage_conflict", "The replacement support card changed ownership.", 409);
21728
- }
21729
- if (replacement?.frontmatter.status === "active") return;
21730
- const prior = await storage.getMemoryById(priorId);
21731
- if (prior && !this.ownsMemory(prior, namespace, principal)) {
21732
- throw new SupportPassportError("storage_conflict", "The prior support card changed ownership.", 409);
21733
- }
21734
- if (prior?.frontmatter.status === "active" && prior.frontmatter.supersededBy === void 0) return;
21735
- if (prior?.frontmatter.status !== "superseded" || prior.frontmatter.supersededBy !== replacementId) {
21736
- throw new SupportPassportError("storage_conflict", "The prior support card could not be restored.", 409);
21737
- }
21738
- await this.requireOwnerLock(lock);
21739
- const restored = await storage.writeMemoryFrontmatterIfUnchanged(
21740
- prior,
21741
- {
21742
- status: "active",
21743
- supersededBy: void 0,
21744
- supersededAt: void 0,
21745
- supersessionCause: void 0,
21746
- invalidatedBy: void 0,
21747
- updated: this.now().toISOString()
21748
- },
21749
- { actor: principal, reasonCode: "replacement-activation-failed" }
21750
- );
21751
- if (restored) return;
21752
- const currentPrior = await storage.getMemoryById(priorId);
21753
- if (currentPrior?.frontmatter.status === "active" && currentPrior.frontmatter.supersededBy === void 0) return;
21754
- throw new SupportPassportError("storage_conflict", "The prior support card could not be restored.", 409);
21755
- }
21756
- async markReplacementComplete(storage, replacementId, lock, principal, namespace) {
21757
- const replacement = await this.requireCard(storage, replacementId, namespace, principal);
21758
- if (replacement.memory.frontmatter.structuredAttributes?.[SUPPORT_PASSPORT_ATTRIBUTE_KEYS.replacementComplete] === "true") {
21759
- return;
21760
- }
21761
- await this.requireOwnerLock(lock);
21762
- const marked = await storage.writeMemoryFrontmatterIfUnchanged(
21763
- replacement.memory,
21764
- {
21765
- structuredAttributes: {
21766
- ...replacement.memory.frontmatter.structuredAttributes,
21767
- [SUPPORT_PASSPORT_ATTRIBUTE_KEYS.replacementComplete]: "true"
21768
- }
21769
- },
21770
- { actor: principal, reasonCode: "replacement-side-effects-complete" }
21771
- );
21772
- if (!marked) log.warn("support passport could not mark replacement side effects complete");
21773
- }
21774
- async requireOwnerLock(lock) {
21775
- if (await lock.refresh()) return;
21776
- throw new SupportPassportError("storage_conflict", "The support passport lock changed. Try again.", 409);
21777
- }
21778
- };
21779
-
21780
- // src/support-passport/grant-contracts.ts
21781
- import { z } from "zod";
21782
- var IsoTimestampSchema = z.string().datetime({ offset: true }).refine((value) => parseIsoOffsetTimestamp(value) !== null, "timestamp must be a real date");
21783
- var RevisionSchema = z.string().regex(/^[a-f0-9]{64}$/);
21784
- var GrantIdSchema = z.string().uuid().transform((value) => value.toLowerCase());
21785
- var SupportPassportGrantCardRefSchema = z.object({
21786
- cardId: SupportPassportMemoryIdSchema,
21787
- revision: RevisionSchema
21788
- }).strict();
21789
- var SupportPassportGrantStateSchema = z.object({
21790
- schemaVersion: z.literal(1),
21791
- stateVersion: z.number().int().positive(),
21792
- grantId: GrantIdSchema,
21793
- namespace: SupportPassportNamespaceSchema,
21794
- principalHash: RevisionSchema,
21795
- ownerLockKey: RevisionSchema,
21796
- secretHash: RevisionSchema,
21797
- cards: z.array(SupportPassportGrantCardRefSchema).min(1).max(8),
21798
- createdAt: IsoTimestampSchema,
21799
- expiresAt: IsoTimestampSchema,
21800
- revokedAt: IsoTimestampSchema.optional()
21801
- }).strict().superRefine((grant, ctx) => {
21802
- const ids = /* @__PURE__ */ new Set();
21803
- for (const [index, card] of grant.cards.entries()) {
21804
- if (ids.has(card.cardId)) {
21805
- ctx.addIssue({
21806
- code: z.ZodIssueCode.custom,
21807
- message: "card IDs must be unique",
21808
- path: ["cards", index, "cardId"]
21809
- });
21810
- }
21811
- ids.add(card.cardId);
21812
- }
21813
- if (Date.parse(grant.expiresAt) <= Date.parse(grant.createdAt)) {
21814
- ctx.addIssue({ code: z.ZodIssueCode.custom, message: "expiresAt must follow createdAt", path: ["expiresAt"] });
21815
- }
21816
- });
21817
- var SupportPassportCreateGrantInputSchema = z.object({
21818
- principal: z.string().trim().min(1).max(512),
21819
- cards: z.array(SupportPassportGrantCardRefSchema).min(1).max(8),
21820
- expiresAt: IsoTimestampSchema
21821
- }).strict().superRefine((input, ctx) => {
21822
- const ids = /* @__PURE__ */ new Set();
21823
- for (const [index, card] of input.cards.entries()) {
21824
- if (ids.has(card.cardId)) {
21825
- ctx.addIssue({
21826
- code: z.ZodIssueCode.custom,
21827
- message: "card IDs must be unique",
21828
- path: ["cards", index, "cardId"]
21829
- });
21830
- }
21831
- ids.add(card.cardId);
21832
- }
21833
- });
21834
- var SupportPassportOwnerGrantSchema = z.object({
21835
- grantId: GrantIdSchema,
21836
- stateVersion: z.number().int().positive(),
21837
- cards: z.array(SupportPassportGrantCardRefSchema).min(1).max(8),
21838
- createdAt: IsoTimestampSchema,
21839
- expiresAt: IsoTimestampSchema,
21840
- revokedAt: IsoTimestampSchema.optional(),
21841
- status: z.enum(["active", "expired", "revoked"])
21842
- }).strict();
21843
- var SupportPassportCreatedGrantSchema = z.object({
21844
- grant: SupportPassportOwnerGrantSchema,
21845
- secret: z.string().regex(/^[A-Za-z0-9_-]{43}$/)
21846
- }).strict();
21847
- var SupportPassportPublicCardSchema = z.object({
21848
- cardId: SupportPassportMemoryIdSchema,
21849
- title: z.string().trim().min(1).max(80),
21850
- statement: z.string().trim().min(1).max(500),
21851
- category: SupportPassportCardCategorySchema,
21852
- updatedAt: IsoTimestampSchema
21853
- }).strict();
21854
- var SupportPassportPublicGuideSchema = z.object({
21855
- schemaVersion: z.literal(1),
21856
- grantId: GrantIdSchema,
21857
- expiresAt: IsoTimestampSchema,
21858
- updatedAt: IsoTimestampSchema,
21859
- cards: z.array(SupportPassportPublicCardSchema).min(1).max(8)
21860
- }).strict();
21861
- var SupportPassportRevokeGrantInputSchema = z.object({
21862
- principal: z.string().trim().min(1).max(512),
21863
- grantId: GrantIdSchema,
21864
- expectedStateVersion: z.number().int().positive().optional()
21865
- }).strict();
21866
- var SupportPassportListGrantsInputSchema = z.object({
21867
- principal: z.string().trim().min(1).max(512)
21868
- }).strict();
21869
-
21870
- // src/support-passport/grant-store.ts
21871
- import { createHash as createHash10, randomBytes as randomBytes3, randomUUID as randomUUID3, timingSafeEqual } from "crypto";
21872
- import { lstat as lstat4, open as open2, readdir as readdir4 } from "fs/promises";
21873
- import path23 from "path";
21874
-
21875
- // src/support-passport/private-file.ts
21876
- import { randomUUID as randomUUID2 } from "crypto";
21877
- import { constants as fsConstants } from "fs";
21878
- import { lstat as lstat3, mkdir as mkdir7, open, rename, rm, stat as stat4 } from "fs/promises";
21879
- import path22 from "path";
21880
- var UNSUPPORTED_DIRECTORY_SYNC_ERRORS = /* @__PURE__ */ new Set(["EINVAL", "ENOSYS", "ENOTSUP", "EOPNOTSUPP"]);
21881
- var NON_WRITABLE_ANCESTOR_SYNC_ERRORS = /* @__PURE__ */ new Set(["EROFS", "EPERM", "EACCES"]);
21882
- function assertStableDirectory(before, opened, after, errorMessage) {
21883
- if (before.isSymbolicLink() || !before.isDirectory() || after.isSymbolicLink() || !after.isDirectory() || before.dev !== opened.dev || before.ino !== opened.ino || after.dev !== opened.dev || after.ino !== opened.ino) {
21884
- throw new Error(errorMessage);
21885
- }
21886
- }
21887
- function assertStableRegularFile(before, opened, after, errorMessage) {
21888
- if (before.isSymbolicLink() || !before.isFile() || after.isSymbolicLink() || !after.isFile() || before.dev !== opened.dev || before.ino !== opened.ino || after.dev !== opened.dev || after.ino !== opened.ino || opened.nlink !== 1) {
21889
- throw new Error(errorMessage);
21890
- }
21891
- }
21892
- function openFlags(...flags) {
21893
- let combined = 0;
21894
- for (const flag of flags) combined |= typeof flag === "number" ? flag : 0;
21895
- return combined;
21896
- }
21897
- function assertContainedPath(trustedRoot, directory, errorMessage) {
21898
- const relative = path22.relative(path22.resolve(trustedRoot), path22.resolve(directory));
21899
- if (relative === ".." || relative.startsWith(`..${path22.sep}`) || path22.isAbsolute(relative)) {
21900
- throw new Error(errorMessage);
21901
- }
21902
- }
21903
- async function openDirectoryNoFollow(directory, errorMessage) {
21904
- const before = await lstat3(directory);
21905
- if (before.isSymbolicLink() || !before.isDirectory()) throw new Error(errorMessage);
21906
- const handle = await open(
21907
- directory,
21908
- openFlags(fsConstants.O_RDONLY, fsConstants.O_DIRECTORY, fsConstants.O_NOFOLLOW)
21909
- );
21910
- try {
21911
- const opened = await handle.stat();
21912
- assertStableDirectory(before, opened, await lstat3(directory), errorMessage);
21913
- return { before, opened, handle };
21914
- } catch (error) {
21915
- await handle.close().catch(() => void 0);
21916
- throw error;
21917
- }
21918
- }
21919
- async function closeDirectoryHandles(handles) {
21920
- for (const handle of handles.reverse()) await handle.close().catch(() => void 0);
21921
- }
21922
- async function syncDirectoryHandle(handle) {
21923
- try {
21924
- await handle.sync();
21925
- } catch (error) {
21926
- const code = error.code;
21927
- if (!UNSUPPORTED_DIRECTORY_SYNC_ERRORS.has(code ?? "")) throw error;
21928
- }
21929
- }
21930
- async function resolvePrivateDirectoryPath(directory, handle, opened, errorMessage, platform = process.platform) {
21931
- const descriptorRoot = requirePrivateFileDescriptorRoot(platform, errorMessage);
21932
- const pinnedPath = path22.join(descriptorRoot, String(handle.fd));
21933
- const metadata = await stat4(pinnedPath);
21934
- if (!metadata.isDirectory() || metadata.dev !== opened.dev || metadata.ino !== opened.ino) {
21935
- throw new Error(errorMessage);
21936
- }
21937
- return pinnedPath;
21938
- }
21939
- function requirePrivateFileDescriptorRoot(platform, errorMessage) {
21940
- if (platform === "linux") return "/proc/self/fd";
21941
- if (platform === "darwin" || platform === "freebsd" || platform === "openbsd") return "/dev/fd";
21942
- throw new Error(errorMessage);
21943
- }
21944
- async function openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform = process.platform) {
21945
- const root = path22.resolve(trustedRoot);
21946
- const target = path22.resolve(directory);
21947
- assertContainedPath(root, target, errorMessage);
21948
- requirePrivateFileDescriptorRoot(platform, errorMessage);
21949
- const relative = path22.relative(root, target);
21950
- const components = relative === "" ? [] : relative.split(path22.sep);
21951
- const handles = [];
21952
- let currentPath = root;
21953
- try {
21954
- let current = await openDirectoryNoFollow(root, errorMessage);
21955
- handles.push(current.handle);
21956
- for (const component of components) {
21957
- const pinnedParent = await resolvePrivateDirectoryPath(currentPath, current.handle, current.opened, errorMessage);
21958
- const child = await openDirectoryNoFollow(path22.join(pinnedParent, component), errorMessage);
21959
- handles.push(child.handle);
21960
- assertStableDirectory(current.before, current.opened, await lstat3(currentPath), errorMessage);
21961
- currentPath = path22.join(currentPath, component);
21962
- current = child;
21963
- }
21964
- assertStableDirectory(current.before, current.opened, await lstat3(target), errorMessage);
21965
- return {
21966
- ...current,
21967
- handles,
21968
- pinnedDirectory: await resolvePrivateDirectoryPath(
21969
- target,
21970
- current.handle,
21971
- current.opened,
21972
- errorMessage,
21973
- platform
21974
- )
21975
- };
21976
- } catch (error) {
21977
- await closeDirectoryHandles(handles);
21978
- throw error;
21979
- }
21980
- }
21981
- async function ensurePrivateDirectoryNoFollow(trustedRoot, directory, errorMessage, syncVerifiedParent = syncDirectoryHandle, hardenExistingChildren = true, platform = process.platform) {
21982
- const root = path22.resolve(trustedRoot);
21983
- const target = path22.resolve(directory);
21984
- assertContainedPath(root, target, errorMessage);
21985
- const relative = path22.relative(root, target);
21986
- requirePrivateFileDescriptorRoot(platform, errorMessage);
21987
- const components = relative === "" ? [] : relative.split(path22.sep);
21988
- const handles = [];
21989
- let currentPath = root;
21990
- try {
21991
- let current = await openDirectoryNoFollow(root, errorMessage);
21992
- handles.push(current.handle);
21993
- for (const component of components) {
21994
- const pinnedParent = await resolvePrivateDirectoryPath(currentPath, current.handle, current.opened, errorMessage);
21995
- const childPath = path22.join(pinnedParent, component);
21996
- let created = false;
21997
- try {
21998
- await mkdir7(childPath, { mode: 448 });
21999
- created = true;
22000
- } catch (error) {
22001
- if (error.code !== "EEXIST") throw error;
22002
- }
22003
- await syncVerifiedParent(current.handle);
22004
- const child = await openDirectoryNoFollow(childPath, errorMessage);
22005
- handles.push(child.handle);
22006
- if (created || hardenExistingChildren && (child.opened.mode & 511) !== 448) {
22007
- await child.handle.chmod(448);
22008
- }
22009
- assertStableDirectory(current.before, current.opened, await lstat3(currentPath), errorMessage);
22010
- currentPath = path22.join(currentPath, component);
22011
- current = child;
22012
- }
22013
- assertStableDirectory(current.before, current.opened, await lstat3(target), errorMessage);
22014
- } finally {
22015
- await closeDirectoryHandles(handles);
22016
- }
22017
- }
22018
- async function ensurePrivateDirectoryTreeNoFollow(directory, errorMessage, syncVerifiedParent = syncDirectoryHandle, platform = process.platform) {
22019
- const target = path22.resolve(directory);
22020
- const filesystemRoot = path22.parse(target).root;
22021
- const rootMetadata = await stat4(filesystemRoot);
22022
- await ensurePrivateDirectoryNoFollow(
22023
- filesystemRoot,
22024
- target,
22025
- errorMessage,
22026
- async (handle) => {
22027
- try {
22028
- await syncVerifiedParent(handle);
22029
- } catch (error) {
22030
- const code = error.code;
22031
- const metadata = await handle.stat();
22032
- if (metadata.ino === rootMetadata.ino && metadata.dev === rootMetadata.dev && NON_WRITABLE_ANCESTOR_SYNC_ERRORS.has(code ?? "")) {
22033
- return;
22034
- }
22035
- throw error;
22036
- }
22037
- },
22038
- false,
22039
- platform
22040
- );
22041
- }
22042
- async function withPrivateDirectoryNoFollow(trustedRoot, directory, errorMessage, task, platform = process.platform) {
22043
- let directoryHandles = [];
22044
- try {
22045
- const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
22046
- directoryHandles = stableDirectory.handles;
22047
- const result = await task(stableDirectory.pinnedDirectory);
22048
- assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
22049
- return result;
22050
- } finally {
22051
- await closeDirectoryHandles(directoryHandles);
22052
- }
22053
- }
22054
- async function readPrivateFileNoFollow(directory, filePath, errorMessage, trustedRoot = directory, platform = process.platform) {
22055
- if (path22.dirname(filePath) !== path22.resolve(directory)) throw new Error(errorMessage);
22056
- const targetName = path22.basename(filePath);
22057
- let directoryHandles = [];
22058
- let fileHandle;
22059
- try {
22060
- const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
22061
- directoryHandles = stableDirectory.handles;
22062
- const pinnedDirectory = stableDirectory.pinnedDirectory;
22063
- const targetPath = path22.join(pinnedDirectory, targetName);
22064
- const before = await lstat3(targetPath);
22065
- if (before.isSymbolicLink() || !before.isFile()) throw new Error(errorMessage);
22066
- try {
22067
- fileHandle = await open(targetPath, openFlags(fsConstants.O_RDONLY, fsConstants.O_NOFOLLOW));
22068
- } catch (error) {
22069
- if (error.code === "ELOOP") throw new Error(errorMessage);
22070
- throw error;
22071
- }
22072
- const fileMetadata = await fileHandle.stat();
22073
- assertStableRegularFile(before, fileMetadata, await lstat3(targetPath), errorMessage);
22074
- assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
22075
- return await fileHandle.readFile("utf8");
22076
- } finally {
22077
- await fileHandle?.close().catch(() => void 0);
22078
- await closeDirectoryHandles(directoryHandles);
22079
- }
22080
- }
22081
- async function writePrivateFileAtomicallyNoFollow(directory, filePath, content, errorMessage, trustedRoot = directory, platform = process.platform) {
22082
- if (path22.dirname(filePath) !== path22.resolve(directory)) throw new Error(errorMessage);
22083
- const targetName = path22.basename(filePath);
22084
- const tempName = `.${targetName}.${randomUUID2()}.tmp`;
22085
- let tempPath;
22086
- let directoryHandles = [];
22087
- let fileHandle;
22088
- try {
22089
- const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
22090
- directoryHandles = stableDirectory.handles;
22091
- const pinnedDirectory = stableDirectory.pinnedDirectory;
22092
- tempPath = path22.join(pinnedDirectory, tempName);
22093
- const targetPath = path22.join(pinnedDirectory, targetName);
22094
- try {
22095
- fileHandle = await open(
22096
- tempPath,
22097
- openFlags(fsConstants.O_WRONLY, fsConstants.O_CREAT, fsConstants.O_EXCL, fsConstants.O_NOFOLLOW),
22098
- 384
22099
- );
22100
- } catch (error) {
22101
- if (error.code === "ELOOP") throw new Error(errorMessage);
22102
- throw error;
22103
- }
22104
- const fileMetadata = await fileHandle.stat();
22105
- const tempMetadata = await lstat3(tempPath);
22106
- assertStableRegularFile(tempMetadata, fileMetadata, await lstat3(tempPath), errorMessage);
22107
- assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
22108
- await fileHandle.chmod(384);
22109
- await fileHandle.writeFile(content, "utf8");
22110
- await fileHandle.sync();
22111
- await fileHandle.close();
22112
- fileHandle = void 0;
22113
- assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
22114
- await rename(tempPath, targetPath);
22115
- assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
22116
- if (stableDirectory.handle) await syncDirectoryHandle(stableDirectory.handle);
22117
- } finally {
22118
- await fileHandle?.close().catch(() => void 0);
22119
- if (tempPath) await rm(tempPath, { force: true }).catch(() => void 0);
22120
- await closeDirectoryHandles(directoryHandles);
22121
- }
22122
- }
22123
- async function removePrivateFilesNoFollow(directory, fileNames, errorMessage, trustedRoot = directory, platform = process.platform) {
22124
- if (fileNames.some(
22125
- (fileName) => fileName.length === 0 || fileName === "." || fileName === ".." || path22.basename(fileName) !== fileName
22126
- )) {
22127
- throw new Error(errorMessage);
22128
- }
22129
- let directoryHandles = [];
22130
- try {
22131
- const stableDirectory = await openStableDirectoryFromRoot(trustedRoot, directory, errorMessage, platform);
22132
- directoryHandles = stableDirectory.handles;
22133
- const pinnedDirectory = stableDirectory.pinnedDirectory;
22134
- for (const fileName of fileNames) {
22135
- await rm(path22.join(pinnedDirectory, fileName), { force: true });
22136
- }
22137
- assertStableDirectory(stableDirectory.before, stableDirectory.opened, await lstat3(directory), errorMessage);
22138
- if (stableDirectory.handle) await syncDirectoryHandle(stableDirectory.handle);
22139
- } finally {
22140
- await closeDirectoryHandles(directoryHandles);
22141
- }
22142
- }
22143
-
22144
- // src/support-passport/grant-store.ts
22145
- var GRANT_LOCK_STALE_MS = 3e4;
22146
- var GRANT_LOCK_WAIT_MS = 5e3;
22147
- var GRANT_LOCK_HEARTBEAT_MS = 1e4;
22148
- var SAFE_GRANT_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
22149
- var UUID_INPUT = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
22150
- var SAFE_OWNER_INDEX_HASH = /^[0-9a-f]{64}$/;
22151
- var UNSUPPORTED_DIRECTORY_SYNC_ERRORS2 = /* @__PURE__ */ new Set(["EINVAL", "ENOSYS", "ENOTSUP", "EOPNOTSUPP"]);
22152
- var MAX_OWNER_GRANT_HISTORY = 100;
22153
- var MAX_OWNER_INDEX_RECOVERY_ATTEMPTS = 3;
22154
- var OwnerIndexLockLostError = class extends Error {
22155
- constructor(cause) {
22156
- super("support passport owner index lock was lost", { cause });
22157
- this.name = "OwnerIndexLockLostError";
22158
- }
22159
- };
22160
- var MalformedGrantStateError = class extends Error {
22161
- constructor(message = "support passport grant state is invalid", cause) {
22162
- super(message, { cause });
22163
- this.name = "MalformedGrantStateError";
22164
- }
22165
- };
22166
- function sha256(domain, value) {
22167
- return createHash10("sha256").update(domain).update("\0").update(value).digest("hex");
22168
- }
22169
- function hashesMatch(left, right) {
22170
- const leftBytes = Buffer.from(left, "hex");
22171
- const rightBytes = Buffer.from(right, "hex");
22172
- return leftBytes.length === 32 && rightBytes.length === 32 && timingSafeEqual(leftBytes, rightBytes);
22173
- }
22174
- function sameGrantState(left, right) {
22175
- return JSON.stringify(left) === JSON.stringify(right);
22176
- }
22177
- function newestGrantFirst(left, right) {
22178
- return Date.parse(right.createdAt) - Date.parse(left.createdAt) || left.grantId.localeCompare(right.grantId);
22179
- }
22180
- function grantNotFound() {
22181
- return new SupportPassportError("grant_not_found", "The share link was not found.", 404);
22182
- }
22183
- function warnCommitNotificationFailure(error) {
22184
- log.warn(`support passport commit notification failed: ${error instanceof Error ? error.message : String(error)}`);
22185
- }
22186
- function notifySupportPassportCommitted(callback) {
22187
- try {
22188
- const completion = callback?.();
22189
- if (completion) void Promise.resolve(completion).catch(warnCommitNotificationFailure);
22190
- } catch (error) {
22191
- warnCommitNotificationFailure(error);
22192
- }
22193
- }
22194
- function normalizeGrantId(grantId) {
22195
- if (typeof grantId !== "string" || !UUID_INPUT.test(grantId)) throw grantNotFound();
22196
- return grantId.toLowerCase();
22197
- }
22198
- function normalizeNamespace(namespace) {
22199
- const parsed = SupportPassportNamespaceSchema.safeParse(namespace);
22200
- if (!parsed.success) {
22201
- throw new SupportPassportError("invalid_input", "The share link request is invalid.", 400);
22202
- }
22203
- return parsed.data;
22204
- }
22205
- function normalizePrincipal(principal) {
22206
- const normalized = typeof principal === "string" ? principal.trim() : "";
22207
- if (normalized.length < 1 || normalized.length > 512) {
22208
- throw new SupportPassportError("invalid_input", "The share link request is invalid.", 400);
22209
- }
22210
- return normalized;
22211
- }
22212
- async function syncDirectoryForDurability(directory, openDirectory = async (target) => await open2(target, "r")) {
22213
- let handle;
22214
- try {
22215
- handle = await openDirectory(directory);
22216
- await handle.sync();
22217
- } catch (error) {
22218
- const code = error.code;
22219
- if (!UNSUPPORTED_DIRECTORY_SYNC_ERRORS2.has(code ?? "")) throw error;
22220
- } finally {
22221
- await handle?.close().catch(() => void 0);
22222
- }
22223
- }
22224
- var SupportPassportGrantStore = class {
22225
- memoryDir;
22226
- grantsDir;
22227
- ownerIndexesDir;
22228
- memoryRootReady;
22229
- safeDirectoriesReady;
22230
- now;
22231
- makeSecret;
22232
- makeGrantId;
22233
- runWithHeldFileLock;
22234
- syncDirectory;
22235
- constructor(options) {
22236
- this.memoryDir = path23.resolve(expandTildePath(options.memoryDir));
22237
- this.grantsDir = path23.join(this.memoryDir, "state", "support-passport", "grants");
22238
- this.ownerIndexesDir = path23.join(this.grantsDir, "owners");
22239
- this.now = options.now ?? (() => /* @__PURE__ */ new Date());
22240
- this.makeSecret = options.makeSecret ?? (() => randomBytes3(32));
22241
- this.makeGrantId = options.makeGrantId ?? randomUUID3;
22242
- this.runWithHeldFileLock = options.withHeldFileLock ?? withHeldFileLock;
22243
- this.syncDirectory = options.syncDirectory ?? syncDirectoryForDurability;
22244
- }
22245
- async create(input, hooks = {}) {
22246
- const mutationHooks = typeof hooks === "function" ? { beforeCommit: hooks } : hooks;
22247
- const namespace = normalizeNamespace(input.namespace);
22248
- const parsed = SupportPassportCreateGrantInputSchema.safeParse({
22249
- principal: input.principal,
22250
- cards: input.cards,
22251
- expiresAt: input.expiresAt
22252
- });
22253
- if (!parsed.success) {
22254
- throw new SupportPassportError("invalid_input", "The share link request is invalid.", 400);
22255
- }
22256
- const requestedAt = input.requestedAt ?? this.now();
22257
- const durationMs = Date.parse(parsed.data.expiresAt) - requestedAt.getTime();
22258
- if (!Number.isFinite(requestedAt.getTime()) || !Number.isFinite(durationMs) || durationMs < 3e5 || durationMs > 6048e5) {
22259
- throw new SupportPassportError("invalid_input", "The share link request is invalid.", 400);
22260
- }
22261
- const principalHash = computeSupportPassportOwnerKey(parsed.data.principal);
22262
- const ownerHash = this.ownerHash(namespace, principalHash);
22263
- let committed;
22264
- try {
22265
- let finalized;
22266
- try {
22267
- finalized = await this.withOwnerIndexLock(ownerHash, async (lock) => {
22268
- await this.requireAvailableOwnerGrantSlot(namespace, principalHash);
22269
- committed = await this.withMutationLock(async (mutationLock) => {
22270
- const secretBytes = this.makeSecret();
22271
- if (!Buffer.isBuffer(secretBytes) || secretBytes.length !== 32) {
22272
- throw new Error("SupportPassportGrantStore.makeSecret must return 32 bytes");
22273
- }
22274
- const rawGrantId = this.makeGrantId();
22275
- if (!UUID_INPUT.test(rawGrantId)) {
22276
- throw new Error("SupportPassportGrantStore.makeGrantId must return a UUID");
22277
- }
22278
- const grantId = rawGrantId.toLowerCase();
22279
- const secret = secretBytes.toString("base64url");
22280
- const createdAt = this.now();
22281
- const createdAtMs = createdAt.getTime();
22282
- const expiresAtMs = Date.parse(parsed.data.expiresAt);
22283
- if (!Number.isFinite(createdAtMs) || requestedAt.getTime() > createdAtMs || expiresAtMs <= createdAtMs || expiresAtMs - createdAtMs > 6048e5) {
22284
- throw new SupportPassportError("invalid_input", "The share link request is invalid.", 400);
22285
- }
22286
- const state = SupportPassportGrantStateSchema.parse({
22287
- schemaVersion: 1,
22288
- stateVersion: 1,
22289
- grantId,
22290
- namespace,
22291
- principalHash,
22292
- ownerLockKey: computeSupportPassportOwnerLockKey(namespace, parsed.data.principal),
22293
- secretHash: sha256("support-passport-secret:v1", secret),
22294
- cards: parsed.data.cards,
22295
- createdAt: createdAt.toISOString(),
22296
- expiresAt: parsed.data.expiresAt
22297
- });
22298
- await this.requireMutationLock(mutationLock);
22299
- await mutationHooks.beforeCommit?.();
22300
- await this.requireMutationLock(mutationLock);
22301
- try {
22302
- await this.writeState(state, true);
22303
- } catch (error) {
22304
- const persisted2 = await this.readState(state.grantId).catch(() => void 0);
22305
- if (!persisted2 || !sameGrantState(persisted2, state)) throw error;
22306
- try {
22307
- await this.syncDirectory(this.grantsDir);
22308
- } catch {
22309
- await this.removeGrantStates([state.grantId]).catch(() => void 0);
22310
- throw error;
22311
- }
22312
- }
22313
- try {
22314
- await this.writeOwnerMembership(state);
22315
- } catch (error) {
22316
- await this.removeStoredGrant(state).catch(() => void 0);
22317
- throw error;
22318
- }
22319
- const persisted = { state, secret };
22320
- committed = persisted;
22321
- return persisted;
22322
- });
22323
- try {
22324
- await this.addToOwnerIndex(committed.state, lock);
22325
- } catch (error) {
22326
- if (error instanceof OwnerIndexLockLostError) throw error;
22327
- const indexed = await this.readOwnerIndexByHash(ownerHash).catch(() => void 0);
22328
- if (!indexed?.includes(committed.state.grantId)) throw error;
22329
- try {
22330
- await this.syncDirectory(this.ownerIndexesDir);
22331
- } catch {
22332
- throw error;
22333
- }
22334
- await this.requireOwnerIndexLock(lock);
22335
- }
22336
- return committed;
22337
- });
22338
- } catch (error) {
22339
- if (!(error instanceof OwnerIndexLockLostError) || !committed) throw error;
22340
- finalized = await this.reconcileCreateAfterOwnerIndexLockLoss(committed);
22341
- }
22342
- notifySupportPassportCommitted(mutationHooks.onCommitted);
22343
- return finalized;
22344
- } catch (error) {
22345
- if (committed) {
22346
- await this.withGrantLock(committed.state.grantId, async (lock) => {
22347
- await this.requireMutationLock(lock);
22348
- await this.removeStoredGrant(committed.state);
22349
- }).catch(() => void 0);
22350
- }
22351
- throw error;
22352
- }
22353
- }
22354
- async authenticate(grantId, secret) {
22355
- const normalizedGrantId = normalizeGrantId(grantId);
22356
- if (typeof secret !== "string" || secret.length > 512) throw grantNotFound();
22357
- let state;
22358
- try {
22359
- state = await this.readState(normalizedGrantId);
22360
- } catch (error) {
22361
- if (error.code === "ENOENT") throw grantNotFound();
22362
- throw error;
22363
- }
22364
- const candidate = sha256("support-passport-secret:v1", secret);
22365
- if (!hashesMatch(candidate, state.secretHash)) throw grantNotFound();
22366
- if (state.revokedAt) {
22367
- throw new SupportPassportError("grant_gone", "The share link is no longer active.", 410);
22368
- }
22369
- if (Date.parse(state.expiresAt) <= this.now().getTime()) {
22370
- throw new SupportPassportError("grant_expired", "The share link has expired.", 410);
22371
- }
22372
- return state;
22373
- }
22374
- async withAuthenticatedGrant(grantId, secret, task, beforeReturn) {
22375
- return await this.withGrantLock(grantId, async (lock) => {
22376
- const state = await this.authenticate(grantId, secret);
22377
- const result = await task(state);
22378
- await this.requireMutationLock(lock);
22379
- const finalState = await this.authenticate(grantId, secret);
22380
- await this.requireMutationLock(lock);
22381
- if (finalState.stateVersion !== state.stateVersion) {
22382
- throw new SupportPassportError("grant_stale", "The shared support guide has changed.", 410);
22383
- }
22384
- this.requireActiveState(finalState);
22385
- await beforeReturn?.(finalState);
22386
- await this.requireMutationLock(lock);
22387
- this.requireActiveState(finalState);
22388
- return result;
22389
- });
22390
- }
22391
- async listForOwner(namespace, principal) {
22392
- const normalizedNamespace = normalizeNamespace(namespace);
22393
- const principalHash = computeSupportPassportOwnerKey(normalizePrincipal(principal));
22394
- const activeCutoff = this.now().getTime();
22395
- const states = this.listedOwnerStates(
22396
- await this.readOwnerMembershipStates(normalizedNamespace, principalHash),
22397
- activeCutoff
22398
- );
22399
- return states.sort((a, b) => {
22400
- const aActive = !a.revokedAt && Date.parse(a.expiresAt) > activeCutoff;
22401
- const bActive = !b.revokedAt && Date.parse(b.expiresAt) > activeCutoff;
22402
- if (aActive !== bActive) return aActive ? -1 : 1;
22403
- return newestGrantFirst(a, b);
22404
- });
22405
- }
22406
- async revoke(input, hooks = {}) {
22407
- const mutationHooks = typeof hooks === "function" ? { beforeCommit: hooks } : hooks;
22408
- const normalizedInput = { ...input, grantId: normalizeGrantId(input.grantId) };
22409
- const namespace = normalizeNamespace(input.namespace);
22410
- return await this.withGrantLock(normalizedInput.grantId, async (lock) => {
22411
- let state;
22412
- try {
22413
- state = await this.readState(normalizedInput.grantId);
22414
- } catch (error) {
22415
- if (error.code === "ENOENT") throw grantNotFound();
22416
- throw error;
22417
- }
22418
- const principalHash = computeSupportPassportOwnerKey(normalizePrincipal(input.principal));
22419
- if (state.namespace !== namespace || !hashesMatch(state.principalHash, principalHash)) throw grantNotFound();
22420
- if (state.revokedAt) {
22421
- return state;
22422
- }
22423
- if (normalizedInput.expectedStateVersion !== void 0 && normalizedInput.expectedStateVersion !== state.stateVersion) {
22424
- throw new SupportPassportError("state_conflict", "The share link changed after it was loaded.", 409);
22425
- }
22426
- const revoked = SupportPassportGrantStateSchema.parse({
22427
- ...state,
22428
- stateVersion: state.stateVersion + 1,
22429
- revokedAt: this.now().toISOString()
22430
- });
22431
- await this.requireMutationLock(lock);
22432
- await mutationHooks.beforeCommit?.();
22433
- await this.requireMutationLock(lock);
22434
- try {
22435
- await this.writeState(revoked);
22436
- } catch (error) {
22437
- const persisted = await this.readState(revoked.grantId).catch(() => void 0);
22438
- if (!persisted || !sameGrantState(persisted, revoked)) throw error;
22439
- await this.syncDirectory(this.grantsDir);
22440
- }
22441
- notifySupportPassportCommitted(mutationHooks.onCommitted);
22442
- return revoked;
22443
- });
22444
- }
22445
- filePath(grantId) {
22446
- const normalizedGrantId = normalizeGrantId(grantId);
22447
- return path23.join(this.grantsDir, `${normalizedGrantId}.json`);
22448
- }
22449
- ownerIndexPath(ownerHash) {
22450
- if (!SAFE_OWNER_INDEX_HASH.test(ownerHash)) throw new Error("support passport owner index hash is invalid");
22451
- return path23.join(this.ownerIndexesDir, `${ownerHash}.json`);
22452
- }
22453
- ownerHash(namespace, principalHash) {
22454
- return sha256("support-passport-owner-index:v1", `${namespace}\0${principalHash}`);
22455
- }
22456
- async addToOwnerIndex(state, lock) {
22457
- const ownerHash = this.ownerHash(state.namespace, state.principalHash);
22458
- const ownerStates = (await this.readOwnerMembershipStates(state.namespace, state.principalHash)).filter((item) => item.grantId !== state.grantId).sort(newestGrantFirst);
22459
- const current = ownerStates.map((item) => item.grantId);
22460
- let retained = current;
22461
- const indexedStates = [...ownerStates];
22462
- if (current.length >= MAX_OWNER_GRANT_HISTORY) {
22463
- const expiryCutoff = this.now().getTime();
22464
- const active = indexedStates.filter((item) => !item.revokedAt && Date.parse(item.expiresAt) > expiryCutoff);
22465
- if (active.length >= MAX_OWNER_GRANT_HISTORY) {
22466
- throw new SupportPassportError(
22467
- "invalid_input",
22468
- "A support passport can contain at most 100 active share links.",
22469
- 400
22470
- );
22471
- }
22472
- const inactive = indexedStates.filter((item) => item.revokedAt || Date.parse(item.expiresAt) <= expiryCutoff).sort(newestGrantFirst);
22473
- retained = [
22474
- ...active.map((item) => item.grantId),
22475
- ...inactive.slice(0, MAX_OWNER_GRANT_HISTORY - active.length - 1).map((item) => item.grantId)
22476
- ];
22477
- }
22478
- const grantIds = [...retained, state.grantId];
22479
- const retainedIds = new Set(grantIds);
22480
- const indexedStateById = new Map(indexedStates.map((indexedState) => [indexedState.grantId, indexedState]));
22481
- const evictedGrantIds = current.filter((grantId) => !retainedIds.has(grantId));
22482
- await this.writeOwnerIndexWhileLocked(ownerHash, grantIds, lock);
22483
- try {
22484
- for (const grantId of evictedGrantIds) {
22485
- await this.withGrantLock(grantId, async (grantLock) => {
22486
- await this.requireMutationLock(grantLock);
22487
- const evictedState = indexedStateById.get(grantId);
22488
- if (evictedState) await this.removeStoredGrant(evictedState);
22489
- else await this.removeGrantStates([grantId]);
22490
- });
22491
- }
22492
- } catch (error) {
22493
- log.warn(
22494
- `support passport could not remove inactive grant state: ${error instanceof Error ? error.message : String(error)}`
22495
- );
22496
- }
22497
- }
22498
- async removeGrantStates(grantIds) {
22499
- if (grantIds.length === 0) return;
22500
- for (const grantId of grantIds) {
22501
- if (!SAFE_GRANT_ID.test(grantId)) throw grantNotFound();
22502
- }
22503
- await removePrivateFilesNoFollow(
22504
- this.grantsDir,
22505
- grantIds.map((grantId) => `${grantId}.json`),
22506
- "support passport grant files must be regular files in a stable directory",
22507
- path23.parse(this.memoryDir).root
22508
- );
22509
- }
22510
- ownerMembershipDirectory(ownerHash) {
22511
- if (!SAFE_OWNER_INDEX_HASH.test(ownerHash)) throw new Error("support passport owner index hash is invalid");
22512
- return path23.join(this.ownerIndexesDir, ownerHash);
22513
- }
22514
- async ensureOwnerMembershipDirectory(ownerHash) {
22515
- const directory = this.ownerMembershipDirectory(ownerHash);
22516
- await ensurePrivateDirectoryTreeNoFollow(
22517
- directory,
22518
- "support passport owner membership must remain inside the memory directory"
22519
- );
22520
- return directory;
22521
- }
22522
- async writeOwnerMembership(state) {
22523
- const ownerHash = this.ownerHash(state.namespace, state.principalHash);
22524
- const directory = await this.ensureOwnerMembershipDirectory(ownerHash);
22525
- await writePrivateFileAtomicallyNoFollow(
22526
- directory,
22527
- path23.join(directory, `${state.grantId}.json`),
22528
- `${JSON.stringify({ schemaVersion: 1, grantId: state.grantId })}
22529
- `,
22530
- "support passport owner membership must be regular files in a stable directory",
22531
- path23.parse(this.memoryDir).root
22532
- );
22533
- }
22534
- async removeOwnerMembership(state) {
22535
- const ownerHash = this.ownerHash(state.namespace, state.principalHash);
22536
- const directory = await this.ensureOwnerMembershipDirectory(ownerHash);
22537
- await removePrivateFilesNoFollow(
22538
- directory,
22539
- [`${state.grantId}.json`],
22540
- "support passport owner membership must be regular files in a stable directory",
22541
- path23.parse(this.memoryDir).root
22542
- );
22543
- }
22544
- async removeStoredGrant(state) {
22545
- await this.removeGrantStates([state.grantId]);
22546
- await this.removeOwnerMembership(state);
22547
- }
22548
- async writeOwnerIndexWhileLocked(ownerHash, grantIds, lock) {
22549
- await this.requireOwnerIndexLock(lock);
22550
- await this.writeOwnerIndex(ownerHash, grantIds);
22551
- await this.requireOwnerIndexLock(lock);
22552
- }
22553
- async reconcileCreateAfterOwnerIndexLockLoss(committed) {
22554
- const ownerHash = this.ownerHash(committed.state.namespace, committed.state.principalHash);
22555
- for (let attempt = 1; attempt <= MAX_OWNER_INDEX_RECOVERY_ATTEMPTS; attempt += 1) {
22556
- try {
22557
- return await this.withOwnerIndexLock(
22558
- ownerHash,
22559
- async (lock) => await this.reconcileCommittedGrant(committed, ownerHash, lock)
22560
- );
22561
- } catch (error) {
22562
- if (!(error instanceof OwnerIndexLockLostError)) throw error;
22563
- }
22564
- }
22565
- throw new SupportPassportError("storage_conflict", "The share link store changed during the request.", 409);
22566
- }
22567
- async reconcileCommittedGrant(committed, ownerHash, lock) {
22568
- const persisted = await this.readState(committed.state.grantId).catch(() => void 0);
22569
- if (!persisted || !sameGrantState(persisted, committed.state)) {
22570
- throw new SupportPassportError("storage_conflict", "The share link store changed during the request.", 409);
22571
- }
22572
- const ownerStates = await this.readOwnerMembershipStates(committed.state.namespace, committed.state.principalHash);
22573
- const committedIndex = ownerStates.findIndex((state) => state.grantId === committed.state.grantId);
22574
- if (committedIndex === -1) ownerStates.push(committed.state);
22575
- else ownerStates[committedIndex] = committed.state;
22576
- const activeCutoff = this.now().getTime();
22577
- const active = ownerStates.filter((state) => !state.revokedAt && Date.parse(state.expiresAt) > activeCutoff);
22578
- if (active.length > MAX_OWNER_GRANT_HISTORY) {
22579
- await this.withGrantLock(committed.state.grantId, async (grantLock) => {
22580
- await this.requireMutationLock(grantLock);
22581
- await this.removeStoredGrant(committed.state);
22582
- });
22583
- const committedIndex2 = ownerStates.findIndex((state) => state.grantId === committed.state.grantId);
22584
- if (committedIndex2 !== -1) ownerStates.splice(committedIndex2, 1);
22585
- }
22586
- const retained = this.retainedOwnerStates(ownerStates, activeCutoff);
22587
- await this.writeOwnerIndexWhileLocked(
22588
- ownerHash,
22589
- retained.map((state) => state.grantId),
22590
- lock
22591
- );
22592
- const retainedIds = new Set(retained.map((state) => state.grantId));
22593
- for (const state of ownerStates) {
22594
- if (retainedIds.has(state.grantId)) continue;
22595
- try {
22596
- await this.withGrantLock(state.grantId, async (grantLock) => {
22597
- await this.requireMutationLock(grantLock);
22598
- await this.removeStoredGrant(state);
22599
- });
22600
- } catch (error) {
22601
- log.warn(
22602
- `support passport could not remove inactive grant state: ${error instanceof Error ? error.message : String(error)}`
22603
- );
22604
- }
22605
- }
22606
- if (active.length > MAX_OWNER_GRANT_HISTORY) {
22607
- throw new SupportPassportError("storage_conflict", "The share link store changed during the request.", 409);
22608
- }
22609
- return committed;
22610
- }
22611
- retainedOwnerStates(states, activeCutoff) {
22612
- const active = states.filter((state) => !state.revokedAt && Date.parse(state.expiresAt) > activeCutoff);
22613
- if (active.length > MAX_OWNER_GRANT_HISTORY) {
22614
- throw new SupportPassportError("storage_conflict", "The share link store contains too many active links.", 409);
22615
- }
22616
- const inactive = states.filter((state) => state.revokedAt || Date.parse(state.expiresAt) <= activeCutoff).sort(newestGrantFirst);
22617
- return [...active, ...inactive.slice(0, MAX_OWNER_GRANT_HISTORY - active.length)];
22618
- }
22619
- listedOwnerStates(states, activeCutoff) {
22620
- const active = states.filter((state) => !state.revokedAt && Date.parse(state.expiresAt) > activeCutoff);
22621
- const inactive = states.filter((state) => state.revokedAt || Date.parse(state.expiresAt) <= activeCutoff).sort(newestGrantFirst);
22622
- return [...active, ...inactive.slice(0, Math.max(0, MAX_OWNER_GRANT_HISTORY - active.length))];
22623
- }
22624
- async requireAvailableOwnerGrantSlot(namespace, principalHash) {
22625
- const activeCutoff = this.now().getTime();
22626
- const active = (await this.readOwnerMembershipStates(namespace, principalHash)).filter(
22627
- (state) => !state.revokedAt && Date.parse(state.expiresAt) > activeCutoff
22628
- );
22629
- if (active.length >= MAX_OWNER_GRANT_HISTORY) {
22630
- throw new SupportPassportError(
22631
- "invalid_input",
22632
- "A support passport can contain at most 100 active share links.",
22633
- 400
22634
- );
22635
- }
22636
- }
22637
- async readOwnerMembershipStates(namespace, principalHash) {
22638
- await this.ensureSafeDirectories();
22639
- const ownerHash = this.ownerHash(namespace, principalHash);
22640
- const directory = await this.ensureOwnerMembershipDirectory(ownerHash);
22641
- const grantIds = await withPrivateDirectoryNoFollow(
22642
- path23.parse(this.memoryDir).root,
22643
- directory,
22644
- "support passport owner membership must be regular files in a stable directory",
22645
- async (pinnedDirectory) => {
22646
- const entries = await readdir4(pinnedDirectory, { withFileTypes: true });
22647
- return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -5)).filter((grantId) => SAFE_GRANT_ID.test(grantId));
22648
- }
22649
- );
22650
- const ownerStates = [];
22651
- for (const grantId of grantIds) {
22652
- try {
22653
- const state = await this.readState(grantId);
22654
- if (state.namespace === namespace && hashesMatch(state.principalHash, principalHash)) {
22655
- ownerStates.push(state);
22656
- }
22657
- } catch (error) {
22658
- if (error.code === "ENOENT" || error instanceof MalformedGrantStateError) continue;
22659
- throw error;
22660
- }
22661
- }
22662
- return ownerStates;
22663
- }
22664
- async readOwnerIndexByHash(ownerHash) {
22665
- await this.ensureSafeDirectories();
22666
- const filePath = this.ownerIndexPath(ownerHash);
22667
- let content;
22668
- try {
22669
- content = await readPrivateFileNoFollow(
22670
- this.ownerIndexesDir,
22671
- filePath,
22672
- "support passport owner indexes must be regular files in a stable directory",
22673
- path23.parse(this.memoryDir).root
22674
- );
22675
- } catch (error) {
22676
- if (error.code === "ENOENT") return [];
22677
- throw error;
22678
- }
22679
- const parsed = JSON.parse(content);
22680
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
22681
- throw new Error("support passport owner index is invalid");
22682
- }
22683
- const record = parsed;
22684
- const grantIds = record.grantIds;
22685
- if (record.schemaVersion !== 1 || record.ownerHash !== ownerHash || !Array.isArray(grantIds)) {
22686
- throw new Error("support passport owner index is invalid");
22687
- }
22688
- if (grantIds.some((grantId) => typeof grantId !== "string" || !SAFE_GRANT_ID.test(grantId))) {
22689
- throw new Error("support passport owner index is invalid");
22690
- }
22691
- const uniqueGrantIds = new Set(grantIds);
22692
- if (uniqueGrantIds.size !== grantIds.length || uniqueGrantIds.size > MAX_OWNER_GRANT_HISTORY) {
22693
- throw new Error("support passport owner index is invalid");
22694
- }
22695
- return [...uniqueGrantIds];
22696
- }
22697
- async writeOwnerIndex(ownerHash, grantIds) {
22698
- const filePath = this.ownerIndexPath(ownerHash);
22699
- try {
22700
- const metadata = await lstat4(filePath);
22701
- if (metadata.isSymbolicLink() || !metadata.isFile()) {
22702
- throw new Error("support passport owner indexes must be regular files");
22703
- }
22704
- } catch (error) {
22705
- if (error.code !== "ENOENT") throw error;
22706
- }
22707
- await writePrivateFileAtomicallyNoFollow(
22708
- this.ownerIndexesDir,
22709
- filePath,
22710
- `${JSON.stringify({ schemaVersion: 1, ownerHash, grantIds }, null, 2)}
22711
- `,
22712
- "support passport owner indexes must be regular files in a stable directory",
22713
- path23.parse(this.memoryDir).root
22714
- );
22715
- }
22716
- async readState(grantId) {
22717
- await this.ensureSafeDirectories();
22718
- const filePath = this.filePath(grantId);
22719
- const content = await readPrivateFileNoFollow(
22720
- this.grantsDir,
22721
- filePath,
22722
- "support passport grant files must be regular files in a stable directory",
22723
- path23.parse(this.memoryDir).root
22724
- );
22725
- try {
22726
- const state = SupportPassportGrantStateSchema.parse(JSON.parse(content));
22727
- if (state.grantId !== grantId) {
22728
- throw new MalformedGrantStateError("support passport grant ID must match its file name");
22729
- }
22730
- return state;
22731
- } catch (error) {
22732
- if (error instanceof MalformedGrantStateError) throw error;
22733
- if (error instanceof SyntaxError || error.name === "ZodError") {
22734
- throw new MalformedGrantStateError(void 0, error);
22735
- }
22736
- throw error;
22737
- }
22738
- }
22739
- async writeState(state, requireAbsent = false) {
22740
- const filePath = this.filePath(state.grantId);
22741
- try {
22742
- const metadata = await lstat4(filePath);
22743
- if (metadata.isSymbolicLink() || !metadata.isFile())
22744
- throw new Error("support passport grant files must be regular files");
22745
- if (requireAbsent) {
22746
- throw new SupportPassportError("storage_conflict", "A new share link could not be allocated.", 409);
22747
- }
22748
- } catch (error) {
22749
- if (error.code !== "ENOENT") throw error;
22750
- }
22751
- await writePrivateFileAtomicallyNoFollow(
22752
- this.grantsDir,
22753
- filePath,
22754
- `${JSON.stringify(state, null, 2)}
22755
- `,
22756
- "support passport grant files must be regular files in a stable directory",
22757
- path23.parse(this.memoryDir).root
22758
- );
22759
- }
22760
- async ensureSafeDirectories() {
22761
- if (!this.safeDirectoriesReady) {
22762
- this.safeDirectoriesReady = (async () => {
22763
- await this.ensureMemoryRoot();
22764
- await ensurePrivateDirectoryNoFollow(
22765
- this.memoryDir,
22766
- this.ownerIndexesDir,
22767
- "support passport grant directories must remain inside the memory directory",
22768
- void 0,
22769
- true
22770
- );
22771
- })();
22772
- }
22773
- const currentAttempt = this.safeDirectoriesReady;
22774
- try {
22775
- await currentAttempt;
22776
- } catch (error) {
22777
- if (this.safeDirectoriesReady === currentAttempt) this.safeDirectoriesReady = void 0;
22778
- throw error;
22779
- }
22780
- }
22781
- async ensureMemoryRoot() {
22782
- const configuredMemoryDir = this.memoryDir;
22783
- if (!this.memoryRootReady) {
22784
- this.memoryRootReady = (async () => {
22785
- await ensurePrivateDirectoryTreeNoFollow(
22786
- configuredMemoryDir,
22787
- "support passport memory directory must be a stable directory",
22788
- void 0
22789
- );
22790
- this.memoryDir = configuredMemoryDir;
22791
- this.grantsDir = path23.join(configuredMemoryDir, "state", "support-passport", "grants");
22792
- this.ownerIndexesDir = path23.join(this.grantsDir, "owners");
22793
- })();
22794
- }
22795
- const currentAttempt = this.memoryRootReady;
22796
- try {
22797
- await currentAttempt;
22798
- } catch (error) {
22799
- if (this.memoryRootReady === currentAttempt) this.memoryRootReady = void 0;
22800
- throw error;
22801
- }
22802
- }
22803
- async withMutationLock(task) {
22804
- await this.ensureSafeDirectories();
22805
- return await withPrivateDirectoryNoFollow(
22806
- path23.parse(this.memoryDir).root,
22807
- this.grantsDir,
22808
- "support passport grant lock directory must remain inside the memory directory",
22809
- async (pinnedDirectory) => await this.withExclusiveLock(
22810
- `support-passport-grants:${this.grantsDir}`,
22811
- path23.join(pinnedDirectory, ".grants.lock"),
22812
- task
22813
- )
22814
- );
22815
- }
22816
- async withGrantLock(grantId, task) {
22817
- const normalizedGrantId = normalizeGrantId(grantId);
22818
- await this.ensureSafeDirectories();
22819
- return await withPrivateDirectoryNoFollow(
22820
- path23.parse(this.memoryDir).root,
22821
- this.grantsDir,
22822
- "support passport grant lock directory must remain inside the memory directory",
22823
- async (pinnedDirectory) => await this.withExclusiveLock(
22824
- `support-passport-grant:${this.grantsDir}:${normalizedGrantId}`,
22825
- path23.join(pinnedDirectory, `.${normalizedGrantId}.lock`),
22826
- task
22827
- )
22828
- );
22829
- }
22830
- async withOwnerIndexLock(ownerHash, task) {
22831
- await this.ensureSafeDirectories();
22832
- return await withPrivateDirectoryNoFollow(
22833
- path23.parse(this.memoryDir).root,
22834
- this.ownerIndexesDir,
22835
- "support passport owner lock directory must remain inside the memory directory",
22836
- async (pinnedDirectory) => await this.withExclusiveLock(
22837
- `support-passport-owner:${this.ownerIndexesDir}:${ownerHash}`,
22838
- path23.join(pinnedDirectory, `.${ownerHash}.lock`),
22839
- task
22840
- )
22841
- );
22842
- }
22843
- async withExclusiveLock(serializationKey, lockPath, task) {
22844
- return await serializeMutations(
22845
- serializationKey,
22846
- () => this.runWithHeldFileLock(
22847
- lockPath,
22848
- {
22849
- staleMs: GRANT_LOCK_STALE_MS,
22850
- maxWaitMs: GRANT_LOCK_WAIT_MS,
22851
- heartbeatMs: GRANT_LOCK_HEARTBEAT_MS
22852
- },
22853
- async (acquired, lock) => {
22854
- if (!acquired) {
22855
- throw new SupportPassportError("storage_conflict", "The share link store is busy. Try again.", 409);
22856
- }
22857
- return await task(lock);
22858
- }
22859
- )
22860
- );
22861
- }
22862
- async requireMutationLock(lock) {
22863
- if (await lock.refresh()) return;
22864
- throw new SupportPassportError("storage_conflict", "The share link store changed during the request.", 409);
22865
- }
22866
- async requireOwnerIndexLock(lock) {
22867
- try {
22868
- await this.requireMutationLock(lock);
22869
- } catch (error) {
22870
- throw new OwnerIndexLockLostError(error);
22871
- }
22872
- }
22873
- requireActiveState(state) {
22874
- if (state.revokedAt) {
22875
- throw new SupportPassportError("grant_gone", "The share link is no longer active.", 410);
22876
- }
22877
- if (Date.parse(state.expiresAt) <= this.now().getTime()) {
22878
- throw new SupportPassportError("grant_expired", "The share link has expired.", 410);
22879
- }
22880
- }
22881
- };
22882
-
22883
- // src/support-passport/grant-service.ts
22884
- function invalidInput2() {
22885
- return new SupportPassportError("invalid_input", "The share link request is invalid.", 400);
22886
- }
22887
- var SupportPassportGrantService = class {
22888
- grantStore;
22889
- resolveOwner;
22890
- resolveNamespace;
22891
- now;
22892
- constructor(dependencies) {
22893
- this.grantStore = dependencies.grantStore;
22894
- this.resolveOwner = dependencies.resolveOwner;
22895
- this.resolveNamespace = dependencies.resolveNamespace;
22896
- this.now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
22897
- }
22898
- async createGrant(input, options = {}) {
22899
- const requestedAt = this.now();
22900
- const parsed = SupportPassportCreateGrantInputSchema.safeParse(input);
22901
- if (!parsed.success) throw invalidInput2();
22902
- const owner = await this.resolveOwnerScope(parsed.data.principal);
22903
- return await withSupportPassportOwnerLock(
22904
- owner.storage,
22905
- { namespace: owner.namespace, principal: owner.principal },
22906
- async (ownerLock) => {
22907
- options.signal?.throwIfAborted();
22908
- const ownerHash = computeSupportPassportOwnerKey(owner.principal);
22909
- const cardsById = new Map(
22910
- this.projectOwnedCards(
22911
- await owner.storage.readAllMemories(),
22912
- owner.namespace,
22913
- ownerHash
22914
- ).map((card) => [card.card.cardId, card])
22915
- );
22916
- for (const cardRef of parsed.data.cards) {
22917
- const stored = cardsById.get(cardRef.cardId);
22918
- if (!stored || stored.namespace !== owner.namespace || stored.owner !== ownerHash || stored.card.status !== "active") {
22919
- throw new SupportPassportError("invalid_card_status", "Only approved support cards can be shared.", 409);
22920
- }
22921
- if (stored.card.revision !== cardRef.revision) {
22922
- throw new SupportPassportError("revision_conflict", "A support card changed after it was selected.", 409);
22923
- }
22924
- if (!this.publicCard(stored.card).success) {
22925
- throw new SupportPassportError("card_data_invalid", "The support card data is invalid.", 500);
22926
- }
22927
- }
22928
- const created = await this.grantStore.create(
22929
- {
22930
- namespace: owner.namespace,
22931
- principal: owner.principal,
22932
- cards: parsed.data.cards,
22933
- expiresAt: parsed.data.expiresAt,
22934
- requestedAt
22935
- },
22936
- {
22937
- beforeCommit: async () => {
22938
- options.signal?.throwIfAborted();
22939
- await requireSupportPassportOwnerLock(ownerLock);
22940
- }
22941
- }
22942
- );
22943
- try {
22944
- await requireSupportPassportOwnerLock(ownerLock);
22945
- } catch (error) {
22946
- await this.revokeCommittedGrant(created, owner);
22947
- throw error;
22948
- }
22949
- if (options.signal?.aborted) {
22950
- await this.revokeCommittedGrant(created, owner);
22951
- options.signal.throwIfAborted();
22952
- }
22953
- const output = SupportPassportCreatedGrantSchema.parse({
22954
- grant: this.ownerGrant(created.state),
22955
- secret: created.secret
22956
- });
22957
- notifySupportPassportCommitted(options.onCommitted);
22958
- return output;
22959
- }
22960
- );
22961
- }
22962
- async listGrants(input) {
22963
- const parsed = SupportPassportListGrantsInputSchema.safeParse(input);
22964
- if (!parsed.success) throw invalidInput2();
22965
- const owner = await this.resolveOwnerScope(parsed.data.principal);
22966
- return (await this.grantStore.listForOwner(owner.namespace, owner.principal)).map(
22967
- (state) => this.ownerGrant(state)
22968
- );
22969
- }
22970
- async revokeGrant(input, options = {}) {
22971
- const parsed = SupportPassportRevokeGrantInputSchema.safeParse(input);
22972
- if (!parsed.success) throw invalidInput2();
22973
- const owner = await this.resolveOwnerScope(parsed.data.principal);
22974
- return await withSupportPassportOwnerLock(
22975
- owner.storage,
22976
- { namespace: owner.namespace, principal: owner.principal },
22977
- async (ownerLock) => {
22978
- options.signal?.throwIfAborted();
22979
- const state = await this.grantStore.revoke(
22980
- {
22981
- grantId: parsed.data.grantId,
22982
- namespace: owner.namespace,
22983
- principal: owner.principal,
22984
- expectedStateVersion: parsed.data.expectedStateVersion
22985
- },
22986
- {
22987
- beforeCommit: async () => {
22988
- options.signal?.throwIfAborted();
22989
- await requireSupportPassportOwnerLock(ownerLock);
22990
- }
22991
- }
22992
- );
22993
- const output = this.ownerGrant(state);
22994
- notifySupportPassportCommitted(options.onCommitted);
22995
- return output;
22996
- }
22997
- );
22998
- }
22999
- async readGrant(input) {
23000
- if (!input || typeof input.grantId !== "string" || typeof input.secret !== "string") {
23001
- throw new SupportPassportError("grant_not_found", "The share link was not found.", 404);
23002
- }
23003
- return await this.readGrantAttempt(input);
23004
- }
23005
- async readGrantAttempt(input) {
23006
- const initialState = await this.grantStore.authenticate(input.grantId, input.secret);
23007
- const storage = await this.resolveNamespace(initialState.namespace);
23008
- const initialSnapshot = await this.readStoredCardSnapshot(
23009
- storage,
23010
- initialState.namespace,
23011
- initialState.principalHash
23012
- );
23013
- const cards = this.readGrantCards(initialSnapshot, initialState);
23014
- const firstCard = cards[0];
23015
- if (!firstCard) throw new SupportPassportError("grant_stale", "The shared support guide has changed.", 410);
23016
- const updatedAt = cards.reduce((latest, card) => {
23017
- return Date.parse(card.updatedAt) > Date.parse(latest) ? card.updatedAt : latest;
23018
- }, firstCard.updatedAt);
23019
- return await withSupportPassportOwnerLock(
23020
- storage,
23021
- { namespace: initialState.namespace, ownerKey: initialState.ownerLockKey },
23022
- async (ownerLock) => {
23023
- return await this.grantStore.withAuthenticatedGrant(
23024
- input.grantId,
23025
- input.secret,
23026
- async (finalState) => {
23027
- if (finalState.namespace !== initialState.namespace) {
23028
- throw new SupportPassportError("grant_stale", "The shared support guide has changed.", 410);
23029
- }
23030
- await requireSupportPassportOwnerLock(ownerLock);
23031
- const currentSnapshot = await this.readStoredCardSnapshot(
23032
- storage,
23033
- finalState.namespace,
23034
- finalState.principalHash
23035
- );
23036
- const currentCards = this.readGrantCards(currentSnapshot, finalState);
23037
- await requireSupportPassportOwnerLock(ownerLock);
23038
- if (JSON.stringify(currentCards) !== JSON.stringify(cards)) {
23039
- throw new SupportPassportError("grant_stale", "The shared support guide has changed.", 410);
23040
- }
23041
- return SupportPassportPublicGuideSchema.parse({
23042
- schemaVersion: 1,
23043
- grantId: finalState.grantId,
23044
- expiresAt: finalState.expiresAt,
23045
- updatedAt,
23046
- cards
23047
- });
23048
- },
23049
- async () => await requireSupportPassportOwnerLock(ownerLock)
23050
- );
23051
- }
23052
- );
23053
- }
23054
- readGrantCards(snapshot, state) {
23055
- return state.cards.map((cardRef) => {
23056
- const stored = snapshot.cardsById.get(cardRef.cardId);
23057
- if (!stored || stored.namespace !== state.namespace || stored.owner !== state.principalHash || stored.card.status !== "active" || stored.card.revision !== cardRef.revision) {
23058
- throw new SupportPassportError("grant_stale", "The shared support guide has changed.", 410);
23059
- }
23060
- const publicCard = this.publicCard(stored.card);
23061
- if (!publicCard.success) {
23062
- throw new SupportPassportError("grant_stale", "The shared support guide has changed.", 410);
23063
- }
23064
- return publicCard.data;
23065
- });
23066
- }
23067
- async readStoredCardSnapshot(storage, namespace, owner) {
23068
- for (let attempt = 0; attempt < 3; attempt += 1) {
23069
- const before = this.cardSnapshotVersion(storage);
23070
- const memories = await storage.readAllMemories();
23071
- const after = this.cardSnapshotVersion(storage);
23072
- if (before !== after) continue;
23073
- const cards = this.projectOwnedCards(memories, namespace, owner);
23074
- const snapshot = {
23075
- version: after,
23076
- cardsById: new Map(cards.map((card) => [card.card.cardId, card]))
23077
- };
23078
- return snapshot;
23079
- }
23080
- throw new SupportPassportError("storage_conflict", "The support card list changed during review.", 409);
23081
- }
23082
- projectOwnedCards(memories, namespace, owner) {
23083
- const cards = memories.map((memory) => projectSupportPassportCard(memory)).filter(
23084
- (card) => card !== null && card.namespace === namespace && card.owner === owner
23085
- );
23086
- const cardIds = /* @__PURE__ */ new Set();
23087
- for (const card of cards) {
23088
- if (cardIds.has(card.card.cardId)) {
23089
- throw new SupportPassportError("card_data_invalid", "Support card IDs must be unique.", 500);
23090
- }
23091
- cardIds.add(card.card.cardId);
23092
- }
23093
- return cards;
23094
- }
23095
- cardSnapshotVersion(storage) {
23096
- return `${storage.getCorpusScanVersion()}:${storage.hotCacheKeyId()}`;
23097
- }
23098
- async revokeCommittedGrant(created, owner) {
23099
- try {
23100
- await this.grantStore.revoke({
23101
- grantId: created.state.grantId,
23102
- namespace: owner.namespace,
23103
- principal: owner.principal,
23104
- expectedStateVersion: created.state.stateVersion
23105
- });
23106
- } catch {
23107
- throw new SupportPassportError(
23108
- "storage_conflict",
23109
- "A share link could not be stopped after owner access changed. Review the active share list.",
23110
- 500
23111
- );
23112
- }
23113
- }
23114
- publicCard(card) {
23115
- return SupportPassportPublicCardSchema.safeParse({
23116
- cardId: card.cardId,
23117
- title: card.title,
23118
- statement: card.statement,
23119
- category: card.category,
23120
- updatedAt: card.updatedAt
23121
- });
23122
- }
23123
- async resolveOwnerScope(principal) {
23124
- const requestedPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal });
23125
- const owner = await this.resolveOwner(principal);
23126
- const namespace = SupportPassportNamespaceSchema.safeParse(owner.namespace);
23127
- const ownerPrincipal = SupportPassportListCardsInputSchema.safeParse({ principal: owner.principal });
23128
- if (!requestedPrincipal.success || !namespace.success || !ownerPrincipal.success || ownerPrincipal.data.principal !== requestedPrincipal.data.principal) {
23129
- throw new SupportPassportError("card_data_invalid", "The support passport owner scope is invalid.", 500);
23130
- }
23131
- return { ...owner, principal: ownerPrincipal.data.principal, namespace: namespace.data };
23132
- }
23133
- ownerGrant(state) {
23134
- const status = state.revokedAt ? "revoked" : Date.parse(state.expiresAt) <= this.now().getTime() ? "expired" : "active";
23135
- return SupportPassportOwnerGrantSchema.parse({
23136
- grantId: state.grantId,
23137
- stateVersion: state.stateVersion,
23138
- cards: state.cards,
23139
- createdAt: state.createdAt,
23140
- expiresAt: state.expiresAt,
23141
- revokedAt: state.revokedAt,
23142
- status
23143
- });
23144
- }
23145
- };
23146
-
23147
- // src/relay/mission-fixture.ts
23148
- var RELAY_DEMO_MISSION_ID = "checkout-token-recovery";
23149
- var RELAY_DEMO_NAMESPACE = "relay-build-week";
23150
- var sourceEvidence = {
23151
- kind: "source",
23152
- id: "source-checkout-contract",
23153
- label: "Checkout token contract",
23154
- locator: "fixture://checkout-service/src/token-policy.ts",
23155
- capture: "fixture"
23156
- };
23157
- var testEvidence = {
23158
- kind: "test",
23159
- id: "test-checkout-contract",
23160
- label: "Checkout integration contract",
23161
- locator: "fixture://checkout-service/test/token-policy.test.ts",
23162
- capture: "fixture"
23163
- };
23164
- var approvalEvidence = {
23165
- kind: "approval",
23166
- id: "approval-build-week-operator",
23167
- label: "Human approval receipt",
23168
- locator: "fixture://relay/approvals/correction-token-refresh.json",
23169
- capture: "fixture"
23170
- };
23171
- var correctionEvidence = {
23172
- kind: "correction",
23173
- id: "correction-token-refresh",
23174
- label: "Applied Remnic correction",
23175
- locator: "fixture://remnic/corrections/correction-token-refresh.json",
23176
- capture: "fixture"
23177
- };
23178
- function at(second) {
23179
- return `2026-07-17T18:00:${String(second).padStart(2, "0")}.000Z`;
23180
- }
23181
- function createRelayMissionFixture() {
23182
- return [
23183
- {
23184
- occurredAt: at(0),
23185
- idempotencyKey: "fixture-001",
23186
- payload: {
23187
- kind: "mission_started",
23188
- title: "The checkout token split",
23189
- objective: "Resolve a conflicting token refresh policy and prove a cold agent acts on it.",
23190
- runMode: "fixture",
23191
- evidence: [sourceEvidence]
23192
- }
23193
- },
23194
- {
23195
- occurredAt: at(2),
23196
- idempotencyKey: "fixture-002",
23197
- payload: {
23198
- kind: "agent_status",
23199
- agentId: "agent-atlas",
23200
- sessionId: "session-atlas",
23201
- label: "Atlas",
23202
- role: "Checkout implementation",
23203
- status: "working",
23204
- evidence: [sourceEvidence]
23205
- }
23206
- },
23207
- {
23208
- occurredAt: at(3),
23209
- idempotencyKey: "fixture-003",
23210
- payload: {
23211
- kind: "agent_status",
23212
- agentId: "agent-nova",
23213
- sessionId: "session-nova",
23214
- label: "Nova",
23215
- role: "Integration verification",
23216
- status: "working",
23217
- evidence: [testEvidence]
23218
- }
23219
- },
23220
- {
23221
- occurredAt: at(6),
23222
- idempotencyKey: "fixture-004",
23223
- payload: {
23224
- kind: "agent_output",
23225
- agentId: "agent-atlas",
23226
- sessionId: "session-atlas",
23227
- outputId: "output-atlas-policy",
23228
- summary: "Implemented a new token for every checkout retry.",
23229
- evidence: [
23230
- {
23231
- kind: "agent_output",
23232
- id: "output-atlas-policy",
23233
- label: "Atlas one-shot output",
23234
- locator: "fixture://codex/atlas/final-output.txt",
23235
- capture: "fixture"
23236
- }
23237
- ]
23238
- }
23239
- },
23240
- {
23241
- occurredAt: at(7),
23242
- idempotencyKey: "fixture-005",
23243
- payload: {
23244
- kind: "belief_observed",
23245
- agentId: "agent-atlas",
23246
- sessionId: "session-atlas",
23247
- beliefId: "belief-new-token-every-request",
23248
- decisionId: "decision-new-token-every-request",
23249
- statement: "Mint a new checkout token for every request and retry.",
23250
- confidence: 0.91,
23251
- evidence: [
23252
- {
23253
- kind: "memory",
23254
- id: "memory-stale-token-policy",
23255
- label: "Stale project decision",
23256
- locator: "fixture://remnic/memories/memory-stale-token-policy.md",
23257
- capture: "fixture"
23258
- }
23259
- ]
23260
- }
23261
- },
23262
- {
23263
- occurredAt: at(9),
23264
- idempotencyKey: "fixture-006",
23265
- payload: {
23266
- kind: "agent_output",
23267
- agentId: "agent-nova",
23268
- sessionId: "session-nova",
23269
- outputId: "output-nova-policy",
23270
- summary: "The contract requires one token per checkout session, refreshed only after expiry.",
23271
- evidence: [
23272
- {
23273
- kind: "agent_output",
23274
- id: "output-nova-policy",
23275
- label: "Nova one-shot output",
23276
- locator: "fixture://codex/nova/final-output.txt",
23277
- capture: "fixture"
23278
- },
23279
- sourceEvidence
23280
- ]
23281
- }
23282
- },
23283
- {
23284
- occurredAt: at(10),
23285
- idempotencyKey: "fixture-007",
23286
- payload: {
23287
- kind: "belief_observed",
23288
- agentId: "agent-nova",
23289
- sessionId: "session-nova",
23290
- beliefId: "belief-refresh-after-expiry",
23291
- decisionId: "decision-refresh-after-expiry",
23292
- statement: "Reuse the checkout-session token and refresh it only after expiry.",
23293
- confidence: 0.98,
23294
- evidence: [sourceEvidence]
23295
- }
23296
- },
23297
- {
23298
- occurredAt: at(12),
23299
- idempotencyKey: "fixture-008",
23300
- payload: {
23301
- kind: "conflict_detected",
23302
- conflictId: "conflict-token-lifecycle",
23303
- decisionIds: ["decision-refresh-after-expiry", "decision-new-token-every-request"],
23304
- agentIds: ["agent-nova", "agent-atlas"],
23305
- summary: "The agents disagree on whether retries reuse or rotate the checkout token.",
23306
- evidence: [sourceEvidence, testEvidence]
21100
+ },
21101
+ {
21102
+ occurredAt: at(12),
21103
+ idempotencyKey: "fixture-008",
21104
+ payload: {
21105
+ kind: "conflict_detected",
21106
+ conflictId: "conflict-token-lifecycle",
21107
+ decisionIds: ["decision-refresh-after-expiry", "decision-new-token-every-request"],
21108
+ agentIds: ["agent-nova", "agent-atlas"],
21109
+ summary: "The agents disagree on whether retries reuse or rotate the checkout token.",
21110
+ evidence: [sourceEvidence, testEvidence]
23307
21111
  }
23308
21112
  },
23309
21113
  {
@@ -23889,9 +21693,9 @@ function readStructuralSymbol(entry) {
23889
21693
  const rec = entry;
23890
21694
  const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
23891
21695
  if (!symbol) return null;
23892
- const path38 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
21696
+ const path35 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
23893
21697
  const kind = typeof rec.kind === "string" && rec.kind.length > 0 ? rec.kind : void 0;
23894
- const item = path38 !== void 0 && kind !== void 0 ? { symbol, path: path38, kind } : path38 !== void 0 ? { symbol, path: path38 } : kind !== void 0 ? { symbol, kind } : { symbol };
21698
+ const item = path35 !== void 0 && kind !== void 0 ? { symbol, path: path35, kind } : path35 !== void 0 ? { symbol, path: path35 } : kind !== void 0 ? { symbol, kind } : { symbol };
23895
21699
  return item;
23896
21700
  }
23897
21701
  function classifySpawnError(err) {
@@ -23965,7 +21769,7 @@ var DEFAULT_GRACE_PERIOD_DAYS = 7;
23965
21769
 
23966
21770
  // src/binary-lifecycle/backend.ts
23967
21771
  import fsp from "fs/promises";
23968
- import path24 from "path";
21772
+ import path21 from "path";
23969
21773
  var FilesystemBackend = class {
23970
21774
  type = "filesystem";
23971
21775
  basePath;
@@ -23973,27 +21777,27 @@ var FilesystemBackend = class {
23973
21777
  if (!basePath || basePath.trim().length === 0) {
23974
21778
  throw new Error("FilesystemBackend requires a non-empty basePath");
23975
21779
  }
23976
- this.basePath = path24.resolve(basePath);
21780
+ this.basePath = path21.resolve(basePath);
23977
21781
  }
23978
21782
  resolveRemotePath(remotePath) {
23979
- const resolved = path24.isAbsolute(remotePath) ? path24.resolve(remotePath) : path24.resolve(this.basePath, remotePath);
23980
- const relative = path24.relative(this.basePath, resolved);
23981
- if (relative === ".." || relative.startsWith(`..${path24.sep}`) || path24.isAbsolute(relative)) {
21783
+ const resolved = path21.isAbsolute(remotePath) ? path21.resolve(remotePath) : path21.resolve(this.basePath, remotePath);
21784
+ const relative = path21.relative(this.basePath, resolved);
21785
+ if (relative === ".." || relative.startsWith(`..${path21.sep}`) || path21.isAbsolute(relative)) {
23982
21786
  throw new Error(`FilesystemBackend remotePath escapes basePath: ${JSON.stringify(remotePath)}`);
23983
21787
  }
23984
21788
  return resolved;
23985
21789
  }
23986
21790
  isInsideBase(candidate, realBase) {
23987
- const relative = path24.relative(realBase, candidate);
23988
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path24.sep}`) && !path24.isAbsolute(relative);
21791
+ const relative = path21.relative(realBase, candidate);
21792
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path21.sep}`) && !path21.isAbsolute(relative);
23989
21793
  }
23990
21794
  async realBasePathIfExists() {
23991
21795
  try {
23992
- const stat6 = await fsp.lstat(this.basePath);
23993
- if (stat6.isSymbolicLink()) {
21796
+ const stat5 = await fsp.lstat(this.basePath);
21797
+ if (stat5.isSymbolicLink()) {
23994
21798
  throw new Error(`FilesystemBackend basePath must not be a symlink: ${this.basePath}`);
23995
21799
  }
23996
- if (!stat6.isDirectory()) {
21800
+ if (!stat5.isDirectory()) {
23997
21801
  throw new Error(`FilesystemBackend basePath must be a directory: ${this.basePath}`);
23998
21802
  }
23999
21803
  return await fsp.realpath(this.basePath);
@@ -24014,19 +21818,19 @@ var FilesystemBackend = class {
24014
21818
  }
24015
21819
  async ensureSafeParentDirectory(dest) {
24016
21820
  const realBase = await this.ensureBaseDirectory();
24017
- const destDir = path24.dirname(dest);
24018
- const relativeDir = path24.relative(this.basePath, destDir);
24019
- const segments = relativeDir === "" ? [] : relativeDir.split(path24.sep);
21821
+ const destDir = path21.dirname(dest);
21822
+ const relativeDir = path21.relative(this.basePath, destDir);
21823
+ const segments = relativeDir === "" ? [] : relativeDir.split(path21.sep);
24020
21824
  let current = this.basePath;
24021
21825
  for (const segment of segments) {
24022
21826
  if (segment === "." || segment === "") continue;
24023
- current = path24.join(current, segment);
21827
+ current = path21.join(current, segment);
24024
21828
  try {
24025
- const stat6 = await fsp.lstat(current);
24026
- if (stat6.isSymbolicLink()) {
21829
+ const stat5 = await fsp.lstat(current);
21830
+ if (stat5.isSymbolicLink()) {
24027
21831
  throw new Error(`FilesystemBackend remotePath traverses symlink: ${current}`);
24028
21832
  }
24029
- if (!stat6.isDirectory()) {
21833
+ if (!stat5.isDirectory()) {
24030
21834
  throw new Error(`FilesystemBackend remotePath parent is not a directory: ${current}`);
24031
21835
  }
24032
21836
  } catch (err) {
@@ -24048,26 +21852,26 @@ var FilesystemBackend = class {
24048
21852
  if (realBase === null) {
24049
21853
  return null;
24050
21854
  }
24051
- const destDir = path24.dirname(dest);
24052
- const relativeDir = path24.relative(this.basePath, destDir);
24053
- const segments = relativeDir === "" ? [] : relativeDir.split(path24.sep);
21855
+ const destDir = path21.dirname(dest);
21856
+ const relativeDir = path21.relative(this.basePath, destDir);
21857
+ const segments = relativeDir === "" ? [] : relativeDir.split(path21.sep);
24054
21858
  let current = this.basePath;
24055
21859
  for (const segment of segments) {
24056
21860
  if (segment === "." || segment === "") continue;
24057
- current = path24.join(current, segment);
24058
- let stat6;
21861
+ current = path21.join(current, segment);
21862
+ let stat5;
24059
21863
  try {
24060
- stat6 = await fsp.lstat(current);
21864
+ stat5 = await fsp.lstat(current);
24061
21865
  } catch (err) {
24062
21866
  if (err.code === "ENOENT") {
24063
21867
  return null;
24064
21868
  }
24065
21869
  throw err;
24066
21870
  }
24067
- if (stat6.isSymbolicLink()) {
21871
+ if (stat5.isSymbolicLink()) {
24068
21872
  throw new Error(`FilesystemBackend remotePath traverses symlink: ${current}`);
24069
21873
  }
24070
- if (!stat6.isDirectory()) {
21874
+ if (!stat5.isDirectory()) {
24071
21875
  return null;
24072
21876
  }
24073
21877
  }
@@ -24082,11 +21886,11 @@ var FilesystemBackend = class {
24082
21886
  throw new Error(`FilesystemBackend remotePath parent escapes basePath: ${JSON.stringify(remotePath)}`);
24083
21887
  }
24084
21888
  try {
24085
- const stat6 = await fsp.lstat(dest);
24086
- if (stat6.isSymbolicLink()) {
21889
+ const stat5 = await fsp.lstat(dest);
21890
+ if (stat5.isSymbolicLink()) {
24087
21891
  throw new Error(`FilesystemBackend remotePath points to symlink: ${dest}`);
24088
21892
  }
24089
- if (!stat6.isFile()) {
21893
+ if (!stat5.isFile()) {
24090
21894
  return null;
24091
21895
  }
24092
21896
  } catch (err) {
@@ -24102,14 +21906,14 @@ var FilesystemBackend = class {
24102
21906
  return dest;
24103
21907
  }
24104
21908
  async upload(localPath, remotePath) {
24105
- if (path24.isAbsolute(remotePath)) {
21909
+ if (path21.isAbsolute(remotePath)) {
24106
21910
  throw new Error(`FilesystemBackend upload remotePath must be relative: ${JSON.stringify(remotePath)}`);
24107
21911
  }
24108
21912
  const dest = this.resolveRemotePath(remotePath);
24109
21913
  const realBase = await this.ensureSafeParentDirectory(dest);
24110
21914
  try {
24111
- const stat6 = await fsp.lstat(dest);
24112
- if (stat6.isSymbolicLink()) {
21915
+ const stat5 = await fsp.lstat(dest);
21916
+ if (stat5.isSymbolicLink()) {
24113
21917
  throw new Error(`FilesystemBackend remotePath points to symlink: ${dest}`);
24114
21918
  }
24115
21919
  } catch (err) {
@@ -24175,7 +21979,7 @@ function createBackend(cfg) {
24175
21979
 
24176
21980
  // src/binary-lifecycle/scanner.ts
24177
21981
  import fsp2 from "fs/promises";
24178
- import path25 from "path";
21982
+ import path22 from "path";
24179
21983
  import crypto from "crypto";
24180
21984
  function matchesPatterns(filename, patterns) {
24181
21985
  const lower = filename.toLowerCase();
@@ -24200,8 +22004,8 @@ async function scanForBinaries(memoryDir, config, manifest) {
24200
22004
  return;
24201
22005
  }
24202
22006
  for (const entry of entries) {
24203
- const fullPath = path25.join(dir, entry.name);
24204
- const relativePath = path25.relative(memoryDir, fullPath).split(path25.sep).join("/");
22007
+ const fullPath = path22.join(dir, entry.name);
22008
+ const relativePath = path22.relative(memoryDir, fullPath).split(path22.sep).join("/");
24205
22009
  if (entry.isDirectory()) {
24206
22010
  if (entry.name === ".binary-lifecycle") continue;
24207
22011
  await walk(fullPath);
@@ -24210,12 +22014,12 @@ async function scanForBinaries(memoryDir, config, manifest) {
24210
22014
  if (!entry.isFile()) continue;
24211
22015
  if (!matchesPatterns(entry.name, config.scanPatterns)) continue;
24212
22016
  try {
24213
- const stat6 = await fsp2.stat(fullPath);
24214
- if (stat6.size > config.maxBinarySizeBytes) continue;
24215
- if (stat6.size === 0) continue;
22017
+ const stat5 = await fsp2.stat(fullPath);
22018
+ if (stat5.size > config.maxBinarySizeBytes) continue;
22019
+ if (stat5.size === 0) continue;
24216
22020
  const existing = tracked.get(relativePath);
24217
22021
  if (existing) {
24218
- if (existing.sizeBytes !== stat6.size) {
22022
+ if (existing.sizeBytes !== stat5.size) {
24219
22023
  results.push(relativePath);
24220
22024
  continue;
24221
22025
  }
@@ -24241,15 +22045,15 @@ async function hashFile(filePath) {
24241
22045
 
24242
22046
  // src/binary-lifecycle/manifest.ts
24243
22047
  import fsp3 from "fs/promises";
24244
- import path26 from "path";
22048
+ import path23 from "path";
24245
22049
  import crypto2 from "crypto";
24246
22050
  var MANIFEST_DIR = ".binary-lifecycle";
24247
22051
  var MANIFEST_FILE = "manifest.json";
24248
22052
  function manifestDir(memoryDir) {
24249
- return path26.join(memoryDir, MANIFEST_DIR);
22053
+ return path23.join(memoryDir, MANIFEST_DIR);
24250
22054
  }
24251
22055
  function manifestPath(memoryDir) {
24252
- return path26.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
22056
+ return path23.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
24253
22057
  }
24254
22058
  async function readManifest(memoryDir) {
24255
22059
  const filePath = manifestPath(memoryDir);
@@ -24301,13 +22105,13 @@ function emptyManifest() {
24301
22105
 
24302
22106
  // src/binary-lifecycle/pipeline.ts
24303
22107
  import fsp4 from "fs/promises";
24304
- import path27 from "path";
22108
+ import path24 from "path";
24305
22109
  import crypto3 from "crypto";
24306
22110
  var historicalIdCache = new HistoricalEntityCanonicalIdCache();
24307
22111
  function isRecallCorpusMarkdown(mdPath, memoryDir) {
24308
- const rel = path27.relative(memoryDir, mdPath);
24309
- if (rel.startsWith("..") || path27.isAbsolute(rel)) return false;
24310
- const top = rel.split(path27.sep)[0];
22112
+ const rel = path24.relative(memoryDir, mdPath);
22113
+ if (rel.startsWith("..") || path24.isAbsolute(rel)) return false;
22114
+ const top = rel.split(path24.sep)[0];
24311
22115
  return RECALL_FALLBACK_DIRS.includes(top);
24312
22116
  }
24313
22117
  async function hashFile2(filePath) {
@@ -24331,13 +22135,13 @@ function escapeRegex(s) {
24331
22135
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
24332
22136
  }
24333
22137
  function resolveManifestAssetPath(memoryDir, originalPath) {
24334
- if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path27.isAbsolute(originalPath) || path27.win32.isAbsolute(originalPath)) {
22138
+ if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path24.isAbsolute(originalPath) || path24.win32.isAbsolute(originalPath)) {
24335
22139
  return null;
24336
22140
  }
24337
- const memoryRoot = path27.resolve(memoryDir);
24338
- const fullPath = path27.resolve(memoryRoot, originalPath);
24339
- const relative = path27.relative(memoryRoot, fullPath);
24340
- if (relative === "" || relative === ".." || relative.startsWith(`..${path27.sep}`) || path27.isAbsolute(relative)) {
22141
+ const memoryRoot = path24.resolve(memoryDir);
22142
+ const fullPath = path24.resolve(memoryRoot, originalPath);
22143
+ const relative = path24.relative(memoryRoot, fullPath);
22144
+ if (relative === "" || relative === ".." || relative.startsWith(`..${path24.sep}`) || path24.isAbsolute(relative)) {
24341
22145
  return null;
24342
22146
  }
24343
22147
  return fullPath;
@@ -24348,7 +22152,7 @@ function validateBinaryLifecycleConfig(config) {
24348
22152
  }
24349
22153
  }
24350
22154
  function remotePathForAsset(backend, relPath) {
24351
- const normalized = relPath.split(path27.sep).join("/");
22155
+ const normalized = relPath.split(path24.sep).join("/");
24352
22156
  if (backend.type === "filesystem") {
24353
22157
  return `.binary-lifecycle/mirrors/${normalized}`;
24354
22158
  }
@@ -24361,11 +22165,11 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
24361
22165
  let mirrored = 0;
24362
22166
  const errors = [];
24363
22167
  for (const relPath of newPaths) {
24364
- const fullPath = path27.join(memoryDir, relPath);
22168
+ const fullPath = path24.join(memoryDir, relPath);
24365
22169
  try {
24366
- const stat6 = await fsp4.stat(fullPath);
22170
+ const stat5 = await fsp4.stat(fullPath);
24367
22171
  const contentHash = await hashFile2(fullPath);
24368
- const ext = path27.extname(relPath);
22172
+ const ext = path24.extname(relPath);
24369
22173
  const mimeType = guessMimeType(ext);
24370
22174
  const remotePath = remotePathForAsset(backend, relPath);
24371
22175
  let backendLocation = remotePath;
@@ -24378,7 +22182,7 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
24378
22182
  mirroredPath: backendLocation,
24379
22183
  ...redirectPath ? { redirectPath } : {},
24380
22184
  contentHash,
24381
- sizeBytes: stat6.size,
22185
+ sizeBytes: stat5.size,
24382
22186
  mimeType,
24383
22187
  mirroredAt: (/* @__PURE__ */ new Date()).toISOString(),
24384
22188
  status: "mirrored"
@@ -24391,7 +22195,7 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
24391
22195
  assets.push(record);
24392
22196
  }
24393
22197
  mirrored++;
24394
- log2.info(`[binary-lifecycle] mirrored: ${relPath} (${stat6.size} bytes)${dryRun ? " [dry-run]" : ""}`);
22198
+ log2.info(`[binary-lifecycle] mirrored: ${relPath} (${stat5.size} bytes)${dryRun ? " [dry-run]" : ""}`);
24395
22199
  } catch (err) {
24396
22200
  const msg = `mirror failed for ${relPath}: ${err instanceof Error ? err.message : String(err)}`;
24397
22201
  log2.error(`[binary-lifecycle] ${msg}`);
@@ -24425,8 +22229,8 @@ async function stageRedirect(memoryDir, assets, log2, dryRun, readMarkdownFile,
24425
22229
  const pattern = markdownReferencePattern(asset, assetAbsolute, mdPath);
24426
22230
  if (!pattern.test(content)) continue;
24427
22231
  pattern.lastIndex = 0;
24428
- const updated = content.replace(pattern, (_match, open3, _target, close) => {
24429
- return `${open3}${markdownTargetForAsset(asset)}${close}`;
22232
+ const updated = content.replace(pattern, (_match, open, _target, close) => {
22233
+ return `${open}${markdownTargetForAsset(asset)}${close}`;
24430
22234
  });
24431
22235
  updates.push({ mdPath, content: updated });
24432
22236
  } catch (err) {
@@ -24503,7 +22307,7 @@ async function stageRedirect(memoryDir, assets, log2, dryRun, readMarkdownFile,
24503
22307
  for (const update of updates) {
24504
22308
  try {
24505
22309
  await withRawEntityPageMutation(memoryDir, update.mdPath, async () => {
24506
- const stateDir = path27.join(memoryDir, "state");
22310
+ const stateDir = path24.join(memoryDir, "state");
24507
22311
  const kind = classifyEntityRefWritePath(memoryDir, update.mdPath);
24508
22312
  if (kind === "memory") {
24509
22313
  const idsAtWrite = historicalIdCache.get(stateDir);
@@ -24597,10 +22401,10 @@ async function countRemainingLocalReferences(memoryDir, asset, assetAbsolute, md
24597
22401
  return { remaining, errors };
24598
22402
  }
24599
22403
  function markdownReferencePattern(asset, assetAbsolute, mdPath) {
24600
- const mdDir = path27.dirname(mdPath);
22404
+ const mdDir = path24.dirname(mdPath);
24601
22405
  const candidates = /* @__PURE__ */ new Set();
24602
22406
  const addCandidate = (candidate) => {
24603
- const normalized = candidate.split(path27.sep).join("/");
22407
+ const normalized = candidate.split(path24.sep).join("/");
24604
22408
  if (normalized.length === 0) return;
24605
22409
  candidates.add(normalized);
24606
22410
  const isParentTraversal = normalized === ".." || normalized.startsWith("../");
@@ -24608,10 +22412,10 @@ function markdownReferencePattern(asset, assetAbsolute, mdPath) {
24608
22412
  candidates.add(`./${normalized}`);
24609
22413
  }
24610
22414
  };
24611
- addCandidate(path27.relative(mdDir, assetAbsolute));
24612
- const originalPath = asset.originalPath.split(path27.sep).join("/");
24613
- const originalAsFileRelative = path27.resolve(mdDir, ...originalPath.split("/"));
24614
- if (path27.resolve(originalAsFileRelative) === path27.resolve(assetAbsolute)) {
22415
+ addCandidate(path24.relative(mdDir, assetAbsolute));
22416
+ const originalPath = asset.originalPath.split(path24.sep).join("/");
22417
+ const originalAsFileRelative = path24.resolve(mdDir, ...originalPath.split("/"));
22418
+ if (path24.resolve(originalAsFileRelative) === path24.resolve(assetAbsolute)) {
24615
22419
  addCandidate(originalPath);
24616
22420
  }
24617
22421
  addCandidate(`/${originalPath}`);
@@ -24707,7 +22511,7 @@ async function findMarkdownFiles(dir) {
24707
22511
  return;
24708
22512
  }
24709
22513
  for (const entry of entries) {
24710
- const full = path27.join(current, entry.name);
22514
+ const full = path24.join(current, entry.name);
24711
22515
  if (entry.isDirectory()) {
24712
22516
  if (entry.name === ".binary-lifecycle") continue;
24713
22517
  await walk(full);
@@ -24782,7 +22586,7 @@ async function runBinaryLifecyclePipeline(memoryDir, config, backend, log2, opts
24782
22586
 
24783
22587
  // src/projection/index.ts
24784
22588
  import fs from "fs";
24785
- import path28 from "path";
22589
+ import path25 from "path";
24786
22590
  var VALID_PROJECTION_CATEGORIES = new Set(ALL_CATEGORY_KEYS);
24787
22591
  async function generateContextTree(options) {
24788
22592
  const startTime = Date.now();
@@ -24797,8 +22601,8 @@ async function generateContextTree(options) {
24797
22601
  let nodesGenerated = 0;
24798
22602
  let nodesSkipped = 0;
24799
22603
  const categoryCounts = {};
24800
- const resolvedMemoryDir = path28.resolve(memoryDir);
24801
- const resolvedOutputDir = path28.resolve(outputDir);
22604
+ const resolvedMemoryDir = path25.resolve(memoryDir);
22605
+ const resolvedOutputDir = path25.resolve(outputDir);
24802
22606
  const requestedCategories = validateProjectionCategories(filterCategories);
24803
22607
  const realMemoryDir = assertSafeMemoryRoot(resolvedMemoryDir);
24804
22608
  assertNotSymlink(resolvedOutputDir, "context tree outputDir");
@@ -24836,7 +22640,7 @@ async function generateContextTree(options) {
24836
22640
  }
24837
22641
  }
24838
22642
  if (includeEntities) {
24839
- const entitiesDir = path28.join(memoryDir, "entities");
22643
+ const entitiesDir = path25.join(memoryDir, "entities");
24840
22644
  if (fs.existsSync(entitiesDir)) {
24841
22645
  assertSafeInputRoot(realMemoryDir, entitiesDir, "entities root");
24842
22646
  categoryCounts["entity"] = 0;
@@ -24848,7 +22652,7 @@ async function generateContextTree(options) {
24848
22652
  continue;
24849
22653
  }
24850
22654
  const content = fs.readFileSync(filePath, "utf8");
24851
- const fileName = path28.basename(filePath, ".md");
22655
+ const fileName = path25.basename(filePath, ".md");
24852
22656
  const node = projectEntityNode(fileName, content);
24853
22657
  const outputPath = resolveContainedOutputPath(realOutputDir, "entities", `${fileName}.md`);
24854
22658
  writeProjectedContent(realOutputDir, outputPath, node.content);
@@ -24860,7 +22664,7 @@ async function generateContextTree(options) {
24860
22664
  }
24861
22665
  const shouldIncludeQuestions = includeQuestions && (requestedCategories === void 0 || requestedCategories.includes("question"));
24862
22666
  if (shouldIncludeQuestions) {
24863
- const questionsDir = path28.join(memoryDir, "questions");
22667
+ const questionsDir = path25.join(memoryDir, "questions");
24864
22668
  if (fs.existsSync(questionsDir)) {
24865
22669
  assertSafeInputRoot(realMemoryDir, questionsDir, "questions root");
24866
22670
  categoryCounts["question"] = 0;
@@ -24901,8 +22705,8 @@ async function generateContextTree(options) {
24901
22705
  };
24902
22706
  }
24903
22707
  function isPathInside(root, candidate) {
24904
- const relative = path28.relative(root, candidate);
24905
- return relative === "" || !relative.startsWith("..") && !path28.isAbsolute(relative);
22708
+ const relative = path25.relative(root, candidate);
22709
+ return relative === "" || !relative.startsWith("..") && !path25.isAbsolute(relative);
24906
22710
  }
24907
22711
  function assertNotSymlink(targetPath, label) {
24908
22712
  try {
@@ -24915,21 +22719,21 @@ function assertNotSymlink(targetPath, label) {
24915
22719
  }
24916
22720
  }
24917
22721
  function assertSafeMemoryRoot(targetPath) {
24918
- const stat6 = fs.lstatSync(targetPath);
24919
- if (stat6.isSymbolicLink()) {
22722
+ const stat5 = fs.lstatSync(targetPath);
22723
+ if (stat5.isSymbolicLink()) {
24920
22724
  throw new Error(`memoryDir must not be a symlink: ${targetPath}`);
24921
22725
  }
24922
- if (!stat6.isDirectory()) {
22726
+ if (!stat5.isDirectory()) {
24923
22727
  throw new Error(`memoryDir must be a directory: ${targetPath}`);
24924
22728
  }
24925
22729
  return fs.realpathSync(targetPath);
24926
22730
  }
24927
22731
  function assertSafeInputRoot(realMemoryDir, targetPath, label) {
24928
- const stat6 = fs.lstatSync(targetPath);
24929
- if (stat6.isSymbolicLink()) {
22732
+ const stat5 = fs.lstatSync(targetPath);
22733
+ if (stat5.isSymbolicLink()) {
24930
22734
  throw new Error(`${label} must not be a symlink: ${targetPath}`);
24931
22735
  }
24932
- if (!stat6.isDirectory()) {
22736
+ if (!stat5.isDirectory()) {
24933
22737
  throw new Error(`${label} must be a directory: ${targetPath}`);
24934
22738
  }
24935
22739
  const realTarget = fs.realpathSync(targetPath);
@@ -24939,15 +22743,15 @@ function assertSafeInputRoot(realMemoryDir, targetPath, label) {
24939
22743
  }
24940
22744
  function assertSafeOutputTarget(realOutputDir, outputPath) {
24941
22745
  let current = realOutputDir;
24942
- const relative = path28.relative(realOutputDir, outputPath);
24943
- if (relative.startsWith("..") || path28.isAbsolute(relative)) {
22746
+ const relative = path25.relative(realOutputDir, outputPath);
22747
+ if (relative.startsWith("..") || path25.isAbsolute(relative)) {
24944
22748
  throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
24945
22749
  }
24946
- for (const segment of relative.split(path28.sep).filter(Boolean)) {
24947
- current = path28.join(current, segment);
22750
+ for (const segment of relative.split(path25.sep).filter(Boolean)) {
22751
+ current = path25.join(current, segment);
24948
22752
  try {
24949
- const stat6 = fs.lstatSync(current);
24950
- if (stat6.isSymbolicLink()) {
22753
+ const stat5 = fs.lstatSync(current);
22754
+ if (stat5.isSymbolicLink()) {
24951
22755
  throw new Error(`context tree output path contains symlink: ${current}`);
24952
22756
  }
24953
22757
  } catch (err) {
@@ -24974,17 +22778,17 @@ function validateProjectionCategories(categories) {
24974
22778
  return validated;
24975
22779
  }
24976
22780
  function resolveContainedOutputPath(outputRoot, ...segments) {
24977
- const resolved = path28.resolve(outputRoot, ...segments);
24978
- const relative = path28.relative(outputRoot, resolved);
24979
- if (relative === "" || !relative.startsWith("..") && !path28.isAbsolute(relative)) {
22781
+ const resolved = path25.resolve(outputRoot, ...segments);
22782
+ const relative = path25.relative(outputRoot, resolved);
22783
+ if (relative === "" || !relative.startsWith("..") && !path25.isAbsolute(relative)) {
24980
22784
  return resolved;
24981
22785
  }
24982
22786
  throw new Error(`context tree output path escapes outputDir: ${segments.join("/")}`);
24983
22787
  }
24984
22788
  function writeProjectedContent(realOutputDir, outputPath, generatedContent) {
24985
22789
  assertSafeOutputTarget(realOutputDir, outputPath);
24986
- fs.mkdirSync(path28.dirname(outputPath), { recursive: true });
24987
- const realParent = fs.realpathSync(path28.dirname(outputPath));
22790
+ fs.mkdirSync(path25.dirname(outputPath), { recursive: true });
22791
+ const realParent = fs.realpathSync(path25.dirname(outputPath));
24988
22792
  if (!isPathInside(realOutputDir, realParent)) {
24989
22793
  throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
24990
22794
  }
@@ -25023,7 +22827,7 @@ function walkR(dir, realMemoryDir) {
25023
22827
  const results = [];
25024
22828
  function walk(directory) {
25025
22829
  for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
25026
- const fullPath = path28.join(directory, entry.name);
22830
+ const fullPath = path25.join(directory, entry.name);
25027
22831
  if (entry.isSymbolicLink()) {
25028
22832
  throw new Error(`context tree input path contains symlink: ${fullPath}`);
25029
22833
  }
@@ -25076,13 +22880,13 @@ function extractBody(content) {
25076
22880
  }
25077
22881
  function projectNode(filePath, category, fm, rawContent) {
25078
22882
  const body = extractBody(rawContent);
25079
- const fileName = path28.basename(filePath, ".md");
25080
- const dateDir = path28.basename(path28.dirname(filePath));
22883
+ const fileName = path25.basename(filePath, ".md");
22884
+ const dateDir = path25.basename(path25.dirname(filePath));
25081
22885
  let relPath;
25082
22886
  if (/^\d{4}-\d{2}-\d{2}$/.test(dateDir)) {
25083
- relPath = path28.join(category, dateDir, `${fileName}.md`);
22887
+ relPath = path25.join(category, dateDir, `${fileName}.md`);
25084
22888
  } else {
25085
- relPath = path28.join(category, `${fileName}.md`);
22889
+ relPath = path25.join(category, `${fileName}.md`);
25086
22890
  }
25087
22891
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
25088
22892
  const md = `# ${fm.id}
@@ -25128,7 +22932,7 @@ function projectEntityNode(fileName, content) {
25128
22932
  ${content}
25129
22933
  `;
25130
22934
  return {
25131
- path: path28.join("entities", `${fileName}.md`),
22935
+ path: path25.join("entities", `${fileName}.md`),
25132
22936
  category: "entity",
25133
22937
  title: fileName,
25134
22938
  content: md,
@@ -25181,7 +22985,7 @@ function generateIndex(categoryCounts, outputDir) {
25181
22985
 
25182
22986
  // src/onboarding/index.ts
25183
22987
  import fs2 from "fs";
25184
- import path29 from "path";
22988
+ import path26 from "path";
25185
22989
  var LANGUAGE_RULES = [
25186
22990
  {
25187
22991
  language: "TypeScript",
@@ -25283,7 +23087,7 @@ function onboard(options) {
25283
23087
  maxDepth = 6,
25284
23088
  excludeDirs = []
25285
23089
  } = options;
25286
- const directory = path29.resolve(options.directory ?? process.cwd());
23090
+ const directory = path26.resolve(options.directory ?? process.cwd());
25287
23091
  let rootStat;
25288
23092
  try {
25289
23093
  rootStat = fs2.statSync(directory);
@@ -25325,7 +23129,7 @@ function walkDir(root, exclude, maxDepth) {
25325
23129
  }
25326
23130
  for (const entry of entries) {
25327
23131
  if (exclude.has(entry.name)) continue;
25328
- const fullPath = path29.join(dir, entry.name);
23132
+ const fullPath = path26.join(dir, entry.name);
25329
23133
  if (entry.isDirectory()) {
25330
23134
  walk(fullPath, depth + 1);
25331
23135
  } else if (entry.isFile()) {
@@ -25340,11 +23144,11 @@ function detectLanguages(files, root) {
25340
23144
  const results = [];
25341
23145
  const extCounts = /* @__PURE__ */ new Map();
25342
23146
  for (const f of files) {
25343
- const ext = path29.extname(f).toLowerCase();
23147
+ const ext = path26.extname(f).toLowerCase();
25344
23148
  if (ext) extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
25345
23149
  }
25346
23150
  const rootFiles = new Set(
25347
- files.filter((f) => path29.dirname(f) === root).map((f) => path29.basename(f))
23151
+ files.filter((f) => path26.dirname(f) === root).map((f) => path26.basename(f))
25348
23152
  );
25349
23153
  for (const rule of LANGUAGE_RULES) {
25350
23154
  const evidence = [];
@@ -25388,7 +23192,7 @@ function detectLanguages(files, root) {
25388
23192
  }
25389
23193
  function detectShape(files, root) {
25390
23194
  const rootFiles = new Set(
25391
- files.filter((f) => path29.dirname(f) === root).map((f) => path29.basename(f))
23195
+ files.filter((f) => path26.dirname(f) === root).map((f) => path26.basename(f))
25392
23196
  );
25393
23197
  const rootDirs = /* @__PURE__ */ new Set();
25394
23198
  try {
@@ -25399,7 +23203,7 @@ function detectShape(files, root) {
25399
23203
  }
25400
23204
  const evidence = [];
25401
23205
  if (rootFiles.has("package.json")) {
25402
- const pkg = readJsonSafe(path29.join(root, "package.json"));
23206
+ const pkg = readJsonSafe(path26.join(root, "package.json"));
25403
23207
  if (pkg?.workspaces) {
25404
23208
  evidence.push("package.json has workspaces");
25405
23209
  return { shape: "monorepo", evidence };
@@ -25413,13 +23217,13 @@ function detectShape(files, root) {
25413
23217
  evidence.push("workspace manifest found");
25414
23218
  return { shape: "workspace", evidence };
25415
23219
  }
25416
- const cargoToml = readTomlWorkspace(path29.join(root, "Cargo.toml"));
23220
+ const cargoToml = readTomlWorkspace(path26.join(root, "Cargo.toml"));
25417
23221
  if (cargoToml) {
25418
23222
  evidence.push("Cargo.toml has workspace");
25419
23223
  return { shape: "workspace", evidence };
25420
23224
  }
25421
23225
  if (rootFiles.has("package.json")) {
25422
- const pkg = readJsonSafe(path29.join(root, "package.json"));
23226
+ const pkg = readJsonSafe(path26.join(root, "package.json"));
25423
23227
  if (pkg?.exports || pkg?.main) {
25424
23228
  if (pkg?.bin) {
25425
23229
  evidence.push("package.json has bin");
@@ -25453,8 +23257,8 @@ function discoverDocs(files, root) {
25453
23257
  { pattern: /^\.editorconfig$/i, kind: "config" }
25454
23258
  ];
25455
23259
  for (const filePath of files) {
25456
- const basename = path29.basename(filePath).toLowerCase();
25457
- const relPath = path29.relative(root, filePath);
23260
+ const basename = path26.basename(filePath).toLowerCase();
23261
+ const relPath = path26.relative(root, filePath);
25458
23262
  let kind;
25459
23263
  for (const { pattern, kind: k } of docPatterns) {
25460
23264
  if (pattern.test(basename)) {
@@ -25466,7 +23270,7 @@ function discoverDocs(files, root) {
25466
23270
  kind = "docs";
25467
23271
  }
25468
23272
  if (!kind && (basename.endsWith(".md") || basename.endsWith(".mdx"))) {
25469
- if (path29.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
23273
+ if (path26.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
25470
23274
  kind = "docs";
25471
23275
  }
25472
23276
  }
@@ -25487,7 +23291,7 @@ function discoverDocs(files, root) {
25487
23291
  return docs;
25488
23292
  }
25489
23293
  function isUnderDocsDir(relPath) {
25490
- const parts = relPath.split(path29.sep);
23294
+ const parts = relPath.split(path26.sep);
25491
23295
  return parts[0] === "docs" || parts[0] === "doc" || parts[0] === "documentation";
25492
23296
  }
25493
23297
  function buildPlan(languages, shape, docs, _root) {
@@ -25531,7 +23335,7 @@ function readTomlWorkspace(filePath) {
25531
23335
 
25532
23336
  // src/curation/index.ts
25533
23337
  import fs3 from "fs";
25534
- import path30 from "path";
23338
+ import path27 from "path";
25535
23339
  import crypto4 from "crypto";
25536
23340
  async function curate(options) {
25537
23341
  const startTime = Date.now();
@@ -25616,18 +23420,18 @@ async function curate(options) {
25616
23420
  };
25617
23421
  }
25618
23422
  function resolveTargets(targetPath) {
25619
- const stat6 = fs3.statSync(targetPath);
25620
- if (stat6.isFile()) return [targetPath];
23423
+ const stat5 = fs3.statSync(targetPath);
23424
+ if (stat5.isFile()) return [targetPath];
25621
23425
  const results = [];
25622
23426
  const extensions = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
25623
23427
  function walk(dir) {
25624
23428
  for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
25625
- const fullPath = path30.join(dir, entry.name);
23429
+ const fullPath = path27.join(dir, entry.name);
25626
23430
  if (entry.isDirectory()) {
25627
23431
  if (entry.name !== "node_modules" && entry.name !== ".git") {
25628
23432
  walk(fullPath);
25629
23433
  }
25630
- } else if (extensions.has(path30.extname(entry.name).toLowerCase())) {
23434
+ } else if (extensions.has(path27.extname(entry.name).toLowerCase())) {
25631
23435
  results.push(fullPath);
25632
23436
  }
25633
23437
  }
@@ -25636,12 +23440,12 @@ function resolveTargets(targetPath) {
25636
23440
  return results;
25637
23441
  }
25638
23442
  function resolveProvenanceRoot(targetPath) {
25639
- const resolvedTarget = path30.resolve(targetPath);
25640
- const stat6 = fs3.statSync(resolvedTarget);
25641
- return stat6.isFile() ? path30.dirname(resolvedTarget) : resolvedTarget;
23443
+ const resolvedTarget = path27.resolve(targetPath);
23444
+ const stat5 = fs3.statSync(resolvedTarget);
23445
+ return stat5.isFile() ? path27.dirname(resolvedTarget) : resolvedTarget;
25642
23446
  }
25643
23447
  function extractStatements(content, filePath, projectRoot, source, sourceFileHash, categoryOverride, confidence, entityRef, tags) {
25644
- const relativePath = path30.relative(projectRoot, path30.resolve(filePath)) || path30.basename(filePath);
23448
+ const relativePath = path27.relative(projectRoot, path27.resolve(filePath)) || path27.basename(filePath);
25645
23449
  const statements = [];
25646
23450
  const now = (/* @__PURE__ */ new Date()).toISOString();
25647
23451
  const paragraphs = content.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 20 && p.length < 2e3);
@@ -25735,7 +23539,7 @@ function loadExistingMemories(memoryDir) {
25735
23539
  if (!fs3.existsSync(memoryDir)) return result;
25736
23540
  const dirs = ALL_CATEGORY_DIRS;
25737
23541
  for (const dir of dirs) {
25738
- const fullDir = path30.join(memoryDir, dir);
23542
+ const fullDir = path27.join(memoryDir, dir);
25739
23543
  if (!fs3.existsSync(fullDir)) continue;
25740
23544
  walkFiles(fullDir, (filePath) => {
25741
23545
  const content = readFileSafe(filePath);
@@ -25758,11 +23562,11 @@ function writeStatement(stmt, memoryDir) {
25758
23562
  const now = /* @__PURE__ */ new Date();
25759
23563
  const dateDir = now.toISOString().split("T")[0];
25760
23564
  const categoryDir = getCategoryDir(memoryDir, stmt.category);
25761
- const dir = path30.join(categoryDir, dateDir);
23565
+ const dir = path27.join(categoryDir, dateDir);
25762
23566
  fs3.mkdirSync(dir, { recursive: true });
25763
23567
  const fileName = `${stmt.category}-${Date.now()}-${stmt.id.slice(0, 8)}.md`;
25764
- const filePath = path30.join(dir, fileName);
25765
- const historicalIds = historicalIdCache2.get(path30.join(memoryDir, "state"));
23568
+ const filePath = path27.join(dir, fileName);
23569
+ const historicalIds = historicalIdCache2.get(path27.join(memoryDir, "state"));
25766
23570
  const rawBody = `${[
25767
23571
  "---",
25768
23572
  `id: ${stmt.id}`,
@@ -25785,7 +23589,7 @@ ${stmt.content}
25785
23589
  fs3.writeFileSync(filePath, body);
25786
23590
  try {
25787
23591
  repairContentAfterJournalMoveSync({
25788
- stateDir: path30.join(memoryDir, "state"),
23592
+ stateDir: path27.join(memoryDir, "state"),
25789
23593
  cache: historicalIdCache2,
25790
23594
  idsAtWrite: historicalIds,
25791
23595
  rawContent: rawBody,
@@ -25846,7 +23650,7 @@ function extractBody2(content) {
25846
23650
  }
25847
23651
  function walkFiles(dir, callback) {
25848
23652
  for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
25849
- const fullPath = path30.join(dir, entry.name);
23653
+ const fullPath = path27.join(dir, entry.name);
25850
23654
  if (entry.isDirectory()) {
25851
23655
  walkFiles(fullPath, callback);
25852
23656
  } else if (entry.name.endsWith(".md")) {
@@ -25858,7 +23662,7 @@ function walkFiles(dir, callback) {
25858
23662
  // src/dedup/index.ts
25859
23663
  import crypto5 from "crypto";
25860
23664
  import fs4 from "fs";
25861
- import path31 from "path";
23665
+ import path28 from "path";
25862
23666
  var DEFAULT_DEDUP_THRESHOLD = 0.85;
25863
23667
  var DEFAULT_MAX_LOAD = 1e4;
25864
23668
  function normalizeThreshold(value, defaultValue) {
@@ -26052,7 +23856,7 @@ function loadMemories(memoryDir, categories, maxLoad = 1e4) {
26052
23856
  const memoryRootReal = fs4.realpathSync(memoryDir);
26053
23857
  for (const category of allCategories) {
26054
23858
  if (result.length >= maxLoad) break;
26055
- const dir = path31.join(memoryDir, category);
23859
+ const dir = path28.join(memoryDir, category);
26056
23860
  if (!fs4.existsSync(dir)) continue;
26057
23861
  const categoryStat = fs4.lstatSync(dir);
26058
23862
  if (categoryStat.isSymbolicLink()) {
@@ -26113,15 +23917,15 @@ function extractBody3(content) {
26113
23917
  return match ? match[1].trim() : content.trim();
26114
23918
  }
26115
23919
  function assertPathInsideRoot2(rootReal, targetReal, sourcePath) {
26116
- const rel = path31.relative(rootReal, targetReal);
26117
- if (rel === "" || !rel.startsWith("..") && !path31.isAbsolute(rel)) {
23920
+ const rel = path28.relative(rootReal, targetReal);
23921
+ if (rel === "" || !rel.startsWith("..") && !path28.isAbsolute(rel)) {
26118
23922
  return;
26119
23923
  }
26120
23924
  throw new Error(`Refusing to scan memory path outside root: ${sourcePath}`);
26121
23925
  }
26122
23926
  function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
26123
23927
  for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
26124
- const fullPath = path31.join(dir, entry.name);
23928
+ const fullPath = path28.join(dir, entry.name);
26125
23929
  const entryStat = fs4.lstatSync(fullPath);
26126
23930
  if (entryStat.isSymbolicLink()) {
26127
23931
  throw new Error(`Refusing to scan symlinked memory path: ${fullPath}`);
@@ -26139,10 +23943,10 @@ function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
26139
23943
 
26140
23944
  // src/review/index.ts
26141
23945
  import fs5 from "fs";
26142
- import path32 from "path";
23946
+ import path29 from "path";
26143
23947
  var historicalIdCache3 = new HistoricalEntityCanonicalIdCache();
26144
23948
  function writeReviewFileCanonicalized(memoryDir, filePath, content) {
26145
- const stateDir = path32.join(memoryDir, "state");
23949
+ const stateDir = path29.join(memoryDir, "state");
26146
23950
  const idsAtWrite = historicalIdCache3.get(stateDir);
26147
23951
  let originalBytes = null;
26148
23952
  try {
@@ -26176,21 +23980,21 @@ function writeReviewFileCanonicalized(memoryDir, filePath, content) {
26176
23980
  var DEFAULT_CONFIDENCE_THRESHOLD = 0.7;
26177
23981
  function realMemoryRoot(memoryDir) {
26178
23982
  try {
26179
- const stat6 = fs5.lstatSync(memoryDir);
26180
- if (!stat6.isDirectory() || stat6.isSymbolicLink()) return null;
23983
+ const stat5 = fs5.lstatSync(memoryDir);
23984
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) return null;
26181
23985
  return fs5.realpathSync(memoryDir);
26182
23986
  } catch {
26183
23987
  return null;
26184
23988
  }
26185
23989
  }
26186
23990
  function isPathInside2(rootReal, candidateReal) {
26187
- const relative = path32.relative(rootReal, candidateReal);
26188
- return relative === "" || !!relative && !relative.startsWith("..") && !path32.isAbsolute(relative);
23991
+ const relative = path29.relative(rootReal, candidateReal);
23992
+ return relative === "" || !!relative && !relative.startsWith("..") && !path29.isAbsolute(relative);
26189
23993
  }
26190
23994
  function isSafeDirectory(rootReal, dir) {
26191
23995
  try {
26192
- const stat6 = fs5.lstatSync(dir);
26193
- if (!stat6.isDirectory() || stat6.isSymbolicLink()) return false;
23996
+ const stat5 = fs5.lstatSync(dir);
23997
+ if (!stat5.isDirectory() || stat5.isSymbolicLink()) return false;
26194
23998
  return isPathInside2(rootReal, fs5.realpathSync(dir));
26195
23999
  } catch {
26196
24000
  return false;
@@ -26228,7 +24032,7 @@ function listReviewItems(options) {
26228
24032
  if (filterReason && item.reviewReason !== filterReason) return;
26229
24033
  items.push(item);
26230
24034
  };
26231
- const suggestionsDir = path32.join(memoryDir, "suggestions");
24035
+ const suggestionsDir = path29.join(memoryDir, "suggestions");
26232
24036
  if (!isLimitReached() && fs5.existsSync(suggestionsDir) && isSafeDirectory(rootReal, suggestionsDir)) {
26233
24037
  walkMd(rootReal, suggestionsDir, (filePath, content) => {
26234
24038
  if (isLimitReached()) return true;
@@ -26249,7 +24053,7 @@ function listReviewItems(options) {
26249
24053
  return isLimitReached();
26250
24054
  });
26251
24055
  }
26252
- const reviewDir = path32.join(memoryDir, "review");
24056
+ const reviewDir = path29.join(memoryDir, "review");
26253
24057
  if (!isLimitReached() && fs5.existsSync(reviewDir) && isSafeDirectory(rootReal, reviewDir)) {
26254
24058
  walkMd(rootReal, reviewDir, (filePath, content) => {
26255
24059
  if (isLimitReached()) return true;
@@ -26274,7 +24078,7 @@ function listReviewItems(options) {
26274
24078
  const categories = ALL_CATEGORY_DIRS;
26275
24079
  for (const category of categories) {
26276
24080
  if (isLimitReached()) break;
26277
- const dir = path32.join(memoryDir, category);
24081
+ const dir = path29.join(memoryDir, category);
26278
24082
  if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
26279
24083
  walkMd(rootReal, dir, (filePath, content) => {
26280
24084
  if (isLimitReached()) return true;
@@ -26356,9 +24160,9 @@ function approveItem(memoryDir, itemId, options) {
26356
24160
  const targetDir = getCategoryDir(memoryDir, category);
26357
24161
  const dateDir = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
26358
24162
  ensureSafeDirectory(rootReal, targetDir);
26359
- const outputPath = path32.join(targetDir, dateDir, path32.basename(found.filePath));
26360
- ensureSafeDirectory(rootReal, path32.dirname(outputPath));
26361
- const reviewStateDir = path32.join(memoryDir, "state");
24163
+ const outputPath = path29.join(targetDir, dateDir, path29.basename(found.filePath));
24164
+ ensureSafeDirectory(rootReal, path29.dirname(outputPath));
24165
+ const reviewStateDir = path29.join(memoryDir, "state");
26362
24166
  const idsAtWrite = historicalIdCache3.get(reviewStateDir);
26363
24167
  const promotedWritten = canonicalizeEntityRefFrontmatter(updatedContent, idsAtWrite);
26364
24168
  const promotedPath = writeFileWithoutClobber(outputPath, promotedWritten, itemId);
@@ -26435,13 +24239,13 @@ function findReviewFileById(memoryDir, id, options = {}) {
26435
24239
  const rootReal = realMemoryRoot(memoryDir);
26436
24240
  if (!rootReal) return null;
26437
24241
  for (const loc of ["suggestions", "review"]) {
26438
- const dir = path32.join(memoryDir, loc);
24242
+ const dir = path29.join(memoryDir, loc);
26439
24243
  if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
26440
24244
  const found = findFileById(rootReal, dir, id);
26441
24245
  if (found) return { filePath: found, location: "queue" };
26442
24246
  }
26443
24247
  for (const category of ALL_CATEGORY_DIRS) {
26444
- const dir = path32.join(memoryDir, category);
24248
+ const dir = path29.join(memoryDir, category);
26445
24249
  if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
26446
24250
  const found = findFileById(rootReal, dir, id, (fm) => isLowConfidenceReviewCandidate(fm, options));
26447
24251
  if (found) return { filePath: found, location: "category" };
@@ -26517,10 +24321,10 @@ function readFileSafe3(filePath) {
26517
24321
  }
26518
24322
  }
26519
24323
  function writeFileWithoutClobber(basePath, content, discriminator) {
26520
- const parsed = path32.parse(basePath);
24324
+ const parsed = path29.parse(basePath);
26521
24325
  const safeDiscriminator = sanitizeFilePart(discriminator);
26522
24326
  for (let attempt = 0; attempt < 1e3; attempt++) {
26523
- const candidate = attempt === 0 ? basePath : path32.join(
24327
+ const candidate = attempt === 0 ? basePath : path29.join(
26524
24328
  parsed.dir,
26525
24329
  `${parsed.name}-${safeDiscriminator}${attempt === 1 ? "" : `-${attempt}`}${parsed.ext || ".md"}`
26526
24330
  );
@@ -26576,7 +24380,7 @@ function extractBody4(content) {
26576
24380
  function walkMd(rootReal, dir, callback) {
26577
24381
  if (!isSafeDirectory(rootReal, dir)) return false;
26578
24382
  for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
26579
- const fullPath = path32.join(dir, entry.name);
24383
+ const fullPath = path29.join(dir, entry.name);
26580
24384
  if (entry.isSymbolicLink()) continue;
26581
24385
  if (entry.isDirectory()) {
26582
24386
  if (walkMd(rootReal, fullPath, callback)) return true;
@@ -26591,7 +24395,7 @@ function walkMdPaths(rootReal, dir) {
26591
24395
  const results = [];
26592
24396
  if (!isSafeDirectory(rootReal, dir)) return results;
26593
24397
  for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
26594
- const fullPath = path32.join(dir, entry.name);
24398
+ const fullPath = path29.join(dir, entry.name);
26595
24399
  if (entry.isSymbolicLink()) continue;
26596
24400
  if (entry.isDirectory()) {
26597
24401
  results.push(...walkMdPaths(rootReal, fullPath));
@@ -26604,7 +24408,7 @@ function walkMdPaths(rootReal, dir) {
26604
24408
 
26605
24409
  // src/sync/index.ts
26606
24410
  import fs6 from "fs";
26607
- import path33 from "path";
24411
+ import path30 from "path";
26608
24412
  import crypto6 from "crypto";
26609
24413
  var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
26610
24414
  var DEFAULT_EXCLUDE2 = /* @__PURE__ */ new Set([
@@ -26626,7 +24430,7 @@ function syncChanges(options) {
26626
24430
  } = options;
26627
24431
  const extSet = new Set(extensions);
26628
24432
  const excludeSet = /* @__PURE__ */ new Set([...DEFAULT_EXCLUDE2, ...excludeDirs]);
26629
- const stateFilePath = options.stateFile ?? path33.join(memoryDir, ".sync-state.json");
24433
+ const stateFilePath = options.stateFile ?? path30.join(memoryDir, ".sync-state.json");
26630
24434
  const prevState = loadState(stateFilePath);
26631
24435
  const currentFiles = scanFiles(sourceDir, extSet, excludeSet);
26632
24436
  const changes = computeDiff(currentFiles, prevState.fileHashes, sourceDir);
@@ -26642,7 +24446,7 @@ function syncChanges(options) {
26642
24446
  for (const [relPath, hash] of Object.entries(currentFiles)) {
26643
24447
  newState.fileHashes[relPath] = hash;
26644
24448
  }
26645
- fs6.mkdirSync(path33.dirname(stateFilePath), { recursive: true });
24449
+ fs6.mkdirSync(path30.dirname(stateFilePath), { recursive: true });
26646
24450
  fs6.writeFileSync(stateFilePath, JSON.stringify(newState, null, 2));
26647
24451
  }
26648
24452
  return {
@@ -26708,13 +24512,13 @@ function scanFiles(root, extensions, exclude) {
26708
24512
  }
26709
24513
  for (const entry of entries) {
26710
24514
  if (exclude.has(entry.name)) continue;
26711
- const fullPath = path33.join(dir, entry.name);
24515
+ const fullPath = path30.join(dir, entry.name);
26712
24516
  if (entry.isDirectory()) {
26713
24517
  walk(fullPath);
26714
24518
  } else if (entry.isFile()) {
26715
- const ext = path33.extname(entry.name).toLowerCase();
24519
+ const ext = path30.extname(entry.name).toLowerCase();
26716
24520
  if (!extensions.has(ext)) continue;
26717
- const relPath = path33.relative(root, fullPath);
24521
+ const relPath = path30.relative(root, fullPath);
26718
24522
  try {
26719
24523
  const content = fs6.readFileSync(fullPath, "utf8");
26720
24524
  result[relPath] = hashContent3(content);
@@ -26729,7 +24533,7 @@ function scanFiles(root, extensions, exclude) {
26729
24533
  function computeDiff(current, previous, sourceDir) {
26730
24534
  const changes = [];
26731
24535
  for (const [relPath, hash] of Object.entries(current)) {
26732
- const fullPath = path33.join(sourceDir, relPath);
24536
+ const fullPath = path30.join(sourceDir, relPath);
26733
24537
  if (!(relPath in previous)) {
26734
24538
  let size = 0;
26735
24539
  try {
@@ -26762,7 +24566,7 @@ function computeDiff(current, previous, sourceDir) {
26762
24566
  for (const relPath of Object.keys(previous)) {
26763
24567
  if (!(relPath in current)) {
26764
24568
  changes.push({
26765
- filePath: path33.join(sourceDir, relPath),
24569
+ filePath: path30.join(sourceDir, relPath),
26766
24570
  relativePath: relPath,
26767
24571
  type: "deleted",
26768
24572
  currentHash: "",
@@ -26792,21 +24596,21 @@ function hashContent3(content) {
26792
24596
  import { spawnSync } from "child_process";
26793
24597
  import crypto7 from "crypto";
26794
24598
  import fs7 from "fs";
26795
- import path34 from "path";
24599
+ import path31 from "path";
26796
24600
  var historicalIdCache4 = new HistoricalEntityCanonicalIdCache();
26797
24601
  var MANIFEST_VERSION = 1;
26798
24602
  var MANIFEST_LOCK_STALE_MS = 3e4;
26799
24603
  var MANIFEST_LOCK_TIMEOUT_MS = MANIFEST_LOCK_STALE_MS + 1e4;
26800
24604
  var MANIFEST_LOCK_SLEEP_MS = 20;
26801
24605
  function normalizeSpaceMemoryDir(memoryDir) {
26802
- return path34.resolve(memoryDir);
24606
+ return path31.resolve(memoryDir);
26803
24607
  }
26804
24608
  function getSpacesDir(baseDir) {
26805
24609
  const homeDir = baseDir ?? resolveHomeDir();
26806
- return path34.join(homeDir, ".config", "engram", "spaces");
24610
+ return path31.join(homeDir, ".config", "engram", "spaces");
26807
24611
  }
26808
24612
  function getManifestPath(baseDir) {
26809
- return path34.join(getSpacesDir(baseDir), "manifest.json");
24613
+ return path31.join(getSpacesDir(baseDir), "manifest.json");
26810
24614
  }
26811
24615
  function loadManifest(baseDir, memoryDirOverride) {
26812
24616
  if (fs7.existsSync(getManifestPath(baseDir))) {
@@ -26853,9 +24657,9 @@ function readManifestUnlocked(baseDir, memoryDirOverride, options = {}) {
26853
24657
  }
26854
24658
  function saveManifestUnlocked(manifest, baseDir) {
26855
24659
  const manifestPath2 = getManifestPath(baseDir);
26856
- const manifestDir2 = path34.dirname(manifestPath2);
24660
+ const manifestDir2 = path31.dirname(manifestPath2);
26857
24661
  fs7.mkdirSync(manifestDir2, { recursive: true });
26858
- const tempPath = path34.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto7.randomUUID()}.tmp`);
24662
+ const tempPath = path31.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto7.randomUUID()}.tmp`);
26859
24663
  try {
26860
24664
  fs7.writeFileSync(tempPath, `${JSON.stringify(manifest, null, 2)}
26861
24665
  `, { flag: "wx" });
@@ -26870,7 +24674,7 @@ function saveManifestUnlocked(manifest, baseDir) {
26870
24674
  }
26871
24675
  function withManifestLock(baseDir, operation) {
26872
24676
  const lockDir = `${getManifestPath(baseDir)}.lock`;
26873
- fs7.mkdirSync(path34.dirname(lockDir), { recursive: true });
24677
+ fs7.mkdirSync(path31.dirname(lockDir), { recursive: true });
26874
24678
  const lockOwner = acquireManifestLock(lockDir);
26875
24679
  try {
26876
24680
  return operation();
@@ -26896,7 +24700,7 @@ function acquireManifestLock(lockDir) {
26896
24700
  try {
26897
24701
  fs7.mkdirSync(lockDir, { recursive: false });
26898
24702
  try {
26899
- fs7.writeFileSync(path34.join(lockDir, "owner"), `${owner}
24703
+ fs7.writeFileSync(path31.join(lockDir, "owner"), `${owner}
26900
24704
  `, { flag: "wx" });
26901
24705
  } catch (error) {
26902
24706
  fs7.rmSync(lockDir, { recursive: true, force: true });
@@ -26926,7 +24730,7 @@ function acquireManifestLock(lockDir) {
26926
24730
  }
26927
24731
  function releaseManifestLock(lockDir, owner) {
26928
24732
  try {
26929
- const ownerPath = path34.join(lockDir, "owner");
24733
+ const ownerPath = path31.join(lockDir, "owner");
26930
24734
  if (fs7.readFileSync(ownerPath, "utf8").trim() === owner) {
26931
24735
  fs7.rmSync(lockDir, { recursive: true, force: true });
26932
24736
  }
@@ -26942,7 +24746,7 @@ function removeStaleManifestLock(lockDir) {
26942
24746
  try {
26943
24747
  fs7.mkdirSync(reclaimDir, { recursive: false });
26944
24748
  try {
26945
- fs7.writeFileSync(path34.join(reclaimDir, "owner"), `${reclaimOwner}
24749
+ fs7.writeFileSync(path31.join(reclaimDir, "owner"), `${reclaimOwner}
26946
24750
  `, { flag: "wx" });
26947
24751
  } catch (error) {
26948
24752
  fs7.rmSync(reclaimDir, { recursive: true, force: true });
@@ -27007,9 +24811,9 @@ function removeStaleManifestReclaimLock(reclaimDir) {
27007
24811
  fs7.rmSync(tombstoneDir, { recursive: true, force: true });
27008
24812
  }
27009
24813
  function readManifestLockSnapshot(lockDir) {
27010
- let stat6;
24814
+ let stat5;
27011
24815
  try {
27012
- stat6 = fs7.statSync(lockDir);
24816
+ stat5 = fs7.statSync(lockDir);
27013
24817
  } catch (error) {
27014
24818
  if (error.code === "ENOENT") {
27015
24819
  return void 0;
@@ -27017,11 +24821,11 @@ function readManifestLockSnapshot(lockDir) {
27017
24821
  throw error;
27018
24822
  }
27019
24823
  try {
27020
- const owner = fs7.readFileSync(path34.join(lockDir, "owner"), "utf8").trim();
27021
- return { mtimeMs: stat6.mtimeMs, owner };
24824
+ const owner = fs7.readFileSync(path31.join(lockDir, "owner"), "utf8").trim();
24825
+ return { mtimeMs: stat5.mtimeMs, owner };
27022
24826
  } catch (error) {
27023
24827
  if (error.code === "ENOENT") {
27024
- return { mtimeMs: stat6.mtimeMs };
24828
+ return { mtimeMs: stat5.mtimeMs };
27025
24829
  }
27026
24830
  throw error;
27027
24831
  }
@@ -27089,8 +24893,8 @@ function sleepSync(ms) {
27089
24893
  }
27090
24894
  function createPersonalSpace(baseDir, memoryDirOverride) {
27091
24895
  const homeDir = baseDir ?? resolveHomeDir();
27092
- const standalonePath = path34.join(homeDir, ".engram", "memory");
27093
- const openclawPath = path34.join(homeDir, ".openclaw", "workspace", "memory", "local");
24896
+ const standalonePath = path31.join(homeDir, ".engram", "memory");
24897
+ const openclawPath = path31.join(homeDir, ".openclaw", "workspace", "memory", "local");
27094
24898
  const memoryDir = memoryDirOverride ?? readEnvVar("REMNIC_MEMORY_DIR") ?? readEnvVar("ENGRAM_MEMORY_DIR") ?? (fs7.existsSync(standalonePath) ? standalonePath : fs7.existsSync(openclawPath) ? openclawPath : standalonePath);
27095
24899
  const normalizedMemoryDir = normalizeSpaceMemoryDir(memoryDir);
27096
24900
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -27119,7 +24923,7 @@ function createSpace(options) {
27119
24923
  const id = options.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
27120
24924
  const now = (/* @__PURE__ */ new Date()).toISOString();
27121
24925
  const memoryDir = normalizeSpaceMemoryDir(
27122
- options.memoryDir ?? path34.join(getSpacesDir(options.baseDir), id, "memory")
24926
+ options.memoryDir ?? path31.join(getSpacesDir(options.baseDir), id, "memory")
27123
24927
  );
27124
24928
  const space = updateManifest(options.baseDir, (manifest) => {
27125
24929
  if (manifest.spaces.some((s) => s.id === id)) {
@@ -27340,14 +25144,14 @@ async function mergeSpaces(sourceSpaceId, targetSpaceId, options) {
27340
25144
  };
27341
25145
  }
27342
25146
  function getAuditLog(baseDir) {
27343
- const auditPath = path34.join(getSpacesDir(baseDir), "audit.jsonl");
25147
+ const auditPath = path31.join(getSpacesDir(baseDir), "audit.jsonl");
27344
25148
  if (!fs7.existsSync(auditPath)) return [];
27345
25149
  const lines = fs7.readFileSync(auditPath, "utf8").trim().split("\n");
27346
25150
  return lines.filter((l) => l.trim()).map((l) => JSON.parse(l));
27347
25151
  }
27348
25152
  function appendAudit(entry, baseDir) {
27349
- const auditPath = path34.join(getSpacesDir(baseDir), "audit.jsonl");
27350
- fs7.mkdirSync(path34.dirname(auditPath), { recursive: true });
25153
+ const auditPath = path31.join(getSpacesDir(baseDir), "audit.jsonl");
25154
+ fs7.mkdirSync(path31.dirname(auditPath), { recursive: true });
27351
25155
  const full = {
27352
25156
  id: crypto7.randomUUID(),
27353
25157
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -27368,11 +25172,11 @@ async function copyMemories(sourceDir, targetDir, options) {
27368
25172
  sourceFiles.filter((p) => {
27369
25173
  const rp = safeRealpath(p);
27370
25174
  if (!rp || !isPathInsideRoot(rp, sourceRoot)) return false;
27371
- const rel = path34.relative(sourceRoot, rp);
27372
- const mapped = path34.resolve(targetRoot, rel);
25175
+ const rel = path31.relative(sourceRoot, rp);
25176
+ const mapped = path31.resolve(targetRoot, rel);
27373
25177
  if (!isPathInsideRoot(mapped, targetRoot)) return false;
27374
25178
  return classifyEntityRefWritePath(targetRoot, mapped) === "entity";
27375
- }).map((p) => path34.basename(p, ".md"))
25179
+ }).map((p) => path31.basename(p, ".md"))
27376
25180
  );
27377
25181
  const firstEntityId = sourceEntityIds.values().next().value;
27378
25182
  if (firstEntityId === void 0) {
@@ -27380,7 +25184,7 @@ async function copyMemories(sourceDir, targetDir, options) {
27380
25184
  }
27381
25185
  return withRawEntityPageMutation(
27382
25186
  targetRoot,
27383
- path34.join(targetRoot, "entities", `${firstEntityId}.md`),
25187
+ path31.join(targetRoot, "entities", `${firstEntityId}.md`),
27384
25188
  async () => copyPreparedMemories(
27385
25189
  sourceFiles,
27386
25190
  sourceRoot,
@@ -27407,14 +25211,14 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27407
25211
  continue;
27408
25212
  }
27409
25213
  const content = fs7.readFileSync(sourcePath, "utf8");
27410
- const relativePath = path34.relative(sourceRoot, sourceRealPath);
27411
- const targetPath = path34.resolve(targetRoot, relativePath);
25214
+ const relativePath = path31.relative(sourceRoot, sourceRealPath);
25215
+ const targetPath = path31.resolve(targetRoot, relativePath);
27412
25216
  if (!isPathInsideRoot(targetPath, targetRoot)) {
27413
25217
  skipped++;
27414
25218
  continue;
27415
25219
  }
27416
25220
  const targetKind = classifyEntityRefWritePath(targetRoot, targetPath);
27417
- const idsAtCompare = historicalIdCache4.get(path34.join(targetRoot, "state"));
25221
+ const idsAtCompare = historicalIdCache4.get(path31.join(targetRoot, "state"));
27418
25222
  const sourceRef = targetKind === "memory" ? readEntityRefFromFrontmatter(content) : null;
27419
25223
  const refHasSourceClaimant = sourceRef !== null && sourceEntityIds.has(sourceRef);
27420
25224
  const canonicalContent = targetKind === "memory" && !refHasSourceClaimant ? canonicalizeEntityRefFrontmatter(content, idsAtCompare) : content;
@@ -27441,7 +25245,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27441
25245
  if (fs7.existsSync(targetPath) && !options?.force) {
27442
25246
  const targetContent = fs7.readFileSync(targetPath, "utf8");
27443
25247
  const targetHash = hashContent4(targetContent);
27444
- if (hashContent4(canonicalContent) === targetHash && historicalIdCache4.get(path34.join(targetRoot, "state")) === idsAtCompare) {
25248
+ if (hashContent4(canonicalContent) === targetHash && historicalIdCache4.get(path31.join(targetRoot, "state")) === idsAtCompare) {
27445
25249
  skipped++;
27446
25250
  continue;
27447
25251
  }
@@ -27457,13 +25261,13 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27457
25261
  continue;
27458
25262
  }
27459
25263
  }
27460
- fs7.mkdirSync(path34.dirname(targetPath), { recursive: true });
27461
- const targetParentRealPath = safeRealpath(path34.dirname(targetPath));
25264
+ fs7.mkdirSync(path31.dirname(targetPath), { recursive: true });
25265
+ const targetParentRealPath = safeRealpath(path31.dirname(targetPath));
27462
25266
  if (!targetParentRealPath || !isPathInsideRoot(targetParentRealPath, targetRoot)) {
27463
25267
  skipped++;
27464
25268
  continue;
27465
25269
  }
27466
- const stateDir = path34.join(targetRoot, "state");
25270
+ const stateDir = path31.join(targetRoot, "state");
27467
25271
  if (targetKind === "memory" && !refHasSourceClaimant) {
27468
25272
  const idsAtWrite = historicalIdCache4.get(stateDir);
27469
25273
  const written = canonicalizeEntityRefFrontmatter(content, idsAtWrite);
@@ -27507,7 +25311,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27507
25311
  bumpMemoryCorpusVersionForDir(targetRoot);
27508
25312
  }
27509
25313
  if (reconcileNeeded) {
27510
- requestEntityCanonicalIdReconcileSync(path34.join(targetRoot, "state"));
25314
+ requestEntityCanonicalIdReconcileSync(path31.join(targetRoot, "state"));
27511
25315
  }
27512
25316
  return { merged, conflicts, skipped };
27513
25317
  }
@@ -27518,7 +25322,7 @@ function walkMd2(dir) {
27518
25322
  const results = [];
27519
25323
  function walk(d) {
27520
25324
  for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
27521
- const fullPath = path34.join(d, entry.name);
25325
+ const fullPath = path31.join(d, entry.name);
27522
25326
  if (entry.isSymbolicLink()) {
27523
25327
  continue;
27524
25328
  }
@@ -27547,8 +25351,8 @@ function safeRealpath(filePath) {
27547
25351
  }
27548
25352
  }
27549
25353
  function isPathInsideRoot(candidatePath, rootPath) {
27550
- const relative = path34.relative(rootPath, candidatePath);
27551
- return relative === "" || !relative.startsWith("..") && !path34.isAbsolute(relative);
25354
+ const relative = path31.relative(rootPath, candidatePath);
25355
+ return relative === "" || !relative.startsWith("..") && !path31.isAbsolute(relative);
27552
25356
  }
27553
25357
  function parseSimpleFrontmatter(content) {
27554
25358
  const match = content.match(/^---\n([\s\S]*?)\n---/);
@@ -27669,7 +25473,7 @@ var REMNIC_RECALL_DECISION_RULES = `## When to Use Recall vs Direct Read
27669
25473
  // src/memory-extension/codex-publisher.ts
27670
25474
  import fs8 from "fs";
27671
25475
  import os from "os";
27672
- import path35 from "path";
25476
+ import path32 from "path";
27673
25477
  var REMNIC_EXTENSION_DIR_NAME = "remnic";
27674
25478
  function resolveEnvHome(env) {
27675
25479
  if (env === void 0) return resolveHomeDir();
@@ -27678,12 +25482,12 @@ function resolveEnvHome(env) {
27678
25482
  function expandTildeWithHome(input, homeDir) {
27679
25483
  if (input === "~") return homeDir;
27680
25484
  if (input.startsWith("~/") || input.startsWith("~\\")) {
27681
- return path35.join(homeDir, input.slice(2));
25485
+ return path32.join(homeDir, input.slice(2));
27682
25486
  }
27683
25487
  return input;
27684
25488
  }
27685
25489
  function normalizeHostRoot(input, homeDir) {
27686
- return path35.resolve(expandTildeWithHome(input.trim(), homeDir));
25490
+ return path32.resolve(expandTildeWithHome(input.trim(), homeDir));
27687
25491
  }
27688
25492
  var CodexMemoryExtensionPublisher = class {
27689
25493
  hostId = "codex";
@@ -27697,12 +25501,12 @@ var CodexMemoryExtensionPublisher = class {
27697
25501
  async resolveExtensionRoot(env) {
27698
25502
  const homeDir = resolveEnvHome(env);
27699
25503
  const codexHomeInput = env === void 0 ? readEnvVar("CODEX_HOME")?.trim() : env.CODEX_HOME?.trim();
27700
- const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path35.resolve(homeDir, ".codex");
27701
- return path35.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
25504
+ const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path32.resolve(homeDir, ".codex");
25505
+ return path32.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
27702
25506
  }
27703
25507
  async isHostAvailable() {
27704
25508
  try {
27705
- const home = readEnvVar("CODEX_HOME")?.trim() || path35.join(resolveHomeDir(), ".codex");
25509
+ const home = readEnvVar("CODEX_HOME")?.trim() || path32.join(resolveHomeDir(), ".codex");
27706
25510
  return fs8.existsSync(home);
27707
25511
  } catch {
27708
25512
  return false;
@@ -27753,7 +25557,7 @@ When running inside the Codex phase-2 consolidation sandbox:
27753
25557
  }
27754
25558
  async publish(ctx) {
27755
25559
  const extensionRoot = await this.resolveExtensionRoot();
27756
- const instructionsPath = path35.join(extensionRoot, "instructions.md");
25560
+ const instructionsPath = path32.join(extensionRoot, "instructions.md");
27757
25561
  const filesWritten = [];
27758
25562
  const skipped = [];
27759
25563
  ctx.log.info(`Publishing Codex memory extension to ${extensionRoot}`);
@@ -28127,9 +25931,9 @@ async function generateActivityMemories(date, digestBody, config, deps) {
28127
25931
  }
28128
25932
 
28129
25933
  // src/session-summaries/index.ts
28130
- import { createHash as createHash11 } from "crypto";
28131
- import { lstat as lstat5, mkdir as mkdir8, readFile as readFile7, readdir as readdir5, rename as rename2, rm as rm2, stat as stat5, writeFile as writeFile7 } from "fs/promises";
28132
- import path36 from "path";
25934
+ import { createHash as createHash9 } from "crypto";
25935
+ import { lstat as lstat3, mkdir as mkdir7, readFile as readFile7, readdir as readdir4, rename, rm, stat as stat4, writeFile as writeFile7 } from "fs/promises";
25936
+ import path33 from "path";
28133
25937
 
28134
25938
  // src/session-summaries/adapters.ts
28135
25939
  var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "other"]);
@@ -28629,28 +26433,28 @@ var DEFAULT_MAX_FILES = 5e3;
28629
26433
  var DEFAULT_MAX_SESSIONS = 500;
28630
26434
  var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([".json", ".jsonl"]);
28631
26435
  function shortHash(value, length = 16) {
28632
- return createHash11("sha256").update(value).digest("hex").slice(0, length);
26436
+ return createHash9("sha256").update(value).digest("hex").slice(0, length);
28633
26437
  }
28634
26438
  async function listTranscriptFiles(root, maxFiles) {
28635
26439
  const out = [];
28636
26440
  let truncated = false;
28637
- const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path36.sep}` : entryName;
26441
+ const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path33.sep}` : entryName;
28638
26442
  async function visit(dir) {
28639
26443
  if (truncated) return;
28640
- const entries = (await readdir5(dir, { withFileTypes: true })).sort(
26444
+ const entries = (await readdir4(dir, { withFileTypes: true })).sort(
28641
26445
  (a, b) => entrySortKey(a.name, a.isDirectory()).localeCompare(entrySortKey(b.name, b.isDirectory()))
28642
26446
  );
28643
26447
  for (const entry of entries) {
28644
26448
  if (truncated) return;
28645
26449
  if (entry.name.startsWith(".")) continue;
28646
26450
  if (entry.isSymbolicLink()) continue;
28647
- const fullPath = path36.join(dir, entry.name);
26451
+ const fullPath = path33.join(dir, entry.name);
28648
26452
  if (entry.isDirectory()) {
28649
26453
  await visit(fullPath);
28650
26454
  continue;
28651
26455
  }
28652
26456
  if (!entry.isFile()) continue;
28653
- const ext = path36.extname(entry.name).toLowerCase();
26457
+ const ext = path33.extname(entry.name).toLowerCase();
28654
26458
  if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
28655
26459
  out.push(fullPath);
28656
26460
  if (out.length > maxFiles) {
@@ -28677,7 +26481,7 @@ function normalizeInputDir(inputDir) {
28677
26481
  if (typeof inputDir !== "string" || inputDir.trim().length === 0) {
28678
26482
  throw new Error("inputDir must be a non-empty string");
28679
26483
  }
28680
- return path36.resolve(expandTildePath(inputDir.trim()));
26484
+ return path33.resolve(expandTildePath(inputDir.trim()));
28681
26485
  }
28682
26486
  function initRoleCounts() {
28683
26487
  return {
@@ -28772,11 +26576,11 @@ function buildDraft(options) {
28772
26576
  }
28773
26577
  async function collectLocalSessionSummaries(options) {
28774
26578
  const inputDir = normalizeInputDir(options.inputDir);
28775
- const inputLstat = await lstat5(inputDir);
26579
+ const inputLstat = await lstat3(inputDir);
28776
26580
  if (inputLstat.isSymbolicLink()) {
28777
26581
  throw new Error(`inputDir must not be a symbolic link: ${options.inputDir}`);
28778
26582
  }
28779
- const inputStat = await stat5(inputDir);
26583
+ const inputStat = await stat4(inputDir);
28780
26584
  if (!inputStat.isDirectory()) {
28781
26585
  throw new Error(`inputDir must be a directory: ${options.inputDir}`);
28782
26586
  }
@@ -28834,11 +26638,11 @@ async function collectLocalSessionSummaries(options) {
28834
26638
  continue;
28835
26639
  }
28836
26640
  seenFileHashes.add(fileHash);
28837
- const fileExtension = path36.extname(filePath).toLowerCase();
26641
+ const fileExtension = path33.extname(filePath).toLowerCase();
28838
26642
  const parsed = await adapter.parseFile(
28839
26643
  {
28840
26644
  content,
28841
- fileName: path36.basename(filePath),
26645
+ fileName: path33.basename(filePath),
28842
26646
  fileExtension,
28843
26647
  fileRef: fileHash
28844
26648
  },
@@ -28894,7 +26698,7 @@ async function collectLocalSessionSummaries(options) {
28894
26698
  }
28895
26699
  async function readRedactionConfig(pathLike) {
28896
26700
  if (!pathLike) return void 0;
28897
- const raw = await readFile7(path36.resolve(expandTildePath(pathLike)), "utf-8");
26701
+ const raw = await readFile7(path33.resolve(expandTildePath(pathLike)), "utf-8");
28898
26702
  const parsed = JSON.parse(raw);
28899
26703
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
28900
26704
  throw new Error("redaction config must be a JSON object");
@@ -28907,21 +26711,21 @@ function toJsonl(drafts) {
28907
26711
  }
28908
26712
  function defaultDraftOutputPath(memoryDir, generatedAt) {
28909
26713
  const stamp = generatedAt.replace(/[:.]/g, "-");
28910
- return path36.join(
28911
- path36.resolve(expandTildePath(memoryDir)),
26714
+ return path33.join(
26715
+ path33.resolve(expandTildePath(memoryDir)),
28912
26716
  "state",
28913
26717
  "session-summary-drafts",
28914
26718
  `session-summaries-${stamp}.jsonl`
28915
26719
  );
28916
26720
  }
28917
26721
  async function writeDrafts(filePath, drafts) {
28918
- await mkdir8(path36.dirname(filePath), { recursive: true });
26722
+ await mkdir7(path33.dirname(filePath), { recursive: true });
28919
26723
  const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
28920
26724
  try {
28921
26725
  await writeFile7(tempPath, toJsonl(drafts), "utf-8");
28922
- await rename2(tempPath, filePath);
26726
+ await rename(tempPath, filePath);
28923
26727
  } catch (error) {
28924
- await rm2(tempPath, { force: true });
26728
+ await rm(tempPath, { force: true });
28925
26729
  throw error;
28926
26730
  }
28927
26731
  }
@@ -28933,7 +26737,7 @@ async function runLocalSessionSummaryCliCommand(options) {
28933
26737
  });
28934
26738
  const wroteFiles = [];
28935
26739
  if (options.output) {
28936
- const outputPath = path36.resolve(expandTildePath(options.output));
26740
+ const outputPath = path33.resolve(expandTildePath(options.output));
28937
26741
  await writeDrafts(outputPath, report.drafts);
28938
26742
  wroteFiles.push(outputPath);
28939
26743
  }
@@ -28967,20 +26771,20 @@ async function runLocalSessionSummaryCliCommand(options) {
28967
26771
  }
28968
26772
 
28969
26773
  // src/transfer/capsule-fork.ts
28970
- import { lstat as lstat6, mkdir as mkdir9, readFile as readFile8, realpath as realpath3, writeFile as writeFile8 } from "fs/promises";
28971
- import path37 from "path";
26774
+ import { lstat as lstat4, mkdir as mkdir8, readFile as readFile8, realpath as realpath3, writeFile as writeFile8 } from "fs/promises";
26775
+ import path34 from "path";
28972
26776
  async function forkCapsule(opts) {
28973
26777
  validateForkId(opts.forkId);
28974
- const rootAbs = path37.resolve(opts.targetRoot);
26778
+ const rootAbs = path34.resolve(opts.targetRoot);
28975
26779
  await assertIsDirectoryNotSymlink(rootAbs, "forkCapsule", "targetRoot");
28976
- const forkDirAbs = path37.join(rootAbs, "forks", opts.forkId);
26780
+ const forkDirAbs = path34.join(rootAbs, "forks", opts.forkId);
28977
26781
  const forkEntryExists = await pathEntryExists(forkDirAbs);
28978
26782
  if (forkEntryExists) {
28979
26783
  throw new Error(
28980
26784
  `forkCapsule: fork path already exists \u2014 forkId "${opts.forkId}" is already in use at: ${forkDirAbs}`
28981
26785
  );
28982
26786
  }
28983
- const archiveAbs = path37.resolve(opts.sourceArchive);
26787
+ const archiveAbs = path34.resolve(opts.sourceArchive);
28984
26788
  const importResult = await importCapsule({
28985
26789
  archivePath: archiveAbs,
28986
26790
  root: rootAbs,
@@ -29002,10 +26806,10 @@ async function forkCapsule(opts) {
29002
26806
  importedRecords: importResult.imported.length,
29003
26807
  skippedRecords: importResult.skipped.length
29004
26808
  };
29005
- const lineagePath = path37.join(forkDirAbs, "lineage.json");
26809
+ const lineagePath = path34.join(forkDirAbs, "lineage.json");
29006
26810
  const rootReal = await realpath3(rootAbs);
29007
26811
  await assertRealpathInsideRoot(rootReal, lineagePath, `forks/${opts.forkId}/lineage.json`, "forkCapsule");
29008
- await mkdir9(path37.dirname(lineagePath), { recursive: true });
26812
+ await mkdir8(path34.dirname(lineagePath), { recursive: true });
29009
26813
  await writeFile8(lineagePath, JSON.stringify(lineage, null, 2) + "\n", "utf-8");
29010
26814
  return {
29011
26815
  archivePath: archiveAbs,
@@ -29019,11 +26823,11 @@ async function readForkLineage(targetRoot, forkId) {
29019
26823
  if (typeof forkId !== "string" || forkId.length === 0 || forkId.length > 64 || !CAPSULE_ID_PATTERN.test(forkId)) {
29020
26824
  return null;
29021
26825
  }
29022
- const rootAbs = path37.resolve(targetRoot);
26826
+ const rootAbs = path34.resolve(targetRoot);
29023
26827
  const rootReal = await realpath3(rootAbs).catch(() => rootAbs);
29024
- const lineagePath = path37.join(rootReal, "forks", forkId, "lineage.json");
29025
- const rel = path37.relative(rootReal, lineagePath);
29026
- if (rel.startsWith("..") || path37.isAbsolute(rel)) {
26828
+ const lineagePath = path34.join(rootReal, "forks", forkId, "lineage.json");
26829
+ const rel = path34.relative(rootReal, lineagePath);
26830
+ if (rel.startsWith("..") || path34.isAbsolute(rel)) {
29027
26831
  return null;
29028
26832
  }
29029
26833
  if (!await isLineagePathContained(rootReal, lineagePath)) {
@@ -29058,45 +26862,30 @@ function validateForkId(forkId) {
29058
26862
  }
29059
26863
  }
29060
26864
  async function pathEntryExists(absPath) {
29061
- const st = await lstat6(absPath).catch(() => null);
26865
+ const st = await lstat4(absPath).catch(() => null);
29062
26866
  return st !== null;
29063
26867
  }
29064
26868
  async function isLineagePathContained(rootReal, lineagePath) {
29065
26869
  let existing = lineagePath;
29066
26870
  const suffix = [];
29067
- while (existing !== path37.dirname(existing)) {
29068
- const st = await lstat6(existing).catch(() => null);
26871
+ while (existing !== path34.dirname(existing)) {
26872
+ const st = await lstat4(existing).catch(() => null);
29069
26873
  if (st !== null) break;
29070
- suffix.unshift(path37.basename(existing));
29071
- existing = path37.dirname(existing);
26874
+ suffix.unshift(path34.basename(existing));
26875
+ existing = path34.dirname(existing);
29072
26876
  }
29073
26877
  const existingReal = await realpath3(existing).catch(() => existing);
29074
- const targetReal = suffix.length > 0 ? path37.join(existingReal, ...suffix) : existingReal;
29075
- const rel = path37.relative(rootReal, targetReal);
26878
+ const targetReal = suffix.length > 0 ? path34.join(existingReal, ...suffix) : existingReal;
26879
+ const rel = path34.relative(rootReal, targetReal);
29076
26880
  if (rel === "") return true;
29077
26881
  if (rel === "..") return false;
29078
- if (rel.startsWith(`..${path37.sep}`)) return false;
29079
- if (path37.isAbsolute(rel)) return false;
26882
+ if (rel.startsWith(`..${path34.sep}`)) return false;
26883
+ if (path34.isAbsolute(rel)) return false;
29080
26884
  return true;
29081
26885
  }
29082
26886
 
29083
26887
  export {
29084
26888
  buildProcedureRecallSection,
29085
- SupportPassportError,
29086
- SupportPassportCardService,
29087
- SupportPassportGrantCardRefSchema,
29088
- SupportPassportGrantStateSchema,
29089
- SupportPassportCreateGrantInputSchema,
29090
- SupportPassportOwnerGrantSchema,
29091
- SupportPassportCreatedGrantSchema,
29092
- SupportPassportPublicCardSchema,
29093
- SupportPassportPublicGuideSchema,
29094
- SupportPassportRevokeGrantInputSchema,
29095
- SupportPassportListGrantsInputSchema,
29096
- notifySupportPassportCommitted,
29097
- syncDirectoryForDurability,
29098
- SupportPassportGrantStore,
29099
- SupportPassportGrantService,
29100
26889
  RELAY_DEMO_MISSION_ID,
29101
26890
  RELAY_DEMO_NAMESPACE,
29102
26891
  createRelayMissionFixture,
@@ -29210,4 +26999,4 @@ export {
29210
26999
  blendGraphExpandedRecallScore,
29211
27000
  Orchestrator
29212
27001
  };
29213
- //# sourceMappingURL=chunk-7HG7MGAP.js.map
27002
+ //# sourceMappingURL=chunk-W5ZKPI34.js.map