@remnic/core 10.0.65 → 10.0.67

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 (262) hide show
  1. package/dist/access-admin-ops-surface.js +16 -16
  2. package/dist/access-authorization-probe.js +17 -17
  3. package/dist/access-boundary.js +16 -16
  4. package/dist/access-cli.js +61 -61
  5. package/dist/access-extraction-force-flush.js +16 -16
  6. package/dist/access-http-briefing.js +17 -17
  7. package/dist/access-http-query.js +18 -18
  8. package/dist/access-http.js +33 -33
  9. package/dist/access-identity-continuity-surface.js +16 -16
  10. package/dist/access-lcm-surface.js +16 -16
  11. package/dist/access-mcp.js +26 -26
  12. package/dist/access-namespace-preflight.js +16 -16
  13. package/dist/access-observe-write-surface.js +16 -16
  14. package/dist/access-operations-batch.js +17 -17
  15. package/dist/access-operations.js +24 -24
  16. package/dist/access-recall-concurrency.js +16 -16
  17. package/dist/access-recall-diagnostics.js +2 -2
  18. package/dist/access-recall-response.js +16 -16
  19. package/dist/access-recall-surface.js +16 -16
  20. package/dist/access-service.js +16 -16
  21. package/dist/access-surface-catalog.js +18 -18
  22. package/dist/active-recall.js +3 -3
  23. package/dist/briefing.js +3 -3
  24. package/dist/buffer.js +2 -2
  25. package/dist/causal-consolidation.js +4 -4
  26. package/dist/{chunk-KISOMGY2.js → chunk-3RHU5MD7.js} +2 -2
  27. package/dist/{chunk-3LSTL6EY.js → chunk-4MPAKYZU.js} +2 -2
  28. package/dist/{chunk-OVL5AD3N.js → chunk-4NV7O76Q.js} +2 -2
  29. package/dist/{chunk-BH7NVSEC.js → chunk-4SOWMA55.js} +3 -3
  30. package/dist/{chunk-GROHOWR5.js → chunk-5MGKGEL7.js} +2 -2
  31. package/dist/{chunk-ZPLQ27MY.js → chunk-5UM4H64E.js} +2 -2
  32. package/dist/{chunk-2DNFRLLL.js → chunk-5Y6VA6X2.js} +2 -2
  33. package/dist/{chunk-GRAUQXQB.js → chunk-6WKWL53V.js} +13 -13
  34. package/dist/{chunk-HOR4RMUM.js → chunk-75DCOS6I.js} +24 -24
  35. package/dist/{chunk-25QK3LR2.js → chunk-7O2MC42R.js} +2 -2
  36. package/dist/{chunk-7ETWIBTO.js → chunk-ADYP7HXE.js} +3 -3
  37. package/dist/{chunk-FUDKGJDN.js → chunk-AVGDYYMA.js} +2 -2
  38. package/dist/{chunk-ECF627KC.js → chunk-AYJQ644F.js} +2 -2
  39. package/dist/{chunk-T22FBDG3.js → chunk-B3MWELZ3.js} +2 -2
  40. package/dist/{chunk-DRTSPRWL.js → chunk-B4DXREWC.js} +2 -2
  41. package/dist/{chunk-5UEGL5BF.js → chunk-CI3MAAIY.js} +2 -2
  42. package/dist/{chunk-7JYK7NNY.js → chunk-CTH2CQCB.js} +2 -2
  43. package/dist/{chunk-UVHXLVFJ.js → chunk-EURPSF4Y.js} +2 -2
  44. package/dist/{chunk-VPEA63FC.js → chunk-EWJZZDRG.js} +2 -2
  45. package/dist/{chunk-BOZQAUAJ.js → chunk-EXQJMFRF.js} +2 -2
  46. package/dist/{chunk-UH6ROXFJ.js → chunk-GGD2YDS6.js} +2 -2
  47. package/dist/{chunk-5JABRT5G.js → chunk-GHHQLSSY.js} +3 -3
  48. package/dist/{chunk-N4T5FW6U.js → chunk-GJ4HU6LK.js} +2 -2
  49. package/dist/{chunk-HRRAOTOQ.js → chunk-H5DIRCZP.js} +12 -12
  50. package/dist/{chunk-434E4BTO.js → chunk-HH73M65H.js} +3 -3
  51. package/dist/{chunk-LIGZO7XN.js → chunk-HPB5TF55.js} +2 -2
  52. package/dist/{chunk-E4QIX2OB.js → chunk-IAGVM7EY.js} +2 -2
  53. package/dist/{chunk-YJQJRXUI.js → chunk-IG3EZ3TF.js} +2 -2
  54. package/dist/{chunk-KNMSD2MQ.js → chunk-IVUVQPTQ.js} +2 -2
  55. package/dist/{chunk-XOFIJGB2.js → chunk-IZBIDPMY.js} +2 -2
  56. package/dist/{chunk-HFEGRMFG.js → chunk-JLGBJ4AX.js} +7 -7
  57. package/dist/{chunk-BBHKN2CN.js → chunk-JLMOH5JA.js} +2 -2
  58. package/dist/{chunk-TPCRDPUY.js → chunk-KZSGBWOJ.js} +2 -2
  59. package/dist/{chunk-SHHZWSSE.js → chunk-KZZ5EZ7O.js} +2 -2
  60. package/dist/{chunk-2ZSRACNK.js → chunk-LFYEQK45.js} +682 -549
  61. package/dist/chunk-LFYEQK45.js.map +1 -0
  62. package/dist/{chunk-FKGLJJVS.js → chunk-LN4X2NDA.js} +2 -2
  63. package/dist/{chunk-5ZHFPUBC.js → chunk-MOIJWWNA.js} +8 -8
  64. package/dist/{chunk-KO224R36.js → chunk-NCZGGGWI.js} +2 -2
  65. package/dist/{chunk-XVQVF2TK.js → chunk-NHWDTOBN.js} +269 -230
  66. package/dist/chunk-NHWDTOBN.js.map +1 -0
  67. package/dist/{chunk-7ZTGMEXF.js → chunk-O5ZINWW3.js} +2 -2
  68. package/dist/{chunk-WWH7GJ42.js → chunk-OCK4D5PC.js} +2 -2
  69. package/dist/{chunk-G6L3REL3.js → chunk-OPFVXM2D.js} +2 -2
  70. package/dist/{chunk-FR7PK7ED.js → chunk-P4TV3TQ2.js} +2 -2
  71. package/dist/{chunk-P2EM5LKH.js → chunk-PMDOGXA2.js} +2 -2
  72. package/dist/{chunk-NM2II57L.js → chunk-PRKNAIGZ.js} +2 -1
  73. package/dist/chunk-PRKNAIGZ.js.map +1 -0
  74. package/dist/{chunk-MRF5V5CD.js → chunk-QGFR73SN.js} +2 -2
  75. package/dist/{chunk-6D3IWYNY.js → chunk-R2BIVU2Z.js} +354 -292
  76. package/dist/chunk-R2BIVU2Z.js.map +1 -0
  77. package/dist/{chunk-HG3CG557.js → chunk-RLVI2M5Q.js} +2 -2
  78. package/dist/{chunk-HHL4MX3W.js → chunk-SXTVZ6JL.js} +2 -2
  79. package/dist/{chunk-CLSKGTAT.js → chunk-TECK5IVY.js} +2 -2
  80. package/dist/{chunk-SNS3DWG6.js → chunk-TVE7W67N.js} +2 -2
  81. package/dist/{chunk-KYSSUY66.js → chunk-U2CAGMUD.js} +2 -2
  82. package/dist/{chunk-XLCEFUAU.js → chunk-UVVFPCPX.js} +2 -2
  83. package/dist/{chunk-KQJUEQ2E.js → chunk-UW6LBFYN.js} +5 -5
  84. package/dist/{chunk-SEA56G6S.js → chunk-V4XE263I.js} +1 -1
  85. package/dist/chunk-V4XE263I.js.map +1 -0
  86. package/dist/{chunk-JL5HXL25.js → chunk-V6SBA5O7.js} +3 -3
  87. package/dist/{chunk-R7WYAXPO.js → chunk-VHSQU3RO.js} +81 -42
  88. package/dist/chunk-VHSQU3RO.js.map +1 -0
  89. package/dist/{chunk-B7VD36TI.js → chunk-WHROVQ5Q.js} +3 -3
  90. package/dist/{chunk-LDHR465K.js → chunk-Y3XPSGNF.js} +2 -2
  91. package/dist/{chunk-JPY3RMG2.js → chunk-ZORS5BG5.js} +4 -4
  92. package/dist/{chunk-KXY4HW2Y.js → chunk-ZXF3O7P4.js} +2 -2
  93. package/dist/cli.js +47 -47
  94. package/dist/coding/export-okf-codegraph.js +2 -2
  95. package/dist/compounding/engine.js +4 -4
  96. package/dist/config.d.ts.map +1 -1
  97. package/dist/config.js +3 -3
  98. package/dist/connectors/codex-materialize-runner.js +3 -3
  99. package/dist/connectors/index.js +3 -3
  100. package/dist/convergence-refresh.js +5 -5
  101. package/dist/corpus-watermark.js +5 -5
  102. package/dist/entity-retrieval.js +3 -3
  103. package/dist/external-wiki-access.js +17 -17
  104. package/dist/extraction.js +6 -6
  105. package/dist/harmonic-retrieval.js +3 -3
  106. package/dist/index.js +61 -61
  107. package/dist/location/index.js +5 -5
  108. package/dist/maintenance/memory-governance.js +3 -3
  109. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  110. package/dist/maintenance/rebuild-memory-projection-runner.js +5 -5
  111. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  112. package/dist/memory-browse-operations.js +17 -17
  113. package/dist/namespaces/migrate.js +4 -4
  114. package/dist/namespaces/storage.js +3 -3
  115. package/dist/operator-doctor-corpus.js +6 -6
  116. package/dist/operator-toolkit.js +12 -12
  117. package/dist/orchestration/buffer-drain-runner.js +61 -61
  118. package/dist/orchestration/consolidation-run.d.ts.map +1 -1
  119. package/dist/orchestration/extraction-drain.d.ts +4 -4
  120. package/dist/orchestration/extraction-drain.d.ts.map +1 -1
  121. package/dist/orchestration/extraction-persist-deps.d.ts +0 -2
  122. package/dist/orchestration/extraction-persist-deps.d.ts.map +1 -1
  123. package/dist/orchestration/extraction-persist.d.ts +10 -4
  124. package/dist/orchestration/extraction-persist.d.ts.map +1 -1
  125. package/dist/orchestration/extraction-queue-coordinator.d.ts +67 -33
  126. package/dist/orchestration/extraction-queue-coordinator.d.ts.map +1 -1
  127. package/dist/orchestration/extraction-run-helpers.d.ts +3 -2
  128. package/dist/orchestration/extraction-run-helpers.d.ts.map +1 -1
  129. package/dist/orchestration/extraction-run.d.ts +4 -14
  130. package/dist/orchestration/extraction-run.d.ts.map +1 -1
  131. package/dist/orchestration/fact-dedup-window.d.ts +49 -0
  132. package/dist/orchestration/fact-dedup-window.d.ts.map +1 -0
  133. package/dist/orchestration/maintenance.js +13 -13
  134. package/dist/orchestration/provider-breaker.d.ts +58 -0
  135. package/dist/orchestration/provider-breaker.d.ts.map +1 -0
  136. package/dist/orchestrator.d.ts +2 -17
  137. package/dist/orchestrator.d.ts.map +1 -1
  138. package/dist/orchestrator.js +61 -61
  139. package/dist/recall-explain-renderer.js +3 -3
  140. package/dist/recall-navigate-access.js +2 -2
  141. package/dist/recall-navigate-disclosure.js +2 -2
  142. package/dist/recall-navigate.js +2 -2
  143. package/dist/recall-navigation-operations.js +17 -17
  144. package/dist/recall-navigation.js +16 -16
  145. package/dist/recall-xray-cli.js +4 -4
  146. package/dist/recall-xray-renderer.js +3 -3
  147. package/dist/recall-xray.js +2 -2
  148. package/dist/resume-bundles.js +4 -4
  149. package/dist/semantic-consolidation.js +4 -4
  150. package/dist/semantic-rule-promotion.js +3 -3
  151. package/dist/semantic-rule-verifier.js +3 -3
  152. package/dist/source-agent-qualifier.js +5 -5
  153. package/dist/standup/build.js +3 -3
  154. package/dist/storage/profile-mutation.d.ts +25 -0
  155. package/dist/storage/profile-mutation.d.ts.map +1 -0
  156. package/dist/storage.d.ts +4 -6
  157. package/dist/storage.d.ts.map +1 -1
  158. package/dist/storage.js +2 -2
  159. package/dist/support-passport/index.js +19 -19
  160. package/dist/threading.d.ts +21 -4
  161. package/dist/threading.d.ts.map +1 -1
  162. package/dist/threading.js +1 -1
  163. package/dist/transfer/export-okf.js +3 -3
  164. package/dist/types.d.ts +2 -0
  165. package/dist/types.d.ts.map +1 -1
  166. package/dist/types.js +1 -1
  167. package/dist/verified-recall.js +3 -3
  168. package/dist/who-knows-cli.js +4 -4
  169. package/dist/who-knows.js +3 -3
  170. package/package.json +2 -2
  171. package/src/access-observe-replay-durability.test.ts +1 -1
  172. package/src/buffer-drain-handover.test.ts +3 -3
  173. package/src/buffer-drop-extraction-chunk.test.ts +0 -1
  174. package/src/config.test.ts +12 -0
  175. package/src/config.ts +2 -0
  176. package/src/connector-provenance-lifecycle.test.ts +5 -8
  177. package/src/fact-dedup-window.test.ts +116 -0
  178. package/src/faithfulness-graph-guard.test.ts +11 -6
  179. package/src/harmonic-construction.test.ts +16 -10
  180. package/src/orchestration/consolidation-profile-race.test.ts +178 -0
  181. package/src/orchestration/consolidation-run.ts +19 -7
  182. package/src/orchestration/extraction-drain.ts +10 -3
  183. package/src/orchestration/extraction-persist-deps.ts +0 -2
  184. package/src/orchestration/extraction-persist.ts +159 -148
  185. package/src/orchestration/extraction-queue-coordinator.ts +167 -56
  186. package/src/orchestration/extraction-run-helpers.ts +5 -4
  187. package/src/orchestration/extraction-run.test.ts +1 -2
  188. package/src/orchestration/extraction-run.ts +56 -99
  189. package/src/orchestration/fact-dedup-window.ts +122 -0
  190. package/src/orchestration/provider-breaker.test.ts +89 -0
  191. package/src/orchestration/provider-breaker.ts +158 -0
  192. package/src/orchestration/turn-ingestion.ts +5 -5
  193. package/src/orchestrator-extraction-queue.test.ts +179 -8
  194. package/src/orchestrator.ts +7 -23
  195. package/src/storage/profile-mutation.ts +119 -0
  196. package/src/storage-append-profile.test.ts +114 -0
  197. package/src/storage.ts +17 -48
  198. package/src/testing/orchestrator-lite.ts +1 -1
  199. package/src/threading.test.ts +153 -0
  200. package/src/threading.ts +95 -45
  201. package/src/types.ts +2 -0
  202. package/dist/chunk-2ZSRACNK.js.map +0 -1
  203. package/dist/chunk-6D3IWYNY.js.map +0 -1
  204. package/dist/chunk-NM2II57L.js.map +0 -1
  205. package/dist/chunk-R7WYAXPO.js.map +0 -1
  206. package/dist/chunk-SEA56G6S.js.map +0 -1
  207. package/dist/chunk-XVQVF2TK.js.map +0 -1
  208. /package/dist/{chunk-KISOMGY2.js.map → chunk-3RHU5MD7.js.map} +0 -0
  209. /package/dist/{chunk-3LSTL6EY.js.map → chunk-4MPAKYZU.js.map} +0 -0
  210. /package/dist/{chunk-OVL5AD3N.js.map → chunk-4NV7O76Q.js.map} +0 -0
  211. /package/dist/{chunk-BH7NVSEC.js.map → chunk-4SOWMA55.js.map} +0 -0
  212. /package/dist/{chunk-GROHOWR5.js.map → chunk-5MGKGEL7.js.map} +0 -0
  213. /package/dist/{chunk-ZPLQ27MY.js.map → chunk-5UM4H64E.js.map} +0 -0
  214. /package/dist/{chunk-2DNFRLLL.js.map → chunk-5Y6VA6X2.js.map} +0 -0
  215. /package/dist/{chunk-GRAUQXQB.js.map → chunk-6WKWL53V.js.map} +0 -0
  216. /package/dist/{chunk-HOR4RMUM.js.map → chunk-75DCOS6I.js.map} +0 -0
  217. /package/dist/{chunk-25QK3LR2.js.map → chunk-7O2MC42R.js.map} +0 -0
  218. /package/dist/{chunk-7ETWIBTO.js.map → chunk-ADYP7HXE.js.map} +0 -0
  219. /package/dist/{chunk-FUDKGJDN.js.map → chunk-AVGDYYMA.js.map} +0 -0
  220. /package/dist/{chunk-ECF627KC.js.map → chunk-AYJQ644F.js.map} +0 -0
  221. /package/dist/{chunk-T22FBDG3.js.map → chunk-B3MWELZ3.js.map} +0 -0
  222. /package/dist/{chunk-DRTSPRWL.js.map → chunk-B4DXREWC.js.map} +0 -0
  223. /package/dist/{chunk-5UEGL5BF.js.map → chunk-CI3MAAIY.js.map} +0 -0
  224. /package/dist/{chunk-7JYK7NNY.js.map → chunk-CTH2CQCB.js.map} +0 -0
  225. /package/dist/{chunk-UVHXLVFJ.js.map → chunk-EURPSF4Y.js.map} +0 -0
  226. /package/dist/{chunk-VPEA63FC.js.map → chunk-EWJZZDRG.js.map} +0 -0
  227. /package/dist/{chunk-BOZQAUAJ.js.map → chunk-EXQJMFRF.js.map} +0 -0
  228. /package/dist/{chunk-UH6ROXFJ.js.map → chunk-GGD2YDS6.js.map} +0 -0
  229. /package/dist/{chunk-5JABRT5G.js.map → chunk-GHHQLSSY.js.map} +0 -0
  230. /package/dist/{chunk-N4T5FW6U.js.map → chunk-GJ4HU6LK.js.map} +0 -0
  231. /package/dist/{chunk-HRRAOTOQ.js.map → chunk-H5DIRCZP.js.map} +0 -0
  232. /package/dist/{chunk-434E4BTO.js.map → chunk-HH73M65H.js.map} +0 -0
  233. /package/dist/{chunk-LIGZO7XN.js.map → chunk-HPB5TF55.js.map} +0 -0
  234. /package/dist/{chunk-E4QIX2OB.js.map → chunk-IAGVM7EY.js.map} +0 -0
  235. /package/dist/{chunk-YJQJRXUI.js.map → chunk-IG3EZ3TF.js.map} +0 -0
  236. /package/dist/{chunk-KNMSD2MQ.js.map → chunk-IVUVQPTQ.js.map} +0 -0
  237. /package/dist/{chunk-XOFIJGB2.js.map → chunk-IZBIDPMY.js.map} +0 -0
  238. /package/dist/{chunk-HFEGRMFG.js.map → chunk-JLGBJ4AX.js.map} +0 -0
  239. /package/dist/{chunk-BBHKN2CN.js.map → chunk-JLMOH5JA.js.map} +0 -0
  240. /package/dist/{chunk-TPCRDPUY.js.map → chunk-KZSGBWOJ.js.map} +0 -0
  241. /package/dist/{chunk-SHHZWSSE.js.map → chunk-KZZ5EZ7O.js.map} +0 -0
  242. /package/dist/{chunk-FKGLJJVS.js.map → chunk-LN4X2NDA.js.map} +0 -0
  243. /package/dist/{chunk-5ZHFPUBC.js.map → chunk-MOIJWWNA.js.map} +0 -0
  244. /package/dist/{chunk-KO224R36.js.map → chunk-NCZGGGWI.js.map} +0 -0
  245. /package/dist/{chunk-7ZTGMEXF.js.map → chunk-O5ZINWW3.js.map} +0 -0
  246. /package/dist/{chunk-WWH7GJ42.js.map → chunk-OCK4D5PC.js.map} +0 -0
  247. /package/dist/{chunk-G6L3REL3.js.map → chunk-OPFVXM2D.js.map} +0 -0
  248. /package/dist/{chunk-FR7PK7ED.js.map → chunk-P4TV3TQ2.js.map} +0 -0
  249. /package/dist/{chunk-P2EM5LKH.js.map → chunk-PMDOGXA2.js.map} +0 -0
  250. /package/dist/{chunk-MRF5V5CD.js.map → chunk-QGFR73SN.js.map} +0 -0
  251. /package/dist/{chunk-HG3CG557.js.map → chunk-RLVI2M5Q.js.map} +0 -0
  252. /package/dist/{chunk-HHL4MX3W.js.map → chunk-SXTVZ6JL.js.map} +0 -0
  253. /package/dist/{chunk-CLSKGTAT.js.map → chunk-TECK5IVY.js.map} +0 -0
  254. /package/dist/{chunk-SNS3DWG6.js.map → chunk-TVE7W67N.js.map} +0 -0
  255. /package/dist/{chunk-KYSSUY66.js.map → chunk-U2CAGMUD.js.map} +0 -0
  256. /package/dist/{chunk-XLCEFUAU.js.map → chunk-UVVFPCPX.js.map} +0 -0
  257. /package/dist/{chunk-KQJUEQ2E.js.map → chunk-UW6LBFYN.js.map} +0 -0
  258. /package/dist/{chunk-JL5HXL25.js.map → chunk-V6SBA5O7.js.map} +0 -0
  259. /package/dist/{chunk-B7VD36TI.js.map → chunk-WHROVQ5Q.js.map} +0 -0
  260. /package/dist/{chunk-LDHR465K.js.map → chunk-Y3XPSGNF.js.map} +0 -0
  261. /package/dist/{chunk-JPY3RMG2.js.map → chunk-ZORS5BG5.js.map} +0 -0
  262. /package/dist/{chunk-KXY4HW2Y.js.map → chunk-ZXF3O7P4.js.map} +0 -0
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  ActivityStore,
15
15
  MaintenanceScheduler
16
- } from "./chunk-HFEGRMFG.js";
16
+ } from "./chunk-JLGBJ4AX.js";
17
17
  import {
18
18
  runPeerProfileReasoner
19
19
  } from "./chunk-I74SUMNI.js";
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  CompoundingEngine,
34
34
  defaultTierMigrationCycleBudget
35
- } from "./chunk-5JABRT5G.js";
35
+ } from "./chunk-GHHQLSSY.js";
36
36
  import {
37
37
  SharedContextManager
38
38
  } from "./chunk-5KBIOI4G.js";
@@ -175,7 +175,7 @@ import {
175
175
  } from "./chunk-VA3GNAWQ.js";
176
176
  import {
177
177
  ExtractionEngine
178
- } from "./chunk-FKGLJJVS.js";
178
+ } from "./chunk-LN4X2NDA.js";
179
179
  import {
180
180
  parseMemoryActionEligibilityContext
181
181
  } from "./chunk-JHU4EYDV.js";
@@ -210,7 +210,7 @@ import {
210
210
  buildEntityRecallSection,
211
211
  entityRecentTranscriptLookbackHours,
212
212
  readRecentEntityTranscriptEntries
213
- } from "./chunk-KO224R36.js";
213
+ } from "./chunk-NCZGGGWI.js";
214
214
  import {
215
215
  planEpisodeWindowsWithFallback
216
216
  } from "./chunk-T3GIETKV.js";
@@ -225,7 +225,7 @@ import {
225
225
  } from "./chunk-7G5NTS7F.js";
226
226
  import {
227
227
  refreshConvergedNamespaces
228
- } from "./chunk-WWH7GJ42.js";
228
+ } from "./chunk-OCK4D5PC.js";
229
229
  import {
230
230
  builtInConnectorPackageSpecifier,
231
231
  ensureBuiltInWearableConnectors,
@@ -234,7 +234,7 @@ import {
234
234
  runTimelinePublishCli,
235
235
  screenCandidateFact,
236
236
  summarizeVaultPublish
237
- } from "./chunk-HOR4RMUM.js";
237
+ } from "./chunk-75DCOS6I.js";
238
238
  import {
239
239
  normalizeReplaySessionKey
240
240
  } from "./chunk-AJVLDJU6.js";
@@ -244,14 +244,14 @@ import {
244
244
  import {
245
245
  compareVerifiedEpisodeResults,
246
246
  searchVerifiedEpisodes
247
- } from "./chunk-SHHZWSSE.js";
247
+ } from "./chunk-KZZ5EZ7O.js";
248
248
  import {
249
249
  ThreadingManager
250
- } from "./chunk-R7WYAXPO.js";
250
+ } from "./chunk-VHSQU3RO.js";
251
251
  import {
252
252
  compareVerifiedSemanticRuleResults,
253
253
  searchVerifiedSemanticRules
254
- } from "./chunk-SNS3DWG6.js";
254
+ } from "./chunk-TVE7W67N.js";
255
255
  import {
256
256
  searchWorkProductLedgerEntries
257
257
  } from "./chunk-B2NXOVZN.js";
@@ -264,10 +264,10 @@ import {
264
264
  import {
265
265
  runNamespaceMaintenanceFanout,
266
266
  summarizeNamespaceMaintenanceHealth
267
- } from "./chunk-5ZHFPUBC.js";
267
+ } from "./chunk-MOIJWWNA.js";
268
268
  import {
269
269
  planNamespaceMaintenance
270
- } from "./chunk-434E4BTO.js";
270
+ } from "./chunk-HH73M65H.js";
271
271
  import {
272
272
  isAboveImportanceThreshold,
273
273
  scoreImportance
@@ -296,10 +296,10 @@ import {
296
296
  materializeAfterSemanticConsolidation,
297
297
  parseConsolidationResponse,
298
298
  parseOperatorAwareConsolidationResponse
299
- } from "./chunk-ECF627KC.js";
299
+ } from "./chunk-AYJQ644F.js";
300
300
  import {
301
301
  SmartBuffer
302
- } from "./chunk-3LSTL6EY.js";
302
+ } from "./chunk-4MPAKYZU.js";
303
303
  import {
304
304
  semanticChunkContent
305
305
  } from "./chunk-2GBFKHBZ.js";
@@ -335,7 +335,7 @@ import {
335
335
  embeddingsFromCosineHits,
336
336
  normalizeConnectorScope,
337
337
  runSeedGraduationPass
338
- } from "./chunk-NM2II57L.js";
338
+ } from "./chunk-PRKNAIGZ.js";
339
339
  import {
340
340
  compileCorrectionRule,
341
341
  correctionsFilePath,
@@ -373,7 +373,7 @@ import {
373
373
  } from "./chunk-QW27DOHG.js";
374
374
  import {
375
375
  MeetingsInputError
376
- } from "./chunk-HRRAOTOQ.js";
376
+ } from "./chunk-H5DIRCZP.js";
377
377
  import {
378
378
  WearablesInputError,
379
379
  describeErrorForOperator
@@ -391,7 +391,7 @@ import {
391
391
  } from "./chunk-W7K5BP3M.js";
392
392
  import {
393
393
  NamespaceCatalog
394
- } from "./chunk-5UEGL5BF.js";
394
+ } from "./chunk-CI3MAAIY.js";
395
395
  import {
396
396
  RecallResultFormatter,
397
397
  SessionContextCoordinator,
@@ -400,7 +400,7 @@ import {
400
400
  detectPassiveCorrections,
401
401
  renderSessionExperiencePreview,
402
402
  scoreSessionExperienceForPrompt
403
- } from "./chunk-GRAUQXQB.js";
403
+ } from "./chunk-6WKWL53V.js";
404
404
  import {
405
405
  importCapsule
406
406
  } from "./chunk-QDZWQBLU.js";
@@ -429,7 +429,7 @@ import {
429
429
  } from "./chunk-MUHGYV2V.js";
430
430
  import {
431
431
  buildXraySnapshot
432
- } from "./chunk-25QK3LR2.js";
432
+ } from "./chunk-7O2MC42R.js";
433
433
  import {
434
434
  objectiveStateStoreOverrideForNamespace,
435
435
  searchObjectiveStateSnapshots
@@ -443,7 +443,7 @@ import {
443
443
  } from "./chunk-BJLCV2P3.js";
444
444
  import {
445
445
  searchHarmonicRetrieval
446
- } from "./chunk-BOZQAUAJ.js";
446
+ } from "./chunk-EXQJMFRF.js";
447
447
  import {
448
448
  ProfilingCollector
449
449
  } from "./chunk-DOWACHYO.js";
@@ -466,7 +466,7 @@ import {
466
466
  } from "./chunk-NVKO5YKP.js";
467
467
  import {
468
468
  NamespaceStorageRouter
469
- } from "./chunk-ZPLQ27MY.js";
469
+ } from "./chunk-5UM4H64E.js";
470
470
  import {
471
471
  pruneOrphanCueAnchors
472
472
  } from "./chunk-LXATZLSC.js";
@@ -480,7 +480,7 @@ import {
480
480
  ExtractionDeadlineError,
481
481
  ExtractionRunCoordinator,
482
482
  classifyExtractionOrigin
483
- } from "./chunk-6D3IWYNY.js";
483
+ } from "./chunk-R2BIVU2Z.js";
484
484
  import {
485
485
  ARTIFACT_STATUS_CACHE_TTL_MS,
486
486
  BulkImportBatchPartialFailureError,
@@ -532,7 +532,7 @@ import {
532
532
  } from "./chunk-74AY3S7U.js";
533
533
  import {
534
534
  buildChainFollowupGenerator
535
- } from "./chunk-E4QIX2OB.js";
535
+ } from "./chunk-IAGVM7EY.js";
536
536
  import {
537
537
  decideLifecycleTransition,
538
538
  resolveLifecycleState
@@ -577,7 +577,7 @@ import {
577
577
  reconstructFusionInputs,
578
578
  selfDeps,
579
579
  serializeFusionDay
580
- } from "./chunk-XVQVF2TK.js";
580
+ } from "./chunk-NHWDTOBN.js";
581
581
  import {
582
582
  bodyIsEscaped,
583
583
  decodeTranscriptBody,
@@ -707,7 +707,7 @@ import {
707
707
  } from "./chunk-PJKTFXE2.js";
708
708
  import {
709
709
  confidenceTier
710
- } from "./chunk-SEA56G6S.js";
710
+ } from "./chunk-V4XE263I.js";
711
711
  import {
712
712
  extractJsonCandidates
713
713
  } from "./chunk-YBA52OKG.js";
@@ -796,6 +796,7 @@ import {
796
796
  assertRealpathInsideRoot
797
797
  } from "./chunk-GCGJW34D.js";
798
798
  import {
799
+ serializeMutations,
799
800
  withHeldFileLock
800
801
  } from "./chunk-EBV6VXKF.js";
801
802
  import {
@@ -890,7 +891,7 @@ import {
890
891
  } from "./chunk-3WCASNQZ.js";
891
892
 
892
893
  // src/orchestrator.ts
893
- import path23 from "path";
894
+ import path24 from "path";
894
895
  import { createHash as createHash10 } from "crypto";
895
896
 
896
897
  // src/orchestration/buffer-swap.ts
@@ -1077,35 +1078,51 @@ var TierMigrationCoordinator = class {
1077
1078
 
1078
1079
  // src/orchestration/extraction-queue-coordinator.ts
1079
1080
  var ExtractionQueueCoordinator = class {
1081
+ /** Maximum tasks that run at the same time (config `extractionQueueConcurrency`). */
1082
+ concurrency;
1080
1083
  /**
1081
- * Background serial queue for extractions (agent_end optimization).
1082
- * Queue stores tasks that resolve when extraction should run.
1084
+ * Background queue for extractions (agent_end optimization). Queue stores
1085
+ * tasks that resolve when extraction should run.
1083
1086
  */
1084
1087
  queue = [];
1085
- /** Whether the serial drain loop is currently running. */
1088
+ /** Whether the drain loop is currently running. */
1086
1089
  processing = false;
1087
1090
  accepting = true;
1088
- runningPreempt;
1091
+ /** Buffer keys with a task currently running (per-key exclusion). */
1092
+ activeKeys = /* @__PURE__ */ new Set();
1093
+ /** Preempt slots of the currently running tasks, keyed by slot identity. */
1094
+ preemptSlots = /* @__PURE__ */ new Map();
1095
+ preemptSeq = 0;
1096
+ /** Resolves the processor's park while a new task arrives mid-drain. */
1097
+ wake;
1098
+ constructor(concurrency = 1) {
1099
+ this.concurrency = Number.isInteger(concurrency) && concurrency >= 1 ? concurrency : 1;
1100
+ }
1089
1101
  /** Current queue depth (idle-wait + test seam). */
1090
1102
  get length() {
1091
1103
  return this.queue.length;
1092
1104
  }
1093
- /** Whether the serial drain loop is currently running (idle-wait + test seam). */
1105
+ /** Whether the drain loop is currently running (idle-wait + test seam). */
1094
1106
  get isProcessing() {
1095
1107
  return this.processing;
1096
1108
  }
1109
+ /** How many tasks may run at once (test seam + diagnostics). */
1110
+ get maxConcurrency() {
1111
+ return this.concurrency;
1112
+ }
1097
1113
  /**
1098
- * Enqueue a task and start the serial processor if it is idle. This is
1114
+ * Enqueue a task and start the processor when capacity is free. This is
1099
1115
  * the production entry point — the orchestrator's `queueBufferedExtraction`
1100
- * builds each task closure and hands it here.
1116
+ * builds each task closure and hands it here with its buffer key.
1101
1117
  */
1102
1118
  enqueue(task, options) {
1103
1119
  if (!this.accepting) return false;
1120
+ const entry = { run: task, key: options?.key };
1104
1121
  if (options?.front) {
1105
- this.preemptRunning();
1106
- this.queue.unshift(task);
1122
+ this.preemptRunning(options.key);
1123
+ this.queue.unshift(entry);
1107
1124
  } else {
1108
- this.queue.push(task);
1125
+ this.queue.push(entry);
1109
1126
  }
1110
1127
  if (!this.processing) {
1111
1128
  this.processing = true;
@@ -1113,27 +1130,28 @@ var ExtractionQueueCoordinator = class {
1113
1130
  this.logExtractionQueueFailure(err, "processor");
1114
1131
  this.processing = false;
1115
1132
  });
1133
+ } else {
1134
+ this.wake?.();
1116
1135
  }
1117
1136
  return true;
1118
1137
  }
1119
- /** Automatic extraction registers this so a fail-closed flush can abort it. */
1120
- beginPreemptable(abort) {
1121
- this.runningPreempt = abort;
1122
- }
1123
- endPreemptable() {
1124
- this.runningPreempt = void 0;
1125
- }
1126
- preemptRunning() {
1127
- const abort = this.runningPreempt;
1128
- this.runningPreempt = void 0;
1138
+ preemptRunning(preferredKey) {
1139
+ const armed = Array.from(this.preemptSlots.values()).filter((slot) => slot.armed !== void 0);
1140
+ if (armed.length === 0) return;
1141
+ const preferred = preferredKey !== void 0 ? armed.find((slot) => slot.key === preferredKey) : void 0;
1142
+ const chosen = preferred ?? armed.reduce((a, b) => (b.armed?.seq ?? -1) > (a.armed?.seq ?? -1) ? b : a);
1143
+ const abort = chosen.armed?.abort;
1144
+ chosen.armed = void 0;
1129
1145
  abort?.();
1130
1146
  }
1131
- runPreemptable(preemptable, parent, run) {
1132
- const preempt = new AbortController();
1133
- if (preemptable) this.beginPreemptable(() => preempt.abort(preemptedExtractionError()));
1134
- const signal = parent ? AbortSignal.any([parent, preempt.signal]) : preempt.signal;
1147
+ runPreemptable(preempt, preemptable, parent, run) {
1148
+ const preemptController = new AbortController();
1149
+ if (preemptable && preempt) {
1150
+ preempt.arm(() => preemptController.abort(preemptedExtractionError()));
1151
+ }
1152
+ const signal = parent ? AbortSignal.any([parent, preemptController.signal]) : preemptController.signal;
1135
1153
  return Promise.resolve(run(signal)).finally(() => {
1136
- if (preemptable) this.endPreemptable();
1154
+ if (preemptable && preempt) preempt.disarm();
1137
1155
  });
1138
1156
  }
1139
1157
  /** Stop new producers from entering the queue. */
@@ -1153,28 +1171,75 @@ var ExtractionQueueCoordinator = class {
1153
1171
  return true;
1154
1172
  }
1155
1173
  /**
1156
- * Background serial queue processor.
1157
- * Processes extractions one at a time to avoid race conditions.
1158
- * Called automatically when items are queued via `enqueue`; also exposed
1159
- * for the characterization tests that push raw tasks and assert drain
1160
- * semantics directly.
1174
+ * Background queue processor. Runs up to `concurrency` tasks at a time,
1175
+ * never two tasks with the same entry key. Called automatically when items
1176
+ * are queued via `enqueue`; also exposed for the characterization tests
1177
+ * that push raw tasks and assert drain semantics directly.
1161
1178
  */
1162
1179
  async processQueue() {
1163
- while (this.queue.length > 0) {
1164
- const task = this.queue.shift();
1165
- if (task) {
1180
+ const inFlight = /* @__PURE__ */ new Set();
1181
+ try {
1182
+ while (this.queue.length > 0 || inFlight.size > 0) {
1183
+ while (inFlight.size < this.concurrency) {
1184
+ const entry = this.takeRunnable();
1185
+ if (!entry) break;
1186
+ const running = this.runEntry(entry).finally(() => {
1187
+ inFlight.delete(running);
1188
+ });
1189
+ inFlight.add(running);
1190
+ }
1191
+ if (inFlight.size === 0) break;
1192
+ const { promise: wakePromise, resolve: wake } = Promise.withResolvers();
1193
+ this.wake = wake;
1166
1194
  try {
1167
- await task();
1168
- } catch (err) {
1169
- this.logExtractionQueueFailure(err, "task");
1195
+ await Promise.race([wakePromise, ...inFlight]);
1196
+ } finally {
1197
+ this.wake = void 0;
1170
1198
  }
1171
1199
  }
1200
+ } finally {
1201
+ this.processing = false;
1202
+ }
1203
+ }
1204
+ /** Take the next queue entry whose key is not already running (FIFO within a key). */
1205
+ takeRunnable() {
1206
+ for (let index = 0; index < this.queue.length; index += 1) {
1207
+ const entry = this.queue[index];
1208
+ if (entry.key !== void 0 && this.activeKeys.has(entry.key)) continue;
1209
+ this.queue.splice(index, 1);
1210
+ if (entry.key !== void 0) this.activeKeys.add(entry.key);
1211
+ return entry;
1212
+ }
1213
+ return void 0;
1214
+ }
1215
+ /** Run one entry with its own preempt slot; failures are classified + logged. */
1216
+ async runEntry(entry) {
1217
+ const slot = {};
1218
+ this.preemptSlots.set(slot, { key: entry.key });
1219
+ try {
1220
+ await entry.run(this.createPreemptHandle(slot));
1221
+ } catch (err) {
1222
+ this.logExtractionQueueFailure(err, "task");
1223
+ } finally {
1224
+ this.preemptSlots.delete(slot);
1225
+ if (entry.key !== void 0) this.activeKeys.delete(entry.key);
1172
1226
  }
1173
- this.processing = false;
1227
+ }
1228
+ createPreemptHandle(slot) {
1229
+ return {
1230
+ arm: (abort) => {
1231
+ const state = this.preemptSlots.get(slot);
1232
+ if (state) state.armed = { abort, seq: this.preemptSeq++ };
1233
+ },
1234
+ disarm: () => {
1235
+ const state = this.preemptSlots.get(slot);
1236
+ if (state) state.armed = void 0;
1237
+ }
1238
+ };
1174
1239
  }
1175
1240
  /**
1176
1241
  * Classify + log a failure from either the per-task catch inside
1177
- * `processQueue()` or the outer `processQueue().catch(...)` in
1242
+ * `runEntry` or the outer `processQueue().catch(...)` in
1178
1243
  * `enqueue()`. Issue #549: `throwIfRecallAborted`
1179
1244
  * (used throughout `runExtraction`) raises an Error whose `name` is
1180
1245
  * `"AbortError"`. That path fires when `before_reset` aborts a
@@ -1227,12 +1292,13 @@ var ExtractionQueueCoordinator = class {
1227
1292
  * pre-extraction `this.extractionQueue.push(...)` used by the
1228
1293
  * characterization tests that drive the drain manually via `processQueue`.
1229
1294
  */
1230
- pushRaw(task) {
1231
- this.queue.push(task);
1295
+ pushRaw(task, options) {
1296
+ this.queue.push({ run: task, key: options?.key });
1297
+ this.wake?.();
1232
1298
  }
1233
1299
  /** Remove + return the front task (test seam for the flush deadline tests). */
1234
1300
  shift() {
1235
- return this.queue.shift();
1301
+ return this.queue.shift()?.run;
1236
1302
  }
1237
1303
  /**
1238
1304
  * Force the processor-busy flag so `enqueue` does not auto-start the
@@ -2495,7 +2561,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2495
2561
  namespaces,
2496
2562
  {
2497
2563
  readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
2498
- readMemoryFrontmatter: async (path41, preferredNamespace) => {
2564
+ readMemoryFrontmatter: async (path42, preferredNamespace) => {
2499
2565
  if (!fallbackReader) {
2500
2566
  for (const ns of namespaces) {
2501
2567
  try {
@@ -2507,7 +2573,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2507
2573
  }
2508
2574
  if (!fallbackReader) return null;
2509
2575
  const memory = await this.readQmdResultMemory(
2510
- path41,
2576
+ path42,
2511
2577
  fallbackReader,
2512
2578
  namespaces,
2513
2579
  preferredNamespace
@@ -4798,11 +4864,20 @@ var ConsolidationRunCoordinator = class {
4798
4864
  profileConsolidationTargetLines
4799
4865
  );
4800
4866
  if (profileResult) {
4801
- await storage.writeProfile(profileResult.consolidatedProfile);
4802
- memoryItemMutated = true;
4803
- log.info(
4804
- `profile.md consolidated: removed ${profileResult.removedCount} items \u2014 ${profileResult.summary}`
4867
+ const outcome = await storage.commitConsolidatedProfile(
4868
+ currentProfile,
4869
+ profileResult.consolidatedProfile
4805
4870
  );
4871
+ if (outcome === "conflict") {
4872
+ log.info(
4873
+ "profile.md changed during consolidation \u2014 skipping stale rewrite (retries next pass)"
4874
+ );
4875
+ } else {
4876
+ memoryItemMutated = true;
4877
+ log.info(
4878
+ `profile.md consolidated: removed ${profileResult.removedCount} items \u2014 ${profileResult.summary}`
4879
+ );
4880
+ }
4806
4881
  }
4807
4882
  }
4808
4883
  }
@@ -4895,6 +4970,78 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
4895
4970
  }
4896
4971
  };
4897
4972
 
4973
+ // src/orchestration/fact-dedup-window.ts
4974
+ import path5 from "path";
4975
+
4976
+ // src/orchestration/extraction-persist-citation.ts
4977
+ function normalizeStoredHashSource(raw, citationEnabled, citationTemplate) {
4978
+ return ContentHashIndex.normalizeContent(
4979
+ sanitizeMemoryContent(
4980
+ citationEnabled && hasCitationForTemplate(raw, citationTemplate) ? stripCitationForTemplate(raw, citationTemplate) : raw
4981
+ ).text
4982
+ );
4983
+ }
4984
+ function applyInlineCitation(content, citationEnabled, citationTemplate, citationContextBase) {
4985
+ if (!citationEnabled) return content;
4986
+ if (typeof content !== "string" || content.length === 0) return content;
4987
+ const citationContext = {
4988
+ ...citationContextBase,
4989
+ ts: (/* @__PURE__ */ new Date()).toISOString()
4990
+ };
4991
+ return attachCitation(content, citationContext, citationTemplate);
4992
+ }
4993
+
4994
+ // src/orchestration/fact-dedup-window.ts
4995
+ function matchesActiveConnectorDuplicate(memory, opts) {
4996
+ if (memory.frontmatter.category !== opts.category) return false;
4997
+ if ((memory.frontmatter.status ?? "active") !== "active") return false;
4998
+ if (normalizeStoredHashSource(stripAttributesSuffix(memory.content ?? ""), opts.citationEnabled, opts.citationTemplate) !== ContentHashIndex.normalizeContent(opts.contentHashDedupKey)) return false;
4999
+ return (memory.frontmatter.sourceConnector?.trim() || void 0) === opts.connector;
5000
+ }
5001
+ async function confirmActiveFactDuplicate(probe, storage, opts) {
5002
+ let needsCorpusConfirm;
5003
+ try {
5004
+ if (!await probe.hasContentHashDedup(storage, opts.contentHashDedupKey)) {
5005
+ if (await storage.isFactContentHashAuthoritative()) return false;
5006
+ needsCorpusConfirm = true;
5007
+ } else {
5008
+ needsCorpusConfirm = true;
5009
+ }
5010
+ } catch {
5011
+ needsCorpusConfirm = true;
5012
+ }
5013
+ try {
5014
+ const [hotMems, coldMems] = await Promise.all([
5015
+ storage.readAllMemories(),
5016
+ storage.readAllColdMemories()
5017
+ ]);
5018
+ return hotMems.some((m) => matchesActiveConnectorDuplicate(m, opts)) || coldMems.some((m) => matchesActiveConnectorDuplicate(m, opts));
5019
+ } catch (err) {
5020
+ log.warn(
5021
+ `connector-aware dedup scan failed for storage ${storage.dir}; writing fail-open: ${err instanceof Error ? err.message : String(err)}`
5022
+ );
5023
+ return false;
5024
+ }
5025
+ }
5026
+ async function persistUnderFactDedupWindow(storageDir, recheck, write) {
5027
+ return serializeMutations(
5028
+ `fact-dedup:${storageDir}`,
5029
+ () => withHeldFileLock(
5030
+ path5.join(storageDir, "fact-dedup.lock"),
5031
+ // Bounded: the window holds one corpus confirm + one memory write, not a
5032
+ // scan-length lock (catalog round 5 adoption note).
5033
+ { staleMs: 5e3, maxWaitMs: 2e3, pollMs: 50 },
5034
+ async (acquired) => {
5035
+ if (!acquired) {
5036
+ throw new Error(`fact write skipped: fact-dedup.lock not acquired (${storageDir})`);
5037
+ }
5038
+ if (await recheck()) return { suppressed: true };
5039
+ return { suppressed: false, result: await write() };
5040
+ }
5041
+ )
5042
+ );
5043
+ }
5044
+
4898
5045
  // src/orchestration/extraction-injection-gate.ts
4899
5046
  function serializeInjectionScreenCandidate(candidate) {
4900
5047
  const body = candidate.category === "procedure" ? buildProcedurePersistBody(candidate.content, candidate.procedureSteps) : candidate.content;
@@ -5571,7 +5718,7 @@ async function retireStaleMergedTargetPromotionCopies(args) {
5571
5718
  }
5572
5719
 
5573
5720
  // src/orchestration/semantic-merge-persist.ts
5574
- import path5 from "path";
5721
+ import path6 from "path";
5575
5722
 
5576
5723
  // src/orchestration/semantic-merge-commit-effects.ts
5577
5724
  import { readFile as readFile3 } from "fs/promises";
@@ -6291,11 +6438,11 @@ async function runMergedTargetPostEffects(deps, storage, merge, input) {
6291
6438
  if (inferMemoryStatus(committed.frontmatter, committed.path) !== "active") return signals;
6292
6439
  const entityRef = committed.frontmatter.entityRef;
6293
6440
  const rawBody = rawPreCitationMergedBody(deps, merge.mergedContent);
6294
- const memoryRelPath = path5.relative(storage.dir, committed.path);
6441
+ const memoryRelPath = path6.relative(storage.dir, committed.path);
6295
6442
  input.graphContext.memoryPathById.set(merge.targetId, memoryRelPath);
6296
6443
  const all = input.graphContext.allMemsForGraph;
6297
6444
  if (Array.isArray(all)) {
6298
- const entry = all.find((m) => path5.relative(storage.dir, m.path) === memoryRelPath);
6445
+ const entry = all.find((m) => path6.relative(storage.dir, m.path) === memoryRelPath);
6299
6446
  if (entry) entry.content = rawBody;
6300
6447
  }
6301
6448
  const rewriteTypes = [];
@@ -6339,7 +6486,7 @@ async function runMergedTargetPostEffects(deps, storage, merge, input) {
6339
6486
  }
6340
6487
 
6341
6488
  // src/orchestration/extraction-anchor-snapshot.ts
6342
- import path6 from "path";
6489
+ import path7 from "path";
6343
6490
  var ExtractionAnchorSnapshot = class {
6344
6491
  constructor(options = {}) {
6345
6492
  this.options = options;
@@ -6377,7 +6524,7 @@ var ExtractionAnchorSnapshot = class {
6377
6524
  if (!cached) return;
6378
6525
  const snapshot = await cached;
6379
6526
  const relativePath = resolvePersistedMemoryRelativePath({ memoryId, pathById, category });
6380
- let memory = await storage.readMemoryByPath(path6.join(storage.dir, relativePath));
6527
+ let memory = await storage.readMemoryByPath(path7.join(storage.dir, relativePath));
6381
6528
  if (!memory) memory = await storage.getMemoryByIdIncludingArchived(memoryId);
6382
6529
  if (!memory) return;
6383
6530
  const existingIndex = snapshot.findIndex((entry) => entry.frontmatter.id === memoryId);
@@ -6397,24 +6544,6 @@ var ExtractionAnchorSnapshot = class {
6397
6544
  }
6398
6545
  };
6399
6546
 
6400
- // src/orchestration/extraction-persist-citation.ts
6401
- function normalizeStoredHashSource(raw, citationEnabled, citationTemplate) {
6402
- return ContentHashIndex.normalizeContent(
6403
- sanitizeMemoryContent(
6404
- citationEnabled && hasCitationForTemplate(raw, citationTemplate) ? stripCitationForTemplate(raw, citationTemplate) : raw
6405
- ).text
6406
- );
6407
- }
6408
- function applyInlineCitation(content, citationEnabled, citationTemplate, citationContextBase) {
6409
- if (!citationEnabled) return content;
6410
- if (typeof content !== "string" || content.length === 0) return content;
6411
- const citationContext = {
6412
- ...citationContextBase,
6413
- ts: (/* @__PURE__ */ new Date()).toISOString()
6414
- };
6415
- return attachCitation(content, citationContext, citationTemplate);
6416
- }
6417
-
6418
6547
  // src/orchestration/extraction-persist.ts
6419
6548
  var ExtractionPersistCoordinator = class {
6420
6549
  constructor(deps) {
@@ -6454,6 +6583,7 @@ var ExtractionPersistCoordinator = class {
6454
6583
  });
6455
6584
  const supersessionOrderingAt = (validAt) => validAt && validAt.length > 0 ? validAt : (/* @__PURE__ */ new Date()).toISOString();
6456
6585
  const pendingReviewPersistedIds = [];
6586
+ let deferredCount = 0;
6457
6587
  const persistedIdsByStorage = /* @__PURE__ */ new Map();
6458
6588
  const trackPersistedId = (targetStorage, id, options = {}) => {
6459
6589
  if (options.includeReturnedIds !== false) {
@@ -6960,7 +7090,7 @@ var ExtractionPersistCoordinator = class {
6960
7090
  "persistExtraction: result or result.facts is invalid, skipping",
6961
7091
  { resultType: typeof result, factsType: typeof result?.facts }
6962
7092
  );
6963
- return { persistedIds, memoryPathById };
7093
+ return { persistedIds, memoryPathById, deferredCount, pendingReviewIds: pendingReviewPersistedIds };
6964
7094
  }
6965
7095
  const chunkingConfig = {
6966
7096
  targetTokens: this.deps.config.chunkingTargetTokens,
@@ -7067,7 +7197,6 @@ var ExtractionPersistCoordinator = class {
7067
7197
  }
7068
7198
  let judgeVerdictsByFactIndex = null;
7069
7199
  let judgeGatedCount = 0;
7070
- this.deps.setLastPersistExtractionDeferredCount(0);
7071
7200
  if (lifecycleCaps.extractionJudge) {
7072
7201
  let preJudgeRedactionRules = [];
7073
7202
  try {
@@ -7195,7 +7324,7 @@ var ExtractionPersistCoordinator = class {
7195
7324
  log.info(
7196
7325
  `extraction-judge: ${judgeResult.verdicts.size}/${judgeCandidates.length} facts evaluated, ${judgeResult.cached} cached, ${judgeResult.judged} judged, ${judgeResult.deferred} deferred` + (judgeResult.deferredCappedToReject > 0 ? ` (${judgeResult.deferredCappedToReject} cap-rejected)` : "") + `, ${judgeResult.elapsed}ms`
7197
7326
  );
7198
- this.deps.setLastPersistExtractionDeferredCount(judgeResult.deferred);
7327
+ deferredCount = judgeResult.deferred;
7199
7328
  } catch (err) {
7200
7329
  log.warn(
7201
7330
  `extraction-judge: pipeline error, proceeding without filtering (fail-open): ${err instanceof Error ? err.message : String(err)}`
@@ -7322,81 +7451,83 @@ var ExtractionPersistCoordinator = class {
7322
7451
  fact.tags
7323
7452
  );
7324
7453
  let exactDuplicate = false;
7325
- let needsCorpusConfirm = false;
7326
7454
  try {
7327
7455
  exactDuplicate = await this.deps.hasContentHashDedup(targetStorage, contentHashDedupKey);
7328
- if (factDedupEnabled && !exactDuplicate) {
7329
- if (await targetStorage.isFactContentHashAuthoritative()) {
7330
- exactDuplicate = await this.deps.hasContentHashDedup(targetStorage, contentHashDedupKey);
7331
- } else {
7332
- needsCorpusConfirm = true;
7333
- }
7334
- }
7335
7456
  } catch (err) {
7336
- needsCorpusConfirm = true;
7457
+ exactDuplicate = false;
7337
7458
  log.warn(
7338
7459
  `content-hash dedup lookup unavailable for storage ${targetStorage.dir}; confirming against corpus: ${err}`
7339
7460
  );
7340
7461
  }
7341
- if (factDedupEnabled && (exactDuplicate || needsCorpusConfirm)) {
7342
- try {
7343
- const [hotMems, coldMems] = await Promise.all([
7344
- targetStorage.readAllMemories(),
7345
- targetStorage.readAllColdMemories()
7346
- ]);
7347
- const nc = sourceContext?.sourceConnector?.trim() || void 0;
7348
- const matchesActiveDuplicate = (m) => {
7349
- if (m.frontmatter.category !== writeCategory) return false;
7350
- if ((m.frontmatter.status ?? "active") !== "active") return false;
7351
- if (normalizeStoredHashSource2(stripAttributesSuffix(m.content ?? "")) !== ContentHashIndex.normalizeContent(contentHashDedupKey)) return false;
7352
- return (m.frontmatter.sourceConnector?.trim() || void 0) === nc;
7353
- };
7354
- exactDuplicate = hotMems.some(matchesActiveDuplicate) || coldMems.some(matchesActiveDuplicate);
7355
- } catch (err) {
7356
- log.warn(
7357
- `connector-aware dedup scan failed for storage ${targetStorage.dir}; writing fail-open: ${err instanceof Error ? err.message : String(err)}`
7358
- );
7359
- exactDuplicate = false;
7360
- }
7462
+ const raceDedupOpts = (key) => ({
7463
+ category: writeCategory,
7464
+ contentHashDedupKey: key,
7465
+ connector: sourceContext?.sourceConnector?.trim() || void 0,
7466
+ citationEnabled,
7467
+ citationTemplate
7468
+ });
7469
+ if (factDedupEnabled) {
7470
+ exactDuplicate = await confirmActiveFactDuplicate(
7471
+ { hasContentHashDedup: (storage2, key) => this.deps.hasContentHashDedup(storage2, key) },
7472
+ targetStorage,
7473
+ raceDedupOpts(contentHashDedupKey)
7474
+ );
7361
7475
  }
7362
- if (exactDuplicate && injectionScreenStatus !== "pending_review") {
7363
- if (biTemporal && writeCategory === "fact" && (biTemporal.validUntil || biTemporal.validFrom)) {
7364
- const fr = faithfulnessResultsByFactIndex?.get(factLoopIndex);
7365
- const faithfulnessWouldPending = faithfulnessMode === "enforce" && fr?.ok === true && (fr.verdict === "unsupported" || fr.verdict === "contradicted");
7366
- const requireSpansWouldPending = this.deps.config.provenance?.requireSpans === true && fact.requireSpansPending === true;
7367
- const judgeVerdict = judgeVerdictsByFactIndex?.get(factLoopIndex);
7368
- const judgeWouldGate = !this.deps.config.extractionJudgeShadow && judgeVerdict !== void 0 && !judgeVerdict.durable;
7369
- if (isAboveImportanceThreshold(importance.level, this.deps.config.extractionMinImportanceLevel) && !faithfulnessWouldPending && !requireSpansWouldPending && !judgeWouldGate) {
7370
- await this.deps.backfillTemporalBoundsOnDedupHit(
7371
- targetStorage,
7372
- contentHashDedupKey,
7373
- {
7374
- invalidAt: biTemporal.validUntil,
7375
- // #1707 thread 2 — carry the corrected start bound too.
7376
- validFrom: biTemporal.validFrom,
7377
- observedAt: biTemporal.observedAt,
7378
- eventTimeSource: biTemporal.eventTimeSource
7379
- },
7380
- fact.entityRef,
7381
- sourceContext?.sourceConnector
7382
- );
7383
- await backfillTemporalBoundsOnPromotionCopies({
7384
- sourceStorage: targetStorage,
7385
- content: fact.content,
7386
- category: writeCategory,
7387
- confidence: fact.confidence,
7388
- entityRef: fact.entityRef,
7389
- structuredAttributes: fact.structuredAttributes,
7390
- sourceConnector: sourceContext?.sourceConnector,
7391
- bounds: {
7392
- invalidAt: biTemporal.validUntil,
7393
- validFrom: biTemporal.validFrom,
7394
- observedAt: biTemporal.observedAt,
7395
- eventTimeSource: biTemporal.eventTimeSource
7396
- }
7397
- });
7398
- }
7476
+ const finalizeOnWindowFailure = async (err) => {
7477
+ await finalizeCommittedWrites(true).catch(
7478
+ (finalizeErr) => log.warn(`committed-write finalization after fact-dedup window failure failed: ${finalizeErr}`)
7479
+ );
7480
+ throw err;
7481
+ };
7482
+ const raceRecheck = (storage2, key) => () => {
7483
+ if (!factDedupEnabled || injectionScreenStatus === "pending_review") return Promise.resolve(false);
7484
+ return confirmActiveFactDuplicate(
7485
+ { hasContentHashDedup: (s, k) => this.deps.hasContentHashDedup(s, k) },
7486
+ storage2,
7487
+ raceDedupOpts(key)
7488
+ );
7489
+ };
7490
+ const backfillDuplicateTemporalBounds = async () => {
7491
+ if (!(biTemporal && writeCategory === "fact" && (biTemporal.validUntil || biTemporal.validFrom))) return;
7492
+ const fr = faithfulnessResultsByFactIndex?.get(factLoopIndex);
7493
+ const faithfulnessWouldPending = faithfulnessMode === "enforce" && fr?.ok === true && (fr.verdict === "unsupported" || fr.verdict === "contradicted");
7494
+ const requireSpansWouldPending = this.deps.config.provenance?.requireSpans === true && fact.requireSpansPending === true;
7495
+ const judgeVerdict = judgeVerdictsByFactIndex?.get(factLoopIndex);
7496
+ const judgeWouldGate = !this.deps.config.extractionJudgeShadow && judgeVerdict !== void 0 && !judgeVerdict.durable;
7497
+ if (!isAboveImportanceThreshold(importance.level, this.deps.config.extractionMinImportanceLevel) || faithfulnessWouldPending || requireSpansWouldPending || judgeWouldGate) {
7498
+ return;
7399
7499
  }
7500
+ await this.deps.backfillTemporalBoundsOnDedupHit(
7501
+ targetStorage,
7502
+ contentHashDedupKey,
7503
+ {
7504
+ invalidAt: biTemporal.validUntil,
7505
+ // #1707 thread 2 — carry the corrected start bound too.
7506
+ validFrom: biTemporal.validFrom,
7507
+ observedAt: biTemporal.observedAt,
7508
+ eventTimeSource: biTemporal.eventTimeSource
7509
+ },
7510
+ fact.entityRef,
7511
+ sourceContext?.sourceConnector
7512
+ );
7513
+ await backfillTemporalBoundsOnPromotionCopies({
7514
+ sourceStorage: targetStorage,
7515
+ content: fact.content,
7516
+ category: writeCategory,
7517
+ confidence: fact.confidence,
7518
+ entityRef: fact.entityRef,
7519
+ structuredAttributes: fact.structuredAttributes,
7520
+ sourceConnector: sourceContext?.sourceConnector,
7521
+ bounds: {
7522
+ invalidAt: biTemporal.validUntil,
7523
+ validFrom: biTemporal.validFrom,
7524
+ observedAt: biTemporal.observedAt,
7525
+ eventTimeSource: biTemporal.eventTimeSource
7526
+ }
7527
+ });
7528
+ };
7529
+ if (exactDuplicate && injectionScreenStatus !== "pending_review") {
7530
+ await backfillDuplicateTemporalBounds();
7400
7531
  log.debug(
7401
7532
  `dedup: skipping duplicate fact "${fact.content.slice(0, 60)}\u2026" in storage ${targetStorage.dir}`
7402
7533
  );
@@ -7605,27 +7736,38 @@ var ExtractionPersistCoordinator = class {
7605
7736
  },
7606
7737
  { source: extractionWriteSource }
7607
7738
  );
7608
- const parentWrite = await targetStorage.writeSealedMemory(parentWriteEnvelope, {
7609
- importance,
7610
- supersedes,
7611
- links: links.length > 0 ? links : void 0,
7612
- intentGoal: inferredIntent?.goal,
7613
- intentActionType: inferredIntent?.actionType,
7614
- intentEntityTypes: inferredIntent?.entityTypes,
7615
- memoryKind: memoryKind2,
7616
- ...biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {} } : {},
7617
- contentHashSource: rawChunkedContent,
7618
- // Faithfulness gate (issue #1576).
7619
- ...faithfulnessFm ? { faithfulness: faithfulnessFm } : {},
7620
- ...faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {},
7621
- // Claim-level provenance spans (issue #1575 PR 2).
7622
- ...fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {},
7623
- ...fact.provenance ? { provenance: fact.provenance } : {},
7624
- // PR #2016: never defer here — fallible chunk/artifact writes follow this
7625
- // durable parent .md; flush the hash now so a throw can't strand it (dup).
7626
- deferHashIndexSave: false,
7627
- ...factToolScoped ? { toolScoped: true } : {}
7628
- });
7739
+ const parentWriteOutcome = await persistUnderFactDedupWindow(
7740
+ targetStorage.dir,
7741
+ raceRecheck(targetStorage, contentHashDedupKey),
7742
+ async () => targetStorage.writeSealedMemory(parentWriteEnvelope, {
7743
+ importance,
7744
+ supersedes,
7745
+ links: links.length > 0 ? links : void 0,
7746
+ intentGoal: inferredIntent?.goal,
7747
+ intentActionType: inferredIntent?.actionType,
7748
+ intentEntityTypes: inferredIntent?.entityTypes,
7749
+ memoryKind: memoryKind2,
7750
+ ...biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {} } : {},
7751
+ contentHashSource: rawChunkedContent,
7752
+ // Faithfulness gate (issue #1576).
7753
+ ...faithfulnessFm ? { faithfulness: faithfulnessFm } : {},
7754
+ ...faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {},
7755
+ // Claim-level provenance spans (issue #1575 PR 2).
7756
+ ...fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {},
7757
+ ...fact.provenance ? { provenance: fact.provenance } : {},
7758
+ // PR #2016: never defer here — fallible chunk/artifact writes follow this
7759
+ // durable parent .md; flush the hash now so a throw can't strand it (dup).
7760
+ deferHashIndexSave: false,
7761
+ ...factToolScoped ? { toolScoped: true } : {}
7762
+ })
7763
+ ).catch(finalizeOnWindowFailure);
7764
+ if (parentWriteOutcome.suppressed) {
7765
+ await backfillDuplicateTemporalBounds();
7766
+ log.info(`dedup: raced duplicate suppressed in fact-dedup window (chunked parent) for storage ${targetStorage.dir}`);
7767
+ dedupedCount++;
7768
+ continue;
7769
+ }
7770
+ const parentWrite = parentWriteOutcome.result;
7629
7771
  const parentId = parentWrite.id;
7630
7772
  const tombstoneBlocked2 = parentWrite.tombstoneBlocked;
7631
7773
  const postWriteGuard2 = faithfulnessEnforceStatus === "pending_review" || tombstoneBlocked2;
@@ -7914,29 +8056,41 @@ var ExtractionPersistCoordinator = class {
7914
8056
  },
7915
8057
  { source: extractionWriteSource }
7916
8058
  );
7917
- const factWrite = await targetStorage.writeSealedMemory(factWriteEnvelope, {
7918
- importance,
7919
- supersedes,
7920
- links: links.length > 0 ? links : void 0,
7921
- intentGoal: inferredIntent?.goal,
7922
- intentActionType: inferredIntent?.actionType,
7923
- intentEntityTypes: inferredIntent?.entityTypes,
7924
- memoryKind,
7925
- ...biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {} } : {},
7926
- contentHashSource: writeCategory === "fact" ? fact.content : void 0,
7927
- // Faithfulness gate (issue #1576).
7928
- ...faithfulnessFm ? { faithfulness: faithfulnessFm } : {},
7929
- ...faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {},
7930
- // Claim-level provenance spans (issue #1575 PR 2). Carry verified
7931
- // sources + the coarse strength tag from the extraction validator
7932
- // through to frontmatter so they survive end-to-end.
7933
- ...fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {},
7934
- ...fact.provenance ? { provenance: fact.provenance } : {},
7935
- // #1909: defer the per-fact index flush to the batch save only when
7936
- // fact dedup is on (the batch saver is a no-op otherwise).
7937
- deferHashIndexSave: factDedupEnabled,
7938
- ...factToolScoped ? { toolScoped: true } : {}
7939
- });
8059
+ const factWriteOutcome = await persistUnderFactDedupWindow(
8060
+ targetStorage.dir,
8061
+ raceRecheck(targetStorage, contentHashDedupKey),
8062
+ async () => targetStorage.writeSealedMemory(factWriteEnvelope, {
8063
+ importance,
8064
+ supersedes,
8065
+ links: links.length > 0 ? links : void 0,
8066
+ intentGoal: inferredIntent?.goal,
8067
+ intentActionType: inferredIntent?.actionType,
8068
+ intentEntityTypes: inferredIntent?.entityTypes,
8069
+ memoryKind,
8070
+ ...biTemporal ? { observedAt: biTemporal.observedAt, eventTimeSource: biTemporal.eventTimeSource, ...biTemporal.validUntil ? { invalidAt: biTemporal.validUntil } : {} } : {},
8071
+ contentHashSource: writeCategory === "fact" ? fact.content : void 0,
8072
+ // Faithfulness gate (issue #1576).
8073
+ ...faithfulnessFm ? { faithfulness: faithfulnessFm } : {},
8074
+ ...faithfulnessEnforceStatus ? { status: faithfulnessEnforceStatus } : {},
8075
+ // Claim-level provenance spans (issue #1575 PR 2). Carry verified
8076
+ // sources + the coarse strength tag from the extraction validator
8077
+ // through to frontmatter so they survive end-to-end.
8078
+ ...fact.sources && fact.sources.length > 0 ? { sources: fact.sources } : {},
8079
+ ...fact.provenance ? { provenance: fact.provenance } : {},
8080
+ // PR #2016: never defer inside the commit window (chunked-path
8081
+ // rule): a peer loading an authoritative index after the release
8082
+ // must see this hash, or its recheck misses and duplicates it.
8083
+ deferHashIndexSave: false,
8084
+ ...factToolScoped ? { toolScoped: true } : {}
8085
+ })
8086
+ ).catch(finalizeOnWindowFailure);
8087
+ if (factWriteOutcome.suppressed) {
8088
+ await backfillDuplicateTemporalBounds();
8089
+ log.info(`dedup: raced duplicate suppressed in fact-dedup window for storage ${targetStorage.dir}`);
8090
+ dedupedCount++;
8091
+ continue;
8092
+ }
8093
+ const factWrite = factWriteOutcome.result;
7940
8094
  const memoryId = factWrite.id;
7941
8095
  const tombstoneBlocked = factWrite.tombstoneBlocked;
7942
8096
  const postWriteGuard = faithfulnessEnforceStatus === "pending_review" || tombstoneBlocked;
@@ -8226,8 +8380,7 @@ ${q.context ?? ""}`], entityScreenOn, entityScreenProfile);
8226
8380
  log.info(
8227
8381
  `persisted: ${facts.length - dedupedCount - importanceGatedCount - judgeGatedCount - redactionGatedCount - semanticMergedCount} facts${dedupSuffix}${gatedSuffix}${judgeSuffix}${redactionSuffix}, ${entities.length} entities, ${questions.length} questions, ${profileUpdates.length} profile updates`
8228
8382
  );
8229
- this.deps.setLastPersistExtractionPendingReviewIds(pendingReviewPersistedIds);
8230
- return { persistedIds, memoryPathById };
8383
+ return { persistedIds, memoryPathById, deferredCount, pendingReviewIds: pendingReviewPersistedIds };
8231
8384
  }
8232
8385
  };
8233
8386
 
@@ -8252,7 +8405,7 @@ async function drainExtractionAndShutdownDependencyPropagation(extractionQueue,
8252
8405
  // src/orchestration/dependency-propagation-delivery.ts
8253
8406
  import { randomUUID } from "crypto";
8254
8407
  import { readFile as readFile4, unlink } from "fs/promises";
8255
- import path7 from "path";
8408
+ import path8 from "path";
8256
8409
 
8257
8410
  // src/orchestration/dependency-propagation-recovery-replay.ts
8258
8411
  import { createHash as createHash4 } from "crypto";
@@ -8935,13 +9088,13 @@ var DependencyPropagationDelivery = class {
8935
9088
  try {
8936
9089
  const job = validateJob(JSON.parse(await this.readQueueFile(filePath)), status);
8937
9090
  if (!job) {
8938
- log.warn(`dependency propagation ignored invalid job file ${path7.basename(filePath)}`);
9091
+ log.warn(`dependency propagation ignored invalid job file ${path8.basename(filePath)}`);
8939
9092
  continue;
8940
9093
  }
8941
9094
  entries.push({ job, filePath });
8942
9095
  } catch (error) {
8943
9096
  if (error instanceof SyntaxError || isNotFound(error)) {
8944
- log.warn(`dependency propagation ignored unreadable job file ${path7.basename(filePath)}: ${error}`);
9097
+ log.warn(`dependency propagation ignored unreadable job file ${path8.basename(filePath)}: ${error}`);
8945
9098
  continue;
8946
9099
  }
8947
9100
  throw error;
@@ -9012,7 +9165,7 @@ var DependencyPropagationDelivery = class {
9012
9165
  await this.writeQueueJob(targetPath, next);
9013
9166
  const terminal = status === "completed" || status === "dead_letter" || status === "canceled";
9014
9167
  for (const entry of entries) {
9015
- if (path7.resolve(entry.filePath) === path7.resolve(targetPath)) continue;
9168
+ if (path8.resolve(entry.filePath) === path8.resolve(targetPath)) continue;
9016
9169
  await unlink(entry.filePath).catch((error) => {
9017
9170
  if (isNotFound(error)) return;
9018
9171
  if (terminal) {
@@ -9076,7 +9229,7 @@ var DependencyPropagationDelivery = class {
9076
9229
  allowMissingDirectory: true
9077
9230
  });
9078
9231
  for (const filePath of files) {
9079
- if (path7.basename(filePath, ".json") !== jobId) continue;
9232
+ if (path8.basename(filePath, ".json") !== jobId) continue;
9080
9233
  try {
9081
9234
  await unlink(filePath);
9082
9235
  } catch (error) {
@@ -9277,11 +9430,11 @@ function createDependencyPropagationReplayReconciliation(host) {
9277
9430
  // src/orchestration/recall-internal.ts
9278
9431
  import { createHash as createHash6 } from "crypto";
9279
9432
  import { readFile as readFile5, stat, unlink as unlink2 } from "fs/promises";
9280
- import path12 from "path";
9433
+ import path13 from "path";
9281
9434
 
9282
9435
  // src/orchestration/graph-path-state-loader.ts
9283
9436
  import { lstat, opendir, realpath } from "fs/promises";
9284
- import path8 from "path";
9437
+ import path9 from "path";
9285
9438
  function isArchivePathIndexUnavailable(index) {
9286
9439
  return "unavailable" in index;
9287
9440
  }
@@ -9300,11 +9453,11 @@ var GraphPathStateLoader = class {
9300
9453
  openArchiveDirectory = opendir;
9301
9454
  async readNode(storage, nodeId, deadlineAtMs, allowArchiveLookup) {
9302
9455
  if (typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) return null;
9303
- const configuredStorageRoot = path8.resolve(storage.dir);
9456
+ const configuredStorageRoot = path9.resolve(storage.dir);
9304
9457
  const storageRoot = await realpath(configuredStorageRoot).catch(() => null);
9305
9458
  if (!storageRoot || storageRoot !== configuredStorageRoot) return null;
9306
- const logicalId = path8.basename(nodeId, path8.extname(nodeId));
9307
- const directRelativePaths = [nodeId, path8.join("cold", nodeId)];
9459
+ const logicalId = path9.basename(nodeId, path9.extname(nodeId));
9460
+ const directRelativePaths = [nodeId, path9.join("cold", nodeId)];
9308
9461
  let inactiveDirectMemory = null;
9309
9462
  for (const relativePath of directRelativePaths) {
9310
9463
  const safePath = await this.resolveContainedPath(storageRoot, relativePath);
@@ -9327,7 +9480,7 @@ var GraphPathStateLoader = class {
9327
9480
  if (!archiveIndex || isArchivePathIndexUnavailable(archiveIndex) || typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) {
9328
9481
  return null;
9329
9482
  }
9330
- const archivePaths = archiveIndex.pathsByBasename.get(path8.basename(nodeId)) ?? [];
9483
+ const archivePaths = archiveIndex.pathsByBasename.get(path9.basename(nodeId)) ?? [];
9331
9484
  for (const archivePath of archivePaths) {
9332
9485
  if (typeof deadlineAtMs === "number" && Date.now() >= deadlineAtMs) return null;
9333
9486
  const memory = await storage.readMemoryByPath(archivePath);
@@ -9337,17 +9490,17 @@ var GraphPathStateLoader = class {
9337
9490
  return null;
9338
9491
  }
9339
9492
  async resolveContainedPath(storageRoot, relativePath) {
9340
- if (path8.isAbsolute(relativePath)) return null;
9493
+ if (path9.isAbsolute(relativePath)) return null;
9341
9494
  const rawSegments = relativePath.replace(/\\/g, "/").split("/");
9342
9495
  if (rawSegments.includes("..")) return null;
9343
- const candidate = path8.resolve(storageRoot, relativePath);
9344
- const lexicalRelative = path8.relative(storageRoot, candidate);
9345
- if (lexicalRelative.length > 0 && (lexicalRelative.startsWith("..") || path8.isAbsolute(lexicalRelative))) {
9496
+ const candidate = path9.resolve(storageRoot, relativePath);
9497
+ const lexicalRelative = path9.relative(storageRoot, candidate);
9498
+ if (lexicalRelative.length > 0 && (lexicalRelative.startsWith("..") || path9.isAbsolute(lexicalRelative))) {
9346
9499
  return null;
9347
9500
  }
9348
9501
  const canonical = await realpath(candidate).catch(() => candidate);
9349
- const canonicalRelative = path8.relative(storageRoot, canonical);
9350
- if (canonicalRelative.length > 0 && (canonicalRelative.startsWith("..") || path8.isAbsolute(canonicalRelative))) {
9502
+ const canonicalRelative = path9.relative(storageRoot, canonical);
9503
+ if (canonicalRelative.length > 0 && (canonicalRelative.startsWith("..") || path9.isAbsolute(canonicalRelative))) {
9351
9504
  return null;
9352
9505
  }
9353
9506
  return canonical;
@@ -9420,7 +9573,7 @@ var GraphPathStateLoader = class {
9420
9573
  }
9421
9574
  async buildArchivePathIndex(storageRoot, version) {
9422
9575
  const pathsByBasename = /* @__PURE__ */ new Map();
9423
- const archiveRoot = path8.join(storageRoot, "archive");
9576
+ const archiveRoot = path9.join(storageRoot, "archive");
9424
9577
  let archiveRootStatus;
9425
9578
  try {
9426
9579
  archiveRootStatus = await this.archiveLstat(archiveRoot);
@@ -9438,8 +9591,8 @@ var GraphPathStateLoader = class {
9438
9591
  if (isArchiveScanAbsenceError(error)) return { version, pathsByBasename };
9439
9592
  return null;
9440
9593
  }
9441
- const archiveRelative = path8.relative(storageRoot, canonicalArchiveRoot);
9442
- if (archiveRelative.length > 0 && (archiveRelative.startsWith("..") || path8.isAbsolute(archiveRelative))) {
9594
+ const archiveRelative = path9.relative(storageRoot, canonicalArchiveRoot);
9595
+ if (archiveRelative.length > 0 && (archiveRelative.startsWith("..") || path9.isAbsolute(archiveRelative))) {
9443
9596
  return { version, pathsByBasename };
9444
9597
  }
9445
9598
  const pending = [canonicalArchiveRoot];
@@ -9465,8 +9618,8 @@ var GraphPathStateLoader = class {
9465
9618
  if (isArchiveScanAbsenceError(error)) continue;
9466
9619
  return null;
9467
9620
  }
9468
- const currentRelative = path8.relative(storageRoot, canonicalCurrent);
9469
- if (currentRelative.length > 0 && (currentRelative.startsWith("..") || path8.isAbsolute(currentRelative))) {
9621
+ const currentRelative = path9.relative(storageRoot, canonicalCurrent);
9622
+ if (currentRelative.length > 0 && (currentRelative.startsWith("..") || path9.isAbsolute(currentRelative))) {
9470
9623
  continue;
9471
9624
  }
9472
9625
  let directory;
@@ -9483,7 +9636,7 @@ var GraphPathStateLoader = class {
9483
9636
  return { version, unavailable: "oversized" };
9484
9637
  }
9485
9638
  if (entry.isSymbolicLink()) continue;
9486
- const entryPath = path8.join(canonicalCurrent, entry.name);
9639
+ const entryPath = path9.join(canonicalCurrent, entry.name);
9487
9640
  if (entry.isDirectory()) {
9488
9641
  pending.push(entryPath);
9489
9642
  continue;
@@ -9499,8 +9652,8 @@ var GraphPathStateLoader = class {
9499
9652
  if (isArchiveScanAbsenceError(error)) continue;
9500
9653
  return null;
9501
9654
  }
9502
- const relative = path8.relative(storageRoot, canonical);
9503
- if (relative.length > 0 && (relative.startsWith("..") || path8.isAbsolute(relative))) {
9655
+ const relative = path9.relative(storageRoot, canonical);
9656
+ if (relative.length > 0 && (relative.startsWith("..") || path9.isAbsolute(relative))) {
9504
9657
  continue;
9505
9658
  }
9506
9659
  const paths = pathsByBasename.get(entry.name);
@@ -9526,7 +9679,7 @@ var GraphPathStateLoader = class {
9526
9679
  // src/orchestration/graph-recall-coordinator.ts
9527
9680
  import { createHash as createHash5 } from "crypto";
9528
9681
  import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
9529
- import path9 from "path";
9682
+ import path10 from "path";
9530
9683
  function mergeGraphExpandedResults(primary, expanded) {
9531
9684
  const mergedByNamespaceAndPath = /* @__PURE__ */ new Map();
9532
9685
  for (const item of [...primary, ...expanded]) {
@@ -9543,11 +9696,11 @@ function mergeGraphExpandedResults(primary, expanded) {
9543
9696
  return Array.from(mergedByNamespaceAndPath.values());
9544
9697
  }
9545
9698
  function graphPathRelativeToStorage(storageDir, candidatePath) {
9546
- const absolutePath = path9.isAbsolute(candidatePath) ? candidatePath : path9.resolve(storageDir, candidatePath);
9547
- const rel = path9.relative(storageDir, absolutePath);
9699
+ const absolutePath = path10.isAbsolute(candidatePath) ? candidatePath : path10.resolve(storageDir, candidatePath);
9700
+ const rel = path10.relative(storageDir, absolutePath);
9548
9701
  if (!rel || rel === ".") return null;
9549
9702
  if (rel.startsWith("..")) return null;
9550
- return rel.split(path9.sep).join("/");
9703
+ return rel.split(path10.sep).join("/");
9551
9704
  }
9552
9705
  function normalizeGraphActivationScore(score) {
9553
9706
  const bounded = Number.isFinite(score) && score > 0 ? score : 0;
@@ -9647,7 +9800,7 @@ var GraphRecallCoordinator = class {
9647
9800
  resolvedPath = resolvedCold.result.path;
9648
9801
  resolvedResult = resolvedCold.result;
9649
9802
  }
9650
- if (!path9.isAbsolute(resolvedPath)) {
9803
+ if (!path10.isAbsolute(resolvedPath)) {
9651
9804
  resolvedAmbiguousSeeds.set(result.path, null);
9652
9805
  return null;
9653
9806
  }
@@ -9672,7 +9825,7 @@ var GraphRecallCoordinator = class {
9672
9825
  }
9673
9826
  continue;
9674
9827
  }
9675
- if (path9.isAbsolute(result.path)) {
9828
+ if (path10.isAbsolute(result.path)) {
9676
9829
  const resolved = await resolveAmbiguousSeedOwner(result, null);
9677
9830
  if (resolved) {
9678
9831
  addResultForNamespace(resolved.namespace, resolved.result);
@@ -9718,7 +9871,7 @@ var GraphRecallCoordinator = class {
9718
9871
  0
9719
9872
  );
9720
9873
  seedPaths.push(
9721
- ...seedRelativePaths.map((rel) => path9.join(storage.dir, rel))
9874
+ ...seedRelativePaths.map((rel) => path10.join(storage.dir, rel))
9722
9875
  );
9723
9876
  const seedSet = new Set(seedRelativePaths);
9724
9877
  const nodeMemoryCache = /* @__PURE__ */ new Map();
@@ -9773,7 +9926,7 @@ var GraphRecallCoordinator = class {
9773
9926
  path: memory.path,
9774
9927
  score,
9775
9928
  namespace,
9776
- seed: path9.resolve(storage.dir, candidate.seed),
9929
+ seed: path10.resolve(storage.dir, candidate.seed),
9777
9930
  hopDepth: candidate.hopDepth,
9778
9931
  decayedWeight: candidate.decayedWeight,
9779
9932
  graphType: candidate.graphType,
@@ -9805,7 +9958,7 @@ var GraphRecallCoordinator = class {
9805
9958
  add(memory.frontmatter.id);
9806
9959
  if (relativePath) {
9807
9960
  add(relativePath);
9808
- if (relativePath.endsWith(".md")) add(path9.basename(relativePath, ".md"));
9961
+ if (relativePath.endsWith(".md")) add(path10.basename(relativePath, ".md"));
9809
9962
  }
9810
9963
  return state;
9811
9964
  };
@@ -9852,7 +10005,7 @@ var GraphRecallCoordinator = class {
9852
10005
  path: memory.path,
9853
10006
  score,
9854
10007
  namespace,
9855
- seed: path9.resolve(storage.dir, candidate.seed),
10008
+ seed: path10.resolve(storage.dir, candidate.seed),
9856
10009
  hopDepth: candidate.hopDepth,
9857
10010
  decayedWeight: candidate.decayedWeight,
9858
10011
  graphType: candidate.graphType,
@@ -9895,12 +10048,12 @@ var GraphRecallCoordinator = class {
9895
10048
  }
9896
10049
  async recordLastGraphRecallSnapshot(options) {
9897
10050
  try {
9898
- const snapshotPath = path9.join(
10051
+ const snapshotPath = path10.join(
9899
10052
  options.storage.dir,
9900
10053
  "state",
9901
10054
  "last_graph_recall.json"
9902
10055
  );
9903
- await mkdir3(path9.dirname(snapshotPath), { recursive: true });
10056
+ await mkdir3(path10.dirname(snapshotPath), { recursive: true });
9904
10057
  const now = (/* @__PURE__ */ new Date()).toISOString();
9905
10058
  const totalSeedCount = options.seedPaths.length;
9906
10059
  const totalExpandedCount = options.expandedPaths.length;
@@ -10200,11 +10353,11 @@ async function appendEpisodicContextSection(deps, options) {
10200
10353
  }
10201
10354
 
10202
10355
  // src/orchestration/recall-profile-storage.ts
10203
- import path10 from "path";
10356
+ import path11 from "path";
10204
10357
  function resolveCompositeProfileStorage(options) {
10205
10358
  const { profileStorages, memoryDir } = options;
10206
10359
  const emptyProfileStorage = new Proxy(
10207
- { dir: path10.join(memoryDir, ".empty-scope-profile") },
10360
+ { dir: path11.join(memoryDir, ".empty-scope-profile") },
10208
10361
  {
10209
10362
  get(target, prop) {
10210
10363
  if (prop in target) return Reflect.get(target, prop);
@@ -10352,7 +10505,7 @@ function resolveCompositeProfileStorage(options) {
10352
10505
  }
10353
10506
 
10354
10507
  // src/orchestration/recall-recognition-search.ts
10355
- import path11 from "path";
10508
+ import path12 from "path";
10356
10509
  async function fetchQmdMemoryResultsWithRecognitionSwap(deps, prompt, qmdFetchLimit, qmdHybridFetchLimit, options) {
10357
10510
  if (deps.config.recallRecognitionTier !== true || options.collection || options.namespacesEnabled !== true) {
10358
10511
  return deps.fetchQmdMemoryResultsWithArtifactTopUp(
@@ -10439,7 +10592,7 @@ async function hitsFromIds(namespace, storage, index, ids) {
10439
10592
  for (const [offset, id] of ids.entries()) {
10440
10593
  const absPath = pathsById.get(id)?.[0];
10441
10594
  if (!absPath) continue;
10442
- const rel = path11.relative(storage.dir, absPath).split(path11.sep).join("/");
10595
+ const rel = path12.relative(storage.dir, absPath).split(path12.sep).join("/");
10443
10596
  if (!rel || rel.startsWith("..")) continue;
10444
10597
  hits.push({
10445
10598
  docid: `${namespace}:${rel}`,
@@ -10687,7 +10840,7 @@ var RecallInternalCoordinator = class {
10687
10840
  const graphExpandedResultPaths = /* @__PURE__ */ new Set();
10688
10841
  const graphSourceLabelsForPath = (resultPath) => {
10689
10842
  const labels = [];
10690
- const normalizedPath = resultPath.split(path12.sep).join("/");
10843
+ const normalizedPath = resultPath.split(path13.sep).join("/");
10691
10844
  const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
10692
10845
  if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
10693
10846
  if (graphExpandedResultPaths.has(resultPath))
@@ -12224,11 +12377,11 @@ ${formatted}`;
12224
12377
  if (!resolveRecallAuxiliaryCapabilities(this.deps.config).compactionReset) return null;
12225
12378
  const workspaceDir = compactionWorkspaceDir || this.deps.config.workspaceDir || defaultWorkspaceDir();
12226
12379
  const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
12227
- const signalPath = path12.join(
12380
+ const signalPath = path13.join(
12228
12381
  workspaceDir,
12229
12382
  `.compaction-reset-signal-${safeSessionKey}`
12230
12383
  );
12231
- const bootPath = path12.join(workspaceDir, "BOOT.md");
12384
+ const bootPath = path13.join(workspaceDir, "BOOT.md");
12232
12385
  try {
12233
12386
  const signalStat = await stat(signalPath).catch(() => null);
12234
12387
  if (!signalStat) return null;
@@ -14508,10 +14661,10 @@ ${tmtNode.summary}`
14508
14661
 
14509
14662
  // src/orchestration/recall-search-pipeline.ts
14510
14663
  import { createHash as createHash7 } from "crypto";
14511
- import path14 from "path";
14664
+ import path15 from "path";
14512
14665
 
14513
14666
  // src/orchestration/recall-search-prefilter.ts
14514
- import path13 from "path";
14667
+ import path14 from "path";
14515
14668
  async function fetchActiveArtifactsForNamespace(deps, namespace, prompt, targetCount, options = {}) {
14516
14669
  const storage = await deps.storageRouter.storageFor(namespace);
14517
14670
  let fetchLimit = computeArtifactCandidateFetchLimit(targetCount);
@@ -14640,7 +14793,7 @@ async function searchEmbeddingFallback(deps, query, limit) {
14640
14793
  if (hits.length === 0) return [];
14641
14794
  const results = [];
14642
14795
  for (const hit of hits) {
14643
- const fullPath = path13.isAbsolute(hit.path) ? hit.path : path13.join(deps.config.memoryDir, hit.path);
14796
+ const fullPath = path14.isAbsolute(hit.path) ? hit.path : path14.join(deps.config.memoryDir, hit.path);
14644
14797
  const memory = await deps.storage.readMemoryByPath(fullPath);
14645
14798
  if (!memory) continue;
14646
14799
  results.push({
@@ -15018,7 +15171,7 @@ var RecallSearchPipelineCoordinator = class {
15018
15171
  const storage = await this.deps.storageRouter.storageFor(namespace);
15019
15172
  const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
15020
15173
  if (!storageDir) continue;
15021
- const recallRoot = path14.resolve(storageDir);
15174
+ const recallRoot = path15.resolve(storageDir);
15022
15175
  if (seenRecallRoots.has(recallRoot)) continue;
15023
15176
  seenRecallRoots.add(recallRoot);
15024
15177
  recallRoots.push(recallRoot);
@@ -15042,8 +15195,8 @@ var RecallSearchPipelineCoordinator = class {
15042
15195
  if (resolvedCold) scopedResults.push(resolvedCold.result);
15043
15196
  continue;
15044
15197
  }
15045
- if (path14.isAbsolute(result.path)) {
15046
- if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot, path14.resolve(result.path)))) {
15198
+ if (path15.isAbsolute(result.path)) {
15199
+ if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot, path15.resolve(result.path)))) {
15047
15200
  scopedResults.push(result);
15048
15201
  }
15049
15202
  continue;
@@ -15764,8 +15917,10 @@ var ExtractionDrain = class {
15764
15917
  * persist step ends the host's preemption registration, so the drain registers
15765
15918
  * it again before every later chunk; a fail-closed flush can then abort the
15766
15919
  * next chunk's model request instead of waiting behind the whole window.
15920
+ * `preemptHandle`: the queue task's own preemption slot (per task, so two
15921
+ * concurrent automatic extractions cannot clobber each other's registration).
15767
15922
  */
15768
- async run(turns, runOptions, preemptable = false) {
15923
+ async run(turns, runOptions, preemptable = false, preemptHandle) {
15769
15924
  const budgetChars = this.deps.extractionWindowBudgetChars?.() ?? Number.POSITIVE_INFINITY;
15770
15925
  const chunkable = runOptions.clearBufferAfterExtraction && !runOptions.forceExtractionAttempt && !runOptions.failOnExtractionFailure && !turns.some((turn) => turn.acceptedCapture === true) && Number.isFinite(budgetChars) && budgetChars > 0;
15771
15926
  const chunks = chunkable ? chunkExtractionWindow(turns, budgetChars) : [];
@@ -15790,7 +15945,7 @@ var ExtractionDrain = class {
15790
15945
  if (preemptable && position > 0) {
15791
15946
  const local = new AbortController();
15792
15947
  preempt = local;
15793
- this.deps.extractionQueueCoordinator.beginPreemptable(() => local.abort(preemptedExtractionError()));
15948
+ preemptHandle?.arm(() => local.abort(preemptedExtractionError()));
15794
15949
  chunkOptions = {
15795
15950
  ...chunkOptions,
15796
15951
  abortSignal: runOptions.abortSignal ? AbortSignal.any([runOptions.abortSignal, local.signal]) : local.signal
@@ -15852,8 +16007,8 @@ var ExtractionDrain = class {
15852
16007
  const reason = `dropped after ${dropAfter} repeated extraction failures (last result: status=${result.status} reason=${result.reason ?? "n/a"})`;
15853
16008
  try {
15854
16009
  const storage = await this.deps.getStorage();
15855
- const path41 = await storage.saveDroppedExtractionChunk(bufferKey, reason, chunk);
15856
- log.warn(`buffer[${bufferKey}]: dropping ${chunk.length} turns \u2014 ${reason}; copy saved to ${path41}`);
16010
+ const path42 = await storage.saveDroppedExtractionChunk(bufferKey, reason, chunk);
16011
+ log.warn(`buffer[${bufferKey}]: dropping ${chunk.length} turns \u2014 ${reason}; copy saved to ${path42}`);
15857
16012
  } catch (err) {
15858
16013
  log.warn(
15859
16014
  `buffer[${bufferKey}]: could not save the dropped-chunk recovery copy; keeping the chunk in the buffer: ${describeError(err)}`
@@ -16421,8 +16576,8 @@ var TurnIngestionCoordinator = class {
16421
16576
  }
16422
16577
  if (settled) return;
16423
16578
  const preemptable = options.preemptable === true && options.preemptRunning !== true;
16424
- const accepted = this.deps.extractionQueueCoordinator.enqueue(async () => {
16425
- await this.deps.extractionQueueCoordinator.runPreemptable(preemptable, options.abortSignal, async (abortSignal) => {
16579
+ const accepted = this.deps.extractionQueueCoordinator.enqueue(async (preemptHandle) => {
16580
+ await this.deps.extractionQueueCoordinator.runPreemptable(preemptHandle, preemptable, options.abortSignal, async (abortSignal) => {
16426
16581
  if (settled) return;
16427
16582
  if (typeof extractionDeadlineMs === "number" && extractionDeadlineMs <= Date.now()) {
16428
16583
  settleTask(new ExtractionDeadlineError("queue_wait"));
@@ -16528,14 +16683,14 @@ var TurnIngestionCoordinator = class {
16528
16683
  deadlineMs: extractionDeadlineMs,
16529
16684
  bufferKey,
16530
16685
  onDurableCommit: options.onDurableCommit,
16531
- onBeforePersist: () => this.deps.extractionQueueCoordinator.endPreemptable(),
16686
+ onBeforePersist: () => preemptHandle?.disarm(),
16532
16687
  abortSignal,
16533
16688
  failOnExtractionFailure: options.failOnExtractionFailure === true,
16534
16689
  writeNamespaceOverride: options.writeNamespaceOverride,
16535
16690
  principalOverride: options.principalOverride,
16536
16691
  scopeProfileWritePlan: effectiveScopePlan,
16537
16692
  forceExtractionAttempt: options.forceExtractionAttempt === true
16538
- }, preemptable);
16693
+ }, preemptable, preemptHandle);
16539
16694
  settleTask(void 0, result);
16540
16695
  } catch (err) {
16541
16696
  const reason2 = abortSignal.reason;
@@ -16545,7 +16700,7 @@ var TurnIngestionCoordinator = class {
16545
16700
  }
16546
16701
  }
16547
16702
  });
16548
- }, { front: options.preemptRunning === true });
16703
+ }, { front: options.preemptRunning === true, key: bufferKey });
16549
16704
  if (!accepted) {
16550
16705
  settleTask(new Error("extraction queue is stopped"));
16551
16706
  return;
@@ -16624,7 +16779,7 @@ var TurnIngestionCoordinator = class {
16624
16779
 
16625
16780
  // src/orchestration/recall-introspection.ts
16626
16781
  import { mkdir as mkdir5, readFile as readFile7, writeFile as writeFile5 } from "fs/promises";
16627
- import path16 from "path";
16782
+ import path17 from "path";
16628
16783
 
16629
16784
  // src/taxonomy/default-taxonomy.ts
16630
16785
  var DEFAULT_TAXONOMY = {
@@ -16747,7 +16902,7 @@ function generateResolverDocument(taxonomy) {
16747
16902
 
16748
16903
  // src/taxonomy/taxonomy-loader.ts
16749
16904
  import { readFile as readFile6, mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
16750
- import path15 from "path";
16905
+ import path16 from "path";
16751
16906
  var TAXONOMY_DIR = ".taxonomy";
16752
16907
  var TAXONOMY_FILE = "taxonomy.json";
16753
16908
  var MAX_SLUG_LENGTH = 32;
@@ -16845,7 +17000,7 @@ function validateTaxonomy(taxonomy) {
16845
17000
  }
16846
17001
  }
16847
17002
  async function loadTaxonomy(memoryDir) {
16848
- const taxonomyPath = path15.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
17003
+ const taxonomyPath = path16.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
16849
17004
  let raw;
16850
17005
  try {
16851
17006
  raw = await readFile6(taxonomyPath, "utf-8");
@@ -16895,16 +17050,16 @@ async function loadTaxonomy(memoryDir) {
16895
17050
  }
16896
17051
  async function saveTaxonomy(memoryDir, taxonomy) {
16897
17052
  validateTaxonomy(taxonomy);
16898
- const dir = path15.join(memoryDir, TAXONOMY_DIR);
17053
+ const dir = path16.join(memoryDir, TAXONOMY_DIR);
16899
17054
  await mkdir4(dir, { recursive: true });
16900
- const filePath = path15.join(dir, TAXONOMY_FILE);
17055
+ const filePath = path16.join(dir, TAXONOMY_FILE);
16901
17056
  await writeFile4(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
16902
17057
  }
16903
17058
  function getTaxonomyDir(memoryDir) {
16904
- return path15.join(memoryDir, TAXONOMY_DIR);
17059
+ return path16.join(memoryDir, TAXONOMY_DIR);
16905
17060
  }
16906
17061
  function getTaxonomyFilePath(memoryDir) {
16907
- return path15.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
17062
+ return path16.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
16908
17063
  }
16909
17064
 
16910
17065
  // src/orchestration/recall-introspection.ts
@@ -16928,7 +17083,7 @@ var RecallIntrospectionCoordinator = class {
16928
17083
  }
16929
17084
  async getLastGraphRecallSnapshot(namespace) {
16930
17085
  const storage = await this.deps.getStorage(namespace);
16931
- const snapshotPath = path16.join(
17086
+ const snapshotPath = path17.join(
16932
17087
  storage.dir,
16933
17088
  "state",
16934
17089
  "last_graph_recall.json"
@@ -16967,7 +17122,7 @@ var RecallIntrospectionCoordinator = class {
16967
17122
  }
16968
17123
  async getLastIntentSnapshot(namespace) {
16969
17124
  const storage = await this.deps.getStorage(namespace);
16970
- const snapshotPath = path16.join(storage.dir, "state", "last_intent.json");
17125
+ const snapshotPath = path17.join(storage.dir, "state", "last_intent.json");
16971
17126
  try {
16972
17127
  const raw = await readFile7(snapshotPath, "utf-8");
16973
17128
  const parsed = JSON.parse(raw);
@@ -17000,7 +17155,7 @@ var RecallIntrospectionCoordinator = class {
17000
17155
  }
17001
17156
  async getLastQmdRecallSnapshot(namespace) {
17002
17157
  const storage = await this.deps.getStorage(namespace);
17003
- const snapshotPath = path16.join(
17158
+ const snapshotPath = path17.join(
17004
17159
  storage.dir,
17005
17160
  "state",
17006
17161
  "last_qmd_recall.json"
@@ -17292,12 +17447,12 @@ var RecallIntrospectionCoordinator = class {
17292
17447
  }
17293
17448
  async recordLastIntentSnapshot(options) {
17294
17449
  try {
17295
- const snapshotPath = path16.join(
17450
+ const snapshotPath = path17.join(
17296
17451
  options.storage.dir,
17297
17452
  "state",
17298
17453
  "last_intent.json"
17299
17454
  );
17300
- await mkdir5(path16.dirname(snapshotPath), { recursive: true });
17455
+ await mkdir5(path17.dirname(snapshotPath), { recursive: true });
17301
17456
  await writeFile5(
17302
17457
  snapshotPath,
17303
17458
  JSON.stringify(options.snapshot, null, 2),
@@ -17309,12 +17464,12 @@ var RecallIntrospectionCoordinator = class {
17309
17464
  }
17310
17465
  async recordLastQmdRecallSnapshot(options) {
17311
17466
  try {
17312
- const snapshotPath = path16.join(
17467
+ const snapshotPath = path17.join(
17313
17468
  options.storage.dir,
17314
17469
  "state",
17315
17470
  "last_qmd_recall.json"
17316
17471
  );
17317
- await mkdir5(path16.dirname(snapshotPath), { recursive: true });
17472
+ await mkdir5(path17.dirname(snapshotPath), { recursive: true });
17318
17473
  await writeFile5(
17319
17474
  snapshotPath,
17320
17475
  JSON.stringify(options.snapshot, null, 2),
@@ -17329,8 +17484,8 @@ var RecallIntrospectionCoordinator = class {
17329
17484
  const stateDir = await this.deps.resolveStateDirForNamespace(
17330
17485
  options.namespace
17331
17486
  );
17332
- const snapshotPath = path16.join(stateDir, "last_intent.json");
17333
- await mkdir5(path16.dirname(snapshotPath), { recursive: true });
17487
+ const snapshotPath = path17.join(stateDir, "last_intent.json");
17488
+ await mkdir5(path17.dirname(snapshotPath), { recursive: true });
17334
17489
  await writeFile5(
17335
17490
  snapshotPath,
17336
17491
  JSON.stringify(options.snapshot, null, 2),
@@ -17344,7 +17499,7 @@ var RecallIntrospectionCoordinator = class {
17344
17499
 
17345
17500
  // src/orchestration/orchestrator-init.ts
17346
17501
  import { readdir as readdir2, stat as stat2, unlink as unlink3 } from "fs/promises";
17347
- import path17 from "path";
17502
+ import path18 from "path";
17348
17503
 
17349
17504
  // src/orchestration/startup-collection-checks.ts
17350
17505
  async function startupDiscoveryWithTimeout(discover, configuredFallback, timeoutMs = qmdStartupCollectionCheckTimeoutMs()) {
@@ -17680,7 +17835,7 @@ var OrchestratorInitCoordinator = class {
17680
17835
  const files = await readdir2(wsDir).catch(() => []);
17681
17836
  for (const f of files) {
17682
17837
  if (!f.startsWith(".compaction-reset-signal-")) continue;
17683
- const fp = path17.join(wsDir, f);
17838
+ const fp = path18.join(wsDir, f);
17684
17839
  const s = await stat2(fp).catch(() => null);
17685
17840
  if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
17686
17841
  await unlink3(fp).catch(() => {
@@ -18100,11 +18255,11 @@ var OrchestratorInitCoordinator = class {
18100
18255
  };
18101
18256
 
18102
18257
  // src/orchestration/persistence-index.ts
18103
- import path19 from "path";
18258
+ import path20 from "path";
18104
18259
 
18105
18260
  // src/orchestration/recall-recognition-index.ts
18106
18261
  import { promises as fsp } from "fs";
18107
- import path18 from "path";
18262
+ import path19 from "path";
18108
18263
  import { setTimeout as delay } from "timers/promises";
18109
18264
  var writeChains = /* @__PURE__ */ new Map();
18110
18265
  var LOCK_POLL_MS = 10;
@@ -18155,7 +18310,7 @@ async function withRecognitionIndexLock(memoryDir, op) {
18155
18310
  } catch (error) {
18156
18311
  const code = error?.code;
18157
18312
  if (code === "ENOENT") {
18158
- await fsp.mkdir(path18.dirname(lockDir), { recursive: true }).catch(() => void 0);
18313
+ await fsp.mkdir(path19.dirname(lockDir), { recursive: true }).catch(() => void 0);
18159
18314
  continue;
18160
18315
  }
18161
18316
  if (code !== "EEXIST") throw error;
@@ -18406,7 +18561,7 @@ var PersistenceIndexCoordinator = class {
18406
18561
  const allMems = allMemsForGraph ?? [];
18407
18562
  for (const m of allMems) {
18408
18563
  if (m.frontmatter.entityRef === entityRef) {
18409
- const rel = path19.relative(storage.dir, m.path);
18564
+ const rel = path20.relative(storage.dir, m.path);
18410
18565
  if (rel !== memoryRelPath) entitySiblings.push(rel);
18411
18566
  }
18412
18567
  }
@@ -18602,7 +18757,7 @@ var PersistenceIndexCoordinator = class {
18602
18757
 
18603
18758
  // src/orchestration/workspace-ops.ts
18604
18759
  import { lstat as lstat2, mkdir as mkdir6, readFile as readFile8, readdir as readdir3, realpath as realpath2, writeFile as writeFile6 } from "fs/promises";
18605
- import path20 from "path";
18760
+ import path21 from "path";
18606
18761
 
18607
18762
  // src/maintenance/pattern-reinforcement.ts
18608
18763
  function patternReinforcementKey(content) {
@@ -20506,8 +20661,8 @@ var MeetingsService = class {
20506
20661
  // src/orchestration/workspace-ops.ts
20507
20662
  var MEETINGS_BUILD_DEBOUNCE_MS = 5e3;
20508
20663
  function matchesMemoryPath(candidatePath, requestedPath, memoryDir) {
20509
- const normalizedCandidate = path20.resolve(candidatePath);
20510
- return normalizedCandidate === path20.resolve(requestedPath) || normalizedCandidate === path20.resolve(memoryDir, requestedPath);
20664
+ const normalizedCandidate = path21.resolve(candidatePath);
20665
+ return normalizedCandidate === path21.resolve(requestedPath) || normalizedCandidate === path21.resolve(memoryDir, requestedPath);
20511
20666
  }
20512
20667
  function accessTrackingPathCandidates(storageDir, memoryPath) {
20513
20668
  const candidates = qmdResultPathCandidates(storageDir, memoryPath);
@@ -20515,12 +20670,12 @@ function accessTrackingPathCandidates(storageDir, memoryPath) {
20515
20670
  if (!parts) return candidates;
20516
20671
  candidates.push(
20517
20672
  ...qmdResultPathCandidates(storageDir, parts.relativePath),
20518
- ...qmdResultPathCandidates(path20.join(storageDir, "cold"), parts.relativePath)
20673
+ ...qmdResultPathCandidates(path21.join(storageDir, "cold"), parts.relativePath)
20519
20674
  );
20520
20675
  return [...new Set(candidates)];
20521
20676
  }
20522
20677
  function canonicalMemoryPath(memoryPath, memoryDir) {
20523
- return path20.resolve(path20.isAbsolute(memoryPath) ? memoryPath : path20.resolve(memoryDir, memoryPath));
20678
+ return path21.resolve(path21.isAbsolute(memoryPath) ? memoryPath : path21.resolve(memoryDir, memoryPath));
20524
20679
  }
20525
20680
  var WorkspaceOpsCoordinator = class {
20526
20681
  constructor(deps) {
@@ -20602,15 +20757,15 @@ var WorkspaceOpsCoordinator = class {
20602
20757
  this.deps.lastFileHygieneRunAtMs = now;
20603
20758
  if (hygiene.rotateEnabled) {
20604
20759
  for (const rel of hygiene.rotatePaths) {
20605
- const abs = path20.isAbsolute(rel) ? rel : path20.join(this.deps.config.workspaceDir, rel);
20760
+ const abs = path21.isAbsolute(rel) ? rel : path21.join(this.deps.config.workspaceDir, rel);
20606
20761
  try {
20607
20762
  const raw = await readFile8(abs, "utf-8");
20608
20763
  if (raw.length > hygiene.rotateMaxBytes) {
20609
- const archiveDir = path20.join(
20764
+ const archiveDir = path21.join(
20610
20765
  this.deps.config.workspaceDir,
20611
20766
  hygiene.archiveDir
20612
20767
  );
20613
- const base = path20.basename(abs);
20768
+ const base = path21.basename(abs);
20614
20769
  const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
20615
20770
  const { newContent } = await rotateMarkdownFileToArchive({
20616
20771
  filePath: abs,
@@ -20635,8 +20790,8 @@ var WorkspaceOpsCoordinator = class {
20635
20790
  log.warn(w.message);
20636
20791
  }
20637
20792
  if (hygiene.warningsLogEnabled && warnings.length > 0) {
20638
- const fp = path20.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
20639
- await mkdir6(path20.dirname(fp), { recursive: true });
20793
+ const fp = path21.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
20794
+ await mkdir6(path21.dirname(fp), { recursive: true });
20640
20795
  const stamp = (/* @__PURE__ */ new Date()).toISOString();
20641
20796
  const block = `
20642
20797
 
@@ -20676,7 +20831,7 @@ var WorkspaceOpsCoordinator = class {
20676
20831
  for (const categoryDir of RECALL_FALLBACK_DIRS) {
20677
20832
  if (memoryRootReal === null) break;
20678
20833
  for (const date of datesToScan) {
20679
- const dateDir = path20.join(storage.dir, categoryDir, date);
20834
+ const dateDir = path21.join(storage.dir, categoryDir, date);
20680
20835
  try {
20681
20836
  const dirStat = await lstat2(dateDir);
20682
20837
  if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
@@ -20685,7 +20840,7 @@ var WorkspaceOpsCoordinator = class {
20685
20840
  for (const entry of entries) {
20686
20841
  if (entry.isSymbolicLink()) continue;
20687
20842
  if (!entry.name.endsWith(".md")) continue;
20688
- const fullPath = path20.join(dateDir, entry.name);
20843
+ const fullPath = path21.join(dateDir, entry.name);
20689
20844
  try {
20690
20845
  assertPathInsideRoot(memoryRootReal, await realpath2(fullPath), fullPath);
20691
20846
  const memory = await storage.readMemoryByPath(fullPath);
@@ -20707,13 +20862,13 @@ var WorkspaceOpsCoordinator = class {
20707
20862
  return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
20708
20863
  });
20709
20864
  const hourlySummaries = [];
20710
- const hourlyBaseDir = path20.join(storage.dir, "summaries", "hourly");
20865
+ const hourlyBaseDir = path21.join(storage.dir, "summaries", "hourly");
20711
20866
  try {
20712
20867
  const sessionKeys = await readdir3(hourlyBaseDir, { withFileTypes: true });
20713
20868
  for (const sk of sessionKeys) {
20714
20869
  if (!sk.isDirectory()) continue;
20715
20870
  for (const date of datesToScan) {
20716
- const summaryFile = path20.join(hourlyBaseDir, sk.name, `${date}.md`);
20871
+ const summaryFile = path21.join(hourlyBaseDir, sk.name, `${date}.md`);
20717
20872
  try {
20718
20873
  const raw = await readFile8(summaryFile, "utf-8");
20719
20874
  const filtered = filterHourlySummaryMarkdownForLocalDay(
@@ -21190,18 +21345,18 @@ ${reflectionsContent.trim()}
21190
21345
  // src/orchestration/namespace-read-fanout.ts
21191
21346
  import { existsSync, readFileSync } from "fs";
21192
21347
  import { stat as stat3 } from "fs/promises";
21193
- import path22 from "path";
21348
+ import path23 from "path";
21194
21349
 
21195
21350
  // src/orchestration/orchestrator-namespace-scope.ts
21196
- import path21 from "path";
21351
+ import path22 from "path";
21197
21352
  function computeSemanticDedupScope(targetStorage, config) {
21198
21353
  if (!resolveNamespaceCapabilities(config).namespaces) return {};
21199
- const memoryDir = path21.resolve(config.memoryDir);
21200
- const storageDir = path21.resolve(targetStorage.dir);
21354
+ const memoryDir = path22.resolve(config.memoryDir);
21355
+ const storageDir = path22.resolve(targetStorage.dir);
21201
21356
  if (storageDir === memoryDir) {
21202
21357
  return { pathExcludePrefixes: ["namespaces/"] };
21203
21358
  }
21204
- let rel = path21.relative(memoryDir, storageDir);
21359
+ let rel = path22.relative(memoryDir, storageDir);
21205
21360
  if (!rel || rel.startsWith("..")) {
21206
21361
  log.debug(
21207
21362
  `semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
@@ -21254,7 +21409,7 @@ var NamespaceReadFanoutCoordinator = class {
21254
21409
  loadNamespaceStorageDirHintsFromCatalog() {
21255
21410
  if (this.deps.namespaceStorageDirHintsLoaded || !this.deps.namespaceCatalog.enabled) return;
21256
21411
  this.deps.namespaceStorageDirHintsLoaded = true;
21257
- const catalogPath = path22.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
21412
+ const catalogPath = path23.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
21258
21413
  if (!existsSync(catalogPath)) return;
21259
21414
  let body;
21260
21415
  try {
@@ -21291,7 +21446,7 @@ var NamespaceReadFanoutCoordinator = class {
21291
21446
  if (!this.deps.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
21292
21447
  continue;
21293
21448
  }
21294
- const resolvedStorageDir = path22.resolve(record.storageDir);
21449
+ const resolvedStorageDir = path23.resolve(record.storageDir);
21295
21450
  const current = preferredByStorageDir.get(resolvedStorageDir);
21296
21451
  preferredByStorageDir.set(
21297
21452
  resolvedStorageDir,
@@ -21476,12 +21631,12 @@ var NamespaceReadFanoutCoordinator = class {
21476
21631
  }
21477
21632
  async resolveStateDirForNamespace(namespace) {
21478
21633
  if (!resolveNamespaceCapabilities(this.deps.config).namespaces) {
21479
- return path22.join(this.deps.config.memoryDir, "state");
21634
+ return path23.join(this.deps.config.memoryDir, "state");
21480
21635
  }
21481
21636
  if (namespace !== this.deps.config.defaultNamespace) {
21482
- return path22.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
21637
+ return path23.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
21483
21638
  }
21484
- const candidate = path22.join(
21639
+ const candidate = path23.join(
21485
21640
  this.deps.config.memoryDir,
21486
21641
  "namespaces",
21487
21642
  this.deps.config.defaultNamespace
@@ -21489,11 +21644,11 @@ var NamespaceReadFanoutCoordinator = class {
21489
21644
  try {
21490
21645
  const candidateStat = await stat3(candidate);
21491
21646
  if (candidateStat.isDirectory()) {
21492
- return path22.join(candidate, "state");
21647
+ return path23.join(candidate, "state");
21493
21648
  }
21494
21649
  } catch {
21495
21650
  }
21496
- return path22.join(this.deps.config.memoryDir, "state");
21651
+ return path23.join(this.deps.config.memoryDir, "state");
21497
21652
  }
21498
21653
  namespaceFromPath(p) {
21499
21654
  if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return this.deps.config.defaultNamespace;
@@ -21874,19 +22029,6 @@ var Orchestrator = class {
21874
22029
  * (rule 11) — these hang off the orchestrator instance.
21875
22030
  */
21876
22031
  faithfulnessCounters = createFaithfulnessCounters();
21877
- /**
21878
- * Side-channel: number of facts deferred in the most recent
21879
- * `persistExtraction` call (issue #562, PR 2). The caller reads this after
21880
- * `persistExtraction` returns to decide whether to retain buffer turns for
21881
- * the next extraction pass. Not part of the return signature because many
21882
- * callers already destructure `persistedIds` by position.
21883
- */
21884
- lastPersistExtractionDeferredCount = 0;
21885
- /**
21886
- * Side-channel (#1635): pending_review persisted ids from the last
21887
- * persistExtraction; runExtraction excludes them from the thread episode set.
21888
- */
21889
- lastPersistExtractionPendingReviewIds = [];
21890
22032
  _fastGatewayLlm;
21891
22033
  get fastGatewayLlm() {
21892
22034
  return this._fastGatewayLlm;
@@ -21986,7 +22128,7 @@ var Orchestrator = class {
21986
22128
  if (this.destroyed) throw new Error("orchestrator has been destroyed");
21987
22129
  if (!this._dependencyPropagationDelivery) {
21988
22130
  this._dependencyPropagationDelivery = new DependencyPropagationDelivery({
21989
- queueRoot: path23.join(this.config.memoryDir, "state", "dependency-propagation"),
22131
+ queueRoot: path24.join(this.config.memoryDir, "state", "dependency-propagation"),
21990
22132
  config: this.config,
21991
22133
  extraction: this.extraction,
21992
22134
  getStorage: (namespace) => this.getStorage(namespace),
@@ -22014,11 +22156,10 @@ var Orchestrator = class {
22014
22156
  getCodingContextForSession: (sessionKey) => this.getCodingContextForSession(sessionKey),
22015
22157
  applyCodingNamespaceOverlay: (sessionKey, namespace) => this.applyCodingNamespaceOverlay(sessionKey, namespace),
22016
22158
  boxBuilderFor: (storage) => this.boxBuilderFor(storage),
22017
- appendPersistedThreadEpisodes: (threadId, ids) => this.appendPersistedThreadEpisodes(threadId, ids),
22159
+ appendPersistedThreadEpisodes: (threadId, ids, pendingReviewIds) => this.appendPersistedThreadEpisodes(threadId, ids, pendingReviewIds),
22018
22160
  maybeScheduleConsolidation: (nonZero) => this.maybeScheduleConsolidation(nonZero),
22019
22161
  requestQmdMaintenance: () => this.requestQmdMaintenance(),
22020
22162
  runTierMigrationCycle: (storage, trigger, options) => this.runTierMigrationCycle(storage, trigger, options),
22021
- getLastPersistExtractionDeferredCount: () => this.lastPersistExtractionDeferredCount,
22022
22163
  recordProcessedExtractionFingerprint: (storage, fingerprint, preloadedMeta) => this.recordProcessedExtractionFingerprint(storage, fingerprint, preloadedMeta)
22023
22164
  });
22024
22165
  }
@@ -22067,12 +22208,6 @@ var Orchestrator = class {
22067
22208
  getJudgeDeferCounts: () => this.judgeDeferCounts,
22068
22209
  getFaithfulnessCounters: () => this.faithfulnessCounters,
22069
22210
  getEmbeddingFallback: () => this.embeddingFallback,
22070
- setLastPersistExtractionDeferredCount: (v) => {
22071
- this.lastPersistExtractionDeferredCount = v;
22072
- },
22073
- setLastPersistExtractionPendingReviewIds: (ids) => {
22074
- this.lastPersistExtractionPendingReviewIds = ids;
22075
- },
22076
22211
  addContentHashDedup: (targetStorage, content) => this.addContentHashDedup(targetStorage, content),
22077
22212
  hasContentHashDedup: (targetStorage, content) => this.hasContentHashDedup(targetStorage, content),
22078
22213
  backfillTemporalBoundsOnDedupHit: (targetStorage, dedupContent, bounds, entityRef, sourceConnector) => this.backfillTemporalBoundsOnDedupHit(targetStorage, dedupContent, bounds, entityRef, sourceConnector),
@@ -22344,7 +22479,7 @@ var Orchestrator = class {
22344
22479
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
22345
22480
  if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
22346
22481
  if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
22347
- const resolvedStorageDir = path23.resolve(storageDir);
22482
+ const resolvedStorageDir = path24.resolve(storageDir);
22348
22483
  let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
22349
22484
  if (!hints) {
22350
22485
  hints = /* @__PURE__ */ new Set();
@@ -22355,21 +22490,21 @@ var Orchestrator = class {
22355
22490
  storageDirMatchesNamespaceHint(namespace, storageDir) {
22356
22491
  const ns = normalizeNamespaceIdentity(namespace);
22357
22492
  if (!ns) return false;
22358
- const resolvedStorageDir = path23.resolve(storageDir);
22359
- const resolvedMemoryDir = path23.resolve(this.config.memoryDir);
22493
+ const resolvedStorageDir = path24.resolve(storageDir);
22494
+ const resolvedMemoryDir = path24.resolve(this.config.memoryDir);
22360
22495
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
22361
22496
  if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
22362
- const resolvedNamespacesDir = path23.join(resolvedMemoryDir, "namespaces");
22497
+ const resolvedNamespacesDir = path24.join(resolvedMemoryDir, "namespaces");
22363
22498
  if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
22364
- const rawRoot = path23.resolve(resolvedNamespacesDir, ns);
22365
- const tokenRoot = path23.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
22499
+ const rawRoot = path24.resolve(resolvedNamespacesDir, ns);
22500
+ const tokenRoot = path24.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
22366
22501
  return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
22367
22502
  }
22368
22503
  namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
22369
- if (resolvedStorageDir === path23.resolve(this.config.memoryDir)) {
22504
+ if (resolvedStorageDir === path24.resolve(this.config.memoryDir)) {
22370
22505
  return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
22371
22506
  }
22372
- const leaf = path23.basename(resolvedStorageDir);
22507
+ const leaf = path24.basename(resolvedStorageDir);
22373
22508
  const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
22374
22509
  if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
22375
22510
  if (record.namespace === leaf) return 1;
@@ -22510,7 +22645,7 @@ var Orchestrator = class {
22510
22645
  StorageManager.setOkfConformanceDefault(config.memoryDir, config.okf?.conformanceEnabled);
22511
22646
  this.profiler = new ProfilingCollector({
22512
22647
  enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
22513
- storageDir: config.profilingStorageDir || path23.join(config.memoryDir, "profiling"),
22648
+ storageDir: config.profilingStorageDir || path24.join(config.memoryDir, "profiling"),
22514
22649
  maxTraces: config.profilingMaxTraces
22515
22650
  });
22516
22651
  this.namespaceCatalog = new NamespaceCatalog(config);
@@ -22588,7 +22723,7 @@ var Orchestrator = class {
22588
22723
  bindStorage(this.storage, this.config.defaultNamespace);
22589
22724
  this.storageRouter.onStorageCreated = bindStorage;
22590
22725
  this.storageRouter.forEachCachedStorage(bindStorage);
22591
- this.extractionQueueCoordinator = new ExtractionQueueCoordinator();
22726
+ this.extractionQueueCoordinator = new ExtractionQueueCoordinator(config.extractionQueueConcurrency);
22592
22727
  this.recallResultFormatter = new RecallResultFormatter(this.config);
22593
22728
  const conversationIndexRuntime = createConversationIndexRuntime(config, {
22594
22729
  getQmd: () => this.conversationQmd,
@@ -22601,7 +22736,7 @@ var Orchestrator = class {
22601
22736
  this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
22602
22737
  this.buffer = new SmartBuffer(config, this.storage);
22603
22738
  this.transcript = new TranscriptManager(config);
22604
- this.conversationIndexDir = path23.join(
22739
+ this.conversationIndexDir = path24.join(
22605
22740
  config.memoryDir,
22606
22741
  "conversation-index",
22607
22742
  "chunks"
@@ -22752,7 +22887,7 @@ var Orchestrator = class {
22752
22887
  getHandleHistory: () => this.handleHistory
22753
22888
  });
22754
22889
  this.threading = new ThreadingManager(
22755
- path23.join(config.memoryDir, "threads"),
22890
+ path24.join(config.memoryDir, "threads"),
22756
22891
  config.threadingGapMinutes
22757
22892
  );
22758
22893
  const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
@@ -23712,7 +23847,7 @@ ${doc.content}` : doc.content,
23712
23847
  this.maintenanceScheduler.requestQmdMaintenanceForTool(reason);
23713
23848
  }
23714
23849
  async persistExtraction(result, storage, threadIdForExtraction, sourceContext, baseNamespace, scopeProfileWritePlan, sourceText, graphCaps = resolveGraphConstructionCapabilities(this.config), lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config)) {
23715
- const { persistedIds, memoryPathById } = await this.extractionPersistCoordinator.persistExtraction(
23850
+ return await this.extractionPersistCoordinator.persistExtraction(
23716
23851
  result,
23717
23852
  storage,
23718
23853
  threadIdForExtraction,
@@ -23723,15 +23858,13 @@ ${doc.content}` : doc.content,
23723
23858
  graphCaps,
23724
23859
  lifecycleCaps
23725
23860
  );
23726
- return { persistedIds, memoryPathById };
23727
23861
  }
23728
23862
  /**
23729
23863
  * Append persisted ids to the thread episode set, excluding pending_review
23730
23864
  * fact ids (#1635) so they don't re-seed predecessor edges. Fail-open like
23731
23865
  * the raw appendEpisodeIds call it replaces.
23732
23866
  */
23733
- async appendPersistedThreadEpisodes(threadId, persistedIds) {
23734
- const pendingReviewIds = this.lastPersistExtractionPendingReviewIds ?? [];
23867
+ async appendPersistedThreadEpisodes(threadId, persistedIds, pendingReviewIds) {
23735
23868
  const episodeIds = pendingReviewIds.length > 0 ? persistedIds.filter((id) => !pendingReviewIds.includes(id)) : persistedIds;
23736
23869
  if (episodeIds.length === 0) return;
23737
23870
  try {
@@ -24868,9 +25001,9 @@ function readStructuralSymbol(entry) {
24868
25001
  const rec = entry;
24869
25002
  const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
24870
25003
  if (!symbol) return null;
24871
- const path41 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
25004
+ const path42 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
24872
25005
  const kind = typeof rec.kind === "string" && rec.kind.length > 0 ? rec.kind : void 0;
24873
- const item = path41 !== void 0 && kind !== void 0 ? { symbol, path: path41, kind } : path41 !== void 0 ? { symbol, path: path41 } : kind !== void 0 ? { symbol, kind } : { symbol };
25006
+ const item = path42 !== void 0 && kind !== void 0 ? { symbol, path: path42, kind } : path42 !== void 0 ? { symbol, path: path42 } : kind !== void 0 ? { symbol, kind } : { symbol };
24874
25007
  return item;
24875
25008
  }
24876
25009
  function classifySpawnError(err) {
@@ -24944,7 +25077,7 @@ var DEFAULT_GRACE_PERIOD_DAYS = 7;
24944
25077
 
24945
25078
  // src/binary-lifecycle/backend.ts
24946
25079
  import fsp2 from "fs/promises";
24947
- import path24 from "path";
25080
+ import path25 from "path";
24948
25081
  var FilesystemBackend = class {
24949
25082
  type = "filesystem";
24950
25083
  basePath;
@@ -24952,19 +25085,19 @@ var FilesystemBackend = class {
24952
25085
  if (!basePath || basePath.trim().length === 0) {
24953
25086
  throw new Error("FilesystemBackend requires a non-empty basePath");
24954
25087
  }
24955
- this.basePath = path24.resolve(basePath);
25088
+ this.basePath = path25.resolve(basePath);
24956
25089
  }
24957
25090
  resolveRemotePath(remotePath) {
24958
- const resolved = path24.isAbsolute(remotePath) ? path24.resolve(remotePath) : path24.resolve(this.basePath, remotePath);
24959
- const relative = path24.relative(this.basePath, resolved);
24960
- if (relative === ".." || relative.startsWith(`..${path24.sep}`) || path24.isAbsolute(relative)) {
25091
+ const resolved = path25.isAbsolute(remotePath) ? path25.resolve(remotePath) : path25.resolve(this.basePath, remotePath);
25092
+ const relative = path25.relative(this.basePath, resolved);
25093
+ if (relative === ".." || relative.startsWith(`..${path25.sep}`) || path25.isAbsolute(relative)) {
24961
25094
  throw new Error(`FilesystemBackend remotePath escapes basePath: ${JSON.stringify(remotePath)}`);
24962
25095
  }
24963
25096
  return resolved;
24964
25097
  }
24965
25098
  isInsideBase(candidate, realBase) {
24966
- const relative = path24.relative(realBase, candidate);
24967
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path24.sep}`) && !path24.isAbsolute(relative);
25099
+ const relative = path25.relative(realBase, candidate);
25100
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path25.sep}`) && !path25.isAbsolute(relative);
24968
25101
  }
24969
25102
  async realBasePathIfExists() {
24970
25103
  try {
@@ -24993,13 +25126,13 @@ var FilesystemBackend = class {
24993
25126
  }
24994
25127
  async ensureSafeParentDirectory(dest) {
24995
25128
  const realBase = await this.ensureBaseDirectory();
24996
- const destDir = path24.dirname(dest);
24997
- const relativeDir = path24.relative(this.basePath, destDir);
24998
- const segments = relativeDir === "" ? [] : relativeDir.split(path24.sep);
25129
+ const destDir = path25.dirname(dest);
25130
+ const relativeDir = path25.relative(this.basePath, destDir);
25131
+ const segments = relativeDir === "" ? [] : relativeDir.split(path25.sep);
24999
25132
  let current = this.basePath;
25000
25133
  for (const segment of segments) {
25001
25134
  if (segment === "." || segment === "") continue;
25002
- current = path24.join(current, segment);
25135
+ current = path25.join(current, segment);
25003
25136
  try {
25004
25137
  const stat5 = await fsp2.lstat(current);
25005
25138
  if (stat5.isSymbolicLink()) {
@@ -25027,13 +25160,13 @@ var FilesystemBackend = class {
25027
25160
  if (realBase === null) {
25028
25161
  return null;
25029
25162
  }
25030
- const destDir = path24.dirname(dest);
25031
- const relativeDir = path24.relative(this.basePath, destDir);
25032
- const segments = relativeDir === "" ? [] : relativeDir.split(path24.sep);
25163
+ const destDir = path25.dirname(dest);
25164
+ const relativeDir = path25.relative(this.basePath, destDir);
25165
+ const segments = relativeDir === "" ? [] : relativeDir.split(path25.sep);
25033
25166
  let current = this.basePath;
25034
25167
  for (const segment of segments) {
25035
25168
  if (segment === "." || segment === "") continue;
25036
- current = path24.join(current, segment);
25169
+ current = path25.join(current, segment);
25037
25170
  let stat5;
25038
25171
  try {
25039
25172
  stat5 = await fsp2.lstat(current);
@@ -25081,7 +25214,7 @@ var FilesystemBackend = class {
25081
25214
  return dest;
25082
25215
  }
25083
25216
  async upload(localPath, remotePath) {
25084
- if (path24.isAbsolute(remotePath)) {
25217
+ if (path25.isAbsolute(remotePath)) {
25085
25218
  throw new Error(`FilesystemBackend upload remotePath must be relative: ${JSON.stringify(remotePath)}`);
25086
25219
  }
25087
25220
  const dest = this.resolveRemotePath(remotePath);
@@ -25154,7 +25287,7 @@ function createBackend(cfg) {
25154
25287
 
25155
25288
  // src/binary-lifecycle/scanner.ts
25156
25289
  import fsp3 from "fs/promises";
25157
- import path25 from "path";
25290
+ import path26 from "path";
25158
25291
  import crypto from "crypto";
25159
25292
  function matchesPatterns(filename, patterns) {
25160
25293
  const lower = filename.toLowerCase();
@@ -25179,8 +25312,8 @@ async function scanForBinaries(memoryDir, config, manifest) {
25179
25312
  return;
25180
25313
  }
25181
25314
  for (const entry of entries) {
25182
- const fullPath = path25.join(dir, entry.name);
25183
- const relativePath = path25.relative(memoryDir, fullPath).split(path25.sep).join("/");
25315
+ const fullPath = path26.join(dir, entry.name);
25316
+ const relativePath = path26.relative(memoryDir, fullPath).split(path26.sep).join("/");
25184
25317
  if (entry.isDirectory()) {
25185
25318
  if (entry.name === ".binary-lifecycle") continue;
25186
25319
  await walk(fullPath);
@@ -25220,15 +25353,15 @@ async function hashFile(filePath) {
25220
25353
 
25221
25354
  // src/binary-lifecycle/manifest.ts
25222
25355
  import fsp4 from "fs/promises";
25223
- import path26 from "path";
25356
+ import path27 from "path";
25224
25357
  import crypto2 from "crypto";
25225
25358
  var MANIFEST_DIR = ".binary-lifecycle";
25226
25359
  var MANIFEST_FILE = "manifest.json";
25227
25360
  function manifestDir(memoryDir) {
25228
- return path26.join(memoryDir, MANIFEST_DIR);
25361
+ return path27.join(memoryDir, MANIFEST_DIR);
25229
25362
  }
25230
25363
  function manifestPath(memoryDir) {
25231
- return path26.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
25364
+ return path27.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
25232
25365
  }
25233
25366
  async function readManifest(memoryDir) {
25234
25367
  const filePath = manifestPath(memoryDir);
@@ -25280,13 +25413,13 @@ function emptyManifest() {
25280
25413
 
25281
25414
  // src/binary-lifecycle/pipeline.ts
25282
25415
  import fsp5 from "fs/promises";
25283
- import path27 from "path";
25416
+ import path28 from "path";
25284
25417
  import crypto3 from "crypto";
25285
25418
  var historicalIdCache = new HistoricalEntityCanonicalIdCache();
25286
25419
  function isRecallCorpusMarkdown(mdPath, memoryDir) {
25287
- const rel = path27.relative(memoryDir, mdPath);
25288
- if (rel.startsWith("..") || path27.isAbsolute(rel)) return false;
25289
- const top = rel.split(path27.sep)[0];
25420
+ const rel = path28.relative(memoryDir, mdPath);
25421
+ if (rel.startsWith("..") || path28.isAbsolute(rel)) return false;
25422
+ const top = rel.split(path28.sep)[0];
25290
25423
  return RECALL_FALLBACK_DIRS.includes(top);
25291
25424
  }
25292
25425
  async function hashFile2(filePath) {
@@ -25310,13 +25443,13 @@ function escapeRegex(s) {
25310
25443
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25311
25444
  }
25312
25445
  function resolveManifestAssetPath(memoryDir, originalPath) {
25313
- if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path27.isAbsolute(originalPath) || path27.win32.isAbsolute(originalPath)) {
25446
+ if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path28.isAbsolute(originalPath) || path28.win32.isAbsolute(originalPath)) {
25314
25447
  return null;
25315
25448
  }
25316
- const memoryRoot = path27.resolve(memoryDir);
25317
- const fullPath = path27.resolve(memoryRoot, originalPath);
25318
- const relative = path27.relative(memoryRoot, fullPath);
25319
- if (relative === "" || relative === ".." || relative.startsWith(`..${path27.sep}`) || path27.isAbsolute(relative)) {
25449
+ const memoryRoot = path28.resolve(memoryDir);
25450
+ const fullPath = path28.resolve(memoryRoot, originalPath);
25451
+ const relative = path28.relative(memoryRoot, fullPath);
25452
+ if (relative === "" || relative === ".." || relative.startsWith(`..${path28.sep}`) || path28.isAbsolute(relative)) {
25320
25453
  return null;
25321
25454
  }
25322
25455
  return fullPath;
@@ -25327,7 +25460,7 @@ function validateBinaryLifecycleConfig(config) {
25327
25460
  }
25328
25461
  }
25329
25462
  function remotePathForAsset(backend, relPath) {
25330
- const normalized = relPath.split(path27.sep).join("/");
25463
+ const normalized = relPath.split(path28.sep).join("/");
25331
25464
  if (backend.type === "filesystem") {
25332
25465
  return `.binary-lifecycle/mirrors/${normalized}`;
25333
25466
  }
@@ -25340,11 +25473,11 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
25340
25473
  let mirrored = 0;
25341
25474
  const errors = [];
25342
25475
  for (const relPath of newPaths) {
25343
- const fullPath = path27.join(memoryDir, relPath);
25476
+ const fullPath = path28.join(memoryDir, relPath);
25344
25477
  try {
25345
25478
  const stat5 = await fsp5.stat(fullPath);
25346
25479
  const contentHash = await hashFile2(fullPath);
25347
- const ext = path27.extname(relPath);
25480
+ const ext = path28.extname(relPath);
25348
25481
  const mimeType = guessMimeType(ext);
25349
25482
  const remotePath = remotePathForAsset(backend, relPath);
25350
25483
  let backendLocation = remotePath;
@@ -25495,7 +25628,7 @@ async function stageRedirect(memoryDir, assets, log2, dryRun, readMarkdownFile,
25495
25628
  for (const update of updates) {
25496
25629
  try {
25497
25630
  await withRawEntityPageMutation(memoryDir, update.mdPath, async () => {
25498
- const stateDir = path27.join(memoryDir, "state");
25631
+ const stateDir = path28.join(memoryDir, "state");
25499
25632
  const kind = classifyEntityRefWritePath(memoryDir, update.mdPath);
25500
25633
  if (kind === "memory") {
25501
25634
  const idsAtWrite = historicalIdCache.get(stateDir);
@@ -25588,10 +25721,10 @@ async function countRemainingLocalReferences(memoryDir, asset, assetAbsolute, md
25588
25721
  return { remaining, errors };
25589
25722
  }
25590
25723
  function markdownReferencePattern(asset, assetAbsolute, mdPath) {
25591
- const mdDir = path27.dirname(mdPath);
25724
+ const mdDir = path28.dirname(mdPath);
25592
25725
  const candidates = /* @__PURE__ */ new Set();
25593
25726
  const addCandidate = (candidate) => {
25594
- const normalized = candidate.split(path27.sep).join("/");
25727
+ const normalized = candidate.split(path28.sep).join("/");
25595
25728
  if (normalized.length === 0) return;
25596
25729
  candidates.add(normalized);
25597
25730
  const isParentTraversal = normalized === ".." || normalized.startsWith("../");
@@ -25599,10 +25732,10 @@ function markdownReferencePattern(asset, assetAbsolute, mdPath) {
25599
25732
  candidates.add(`./${normalized}`);
25600
25733
  }
25601
25734
  };
25602
- addCandidate(path27.relative(mdDir, assetAbsolute));
25603
- const originalPath = asset.originalPath.split(path27.sep).join("/");
25604
- const originalAsFileRelative = path27.resolve(mdDir, ...originalPath.split("/"));
25605
- if (path27.resolve(originalAsFileRelative) === path27.resolve(assetAbsolute)) {
25735
+ addCandidate(path28.relative(mdDir, assetAbsolute));
25736
+ const originalPath = asset.originalPath.split(path28.sep).join("/");
25737
+ const originalAsFileRelative = path28.resolve(mdDir, ...originalPath.split("/"));
25738
+ if (path28.resolve(originalAsFileRelative) === path28.resolve(assetAbsolute)) {
25606
25739
  addCandidate(originalPath);
25607
25740
  }
25608
25741
  addCandidate(`/${originalPath}`);
@@ -25698,7 +25831,7 @@ async function findMarkdownFiles(dir) {
25698
25831
  return;
25699
25832
  }
25700
25833
  for (const entry of entries) {
25701
- const full = path27.join(current, entry.name);
25834
+ const full = path28.join(current, entry.name);
25702
25835
  if (entry.isDirectory()) {
25703
25836
  if (entry.name === ".binary-lifecycle") continue;
25704
25837
  await walk(full);
@@ -25773,7 +25906,7 @@ async function runBinaryLifecyclePipeline(memoryDir, config, backend, log2, opts
25773
25906
 
25774
25907
  // src/projection/index.ts
25775
25908
  import fs from "fs";
25776
- import path28 from "path";
25909
+ import path29 from "path";
25777
25910
  var VALID_PROJECTION_CATEGORIES = new Set(ALL_CATEGORY_KEYS);
25778
25911
  async function generateContextTree(options) {
25779
25912
  const startTime = Date.now();
@@ -25788,8 +25921,8 @@ async function generateContextTree(options) {
25788
25921
  let nodesGenerated = 0;
25789
25922
  let nodesSkipped = 0;
25790
25923
  const categoryCounts = {};
25791
- const resolvedMemoryDir = path28.resolve(memoryDir);
25792
- const resolvedOutputDir = path28.resolve(outputDir);
25924
+ const resolvedMemoryDir = path29.resolve(memoryDir);
25925
+ const resolvedOutputDir = path29.resolve(outputDir);
25793
25926
  const requestedCategories = validateProjectionCategories(filterCategories);
25794
25927
  const realMemoryDir = assertSafeMemoryRoot(resolvedMemoryDir);
25795
25928
  assertNotSymlink(resolvedOutputDir, "context tree outputDir");
@@ -25827,7 +25960,7 @@ async function generateContextTree(options) {
25827
25960
  }
25828
25961
  }
25829
25962
  if (includeEntities) {
25830
- const entitiesDir = path28.join(memoryDir, "entities");
25963
+ const entitiesDir = path29.join(memoryDir, "entities");
25831
25964
  if (fs.existsSync(entitiesDir)) {
25832
25965
  assertSafeInputRoot(realMemoryDir, entitiesDir, "entities root");
25833
25966
  categoryCounts["entity"] = 0;
@@ -25839,7 +25972,7 @@ async function generateContextTree(options) {
25839
25972
  continue;
25840
25973
  }
25841
25974
  const content = fs.readFileSync(filePath, "utf8");
25842
- const fileName = path28.basename(filePath, ".md");
25975
+ const fileName = path29.basename(filePath, ".md");
25843
25976
  const node = projectEntityNode(fileName, content);
25844
25977
  const outputPath = resolveContainedOutputPath(realOutputDir, "entities", `${fileName}.md`);
25845
25978
  writeProjectedContent(realOutputDir, outputPath, node.content);
@@ -25851,7 +25984,7 @@ async function generateContextTree(options) {
25851
25984
  }
25852
25985
  const shouldIncludeQuestions = includeQuestions && (requestedCategories === void 0 || requestedCategories.includes("question"));
25853
25986
  if (shouldIncludeQuestions) {
25854
- const questionsDir = path28.join(memoryDir, "questions");
25987
+ const questionsDir = path29.join(memoryDir, "questions");
25855
25988
  if (fs.existsSync(questionsDir)) {
25856
25989
  assertSafeInputRoot(realMemoryDir, questionsDir, "questions root");
25857
25990
  categoryCounts["question"] = 0;
@@ -25892,8 +26025,8 @@ async function generateContextTree(options) {
25892
26025
  };
25893
26026
  }
25894
26027
  function isPathInside(root, candidate) {
25895
- const relative = path28.relative(root, candidate);
25896
- return relative === "" || !relative.startsWith("..") && !path28.isAbsolute(relative);
26028
+ const relative = path29.relative(root, candidate);
26029
+ return relative === "" || !relative.startsWith("..") && !path29.isAbsolute(relative);
25897
26030
  }
25898
26031
  function assertNotSymlink(targetPath, label) {
25899
26032
  try {
@@ -25930,12 +26063,12 @@ function assertSafeInputRoot(realMemoryDir, targetPath, label) {
25930
26063
  }
25931
26064
  function assertSafeOutputTarget(realOutputDir, outputPath) {
25932
26065
  let current = realOutputDir;
25933
- const relative = path28.relative(realOutputDir, outputPath);
25934
- if (relative.startsWith("..") || path28.isAbsolute(relative)) {
26066
+ const relative = path29.relative(realOutputDir, outputPath);
26067
+ if (relative.startsWith("..") || path29.isAbsolute(relative)) {
25935
26068
  throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
25936
26069
  }
25937
- for (const segment of relative.split(path28.sep).filter(Boolean)) {
25938
- current = path28.join(current, segment);
26070
+ for (const segment of relative.split(path29.sep).filter(Boolean)) {
26071
+ current = path29.join(current, segment);
25939
26072
  try {
25940
26073
  const stat5 = fs.lstatSync(current);
25941
26074
  if (stat5.isSymbolicLink()) {
@@ -25965,17 +26098,17 @@ function validateProjectionCategories(categories) {
25965
26098
  return validated;
25966
26099
  }
25967
26100
  function resolveContainedOutputPath(outputRoot, ...segments) {
25968
- const resolved = path28.resolve(outputRoot, ...segments);
25969
- const relative = path28.relative(outputRoot, resolved);
25970
- if (relative === "" || !relative.startsWith("..") && !path28.isAbsolute(relative)) {
26101
+ const resolved = path29.resolve(outputRoot, ...segments);
26102
+ const relative = path29.relative(outputRoot, resolved);
26103
+ if (relative === "" || !relative.startsWith("..") && !path29.isAbsolute(relative)) {
25971
26104
  return resolved;
25972
26105
  }
25973
26106
  throw new Error(`context tree output path escapes outputDir: ${segments.join("/")}`);
25974
26107
  }
25975
26108
  function writeProjectedContent(realOutputDir, outputPath, generatedContent) {
25976
26109
  assertSafeOutputTarget(realOutputDir, outputPath);
25977
- fs.mkdirSync(path28.dirname(outputPath), { recursive: true });
25978
- const realParent = fs.realpathSync(path28.dirname(outputPath));
26110
+ fs.mkdirSync(path29.dirname(outputPath), { recursive: true });
26111
+ const realParent = fs.realpathSync(path29.dirname(outputPath));
25979
26112
  if (!isPathInside(realOutputDir, realParent)) {
25980
26113
  throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
25981
26114
  }
@@ -26014,7 +26147,7 @@ function walkR(dir, realMemoryDir) {
26014
26147
  const results = [];
26015
26148
  function walk(directory) {
26016
26149
  for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
26017
- const fullPath = path28.join(directory, entry.name);
26150
+ const fullPath = path29.join(directory, entry.name);
26018
26151
  if (entry.isSymbolicLink()) {
26019
26152
  throw new Error(`context tree input path contains symlink: ${fullPath}`);
26020
26153
  }
@@ -26067,13 +26200,13 @@ function extractBody(content) {
26067
26200
  }
26068
26201
  function projectNode(filePath, category, fm, rawContent) {
26069
26202
  const body = extractBody(rawContent);
26070
- const fileName = path28.basename(filePath, ".md");
26071
- const dateDir = path28.basename(path28.dirname(filePath));
26203
+ const fileName = path29.basename(filePath, ".md");
26204
+ const dateDir = path29.basename(path29.dirname(filePath));
26072
26205
  let relPath;
26073
26206
  if (/^\d{4}-\d{2}-\d{2}$/.test(dateDir)) {
26074
- relPath = path28.join(category, dateDir, `${fileName}.md`);
26207
+ relPath = path29.join(category, dateDir, `${fileName}.md`);
26075
26208
  } else {
26076
- relPath = path28.join(category, `${fileName}.md`);
26209
+ relPath = path29.join(category, `${fileName}.md`);
26077
26210
  }
26078
26211
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
26079
26212
  const md = `# ${fm.id}
@@ -26119,7 +26252,7 @@ function projectEntityNode(fileName, content) {
26119
26252
  ${content}
26120
26253
  `;
26121
26254
  return {
26122
- path: path28.join("entities", `${fileName}.md`),
26255
+ path: path29.join("entities", `${fileName}.md`),
26123
26256
  category: "entity",
26124
26257
  title: fileName,
26125
26258
  content: md,
@@ -26172,7 +26305,7 @@ function generateIndex(categoryCounts, outputDir) {
26172
26305
 
26173
26306
  // src/onboarding/index.ts
26174
26307
  import fs2 from "fs";
26175
- import path29 from "path";
26308
+ import path30 from "path";
26176
26309
  var LANGUAGE_RULES = [
26177
26310
  {
26178
26311
  language: "TypeScript",
@@ -26274,7 +26407,7 @@ function onboard(options) {
26274
26407
  maxDepth = 6,
26275
26408
  excludeDirs = []
26276
26409
  } = options;
26277
- const directory = path29.resolve(options.directory ?? process.cwd());
26410
+ const directory = path30.resolve(options.directory ?? process.cwd());
26278
26411
  let rootStat;
26279
26412
  try {
26280
26413
  rootStat = fs2.statSync(directory);
@@ -26316,7 +26449,7 @@ function walkDir(root, exclude, maxDepth) {
26316
26449
  }
26317
26450
  for (const entry of entries) {
26318
26451
  if (exclude.has(entry.name)) continue;
26319
- const fullPath = path29.join(dir, entry.name);
26452
+ const fullPath = path30.join(dir, entry.name);
26320
26453
  if (entry.isDirectory()) {
26321
26454
  walk(fullPath, depth + 1);
26322
26455
  } else if (entry.isFile()) {
@@ -26331,11 +26464,11 @@ function detectLanguages(files, root) {
26331
26464
  const results = [];
26332
26465
  const extCounts = /* @__PURE__ */ new Map();
26333
26466
  for (const f of files) {
26334
- const ext = path29.extname(f).toLowerCase();
26467
+ const ext = path30.extname(f).toLowerCase();
26335
26468
  if (ext) extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
26336
26469
  }
26337
26470
  const rootFiles = new Set(
26338
- files.filter((f) => path29.dirname(f) === root).map((f) => path29.basename(f))
26471
+ files.filter((f) => path30.dirname(f) === root).map((f) => path30.basename(f))
26339
26472
  );
26340
26473
  for (const rule of LANGUAGE_RULES) {
26341
26474
  const evidence = [];
@@ -26379,7 +26512,7 @@ function detectLanguages(files, root) {
26379
26512
  }
26380
26513
  function detectShape(files, root) {
26381
26514
  const rootFiles = new Set(
26382
- files.filter((f) => path29.dirname(f) === root).map((f) => path29.basename(f))
26515
+ files.filter((f) => path30.dirname(f) === root).map((f) => path30.basename(f))
26383
26516
  );
26384
26517
  const rootDirs = /* @__PURE__ */ new Set();
26385
26518
  try {
@@ -26390,7 +26523,7 @@ function detectShape(files, root) {
26390
26523
  }
26391
26524
  const evidence = [];
26392
26525
  if (rootFiles.has("package.json")) {
26393
- const pkg = readJsonSafe(path29.join(root, "package.json"));
26526
+ const pkg = readJsonSafe(path30.join(root, "package.json"));
26394
26527
  if (pkg?.workspaces) {
26395
26528
  evidence.push("package.json has workspaces");
26396
26529
  return { shape: "monorepo", evidence };
@@ -26404,13 +26537,13 @@ function detectShape(files, root) {
26404
26537
  evidence.push("workspace manifest found");
26405
26538
  return { shape: "workspace", evidence };
26406
26539
  }
26407
- const cargoToml = readTomlWorkspace(path29.join(root, "Cargo.toml"));
26540
+ const cargoToml = readTomlWorkspace(path30.join(root, "Cargo.toml"));
26408
26541
  if (cargoToml) {
26409
26542
  evidence.push("Cargo.toml has workspace");
26410
26543
  return { shape: "workspace", evidence };
26411
26544
  }
26412
26545
  if (rootFiles.has("package.json")) {
26413
- const pkg = readJsonSafe(path29.join(root, "package.json"));
26546
+ const pkg = readJsonSafe(path30.join(root, "package.json"));
26414
26547
  if (pkg?.exports || pkg?.main) {
26415
26548
  if (pkg?.bin) {
26416
26549
  evidence.push("package.json has bin");
@@ -26444,8 +26577,8 @@ function discoverDocs(files, root) {
26444
26577
  { pattern: /^\.editorconfig$/i, kind: "config" }
26445
26578
  ];
26446
26579
  for (const filePath of files) {
26447
- const basename = path29.basename(filePath).toLowerCase();
26448
- const relPath = path29.relative(root, filePath);
26580
+ const basename = path30.basename(filePath).toLowerCase();
26581
+ const relPath = path30.relative(root, filePath);
26449
26582
  let kind;
26450
26583
  for (const { pattern, kind: k } of docPatterns) {
26451
26584
  if (pattern.test(basename)) {
@@ -26457,7 +26590,7 @@ function discoverDocs(files, root) {
26457
26590
  kind = "docs";
26458
26591
  }
26459
26592
  if (!kind && (basename.endsWith(".md") || basename.endsWith(".mdx"))) {
26460
- if (path29.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
26593
+ if (path30.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
26461
26594
  kind = "docs";
26462
26595
  }
26463
26596
  }
@@ -26478,7 +26611,7 @@ function discoverDocs(files, root) {
26478
26611
  return docs;
26479
26612
  }
26480
26613
  function isUnderDocsDir(relPath) {
26481
- const parts = relPath.split(path29.sep);
26614
+ const parts = relPath.split(path30.sep);
26482
26615
  return parts[0] === "docs" || parts[0] === "doc" || parts[0] === "documentation";
26483
26616
  }
26484
26617
  function buildPlan(languages, shape, docs, _root) {
@@ -26522,7 +26655,7 @@ function readTomlWorkspace(filePath) {
26522
26655
 
26523
26656
  // src/curation/index.ts
26524
26657
  import fs3 from "fs";
26525
- import path30 from "path";
26658
+ import path31 from "path";
26526
26659
  import crypto4 from "crypto";
26527
26660
  async function curate(options) {
26528
26661
  const startTime = Date.now();
@@ -26613,12 +26746,12 @@ function resolveTargets(targetPath) {
26613
26746
  const extensions = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
26614
26747
  function walk(dir) {
26615
26748
  for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
26616
- const fullPath = path30.join(dir, entry.name);
26749
+ const fullPath = path31.join(dir, entry.name);
26617
26750
  if (entry.isDirectory()) {
26618
26751
  if (entry.name !== "node_modules" && entry.name !== ".git") {
26619
26752
  walk(fullPath);
26620
26753
  }
26621
- } else if (extensions.has(path30.extname(entry.name).toLowerCase())) {
26754
+ } else if (extensions.has(path31.extname(entry.name).toLowerCase())) {
26622
26755
  results.push(fullPath);
26623
26756
  }
26624
26757
  }
@@ -26627,12 +26760,12 @@ function resolveTargets(targetPath) {
26627
26760
  return results;
26628
26761
  }
26629
26762
  function resolveProvenanceRoot(targetPath) {
26630
- const resolvedTarget = path30.resolve(targetPath);
26763
+ const resolvedTarget = path31.resolve(targetPath);
26631
26764
  const stat5 = fs3.statSync(resolvedTarget);
26632
- return stat5.isFile() ? path30.dirname(resolvedTarget) : resolvedTarget;
26765
+ return stat5.isFile() ? path31.dirname(resolvedTarget) : resolvedTarget;
26633
26766
  }
26634
26767
  function extractStatements(content, filePath, projectRoot, source, sourceFileHash, categoryOverride, confidence, entityRef, tags) {
26635
- const relativePath = path30.relative(projectRoot, path30.resolve(filePath)) || path30.basename(filePath);
26768
+ const relativePath = path31.relative(projectRoot, path31.resolve(filePath)) || path31.basename(filePath);
26636
26769
  const statements = [];
26637
26770
  const now = (/* @__PURE__ */ new Date()).toISOString();
26638
26771
  const paragraphs = content.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 20 && p.length < 2e3);
@@ -26726,7 +26859,7 @@ function loadExistingMemories(memoryDir) {
26726
26859
  if (!fs3.existsSync(memoryDir)) return result;
26727
26860
  const dirs = ALL_CATEGORY_DIRS;
26728
26861
  for (const dir of dirs) {
26729
- const fullDir = path30.join(memoryDir, dir);
26862
+ const fullDir = path31.join(memoryDir, dir);
26730
26863
  if (!fs3.existsSync(fullDir)) continue;
26731
26864
  walkFiles(fullDir, (filePath) => {
26732
26865
  const content = readFileSafe(filePath);
@@ -26749,11 +26882,11 @@ function writeStatement(stmt, memoryDir) {
26749
26882
  const now = /* @__PURE__ */ new Date();
26750
26883
  const dateDir = now.toISOString().split("T")[0];
26751
26884
  const categoryDir = getCategoryDir(memoryDir, stmt.category);
26752
- const dir = path30.join(categoryDir, dateDir);
26885
+ const dir = path31.join(categoryDir, dateDir);
26753
26886
  fs3.mkdirSync(dir, { recursive: true });
26754
26887
  const fileName = `${stmt.category}-${Date.now()}-${stmt.id.slice(0, 8)}.md`;
26755
- const filePath = path30.join(dir, fileName);
26756
- const historicalIds = historicalIdCache2.get(path30.join(memoryDir, "state"));
26888
+ const filePath = path31.join(dir, fileName);
26889
+ const historicalIds = historicalIdCache2.get(path31.join(memoryDir, "state"));
26757
26890
  const rawBody = `${[
26758
26891
  "---",
26759
26892
  `id: ${stmt.id}`,
@@ -26776,7 +26909,7 @@ ${stmt.content}
26776
26909
  fs3.writeFileSync(filePath, body);
26777
26910
  try {
26778
26911
  repairContentAfterJournalMoveSync({
26779
- stateDir: path30.join(memoryDir, "state"),
26912
+ stateDir: path31.join(memoryDir, "state"),
26780
26913
  cache: historicalIdCache2,
26781
26914
  idsAtWrite: historicalIds,
26782
26915
  rawContent: rawBody,
@@ -26837,7 +26970,7 @@ function extractBody2(content) {
26837
26970
  }
26838
26971
  function walkFiles(dir, callback) {
26839
26972
  for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
26840
- const fullPath = path30.join(dir, entry.name);
26973
+ const fullPath = path31.join(dir, entry.name);
26841
26974
  if (entry.isDirectory()) {
26842
26975
  walkFiles(fullPath, callback);
26843
26976
  } else if (entry.name.endsWith(".md")) {
@@ -26848,7 +26981,7 @@ function walkFiles(dir, callback) {
26848
26981
 
26849
26982
  // src/sync/index.ts
26850
26983
  import fs4 from "fs";
26851
- import path31 from "path";
26984
+ import path32 from "path";
26852
26985
  import crypto5 from "crypto";
26853
26986
  var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
26854
26987
  var DEFAULT_EXCLUDE2 = /* @__PURE__ */ new Set([
@@ -26870,7 +27003,7 @@ function syncChanges(options) {
26870
27003
  } = options;
26871
27004
  const extSet = new Set(extensions);
26872
27005
  const excludeSet = /* @__PURE__ */ new Set([...DEFAULT_EXCLUDE2, ...excludeDirs]);
26873
- const stateFilePath = options.stateFile ?? path31.join(memoryDir, ".sync-state.json");
27006
+ const stateFilePath = options.stateFile ?? path32.join(memoryDir, ".sync-state.json");
26874
27007
  const prevState = loadState(stateFilePath);
26875
27008
  const currentFiles = scanFiles(sourceDir, extSet, excludeSet);
26876
27009
  const changes = computeDiff(currentFiles, prevState.fileHashes, sourceDir);
@@ -26886,7 +27019,7 @@ function syncChanges(options) {
26886
27019
  for (const [relPath, hash] of Object.entries(currentFiles)) {
26887
27020
  newState.fileHashes[relPath] = hash;
26888
27021
  }
26889
- fs4.mkdirSync(path31.dirname(stateFilePath), { recursive: true });
27022
+ fs4.mkdirSync(path32.dirname(stateFilePath), { recursive: true });
26890
27023
  fs4.writeFileSync(stateFilePath, JSON.stringify(newState, null, 2));
26891
27024
  }
26892
27025
  return {
@@ -26952,13 +27085,13 @@ function scanFiles(root, extensions, exclude) {
26952
27085
  }
26953
27086
  for (const entry of entries) {
26954
27087
  if (exclude.has(entry.name)) continue;
26955
- const fullPath = path31.join(dir, entry.name);
27088
+ const fullPath = path32.join(dir, entry.name);
26956
27089
  if (entry.isDirectory()) {
26957
27090
  walk(fullPath);
26958
27091
  } else if (entry.isFile()) {
26959
- const ext = path31.extname(entry.name).toLowerCase();
27092
+ const ext = path32.extname(entry.name).toLowerCase();
26960
27093
  if (!extensions.has(ext)) continue;
26961
- const relPath = path31.relative(root, fullPath);
27094
+ const relPath = path32.relative(root, fullPath);
26962
27095
  try {
26963
27096
  const content = fs4.readFileSync(fullPath, "utf8");
26964
27097
  result[relPath] = hashContent2(content);
@@ -26973,7 +27106,7 @@ function scanFiles(root, extensions, exclude) {
26973
27106
  function computeDiff(current, previous, sourceDir) {
26974
27107
  const changes = [];
26975
27108
  for (const [relPath, hash] of Object.entries(current)) {
26976
- const fullPath = path31.join(sourceDir, relPath);
27109
+ const fullPath = path32.join(sourceDir, relPath);
26977
27110
  if (!(relPath in previous)) {
26978
27111
  let size = 0;
26979
27112
  try {
@@ -27006,7 +27139,7 @@ function computeDiff(current, previous, sourceDir) {
27006
27139
  for (const relPath of Object.keys(previous)) {
27007
27140
  if (!(relPath in current)) {
27008
27141
  changes.push({
27009
- filePath: path31.join(sourceDir, relPath),
27142
+ filePath: path32.join(sourceDir, relPath),
27010
27143
  relativePath: relPath,
27011
27144
  type: "deleted",
27012
27145
  currentHash: "",
@@ -27036,21 +27169,21 @@ function hashContent2(content) {
27036
27169
  import { spawnSync } from "child_process";
27037
27170
  import crypto6 from "crypto";
27038
27171
  import fs5 from "fs";
27039
- import path32 from "path";
27172
+ import path33 from "path";
27040
27173
  var historicalIdCache3 = new HistoricalEntityCanonicalIdCache();
27041
27174
  var MANIFEST_VERSION = 1;
27042
27175
  var MANIFEST_LOCK_STALE_MS = 3e4;
27043
27176
  var MANIFEST_LOCK_TIMEOUT_MS = MANIFEST_LOCK_STALE_MS + 1e4;
27044
27177
  var MANIFEST_LOCK_SLEEP_MS = 20;
27045
27178
  function normalizeSpaceMemoryDir(memoryDir) {
27046
- return path32.resolve(memoryDir);
27179
+ return path33.resolve(memoryDir);
27047
27180
  }
27048
27181
  function getSpacesDir(baseDir) {
27049
27182
  const homeDir = baseDir ?? resolveHomeDir();
27050
- return path32.join(homeDir, ".config", "engram", "spaces");
27183
+ return path33.join(homeDir, ".config", "engram", "spaces");
27051
27184
  }
27052
27185
  function getManifestPath(baseDir) {
27053
- return path32.join(getSpacesDir(baseDir), "manifest.json");
27186
+ return path33.join(getSpacesDir(baseDir), "manifest.json");
27054
27187
  }
27055
27188
  function loadManifest(baseDir, memoryDirOverride) {
27056
27189
  if (fs5.existsSync(getManifestPath(baseDir))) {
@@ -27097,9 +27230,9 @@ function readManifestUnlocked(baseDir, memoryDirOverride, options = {}) {
27097
27230
  }
27098
27231
  function saveManifestUnlocked(manifest, baseDir) {
27099
27232
  const manifestPath2 = getManifestPath(baseDir);
27100
- const manifestDir2 = path32.dirname(manifestPath2);
27233
+ const manifestDir2 = path33.dirname(manifestPath2);
27101
27234
  fs5.mkdirSync(manifestDir2, { recursive: true });
27102
- const tempPath = path32.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto6.randomUUID()}.tmp`);
27235
+ const tempPath = path33.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto6.randomUUID()}.tmp`);
27103
27236
  try {
27104
27237
  fs5.writeFileSync(tempPath, `${JSON.stringify(manifest, null, 2)}
27105
27238
  `, { flag: "wx" });
@@ -27114,7 +27247,7 @@ function saveManifestUnlocked(manifest, baseDir) {
27114
27247
  }
27115
27248
  function withManifestLock(baseDir, operation) {
27116
27249
  const lockDir = `${getManifestPath(baseDir)}.lock`;
27117
- fs5.mkdirSync(path32.dirname(lockDir), { recursive: true });
27250
+ fs5.mkdirSync(path33.dirname(lockDir), { recursive: true });
27118
27251
  const lockOwner = acquireManifestLock(lockDir);
27119
27252
  try {
27120
27253
  return operation();
@@ -27140,7 +27273,7 @@ function acquireManifestLock(lockDir) {
27140
27273
  try {
27141
27274
  fs5.mkdirSync(lockDir, { recursive: false });
27142
27275
  try {
27143
- fs5.writeFileSync(path32.join(lockDir, "owner"), `${owner}
27276
+ fs5.writeFileSync(path33.join(lockDir, "owner"), `${owner}
27144
27277
  `, { flag: "wx" });
27145
27278
  } catch (error) {
27146
27279
  fs5.rmSync(lockDir, { recursive: true, force: true });
@@ -27170,7 +27303,7 @@ function acquireManifestLock(lockDir) {
27170
27303
  }
27171
27304
  function releaseManifestLock(lockDir, owner) {
27172
27305
  try {
27173
- const ownerPath = path32.join(lockDir, "owner");
27306
+ const ownerPath = path33.join(lockDir, "owner");
27174
27307
  if (fs5.readFileSync(ownerPath, "utf8").trim() === owner) {
27175
27308
  fs5.rmSync(lockDir, { recursive: true, force: true });
27176
27309
  }
@@ -27186,7 +27319,7 @@ function removeStaleManifestLock(lockDir) {
27186
27319
  try {
27187
27320
  fs5.mkdirSync(reclaimDir, { recursive: false });
27188
27321
  try {
27189
- fs5.writeFileSync(path32.join(reclaimDir, "owner"), `${reclaimOwner}
27322
+ fs5.writeFileSync(path33.join(reclaimDir, "owner"), `${reclaimOwner}
27190
27323
  `, { flag: "wx" });
27191
27324
  } catch (error) {
27192
27325
  fs5.rmSync(reclaimDir, { recursive: true, force: true });
@@ -27261,7 +27394,7 @@ function readManifestLockSnapshot(lockDir) {
27261
27394
  throw error;
27262
27395
  }
27263
27396
  try {
27264
- const owner = fs5.readFileSync(path32.join(lockDir, "owner"), "utf8").trim();
27397
+ const owner = fs5.readFileSync(path33.join(lockDir, "owner"), "utf8").trim();
27265
27398
  return { mtimeMs: stat5.mtimeMs, owner };
27266
27399
  } catch (error) {
27267
27400
  if (error.code === "ENOENT") {
@@ -27333,8 +27466,8 @@ function sleepSync(ms) {
27333
27466
  }
27334
27467
  function createPersonalSpace(baseDir, memoryDirOverride) {
27335
27468
  const homeDir = baseDir ?? resolveHomeDir();
27336
- const standalonePath = path32.join(homeDir, ".engram", "memory");
27337
- const openclawPath = path32.join(homeDir, ".openclaw", "workspace", "memory", "local");
27469
+ const standalonePath = path33.join(homeDir, ".engram", "memory");
27470
+ const openclawPath = path33.join(homeDir, ".openclaw", "workspace", "memory", "local");
27338
27471
  const memoryDir = memoryDirOverride ?? readEnvVar("REMNIC_MEMORY_DIR") ?? readEnvVar("ENGRAM_MEMORY_DIR") ?? (fs5.existsSync(standalonePath) ? standalonePath : fs5.existsSync(openclawPath) ? openclawPath : standalonePath);
27339
27472
  const normalizedMemoryDir = normalizeSpaceMemoryDir(memoryDir);
27340
27473
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -27363,7 +27496,7 @@ function createSpace(options) {
27363
27496
  const id = options.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
27364
27497
  const now = (/* @__PURE__ */ new Date()).toISOString();
27365
27498
  const memoryDir = normalizeSpaceMemoryDir(
27366
- options.memoryDir ?? path32.join(getSpacesDir(options.baseDir), id, "memory")
27499
+ options.memoryDir ?? path33.join(getSpacesDir(options.baseDir), id, "memory")
27367
27500
  );
27368
27501
  const space = updateManifest(options.baseDir, (manifest) => {
27369
27502
  if (manifest.spaces.some((s) => s.id === id)) {
@@ -27609,14 +27742,14 @@ async function mergeSpaces(sourceSpaceId, targetSpaceId, options) {
27609
27742
  };
27610
27743
  }
27611
27744
  function getAuditLog(baseDir) {
27612
- const auditPath = path32.join(getSpacesDir(baseDir), "audit.jsonl");
27745
+ const auditPath = path33.join(getSpacesDir(baseDir), "audit.jsonl");
27613
27746
  if (!fs5.existsSync(auditPath)) return [];
27614
27747
  const lines = fs5.readFileSync(auditPath, "utf8").trim().split("\n");
27615
27748
  return lines.filter((l) => l.trim()).map((l) => JSON.parse(l));
27616
27749
  }
27617
27750
  function appendAudit(entry, baseDir) {
27618
- const auditPath = path32.join(getSpacesDir(baseDir), "audit.jsonl");
27619
- fs5.mkdirSync(path32.dirname(auditPath), { recursive: true });
27751
+ const auditPath = path33.join(getSpacesDir(baseDir), "audit.jsonl");
27752
+ fs5.mkdirSync(path33.dirname(auditPath), { recursive: true });
27620
27753
  const full = {
27621
27754
  id: crypto6.randomUUID(),
27622
27755
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -27637,11 +27770,11 @@ async function copyMemories(sourceDir, targetDir, options) {
27637
27770
  sourceFiles.filter((p) => {
27638
27771
  const rp = safeRealpath(p);
27639
27772
  if (!rp || !isPathInsideRoot(rp, sourceRoot)) return false;
27640
- const rel = path32.relative(sourceRoot, rp);
27641
- const mapped = path32.resolve(targetRoot, rel);
27773
+ const rel = path33.relative(sourceRoot, rp);
27774
+ const mapped = path33.resolve(targetRoot, rel);
27642
27775
  if (!isPathInsideRoot(mapped, targetRoot)) return false;
27643
27776
  return classifyEntityRefWritePath(targetRoot, mapped) === "entity";
27644
- }).map((p) => path32.basename(p, ".md"))
27777
+ }).map((p) => path33.basename(p, ".md"))
27645
27778
  );
27646
27779
  const firstEntityId = sourceEntityIds.values().next().value;
27647
27780
  if (firstEntityId === void 0) {
@@ -27649,7 +27782,7 @@ async function copyMemories(sourceDir, targetDir, options) {
27649
27782
  }
27650
27783
  return withRawEntityPageMutation(
27651
27784
  targetRoot,
27652
- path32.join(targetRoot, "entities", `${firstEntityId}.md`),
27785
+ path33.join(targetRoot, "entities", `${firstEntityId}.md`),
27653
27786
  async () => copyPreparedMemories(
27654
27787
  sourceFiles,
27655
27788
  sourceRoot,
@@ -27676,14 +27809,14 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27676
27809
  continue;
27677
27810
  }
27678
27811
  const content = fs5.readFileSync(sourcePath, "utf8");
27679
- const relativePath = path32.relative(sourceRoot, sourceRealPath);
27680
- const targetPath = path32.resolve(targetRoot, relativePath);
27812
+ const relativePath = path33.relative(sourceRoot, sourceRealPath);
27813
+ const targetPath = path33.resolve(targetRoot, relativePath);
27681
27814
  if (!isPathInsideRoot(targetPath, targetRoot)) {
27682
27815
  skipped++;
27683
27816
  continue;
27684
27817
  }
27685
27818
  const targetKind = classifyEntityRefWritePath(targetRoot, targetPath);
27686
- const idsAtCompare = historicalIdCache3.get(path32.join(targetRoot, "state"));
27819
+ const idsAtCompare = historicalIdCache3.get(path33.join(targetRoot, "state"));
27687
27820
  const sourceRef = targetKind === "memory" ? readEntityRefFromFrontmatter(content) : null;
27688
27821
  const refHasSourceClaimant = sourceRef !== null && sourceEntityIds.has(sourceRef);
27689
27822
  const canonicalContent = targetKind === "memory" && !refHasSourceClaimant ? canonicalizeEntityRefFrontmatter(content, idsAtCompare) : content;
@@ -27710,7 +27843,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27710
27843
  if (fs5.existsSync(targetPath) && !options?.force) {
27711
27844
  const targetContent = fs5.readFileSync(targetPath, "utf8");
27712
27845
  const targetHash = hashContent3(targetContent);
27713
- if (hashContent3(canonicalContent) === targetHash && historicalIdCache3.get(path32.join(targetRoot, "state")) === idsAtCompare) {
27846
+ if (hashContent3(canonicalContent) === targetHash && historicalIdCache3.get(path33.join(targetRoot, "state")) === idsAtCompare) {
27714
27847
  skipped++;
27715
27848
  continue;
27716
27849
  }
@@ -27726,13 +27859,13 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27726
27859
  continue;
27727
27860
  }
27728
27861
  }
27729
- fs5.mkdirSync(path32.dirname(targetPath), { recursive: true });
27730
- const targetParentRealPath = safeRealpath(path32.dirname(targetPath));
27862
+ fs5.mkdirSync(path33.dirname(targetPath), { recursive: true });
27863
+ const targetParentRealPath = safeRealpath(path33.dirname(targetPath));
27731
27864
  if (!targetParentRealPath || !isPathInsideRoot(targetParentRealPath, targetRoot)) {
27732
27865
  skipped++;
27733
27866
  continue;
27734
27867
  }
27735
- const stateDir = path32.join(targetRoot, "state");
27868
+ const stateDir = path33.join(targetRoot, "state");
27736
27869
  if (targetKind === "memory" && !refHasSourceClaimant) {
27737
27870
  const idsAtWrite = historicalIdCache3.get(stateDir);
27738
27871
  const written = canonicalizeEntityRefFrontmatter(content, idsAtWrite);
@@ -27776,7 +27909,7 @@ function copyPreparedMemories(sourceFiles, sourceRoot, targetRoot, sourceEntityI
27776
27909
  bumpMemoryCorpusVersionForDir(targetRoot);
27777
27910
  }
27778
27911
  if (reconcileNeeded) {
27779
- requestEntityCanonicalIdReconcileSync(path32.join(targetRoot, "state"));
27912
+ requestEntityCanonicalIdReconcileSync(path33.join(targetRoot, "state"));
27780
27913
  }
27781
27914
  return { merged, conflicts, skipped };
27782
27915
  }
@@ -27787,7 +27920,7 @@ function walkMd(dir) {
27787
27920
  const results = [];
27788
27921
  function walk(d) {
27789
27922
  for (const entry of fs5.readdirSync(d, { withFileTypes: true })) {
27790
- const fullPath = path32.join(d, entry.name);
27923
+ const fullPath = path33.join(d, entry.name);
27791
27924
  if (entry.isSymbolicLink()) {
27792
27925
  continue;
27793
27926
  }
@@ -27816,8 +27949,8 @@ function safeRealpath(filePath) {
27816
27949
  }
27817
27950
  }
27818
27951
  function isPathInsideRoot(candidatePath, rootPath) {
27819
- const relative = path32.relative(rootPath, candidatePath);
27820
- return relative === "" || !relative.startsWith("..") && !path32.isAbsolute(relative);
27952
+ const relative = path33.relative(rootPath, candidatePath);
27953
+ return relative === "" || !relative.startsWith("..") && !path33.isAbsolute(relative);
27821
27954
  }
27822
27955
  function parseSimpleFrontmatter(content) {
27823
27956
  const match = content.match(/^---\n([\s\S]*?)\n---/);
@@ -27938,7 +28071,7 @@ var REMNIC_RECALL_DECISION_RULES = `## When to Use Recall vs Direct Read
27938
28071
  // src/memory-extension/codex-publisher.ts
27939
28072
  import fs6 from "fs";
27940
28073
  import os from "os";
27941
- import path33 from "path";
28074
+ import path34 from "path";
27942
28075
  var REMNIC_EXTENSION_DIR_NAME = "remnic";
27943
28076
  function resolveEnvHome(env) {
27944
28077
  if (env === void 0) return resolveHomeDir();
@@ -27947,12 +28080,12 @@ function resolveEnvHome(env) {
27947
28080
  function expandTildeWithHome(input, homeDir) {
27948
28081
  if (input === "~") return homeDir;
27949
28082
  if (input.startsWith("~/") || input.startsWith("~\\")) {
27950
- return path33.join(homeDir, input.slice(2));
28083
+ return path34.join(homeDir, input.slice(2));
27951
28084
  }
27952
28085
  return input;
27953
28086
  }
27954
28087
  function normalizeHostRoot(input, homeDir) {
27955
- return path33.resolve(expandTildeWithHome(input.trim(), homeDir));
28088
+ return path34.resolve(expandTildeWithHome(input.trim(), homeDir));
27956
28089
  }
27957
28090
  var CodexMemoryExtensionPublisher = class {
27958
28091
  hostId = "codex";
@@ -27966,12 +28099,12 @@ var CodexMemoryExtensionPublisher = class {
27966
28099
  async resolveExtensionRoot(env) {
27967
28100
  const homeDir = resolveEnvHome(env);
27968
28101
  const codexHomeInput = env === void 0 ? readEnvVar("CODEX_HOME")?.trim() : env.CODEX_HOME?.trim();
27969
- const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path33.resolve(homeDir, ".codex");
27970
- return path33.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
28102
+ const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path34.resolve(homeDir, ".codex");
28103
+ return path34.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
27971
28104
  }
27972
28105
  async isHostAvailable() {
27973
28106
  try {
27974
- const home = readEnvVar("CODEX_HOME")?.trim() || path33.join(resolveHomeDir(), ".codex");
28107
+ const home = readEnvVar("CODEX_HOME")?.trim() || path34.join(resolveHomeDir(), ".codex");
27975
28108
  return fs6.existsSync(home);
27976
28109
  } catch {
27977
28110
  return false;
@@ -28022,7 +28155,7 @@ When running inside the Codex phase-2 consolidation sandbox:
28022
28155
  }
28023
28156
  async publish(ctx) {
28024
28157
  const extensionRoot = await this.resolveExtensionRoot();
28025
- const instructionsPath = path33.join(extensionRoot, "instructions.md");
28158
+ const instructionsPath = path34.join(extensionRoot, "instructions.md");
28026
28159
  const filesWritten = [];
28027
28160
  const skipped = [];
28028
28161
  ctx.log.info(`Publishing Codex memory extension to ${extensionRoot}`);
@@ -28654,9 +28787,9 @@ function buildWeeklyActivitySummary(cards, options) {
28654
28787
  // src/activity/timeline/weekly-persist.ts
28655
28788
  import { randomBytes as randomBytes3 } from "crypto";
28656
28789
  import { mkdirSync, readFileSync as readFileSync2, renameSync, unlinkSync, writeFileSync } from "fs";
28657
- import path34 from "path";
28790
+ import path35 from "path";
28658
28791
  var WEEKLY_SNAPSHOT_FORMAT_VERSION = 1;
28659
- var WEEKLY_SNAPSHOT_DIR = path34.join("activity", "weekly");
28792
+ var WEEKLY_SNAPSHOT_DIR = path35.join("activity", "weekly");
28660
28793
  function requireToken(value, name) {
28661
28794
  if (typeof value !== "string" || value.trim().length === 0) {
28662
28795
  throw new TypeError(`${name} must be a non-empty string`);
@@ -28679,8 +28812,8 @@ function weeklySnapshotPath(input) {
28679
28812
  const identity = hashActivityBody(
28680
28813
  `${input.summary.weekStartUtc}\0${input.summary.weekEndUtc}\0${sourceRevision}\0${configHash}`
28681
28814
  );
28682
- return path34.join(
28683
- path34.resolve(memoryDir),
28815
+ return path35.join(
28816
+ path35.resolve(memoryDir),
28684
28817
  WEEKLY_SNAPSHOT_DIR,
28685
28818
  namespaceIdentityToken(namespace),
28686
28819
  `${weekDate}--${identity}.json`
@@ -28710,7 +28843,7 @@ function persistWeeklySnapshot(input) {
28710
28843
  throw error;
28711
28844
  }
28712
28845
  }
28713
- mkdirSync(path34.dirname(filePath), { recursive: true, mode: 448 });
28846
+ mkdirSync(path35.dirname(filePath), { recursive: true, mode: 448 });
28714
28847
  const tmpPath = `${filePath}.${process.pid}.${randomBytes3(8).toString("hex")}.tmp`;
28715
28848
  writeFileSync(tmpPath, text, { encoding: "utf8", mode: 384 });
28716
28849
  try {
@@ -29362,7 +29495,7 @@ function selectRecapForDay(input) {
29362
29495
 
29363
29496
  // src/activity/journal-read.ts
29364
29497
  import { closeSync, constants as fsConstants, fstatSync, lstatSync, openSync, readFileSync as readFileSync3, realpathSync, statSync as statSync2 } from "fs";
29365
- import path35 from "path";
29498
+ import path36 from "path";
29366
29499
 
29367
29500
  // src/activity/journal-section.ts
29368
29501
  function parseAtxHeading(line) {
@@ -29553,8 +29686,8 @@ function readJournalForDate(input) {
29553
29686
  const relative = resolveVaultNotePath(input.vault.dailyNotePath, input.date, {
29554
29687
  timezone: input.timezone
29555
29688
  });
29556
- const root = path35.resolve(expandTildePath(input.vault.vaultPath));
29557
- const filePath = path35.join(root, relative);
29689
+ const root = path36.resolve(expandTildePath(input.vault.vaultPath));
29690
+ const filePath = path36.join(root, relative);
29558
29691
  try {
29559
29692
  const rootStat = lstatSync(root);
29560
29693
  if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
@@ -29563,8 +29696,8 @@ function readJournalForDate(input) {
29563
29696
  } catch {
29564
29697
  return { ok: true, exists: false, reason: "missing_file", filePath };
29565
29698
  }
29566
- const lexical = path35.relative(root, filePath);
29567
- if (lexical.length === 0 || lexical === ".." || lexical.startsWith(`..${path35.sep}`) || path35.isAbsolute(lexical)) {
29699
+ const lexical = path36.relative(root, filePath);
29700
+ if (lexical.length === 0 || lexical === ".." || lexical.startsWith(`..${path36.sep}`) || path36.isAbsolute(lexical)) {
29568
29701
  return { ok: false, reason: "path_escape", filePath };
29569
29702
  }
29570
29703
  if (!containedBySymlinks(root, filePath)) {
@@ -29597,11 +29730,11 @@ function containedBySymlinks(root, dest) {
29597
29730
  try {
29598
29731
  if (statSync2(probe).isFile() || statSync2(probe).isDirectory()) {
29599
29732
  const real = realpathSync(probe);
29600
- return real === realRoot || real.startsWith(`${realRoot}${path35.sep}`);
29733
+ return real === realRoot || real.startsWith(`${realRoot}${path36.sep}`);
29601
29734
  }
29602
29735
  } catch {
29603
29736
  }
29604
- const parent = path35.dirname(probe);
29737
+ const parent = path36.dirname(probe);
29605
29738
  if (parent === probe) return false;
29606
29739
  probe = parent;
29607
29740
  }
@@ -29612,15 +29745,15 @@ function symlinkRejected() {
29612
29745
  return err;
29613
29746
  }
29614
29747
  function readVerifiedDailyNote(root, filePath) {
29615
- const relative = path35.relative(root, filePath);
29616
- const parts = relative.split(path35.sep).filter((part) => part.length > 0 && part !== ".");
29748
+ const relative = path36.relative(root, filePath);
29749
+ const parts = relative.split(path36.sep).filter((part) => part.length > 0 && part !== ".");
29617
29750
  let cursor = root;
29618
29751
  for (const part of parts) {
29619
- cursor = path35.join(cursor, part);
29752
+ cursor = path36.join(cursor, part);
29620
29753
  const st = lstatSync(cursor);
29621
29754
  if (st.isSymbolicLink()) throw symlinkRejected();
29622
29755
  }
29623
- const parent = path35.dirname(filePath);
29756
+ const parent = path36.dirname(filePath);
29624
29757
  const parentLstat = lstatSync(parent);
29625
29758
  if (parentLstat.isSymbolicLink() || !parentLstat.isDirectory()) throw symlinkRejected();
29626
29759
  const nofollow = fsConstants.O_NOFOLLOW ?? 0;
@@ -29644,7 +29777,7 @@ function readVerifiedDailyNote(root, filePath) {
29644
29777
  try {
29645
29778
  const fdPath = realpathSync(`/proc/self/fd/${fd}`);
29646
29779
  const realRoot = realpathSync(root);
29647
- if (fdPath !== realRoot && !fdPath.startsWith(`${realRoot}${path35.sep}`)) {
29780
+ if (fdPath !== realRoot && !fdPath.startsWith(`${realRoot}${path36.sep}`)) {
29648
29781
  throw symlinkRejected();
29649
29782
  }
29650
29783
  } catch (err) {
@@ -29659,11 +29792,11 @@ function readVerifiedDailyNote(root, filePath) {
29659
29792
  // src/activity/journal-state.ts
29660
29793
  import { createHash as createHash11, randomBytes as randomBytes4 } from "crypto";
29661
29794
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "fs";
29662
- import path36 from "path";
29795
+ import path37 from "path";
29663
29796
  var STATE_DIR_NAME = "state";
29664
29797
  var STATE_FILE_NAME = "timeline.json";
29665
29798
  function timelineStatePath(memoryDir) {
29666
- return path36.join(memoryDir, STATE_DIR_NAME, STATE_FILE_NAME);
29799
+ return path37.join(memoryDir, STATE_DIR_NAME, STATE_FILE_NAME);
29667
29800
  }
29668
29801
  function hashJournalText(text) {
29669
29802
  return createHash11("sha256").update(text, "utf8").digest("hex");
@@ -29689,14 +29822,14 @@ function readTimelineState(memoryDir) {
29689
29822
  }
29690
29823
  function writeTimelineState(memoryDir, state) {
29691
29824
  const filePath = timelineStatePath(memoryDir);
29692
- mkdirSync2(path36.dirname(filePath), { recursive: true });
29825
+ mkdirSync2(path37.dirname(filePath), { recursive: true });
29693
29826
  const tempPath = `${filePath}.${process.pid}.${randomBytes4(8).toString("hex")}.tmp`;
29694
29827
  writeFileSync2(tempPath, `${JSON.stringify(state, null, 2)}
29695
29828
  `);
29696
29829
  renameSync2(tempPath, filePath);
29697
29830
  }
29698
29831
  function journalDateLockPath(memoryDir, date) {
29699
- return path36.join(memoryDir, STATE_DIR_NAME, `journal-extract-${date}.lock`);
29832
+ return path37.join(memoryDir, STATE_DIR_NAME, `journal-extract-${date}.lock`);
29700
29833
  }
29701
29834
  function timelineStateLockPath(memoryDir) {
29702
29835
  return `${timelineStatePath(memoryDir)}.lock`;
@@ -30404,7 +30537,7 @@ function normalizeDropKeys(keys) {
30404
30537
  }
30405
30538
 
30406
30539
  // src/activity/vault-wikilink.ts
30407
- import path37 from "path";
30540
+ import path38 from "path";
30408
30541
  function formatVaultWikilink(notePath) {
30409
30542
  if (typeof notePath !== "string" || notePath.trim().length === 0) {
30410
30543
  throw new RangeError("Vault wikilink path must be a non-empty relative path.");
@@ -30412,7 +30545,7 @@ function formatVaultWikilink(notePath) {
30412
30545
  if (notePath.includes("\n") || notePath.includes("\r")) {
30413
30546
  throw new RangeError("Vault wikilink path must not contain newlines.");
30414
30547
  }
30415
- if (path37.posix.isAbsolute(notePath) || path37.win32.isAbsolute(notePath)) {
30548
+ if (path38.posix.isAbsolute(notePath) || path38.win32.isAbsolute(notePath)) {
30416
30549
  throw new RangeError("Vault wikilink path must be relative; absolute paths are rejected.");
30417
30550
  }
30418
30551
  if (notePath.split(/[\\/]/).some((segment) => segment === "..")) {
@@ -30434,7 +30567,7 @@ function stripVaultMdSuffix(notePath) {
30434
30567
  }
30435
30568
 
30436
30569
  // src/activity/vault-join.ts
30437
- import path38 from "path";
30570
+ import path39 from "path";
30438
30571
  function joinVaultSegments(parts) {
30439
30572
  if (parts.length === 0) {
30440
30573
  throw new RangeError("Vault path parts must be a non-empty list.");
@@ -30449,7 +30582,7 @@ function joinVaultSegments(parts) {
30449
30582
  if (part.includes("\n") || part.includes("\r")) {
30450
30583
  throw new RangeError("Vault path part must not contain a newline.");
30451
30584
  }
30452
- if (path38.posix.isAbsolute(part) || path38.win32.isAbsolute(part)) {
30585
+ if (path39.posix.isAbsolute(part) || path39.win32.isAbsolute(part)) {
30453
30586
  throw new RangeError("Vault path part must be relative.");
30454
30587
  }
30455
30588
  if (part.split("/").includes("..")) {
@@ -30504,7 +30637,7 @@ function planVaultDryRun(inputs) {
30504
30637
  // src/session-summaries/index.ts
30505
30638
  import { createHash as createHash12 } from "crypto";
30506
30639
  import { lstat as lstat3, mkdir as mkdir7, readFile as readFile9, readdir as readdir4, rename, rm, stat as stat4, writeFile as writeFile7 } from "fs/promises";
30507
- import path39 from "path";
30640
+ import path40 from "path";
30508
30641
 
30509
30642
  // src/session-summaries/adapters.ts
30510
30643
  var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "other"]);
@@ -31009,7 +31142,7 @@ function shortHash(value, length = 16) {
31009
31142
  async function listTranscriptFiles(root, maxFiles) {
31010
31143
  const out = [];
31011
31144
  let truncated = false;
31012
- const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path39.sep}` : entryName;
31145
+ const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path40.sep}` : entryName;
31013
31146
  async function visit(dir) {
31014
31147
  if (truncated) return;
31015
31148
  const entries = (await readdir4(dir, { withFileTypes: true })).sort(
@@ -31019,13 +31152,13 @@ async function listTranscriptFiles(root, maxFiles) {
31019
31152
  if (truncated) return;
31020
31153
  if (entry.name.startsWith(".")) continue;
31021
31154
  if (entry.isSymbolicLink()) continue;
31022
- const fullPath = path39.join(dir, entry.name);
31155
+ const fullPath = path40.join(dir, entry.name);
31023
31156
  if (entry.isDirectory()) {
31024
31157
  await visit(fullPath);
31025
31158
  continue;
31026
31159
  }
31027
31160
  if (!entry.isFile()) continue;
31028
- const ext = path39.extname(entry.name).toLowerCase();
31161
+ const ext = path40.extname(entry.name).toLowerCase();
31029
31162
  if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
31030
31163
  out.push(fullPath);
31031
31164
  if (out.length > maxFiles) {
@@ -31052,7 +31185,7 @@ function normalizeInputDir(inputDir) {
31052
31185
  if (typeof inputDir !== "string" || inputDir.trim().length === 0) {
31053
31186
  throw new Error("inputDir must be a non-empty string");
31054
31187
  }
31055
- return path39.resolve(expandTildePath(inputDir.trim()));
31188
+ return path40.resolve(expandTildePath(inputDir.trim()));
31056
31189
  }
31057
31190
  function initRoleCounts() {
31058
31191
  return {
@@ -31209,11 +31342,11 @@ async function collectLocalSessionSummaries(options) {
31209
31342
  continue;
31210
31343
  }
31211
31344
  seenFileHashes.add(fileHash);
31212
- const fileExtension = path39.extname(filePath).toLowerCase();
31345
+ const fileExtension = path40.extname(filePath).toLowerCase();
31213
31346
  const parsed = await adapter.parseFile(
31214
31347
  {
31215
31348
  content,
31216
- fileName: path39.basename(filePath),
31349
+ fileName: path40.basename(filePath),
31217
31350
  fileExtension,
31218
31351
  fileRef: fileHash
31219
31352
  },
@@ -31269,7 +31402,7 @@ async function collectLocalSessionSummaries(options) {
31269
31402
  }
31270
31403
  async function readRedactionConfig(pathLike) {
31271
31404
  if (!pathLike) return void 0;
31272
- const raw = await readFile9(path39.resolve(expandTildePath(pathLike)), "utf-8");
31405
+ const raw = await readFile9(path40.resolve(expandTildePath(pathLike)), "utf-8");
31273
31406
  const parsed = JSON.parse(raw);
31274
31407
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
31275
31408
  throw new Error("redaction config must be a JSON object");
@@ -31282,15 +31415,15 @@ function toJsonl(drafts) {
31282
31415
  }
31283
31416
  function defaultDraftOutputPath(memoryDir, generatedAt) {
31284
31417
  const stamp = generatedAt.replace(/[:.]/g, "-");
31285
- return path39.join(
31286
- path39.resolve(expandTildePath(memoryDir)),
31418
+ return path40.join(
31419
+ path40.resolve(expandTildePath(memoryDir)),
31287
31420
  "state",
31288
31421
  "session-summary-drafts",
31289
31422
  `session-summaries-${stamp}.jsonl`
31290
31423
  );
31291
31424
  }
31292
31425
  async function writeDrafts(filePath, drafts) {
31293
- await mkdir7(path39.dirname(filePath), { recursive: true });
31426
+ await mkdir7(path40.dirname(filePath), { recursive: true });
31294
31427
  const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
31295
31428
  try {
31296
31429
  await writeFile7(tempPath, toJsonl(drafts), "utf-8");
@@ -31308,7 +31441,7 @@ async function runLocalSessionSummaryCliCommand(options) {
31308
31441
  });
31309
31442
  const wroteFiles = [];
31310
31443
  if (options.output) {
31311
- const outputPath = path39.resolve(expandTildePath(options.output));
31444
+ const outputPath = path40.resolve(expandTildePath(options.output));
31312
31445
  await writeDrafts(outputPath, report.drafts);
31313
31446
  wroteFiles.push(outputPath);
31314
31447
  }
@@ -31343,19 +31476,19 @@ async function runLocalSessionSummaryCliCommand(options) {
31343
31476
 
31344
31477
  // src/transfer/capsule-fork.ts
31345
31478
  import { lstat as lstat4, mkdir as mkdir8, readFile as readFile10, realpath as realpath3, writeFile as writeFile8 } from "fs/promises";
31346
- import path40 from "path";
31479
+ import path41 from "path";
31347
31480
  async function forkCapsule(opts) {
31348
31481
  validateForkId(opts.forkId);
31349
- const rootAbs = path40.resolve(opts.targetRoot);
31482
+ const rootAbs = path41.resolve(opts.targetRoot);
31350
31483
  await assertIsDirectoryNotSymlink(rootAbs, "forkCapsule", "targetRoot");
31351
- const forkDirAbs = path40.join(rootAbs, "forks", opts.forkId);
31484
+ const forkDirAbs = path41.join(rootAbs, "forks", opts.forkId);
31352
31485
  const forkEntryExists = await pathEntryExists(forkDirAbs);
31353
31486
  if (forkEntryExists) {
31354
31487
  throw new Error(
31355
31488
  `forkCapsule: fork path already exists \u2014 forkId "${opts.forkId}" is already in use at: ${forkDirAbs}`
31356
31489
  );
31357
31490
  }
31358
- const archiveAbs = path40.resolve(opts.sourceArchive);
31491
+ const archiveAbs = path41.resolve(opts.sourceArchive);
31359
31492
  const importResult = await importCapsule({
31360
31493
  archivePath: archiveAbs,
31361
31494
  root: rootAbs,
@@ -31377,10 +31510,10 @@ async function forkCapsule(opts) {
31377
31510
  importedRecords: importResult.imported.length,
31378
31511
  skippedRecords: importResult.skipped.length
31379
31512
  };
31380
- const lineagePath = path40.join(forkDirAbs, "lineage.json");
31513
+ const lineagePath = path41.join(forkDirAbs, "lineage.json");
31381
31514
  const rootReal = await realpath3(rootAbs);
31382
31515
  await assertRealpathInsideRoot(rootReal, lineagePath, `forks/${opts.forkId}/lineage.json`, "forkCapsule");
31383
- await mkdir8(path40.dirname(lineagePath), { recursive: true });
31516
+ await mkdir8(path41.dirname(lineagePath), { recursive: true });
31384
31517
  await writeFile8(lineagePath, JSON.stringify(lineage, null, 2) + "\n", "utf-8");
31385
31518
  return {
31386
31519
  archivePath: archiveAbs,
@@ -31394,11 +31527,11 @@ async function readForkLineage(targetRoot, forkId) {
31394
31527
  if (typeof forkId !== "string" || forkId.length === 0 || forkId.length > 64 || !CAPSULE_ID_PATTERN.test(forkId)) {
31395
31528
  return null;
31396
31529
  }
31397
- const rootAbs = path40.resolve(targetRoot);
31530
+ const rootAbs = path41.resolve(targetRoot);
31398
31531
  const rootReal = await realpath3(rootAbs).catch(() => rootAbs);
31399
- const lineagePath = path40.join(rootReal, "forks", forkId, "lineage.json");
31400
- const rel = path40.relative(rootReal, lineagePath);
31401
- if (rel.startsWith("..") || path40.isAbsolute(rel)) {
31532
+ const lineagePath = path41.join(rootReal, "forks", forkId, "lineage.json");
31533
+ const rel = path41.relative(rootReal, lineagePath);
31534
+ if (rel.startsWith("..") || path41.isAbsolute(rel)) {
31402
31535
  return null;
31403
31536
  }
31404
31537
  if (!await isLineagePathContained(rootReal, lineagePath)) {
@@ -31439,19 +31572,19 @@ async function pathEntryExists(absPath) {
31439
31572
  async function isLineagePathContained(rootReal, lineagePath) {
31440
31573
  let existing = lineagePath;
31441
31574
  const suffix = [];
31442
- while (existing !== path40.dirname(existing)) {
31575
+ while (existing !== path41.dirname(existing)) {
31443
31576
  const st = await lstat4(existing).catch(() => null);
31444
31577
  if (st !== null) break;
31445
- suffix.unshift(path40.basename(existing));
31446
- existing = path40.dirname(existing);
31578
+ suffix.unshift(path41.basename(existing));
31579
+ existing = path41.dirname(existing);
31447
31580
  }
31448
31581
  const existingReal = await realpath3(existing).catch(() => existing);
31449
- const targetReal = suffix.length > 0 ? path40.join(existingReal, ...suffix) : existingReal;
31450
- const rel = path40.relative(rootReal, targetReal);
31582
+ const targetReal = suffix.length > 0 ? path41.join(existingReal, ...suffix) : existingReal;
31583
+ const rel = path41.relative(rootReal, targetReal);
31451
31584
  if (rel === "") return true;
31452
31585
  if (rel === "..") return false;
31453
- if (rel.startsWith(`..${path40.sep}`)) return false;
31454
- if (path40.isAbsolute(rel)) return false;
31586
+ if (rel.startsWith(`..${path41.sep}`)) return false;
31587
+ if (path41.isAbsolute(rel)) return false;
31455
31588
  return true;
31456
31589
  }
31457
31590
 
@@ -31644,4 +31777,4 @@ export {
31644
31777
  qmdStartupCollectionChecksWithTimeout,
31645
31778
  Orchestrator
31646
31779
  };
31647
- //# sourceMappingURL=chunk-2ZSRACNK.js.map
31780
+ //# sourceMappingURL=chunk-LFYEQK45.js.map