@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.
- package/dist/access-admin-ops-surface.js +16 -16
- package/dist/access-authorization-probe.js +17 -17
- package/dist/access-boundary.js +16 -16
- package/dist/access-cli.js +61 -61
- package/dist/access-extraction-force-flush.js +16 -16
- package/dist/access-http-briefing.js +17 -17
- package/dist/access-http-query.js +18 -18
- package/dist/access-http.js +33 -33
- package/dist/access-identity-continuity-surface.js +16 -16
- package/dist/access-lcm-surface.js +16 -16
- package/dist/access-mcp.js +26 -26
- package/dist/access-namespace-preflight.js +16 -16
- package/dist/access-observe-write-surface.js +16 -16
- package/dist/access-operations-batch.js +17 -17
- package/dist/access-operations.js +24 -24
- package/dist/access-recall-concurrency.js +16 -16
- package/dist/access-recall-diagnostics.js +2 -2
- package/dist/access-recall-response.js +16 -16
- package/dist/access-recall-surface.js +16 -16
- package/dist/access-service.js +16 -16
- package/dist/access-surface-catalog.js +18 -18
- package/dist/active-recall.js +3 -3
- package/dist/briefing.js +3 -3
- package/dist/buffer.js +2 -2
- package/dist/causal-consolidation.js +4 -4
- package/dist/{chunk-KISOMGY2.js → chunk-3RHU5MD7.js} +2 -2
- package/dist/{chunk-3LSTL6EY.js → chunk-4MPAKYZU.js} +2 -2
- package/dist/{chunk-OVL5AD3N.js → chunk-4NV7O76Q.js} +2 -2
- package/dist/{chunk-BH7NVSEC.js → chunk-4SOWMA55.js} +3 -3
- package/dist/{chunk-GROHOWR5.js → chunk-5MGKGEL7.js} +2 -2
- package/dist/{chunk-ZPLQ27MY.js → chunk-5UM4H64E.js} +2 -2
- package/dist/{chunk-2DNFRLLL.js → chunk-5Y6VA6X2.js} +2 -2
- package/dist/{chunk-GRAUQXQB.js → chunk-6WKWL53V.js} +13 -13
- package/dist/{chunk-HOR4RMUM.js → chunk-75DCOS6I.js} +24 -24
- package/dist/{chunk-25QK3LR2.js → chunk-7O2MC42R.js} +2 -2
- package/dist/{chunk-7ETWIBTO.js → chunk-ADYP7HXE.js} +3 -3
- package/dist/{chunk-FUDKGJDN.js → chunk-AVGDYYMA.js} +2 -2
- package/dist/{chunk-ECF627KC.js → chunk-AYJQ644F.js} +2 -2
- package/dist/{chunk-T22FBDG3.js → chunk-B3MWELZ3.js} +2 -2
- package/dist/{chunk-DRTSPRWL.js → chunk-B4DXREWC.js} +2 -2
- package/dist/{chunk-5UEGL5BF.js → chunk-CI3MAAIY.js} +2 -2
- package/dist/{chunk-7JYK7NNY.js → chunk-CTH2CQCB.js} +2 -2
- package/dist/{chunk-UVHXLVFJ.js → chunk-EURPSF4Y.js} +2 -2
- package/dist/{chunk-VPEA63FC.js → chunk-EWJZZDRG.js} +2 -2
- package/dist/{chunk-BOZQAUAJ.js → chunk-EXQJMFRF.js} +2 -2
- package/dist/{chunk-UH6ROXFJ.js → chunk-GGD2YDS6.js} +2 -2
- package/dist/{chunk-5JABRT5G.js → chunk-GHHQLSSY.js} +3 -3
- package/dist/{chunk-N4T5FW6U.js → chunk-GJ4HU6LK.js} +2 -2
- package/dist/{chunk-HRRAOTOQ.js → chunk-H5DIRCZP.js} +12 -12
- package/dist/{chunk-434E4BTO.js → chunk-HH73M65H.js} +3 -3
- package/dist/{chunk-LIGZO7XN.js → chunk-HPB5TF55.js} +2 -2
- package/dist/{chunk-E4QIX2OB.js → chunk-IAGVM7EY.js} +2 -2
- package/dist/{chunk-YJQJRXUI.js → chunk-IG3EZ3TF.js} +2 -2
- package/dist/{chunk-KNMSD2MQ.js → chunk-IVUVQPTQ.js} +2 -2
- package/dist/{chunk-XOFIJGB2.js → chunk-IZBIDPMY.js} +2 -2
- package/dist/{chunk-HFEGRMFG.js → chunk-JLGBJ4AX.js} +7 -7
- package/dist/{chunk-BBHKN2CN.js → chunk-JLMOH5JA.js} +2 -2
- package/dist/{chunk-TPCRDPUY.js → chunk-KZSGBWOJ.js} +2 -2
- package/dist/{chunk-SHHZWSSE.js → chunk-KZZ5EZ7O.js} +2 -2
- package/dist/{chunk-2ZSRACNK.js → chunk-LFYEQK45.js} +682 -549
- package/dist/chunk-LFYEQK45.js.map +1 -0
- package/dist/{chunk-FKGLJJVS.js → chunk-LN4X2NDA.js} +2 -2
- package/dist/{chunk-5ZHFPUBC.js → chunk-MOIJWWNA.js} +8 -8
- package/dist/{chunk-KO224R36.js → chunk-NCZGGGWI.js} +2 -2
- package/dist/{chunk-XVQVF2TK.js → chunk-NHWDTOBN.js} +269 -230
- package/dist/chunk-NHWDTOBN.js.map +1 -0
- package/dist/{chunk-7ZTGMEXF.js → chunk-O5ZINWW3.js} +2 -2
- package/dist/{chunk-WWH7GJ42.js → chunk-OCK4D5PC.js} +2 -2
- package/dist/{chunk-G6L3REL3.js → chunk-OPFVXM2D.js} +2 -2
- package/dist/{chunk-FR7PK7ED.js → chunk-P4TV3TQ2.js} +2 -2
- package/dist/{chunk-P2EM5LKH.js → chunk-PMDOGXA2.js} +2 -2
- package/dist/{chunk-NM2II57L.js → chunk-PRKNAIGZ.js} +2 -1
- package/dist/chunk-PRKNAIGZ.js.map +1 -0
- package/dist/{chunk-MRF5V5CD.js → chunk-QGFR73SN.js} +2 -2
- package/dist/{chunk-6D3IWYNY.js → chunk-R2BIVU2Z.js} +354 -292
- package/dist/chunk-R2BIVU2Z.js.map +1 -0
- package/dist/{chunk-HG3CG557.js → chunk-RLVI2M5Q.js} +2 -2
- package/dist/{chunk-HHL4MX3W.js → chunk-SXTVZ6JL.js} +2 -2
- package/dist/{chunk-CLSKGTAT.js → chunk-TECK5IVY.js} +2 -2
- package/dist/{chunk-SNS3DWG6.js → chunk-TVE7W67N.js} +2 -2
- package/dist/{chunk-KYSSUY66.js → chunk-U2CAGMUD.js} +2 -2
- package/dist/{chunk-XLCEFUAU.js → chunk-UVVFPCPX.js} +2 -2
- package/dist/{chunk-KQJUEQ2E.js → chunk-UW6LBFYN.js} +5 -5
- package/dist/{chunk-SEA56G6S.js → chunk-V4XE263I.js} +1 -1
- package/dist/chunk-V4XE263I.js.map +1 -0
- package/dist/{chunk-JL5HXL25.js → chunk-V6SBA5O7.js} +3 -3
- package/dist/{chunk-R7WYAXPO.js → chunk-VHSQU3RO.js} +81 -42
- package/dist/chunk-VHSQU3RO.js.map +1 -0
- package/dist/{chunk-B7VD36TI.js → chunk-WHROVQ5Q.js} +3 -3
- package/dist/{chunk-LDHR465K.js → chunk-Y3XPSGNF.js} +2 -2
- package/dist/{chunk-JPY3RMG2.js → chunk-ZORS5BG5.js} +4 -4
- package/dist/{chunk-KXY4HW2Y.js → chunk-ZXF3O7P4.js} +2 -2
- package/dist/cli.js +47 -47
- package/dist/coding/export-okf-codegraph.js +2 -2
- package/dist/compounding/engine.js +4 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -3
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/index.js +3 -3
- package/dist/convergence-refresh.js +5 -5
- package/dist/corpus-watermark.js +5 -5
- package/dist/entity-retrieval.js +3 -3
- package/dist/external-wiki-access.js +17 -17
- package/dist/extraction.js +6 -6
- package/dist/harmonic-retrieval.js +3 -3
- package/dist/index.js +61 -61
- package/dist/location/index.js +5 -5
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection-runner.js +5 -5
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/memory-browse-operations.js +17 -17
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/storage.js +3 -3
- package/dist/operator-doctor-corpus.js +6 -6
- package/dist/operator-toolkit.js +12 -12
- package/dist/orchestration/buffer-drain-runner.js +61 -61
- package/dist/orchestration/consolidation-run.d.ts.map +1 -1
- package/dist/orchestration/extraction-drain.d.ts +4 -4
- package/dist/orchestration/extraction-drain.d.ts.map +1 -1
- package/dist/orchestration/extraction-persist-deps.d.ts +0 -2
- package/dist/orchestration/extraction-persist-deps.d.ts.map +1 -1
- package/dist/orchestration/extraction-persist.d.ts +10 -4
- package/dist/orchestration/extraction-persist.d.ts.map +1 -1
- package/dist/orchestration/extraction-queue-coordinator.d.ts +67 -33
- package/dist/orchestration/extraction-queue-coordinator.d.ts.map +1 -1
- package/dist/orchestration/extraction-run-helpers.d.ts +3 -2
- package/dist/orchestration/extraction-run-helpers.d.ts.map +1 -1
- package/dist/orchestration/extraction-run.d.ts +4 -14
- package/dist/orchestration/extraction-run.d.ts.map +1 -1
- package/dist/orchestration/fact-dedup-window.d.ts +49 -0
- package/dist/orchestration/fact-dedup-window.d.ts.map +1 -0
- package/dist/orchestration/maintenance.js +13 -13
- package/dist/orchestration/provider-breaker.d.ts +58 -0
- package/dist/orchestration/provider-breaker.d.ts.map +1 -0
- package/dist/orchestrator.d.ts +2 -17
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +61 -61
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.js +2 -2
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-navigation-operations.js +17 -17
- package/dist/recall-navigation.js +16 -16
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/resume-bundles.js +4 -4
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/source-agent-qualifier.js +5 -5
- package/dist/standup/build.js +3 -3
- package/dist/storage/profile-mutation.d.ts +25 -0
- package/dist/storage/profile-mutation.d.ts.map +1 -0
- package/dist/storage.d.ts +4 -6
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +2 -2
- package/dist/support-passport/index.js +19 -19
- package/dist/threading.d.ts +21 -4
- package/dist/threading.d.ts.map +1 -1
- package/dist/threading.js +1 -1
- package/dist/transfer/export-okf.js +3 -3
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/verified-recall.js +3 -3
- package/dist/who-knows-cli.js +4 -4
- package/dist/who-knows.js +3 -3
- package/package.json +2 -2
- package/src/access-observe-replay-durability.test.ts +1 -1
- package/src/buffer-drain-handover.test.ts +3 -3
- package/src/buffer-drop-extraction-chunk.test.ts +0 -1
- package/src/config.test.ts +12 -0
- package/src/config.ts +2 -0
- package/src/connector-provenance-lifecycle.test.ts +5 -8
- package/src/fact-dedup-window.test.ts +116 -0
- package/src/faithfulness-graph-guard.test.ts +11 -6
- package/src/harmonic-construction.test.ts +16 -10
- package/src/orchestration/consolidation-profile-race.test.ts +178 -0
- package/src/orchestration/consolidation-run.ts +19 -7
- package/src/orchestration/extraction-drain.ts +10 -3
- package/src/orchestration/extraction-persist-deps.ts +0 -2
- package/src/orchestration/extraction-persist.ts +159 -148
- package/src/orchestration/extraction-queue-coordinator.ts +167 -56
- package/src/orchestration/extraction-run-helpers.ts +5 -4
- package/src/orchestration/extraction-run.test.ts +1 -2
- package/src/orchestration/extraction-run.ts +56 -99
- package/src/orchestration/fact-dedup-window.ts +122 -0
- package/src/orchestration/provider-breaker.test.ts +89 -0
- package/src/orchestration/provider-breaker.ts +158 -0
- package/src/orchestration/turn-ingestion.ts +5 -5
- package/src/orchestrator-extraction-queue.test.ts +179 -8
- package/src/orchestrator.ts +7 -23
- package/src/storage/profile-mutation.ts +119 -0
- package/src/storage-append-profile.test.ts +114 -0
- package/src/storage.ts +17 -48
- package/src/testing/orchestrator-lite.ts +1 -1
- package/src/threading.test.ts +153 -0
- package/src/threading.ts +95 -45
- package/src/types.ts +2 -0
- package/dist/chunk-2ZSRACNK.js.map +0 -1
- package/dist/chunk-6D3IWYNY.js.map +0 -1
- package/dist/chunk-NM2II57L.js.map +0 -1
- package/dist/chunk-R7WYAXPO.js.map +0 -1
- package/dist/chunk-SEA56G6S.js.map +0 -1
- package/dist/chunk-XVQVF2TK.js.map +0 -1
- /package/dist/{chunk-KISOMGY2.js.map → chunk-3RHU5MD7.js.map} +0 -0
- /package/dist/{chunk-3LSTL6EY.js.map → chunk-4MPAKYZU.js.map} +0 -0
- /package/dist/{chunk-OVL5AD3N.js.map → chunk-4NV7O76Q.js.map} +0 -0
- /package/dist/{chunk-BH7NVSEC.js.map → chunk-4SOWMA55.js.map} +0 -0
- /package/dist/{chunk-GROHOWR5.js.map → chunk-5MGKGEL7.js.map} +0 -0
- /package/dist/{chunk-ZPLQ27MY.js.map → chunk-5UM4H64E.js.map} +0 -0
- /package/dist/{chunk-2DNFRLLL.js.map → chunk-5Y6VA6X2.js.map} +0 -0
- /package/dist/{chunk-GRAUQXQB.js.map → chunk-6WKWL53V.js.map} +0 -0
- /package/dist/{chunk-HOR4RMUM.js.map → chunk-75DCOS6I.js.map} +0 -0
- /package/dist/{chunk-25QK3LR2.js.map → chunk-7O2MC42R.js.map} +0 -0
- /package/dist/{chunk-7ETWIBTO.js.map → chunk-ADYP7HXE.js.map} +0 -0
- /package/dist/{chunk-FUDKGJDN.js.map → chunk-AVGDYYMA.js.map} +0 -0
- /package/dist/{chunk-ECF627KC.js.map → chunk-AYJQ644F.js.map} +0 -0
- /package/dist/{chunk-T22FBDG3.js.map → chunk-B3MWELZ3.js.map} +0 -0
- /package/dist/{chunk-DRTSPRWL.js.map → chunk-B4DXREWC.js.map} +0 -0
- /package/dist/{chunk-5UEGL5BF.js.map → chunk-CI3MAAIY.js.map} +0 -0
- /package/dist/{chunk-7JYK7NNY.js.map → chunk-CTH2CQCB.js.map} +0 -0
- /package/dist/{chunk-UVHXLVFJ.js.map → chunk-EURPSF4Y.js.map} +0 -0
- /package/dist/{chunk-VPEA63FC.js.map → chunk-EWJZZDRG.js.map} +0 -0
- /package/dist/{chunk-BOZQAUAJ.js.map → chunk-EXQJMFRF.js.map} +0 -0
- /package/dist/{chunk-UH6ROXFJ.js.map → chunk-GGD2YDS6.js.map} +0 -0
- /package/dist/{chunk-5JABRT5G.js.map → chunk-GHHQLSSY.js.map} +0 -0
- /package/dist/{chunk-N4T5FW6U.js.map → chunk-GJ4HU6LK.js.map} +0 -0
- /package/dist/{chunk-HRRAOTOQ.js.map → chunk-H5DIRCZP.js.map} +0 -0
- /package/dist/{chunk-434E4BTO.js.map → chunk-HH73M65H.js.map} +0 -0
- /package/dist/{chunk-LIGZO7XN.js.map → chunk-HPB5TF55.js.map} +0 -0
- /package/dist/{chunk-E4QIX2OB.js.map → chunk-IAGVM7EY.js.map} +0 -0
- /package/dist/{chunk-YJQJRXUI.js.map → chunk-IG3EZ3TF.js.map} +0 -0
- /package/dist/{chunk-KNMSD2MQ.js.map → chunk-IVUVQPTQ.js.map} +0 -0
- /package/dist/{chunk-XOFIJGB2.js.map → chunk-IZBIDPMY.js.map} +0 -0
- /package/dist/{chunk-HFEGRMFG.js.map → chunk-JLGBJ4AX.js.map} +0 -0
- /package/dist/{chunk-BBHKN2CN.js.map → chunk-JLMOH5JA.js.map} +0 -0
- /package/dist/{chunk-TPCRDPUY.js.map → chunk-KZSGBWOJ.js.map} +0 -0
- /package/dist/{chunk-SHHZWSSE.js.map → chunk-KZZ5EZ7O.js.map} +0 -0
- /package/dist/{chunk-FKGLJJVS.js.map → chunk-LN4X2NDA.js.map} +0 -0
- /package/dist/{chunk-5ZHFPUBC.js.map → chunk-MOIJWWNA.js.map} +0 -0
- /package/dist/{chunk-KO224R36.js.map → chunk-NCZGGGWI.js.map} +0 -0
- /package/dist/{chunk-7ZTGMEXF.js.map → chunk-O5ZINWW3.js.map} +0 -0
- /package/dist/{chunk-WWH7GJ42.js.map → chunk-OCK4D5PC.js.map} +0 -0
- /package/dist/{chunk-G6L3REL3.js.map → chunk-OPFVXM2D.js.map} +0 -0
- /package/dist/{chunk-FR7PK7ED.js.map → chunk-P4TV3TQ2.js.map} +0 -0
- /package/dist/{chunk-P2EM5LKH.js.map → chunk-PMDOGXA2.js.map} +0 -0
- /package/dist/{chunk-MRF5V5CD.js.map → chunk-QGFR73SN.js.map} +0 -0
- /package/dist/{chunk-HG3CG557.js.map → chunk-RLVI2M5Q.js.map} +0 -0
- /package/dist/{chunk-HHL4MX3W.js.map → chunk-SXTVZ6JL.js.map} +0 -0
- /package/dist/{chunk-CLSKGTAT.js.map → chunk-TECK5IVY.js.map} +0 -0
- /package/dist/{chunk-SNS3DWG6.js.map → chunk-TVE7W67N.js.map} +0 -0
- /package/dist/{chunk-KYSSUY66.js.map → chunk-U2CAGMUD.js.map} +0 -0
- /package/dist/{chunk-XLCEFUAU.js.map → chunk-UVVFPCPX.js.map} +0 -0
- /package/dist/{chunk-KQJUEQ2E.js.map → chunk-UW6LBFYN.js.map} +0 -0
- /package/dist/{chunk-JL5HXL25.js.map → chunk-V6SBA5O7.js.map} +0 -0
- /package/dist/{chunk-B7VD36TI.js.map → chunk-WHROVQ5Q.js.map} +0 -0
- /package/dist/{chunk-LDHR465K.js.map → chunk-Y3XPSGNF.js.map} +0 -0
- /package/dist/{chunk-JPY3RMG2.js.map → chunk-ZORS5BG5.js.map} +0 -0
- /package/dist/{chunk-KXY4HW2Y.js.map → chunk-ZXF3O7P4.js.map} +0 -0
|
@@ -177,7 +177,7 @@ import {
|
|
|
177
177
|
import {
|
|
178
178
|
SPECULATIVE_TTL_DAYS,
|
|
179
179
|
confidenceTier
|
|
180
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-V4XE263I.js";
|
|
181
181
|
import {
|
|
182
182
|
composeMemoryEnvelope,
|
|
183
183
|
isSealedMemoryEnvelope,
|
|
@@ -241,7 +241,9 @@ import {
|
|
|
241
241
|
sanitizeMemoryContent
|
|
242
242
|
} from "./chunk-5GKPFL3S.js";
|
|
243
243
|
import {
|
|
244
|
-
|
|
244
|
+
serializeMutations,
|
|
245
|
+
updateMetaSerialized,
|
|
246
|
+
withHeldFileLock
|
|
245
247
|
} from "./chunk-EBV6VXKF.js";
|
|
246
248
|
import {
|
|
247
249
|
parseFlexibleIsoTimestamp
|
|
@@ -331,7 +333,7 @@ function parseDriftProvenance(fm) {
|
|
|
331
333
|
}
|
|
332
334
|
|
|
333
335
|
// src/storage.ts
|
|
334
|
-
import
|
|
336
|
+
import path16 from "path";
|
|
335
337
|
|
|
336
338
|
// src/storage/tombstone-migration-sources.ts
|
|
337
339
|
import { statSync } from "fs";
|
|
@@ -1654,15 +1656,76 @@ function stripOkfProfileFrontmatter(content) {
|
|
|
1654
1656
|
return content;
|
|
1655
1657
|
}
|
|
1656
1658
|
|
|
1657
|
-
// src/storage/
|
|
1659
|
+
// src/storage/profile-mutation.ts
|
|
1658
1660
|
import path4 from "path";
|
|
1661
|
+
function normalizeForDedup(s) {
|
|
1662
|
+
return s.toLowerCase().replace(/[^a-z0-9\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
1663
|
+
}
|
|
1664
|
+
function isFuzzyDuplicate(newNorm, existingNorms) {
|
|
1665
|
+
for (const existing of existingNorms) {
|
|
1666
|
+
if (newNorm === existing) return true;
|
|
1667
|
+
const shorter = newNorm.length <= existing.length ? newNorm : existing;
|
|
1668
|
+
const longer = newNorm.length > existing.length ? newNorm : existing;
|
|
1669
|
+
if (shorter.length > 20 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {
|
|
1670
|
+
return true;
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
return false;
|
|
1674
|
+
}
|
|
1675
|
+
async function appendToProfileUnlocked(ports, updates) {
|
|
1676
|
+
updates = updates.filter((u) => u.trim().length > 0);
|
|
1677
|
+
if (updates.length === 0) return;
|
|
1678
|
+
const existing = await ports.readProfile();
|
|
1679
|
+
const existingNorms = (existing ? existing.split("\n") : []).filter((l) => l.startsWith("- ")).map((l) => normalizeForDedup(l.slice(2).trim()));
|
|
1680
|
+
const newBullets = updates.filter((u) => {
|
|
1681
|
+
const norm = normalizeForDedup(u);
|
|
1682
|
+
return !isFuzzyDuplicate(norm, existingNorms);
|
|
1683
|
+
});
|
|
1684
|
+
if (newBullets.length === 0) return;
|
|
1685
|
+
await ports.writeProfile(
|
|
1686
|
+
existing ? existing.trimEnd() + "\n" + newBullets.map((b) => `- ${b}`).join("\n") + "\n" : ["# Behavioral Profile", "", ...newBullets.map((b) => `- ${b}`), ""].join("\n")
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
async function withProfileMutationLock(ports, task) {
|
|
1690
|
+
return withHeldFileLock(
|
|
1691
|
+
path4.join(ports.baseDir, "profile.md.lock"),
|
|
1692
|
+
// Bounded: a profile RMW is a short read-merge-write, never a scan.
|
|
1693
|
+
{ staleMs: 5e3, maxWaitMs: 2e3, pollMs: 50 },
|
|
1694
|
+
async (acquired) => {
|
|
1695
|
+
if (!acquired) {
|
|
1696
|
+
throw new Error(`profile update skipped: profile.md.lock not acquired (${ports.baseDir})`);
|
|
1697
|
+
}
|
|
1698
|
+
return task();
|
|
1699
|
+
}
|
|
1700
|
+
);
|
|
1701
|
+
}
|
|
1702
|
+
async function appendToProfileSerialized(ports, updates) {
|
|
1703
|
+
await serializeMutations(
|
|
1704
|
+
`profile:${ports.baseDir}`,
|
|
1705
|
+
() => withProfileMutationLock(ports, () => appendToProfileUnlocked(ports, updates))
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1708
|
+
async function commitConsolidatedProfileSerialized(ports, baseline, consolidated) {
|
|
1709
|
+
return serializeMutations(
|
|
1710
|
+
`profile:${ports.baseDir}`,
|
|
1711
|
+
() => withProfileMutationLock(ports, async () => {
|
|
1712
|
+
const current = await ports.readProfile();
|
|
1713
|
+
if (current !== baseline) return "conflict";
|
|
1714
|
+
await ports.writeProfile(consolidated);
|
|
1715
|
+
return "committed";
|
|
1716
|
+
})
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
// src/storage/questions-file.ts
|
|
1721
|
+
import path5 from "path";
|
|
1659
1722
|
function parseQuestionFile(raw, filePath) {
|
|
1660
1723
|
if (!raw.startsWith("---\n")) return null;
|
|
1661
1724
|
const close = raw.indexOf("\n---\n\n", 4);
|
|
1662
1725
|
if (close === -1) return null;
|
|
1663
1726
|
const frontmatterStr = raw.slice(4, close);
|
|
1664
1727
|
const body = raw.slice(close + 6).trim();
|
|
1665
|
-
const id = extractFrontmatterValue(frontmatterStr, "id") ??
|
|
1728
|
+
const id = extractFrontmatterValue(frontmatterStr, "id") ?? path5.basename(filePath, ".md");
|
|
1666
1729
|
const created = extractFrontmatterValue(frontmatterStr, "created") ?? "";
|
|
1667
1730
|
const priority = parseFloat(extractFrontmatterValue(frontmatterStr, "priority") ?? "0.5");
|
|
1668
1731
|
const resolved = extractFrontmatterValue(frontmatterStr, "resolved") === "true";
|
|
@@ -1731,11 +1794,11 @@ function selfDeps(self) {
|
|
|
1731
1794
|
|
|
1732
1795
|
// src/storage/entity-store.ts
|
|
1733
1796
|
import { lstat as lstat3, readdir as readdir2, unlink } from "fs/promises";
|
|
1734
|
-
import
|
|
1797
|
+
import path7 from "path";
|
|
1735
1798
|
|
|
1736
1799
|
// src/storage/entity-migration-completion-cache.ts
|
|
1737
1800
|
import { lstat as lstat2, realpath } from "fs/promises";
|
|
1738
|
-
import
|
|
1801
|
+
import path6 from "path";
|
|
1739
1802
|
async function isTrustedEntitiesRoot(baseDir, entitiesDir) {
|
|
1740
1803
|
let rootStat;
|
|
1741
1804
|
try {
|
|
@@ -1772,14 +1835,14 @@ var EntityMigrationCompletionCache = class {
|
|
|
1772
1835
|
* we never pin a false complete.
|
|
1773
1836
|
*/
|
|
1774
1837
|
async inputSig(deps) {
|
|
1775
|
-
const stateDir =
|
|
1838
|
+
const stateDir = path6.join(deps.baseDir, "state");
|
|
1776
1839
|
const entitiesSig = await this.inputPathSig(deps.entitiesDir);
|
|
1777
1840
|
if (entitiesSig === "missing") return `entities-missing:${Math.random()}`;
|
|
1778
1841
|
const [aliasesSig, journalSig, reconcileSig, consumingSig] = await Promise.all([
|
|
1779
|
-
this.inputPathSig(
|
|
1780
|
-
this.inputPathSig(
|
|
1781
|
-
this.inputPathSig(
|
|
1782
|
-
this.inputPathSig(
|
|
1842
|
+
this.inputPathSig(path6.join(deps.baseDir, "config", "aliases.json")),
|
|
1843
|
+
this.inputPathSig(path6.join(stateDir, ENTITY_CANONICAL_ID_MIGRATION_FILE)),
|
|
1844
|
+
this.inputPathSig(path6.join(stateDir, ENTITY_CANONICAL_ID_RECONCILE_MARKER)),
|
|
1845
|
+
this.inputPathSig(path6.join(stateDir, ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER))
|
|
1783
1846
|
]);
|
|
1784
1847
|
return [entitiesSig, aliasesSig, journalSig, reconcileSig, consumingSig].join("|");
|
|
1785
1848
|
}
|
|
@@ -1796,7 +1859,7 @@ var EntityMigrationCompletionCache = class {
|
|
|
1796
1859
|
this.cache = { version, inputSig, completed: false };
|
|
1797
1860
|
return false;
|
|
1798
1861
|
}
|
|
1799
|
-
const completed = await entityCanonicalIdMigrationCompleted(
|
|
1862
|
+
const completed = await entityCanonicalIdMigrationCompleted(path6.join(deps.baseDir, "state"), () => getFingerprint(deps.baseDir, deps.entitiesDir, () => String(version)));
|
|
1800
1863
|
this.cache = { version, inputSig, completed };
|
|
1801
1864
|
return completed;
|
|
1802
1865
|
}
|
|
@@ -1821,7 +1884,7 @@ async function readEntityFileResolvingRename(deps, firstPath, entityId) {
|
|
|
1821
1884
|
return {
|
|
1822
1885
|
id: candidate,
|
|
1823
1886
|
content: await deps.readStorageSecureFile(
|
|
1824
|
-
|
|
1887
|
+
path6.join(deps.entitiesDir, `${candidate}.md`)
|
|
1825
1888
|
)
|
|
1826
1889
|
};
|
|
1827
1890
|
} catch (err) {
|
|
@@ -1857,7 +1920,7 @@ var EntityStore = class {
|
|
|
1857
1920
|
assertSafeEntityId(name);
|
|
1858
1921
|
const canonical = resolveHistoricalEntityCanonicalId(name, historicalIds);
|
|
1859
1922
|
for (const candidate of canonical === name ? [name] : [canonical, name]) {
|
|
1860
|
-
const filePath =
|
|
1923
|
+
const filePath = path7.join(this.deps.entitiesDir, `${candidate}.md`);
|
|
1861
1924
|
try {
|
|
1862
1925
|
const entity = parseEntityFile(await this.deps.readStorageSecureFile(filePath), this.deps.entitySchemas);
|
|
1863
1926
|
return { filePath, entity };
|
|
@@ -1883,7 +1946,7 @@ var EntityStore = class {
|
|
|
1883
1946
|
*/
|
|
1884
1947
|
async mutateEntityFile(name, method, mutate) {
|
|
1885
1948
|
await this.deps.ensureDirectories();
|
|
1886
|
-
const stateDir =
|
|
1949
|
+
const stateDir = path7.join(this.deps.baseDir, "state");
|
|
1887
1950
|
return withEntityCanonicalMutationLock(stateDir, async () => {
|
|
1888
1951
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1889
1952
|
const idsAtResolve = this.deps.currentHistoricalIds();
|
|
@@ -1938,7 +2001,7 @@ var EntityStore = class {
|
|
|
1938
2001
|
async writeEntity(name, type, facts, options = {}) {
|
|
1939
2002
|
await this.deps.ensureDirectories();
|
|
1940
2003
|
return withEntityCanonicalMutationLock(
|
|
1941
|
-
|
|
2004
|
+
path7.join(this.deps.baseDir, "state"),
|
|
1942
2005
|
() => this.writeEntityUnlocked(name, type, facts, options)
|
|
1943
2006
|
);
|
|
1944
2007
|
}
|
|
@@ -1959,7 +2022,7 @@ var EntityStore = class {
|
|
|
1959
2022
|
log.debug(`fuzzy match: "${normalized}" \u2192 existing "${match}"`);
|
|
1960
2023
|
normalized = match;
|
|
1961
2024
|
}
|
|
1962
|
-
const filePath =
|
|
2025
|
+
const filePath = path7.join(this.deps.entitiesDir, `${normalized}.md`);
|
|
1963
2026
|
let entity = {
|
|
1964
2027
|
name,
|
|
1965
2028
|
type,
|
|
@@ -2077,7 +2140,7 @@ var EntityStore = class {
|
|
|
2077
2140
|
if (!file.endsWith(".md") || !await this.isContainedRegularEntityFile(file)) continue;
|
|
2078
2141
|
let content;
|
|
2079
2142
|
try {
|
|
2080
|
-
content = await this.deps.readStorageSecureFile(
|
|
2143
|
+
content = await this.deps.readStorageSecureFile(path7.join(this.deps.entitiesDir, file));
|
|
2081
2144
|
} catch (err) {
|
|
2082
2145
|
if (err instanceof SecureStoreLockedError) throw err;
|
|
2083
2146
|
if (isErrnoCode(err, "ENOENT") || isErrnoCode(err, "ELOOP")) continue;
|
|
@@ -2113,7 +2176,7 @@ var EntityStore = class {
|
|
|
2113
2176
|
*/
|
|
2114
2177
|
async isMissingEntry(file) {
|
|
2115
2178
|
try {
|
|
2116
|
-
await lstat3(
|
|
2179
|
+
await lstat3(path7.join(this.deps.entitiesDir, file));
|
|
2117
2180
|
return false;
|
|
2118
2181
|
} catch (err) {
|
|
2119
2182
|
if (isErrnoCode(err, "ENOENT")) return true;
|
|
@@ -2121,7 +2184,7 @@ var EntityStore = class {
|
|
|
2121
2184
|
}
|
|
2122
2185
|
}
|
|
2123
2186
|
async isContainedRegularEntityFile(file) {
|
|
2124
|
-
const filePath =
|
|
2187
|
+
const filePath = path7.join(this.deps.entitiesDir, file);
|
|
2125
2188
|
let entryStat;
|
|
2126
2189
|
try {
|
|
2127
2190
|
entryStat = await lstat3(filePath);
|
|
@@ -2138,7 +2201,7 @@ var EntityStore = class {
|
|
|
2138
2201
|
* reread the whole directory on every extraction write.
|
|
2139
2202
|
*/
|
|
2140
2203
|
async isIndexableEntityMarkdown(file) {
|
|
2141
|
-
const filePath =
|
|
2204
|
+
const filePath = path7.join(this.deps.entitiesDir, file);
|
|
2142
2205
|
let entryStat;
|
|
2143
2206
|
try {
|
|
2144
2207
|
entryStat = await lstat3(filePath);
|
|
@@ -2214,7 +2277,7 @@ var EntityStore = class {
|
|
|
2214
2277
|
async migrateEntityFilesToCompiledTruthTimeline() {
|
|
2215
2278
|
await this.deps.ensureDirectories();
|
|
2216
2279
|
const entityNames = await this.listEntityNames();
|
|
2217
|
-
const stateDir =
|
|
2280
|
+
const stateDir = path7.join(this.deps.baseDir, "state");
|
|
2218
2281
|
let migrated = 0;
|
|
2219
2282
|
for (const entityName of entityNames) {
|
|
2220
2283
|
const wrote = await withEntityCanonicalMutationLock(stateDir, async () => {
|
|
@@ -2250,7 +2313,7 @@ var EntityStore = class {
|
|
|
2250
2313
|
async updateEntitySynthesis(name, synthesis, options = {}) {
|
|
2251
2314
|
await this.deps.ensureDirectories();
|
|
2252
2315
|
return withEntityCanonicalMutationLock(
|
|
2253
|
-
|
|
2316
|
+
path7.join(this.deps.baseDir, "state"),
|
|
2254
2317
|
() => this.updateEntitySynthesisUnlocked(name, synthesis, options)
|
|
2255
2318
|
);
|
|
2256
2319
|
}
|
|
@@ -2312,7 +2375,7 @@ var EntityStore = class {
|
|
|
2312
2375
|
const results = await Promise.all(
|
|
2313
2376
|
batch.map(async (entry) => {
|
|
2314
2377
|
const entityId = entry.slice(0, -".md".length);
|
|
2315
|
-
const entryPath =
|
|
2378
|
+
const entryPath = path7.join(this.deps.entitiesDir, entry);
|
|
2316
2379
|
try {
|
|
2317
2380
|
if (!await this.isContainedRegularEntityFile(entry)) {
|
|
2318
2381
|
if (await this.isMissingEntry(entry)) {
|
|
@@ -2407,7 +2470,7 @@ ${rows.join("\n")}
|
|
|
2407
2470
|
async mergeFragmentedEntities() {
|
|
2408
2471
|
await this.deps.ensureDirectories();
|
|
2409
2472
|
return withEntityCanonicalMutationLock(
|
|
2410
|
-
|
|
2473
|
+
path7.join(this.deps.baseDir, "state"),
|
|
2411
2474
|
() => this.mergeFragmentedEntitiesUnlocked()
|
|
2412
2475
|
);
|
|
2413
2476
|
}
|
|
@@ -2435,7 +2498,7 @@ ${rows.join("\n")}
|
|
|
2435
2498
|
const canonicalDestinationOccupied = async (canonicalName, members) => {
|
|
2436
2499
|
if (members.includes(canonicalName)) return false;
|
|
2437
2500
|
try {
|
|
2438
|
-
await lstat3(
|
|
2501
|
+
await lstat3(path7.join(this.deps.entitiesDir, canonicalName));
|
|
2439
2502
|
return true;
|
|
2440
2503
|
} catch (err) {
|
|
2441
2504
|
if (isErrnoCode(err, "ENOENT")) return false;
|
|
@@ -2472,7 +2535,7 @@ ${rows.join("\n")}
|
|
|
2472
2535
|
extraSections: []
|
|
2473
2536
|
};
|
|
2474
2537
|
for (const file of files) {
|
|
2475
|
-
const filePath =
|
|
2538
|
+
const filePath = path7.join(this.deps.entitiesDir, file);
|
|
2476
2539
|
try {
|
|
2477
2540
|
const content = await this.deps.readStorageSecureFile(filePath);
|
|
2478
2541
|
const parsed = parseEntityFile(content, this.deps.entitySchemas);
|
|
@@ -2625,7 +2688,7 @@ ${rows.join("\n")}
|
|
|
2625
2688
|
}
|
|
2626
2689
|
mergedEntity.created = mergedEntity.created || mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2627
2690
|
mergedEntity.updated = mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2628
|
-
const canonicalPath =
|
|
2691
|
+
const canonicalPath = path7.join(this.deps.entitiesDir, canonicalName);
|
|
2629
2692
|
if (await canonicalDestinationOccupied(canonicalName, files)) {
|
|
2630
2693
|
log.warn(`skipped entity merge into occupied ${canonicalName}`);
|
|
2631
2694
|
continue;
|
|
@@ -2633,7 +2696,7 @@ ${rows.join("\n")}
|
|
|
2633
2696
|
await this.deps.writeStorageSecureFile(canonicalPath, serializeEntityFile(mergedEntity, this.deps.entitySchemas, this.deps.okfConformanceEnabled()));
|
|
2634
2697
|
this.deps.bumpEntityMutationVersion();
|
|
2635
2698
|
for (const file of files) {
|
|
2636
|
-
const filePath =
|
|
2699
|
+
const filePath = path7.join(this.deps.entitiesDir, file);
|
|
2637
2700
|
if (filePath !== canonicalPath) {
|
|
2638
2701
|
try {
|
|
2639
2702
|
await unlink(filePath);
|
|
@@ -2653,7 +2716,7 @@ ${rows.join("\n")}
|
|
|
2653
2716
|
|
|
2654
2717
|
// src/storage/identity-continuity-store.ts
|
|
2655
2718
|
import { readdir as readdir3 } from "fs/promises";
|
|
2656
|
-
import
|
|
2719
|
+
import path8 from "path";
|
|
2657
2720
|
var IdentityContinuityStore = class {
|
|
2658
2721
|
constructor(deps) {
|
|
2659
2722
|
this.deps = deps;
|
|
@@ -2678,7 +2741,7 @@ var IdentityContinuityStore = class {
|
|
|
2678
2741
|
const date = nowIso.slice(0, 10);
|
|
2679
2742
|
const id = this.deps.generateId("incident");
|
|
2680
2743
|
const incident = createContinuityIncidentRecord(id, input, nowIso);
|
|
2681
|
-
const filePath =
|
|
2744
|
+
const filePath = path8.join(this.deps.identityIncidentsDir, `${date}-${id}.md`);
|
|
2682
2745
|
await this.deps.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));
|
|
2683
2746
|
return { ...incident, filePath };
|
|
2684
2747
|
}
|
|
@@ -2691,7 +2754,7 @@ var IdentityContinuityStore = class {
|
|
|
2691
2754
|
const incidents = [];
|
|
2692
2755
|
for (const file of candidates) {
|
|
2693
2756
|
if (incidents.length >= cappedLimit) break;
|
|
2694
|
-
const filePath =
|
|
2757
|
+
const filePath = path8.join(this.deps.identityIncidentsDir, file);
|
|
2695
2758
|
try {
|
|
2696
2759
|
const raw = await this.deps.readStorageSecureFile(filePath);
|
|
2697
2760
|
const parsed = parseContinuityIncident(raw);
|
|
@@ -2722,7 +2785,7 @@ var IdentityContinuityStore = class {
|
|
|
2722
2785
|
await this.deps.ensureDirectories();
|
|
2723
2786
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2724
2787
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2725
|
-
const filePath =
|
|
2788
|
+
const filePath = path8.join(dir, `${safeKey}.md`);
|
|
2726
2789
|
await this.deps.writeStorageSecureFile(filePath, content);
|
|
2727
2790
|
return filePath;
|
|
2728
2791
|
}
|
|
@@ -2730,7 +2793,7 @@ var IdentityContinuityStore = class {
|
|
|
2730
2793
|
try {
|
|
2731
2794
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2732
2795
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2733
|
-
return await this.deps.readStorageSecureFile(
|
|
2796
|
+
return await this.deps.readStorageSecureFile(path8.join(dir, `${safeKey}.md`));
|
|
2734
2797
|
} catch (err) {
|
|
2735
2798
|
if (err instanceof Error && err.message === "Invalid identity audit key") return null;
|
|
2736
2799
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -2786,12 +2849,12 @@ var IdentityContinuityStore = class {
|
|
|
2786
2849
|
const fileNames = await this.readContinuityIncidentFileNames();
|
|
2787
2850
|
const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));
|
|
2788
2851
|
if (directMatch) {
|
|
2789
|
-
const directPath =
|
|
2852
|
+
const directPath = path8.join(this.deps.identityIncidentsDir, directMatch);
|
|
2790
2853
|
const parsed = await this.readContinuityIncidentFile(directPath);
|
|
2791
2854
|
if (parsed?.id === id) return directPath;
|
|
2792
2855
|
}
|
|
2793
2856
|
for (const fileName of fileNames) {
|
|
2794
|
-
const filePath =
|
|
2857
|
+
const filePath = path8.join(this.deps.identityIncidentsDir, fileName);
|
|
2795
2858
|
const parsed = await this.readContinuityIncidentFile(filePath);
|
|
2796
2859
|
if (parsed?.id === id) return filePath;
|
|
2797
2860
|
}
|
|
@@ -2913,11 +2976,11 @@ ${before.content}
|
|
|
2913
2976
|
// src/storage/entity-migration-maintenance-pending.ts
|
|
2914
2977
|
import { randomUUID } from "crypto";
|
|
2915
2978
|
import { readdir as readdir4, rename, unlink as unlink3, writeFile } from "fs/promises";
|
|
2916
|
-
import
|
|
2979
|
+
import path9 from "path";
|
|
2917
2980
|
var ENTITY_MIGRATION_MAINTENANCE_PENDING_PREFIX = "entity-canonical-id-maintenance.pending";
|
|
2918
2981
|
async function writeMaintenancePending(stateDir) {
|
|
2919
2982
|
const name = `${ENTITY_MIGRATION_MAINTENANCE_PENDING_PREFIX}.${process.pid}-${randomUUID()}`;
|
|
2920
|
-
const destination =
|
|
2983
|
+
const destination = path9.join(stateDir, name);
|
|
2921
2984
|
const temporary = `${destination}.tmp`;
|
|
2922
2985
|
try {
|
|
2923
2986
|
await writeFile(temporary, `${(/* @__PURE__ */ new Date()).toISOString()}
|
|
@@ -2941,7 +3004,7 @@ async function listMaintenancePending(stateDir) {
|
|
|
2941
3004
|
async function clearMaintenancePending(stateDir, names) {
|
|
2942
3005
|
for (const name of names) {
|
|
2943
3006
|
try {
|
|
2944
|
-
await unlink3(
|
|
3007
|
+
await unlink3(path9.join(stateDir, name));
|
|
2945
3008
|
} catch (error) {
|
|
2946
3009
|
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
2947
3010
|
}
|
|
@@ -3141,7 +3204,7 @@ import {
|
|
|
3141
3204
|
readFileSync,
|
|
3142
3205
|
realpathSync
|
|
3143
3206
|
} from "fs";
|
|
3144
|
-
import
|
|
3207
|
+
import path10 from "path";
|
|
3145
3208
|
function resolveSafeAliasRoots(baseDir, configDir) {
|
|
3146
3209
|
let baseStat;
|
|
3147
3210
|
try {
|
|
@@ -3168,8 +3231,8 @@ function resolveSafeAliasRoots(baseDir, configDir) {
|
|
|
3168
3231
|
return memoryRoot;
|
|
3169
3232
|
}
|
|
3170
3233
|
function readEntityAliasConfigSync(baseDir) {
|
|
3171
|
-
const configDir =
|
|
3172
|
-
const aliasPath =
|
|
3234
|
+
const configDir = path10.join(baseDir, "config");
|
|
3235
|
+
const aliasPath = path10.join(configDir, "aliases.json");
|
|
3173
3236
|
let memoryRoot = resolveSafeAliasRoots(baseDir, configDir);
|
|
3174
3237
|
if (memoryRoot === void 0) return void 0;
|
|
3175
3238
|
let aliasPreflight;
|
|
@@ -3231,7 +3294,7 @@ function decodeYamlScalar(value) {
|
|
|
3231
3294
|
|
|
3232
3295
|
// src/orchestration/qmd-result-resolver.ts
|
|
3233
3296
|
import { existsSync } from "fs";
|
|
3234
|
-
import
|
|
3297
|
+
import path11 from "path";
|
|
3235
3298
|
var INTERNAL_QMD_ROOTS = /* @__PURE__ */ new Set([
|
|
3236
3299
|
...ALL_CATEGORY_DIRS,
|
|
3237
3300
|
"activity",
|
|
@@ -3253,7 +3316,7 @@ var INTERNAL_QMD_ROOTS = /* @__PURE__ */ new Set([
|
|
|
3253
3316
|
]);
|
|
3254
3317
|
var PRIVATE_RESULT_RESOLUTION_CONCURRENCY = 16;
|
|
3255
3318
|
function qmdCollectionPathParts(resultPath) {
|
|
3256
|
-
if (!resultPath ||
|
|
3319
|
+
if (!resultPath || path11.isAbsolute(resultPath)) return null;
|
|
3257
3320
|
if (resultPath.trim().startsWith("qmd://")) {
|
|
3258
3321
|
try {
|
|
3259
3322
|
const parsed = new URL(resultPath.trim());
|
|
@@ -3278,9 +3341,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
3278
3341
|
}
|
|
3279
3342
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
3280
3343
|
const candidates = /* @__PURE__ */ new Set();
|
|
3281
|
-
const storageRoot =
|
|
3344
|
+
const storageRoot = path11.resolve(storageDir);
|
|
3282
3345
|
const addCandidate = (candidate) => {
|
|
3283
|
-
const resolved =
|
|
3346
|
+
const resolved = path11.resolve(candidate);
|
|
3284
3347
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
3285
3348
|
candidates.add(resolved);
|
|
3286
3349
|
}
|
|
@@ -3288,18 +3351,18 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
3288
3351
|
const addRelativeCandidates = (relativePath) => {
|
|
3289
3352
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3290
3353
|
if (!normalized) return;
|
|
3291
|
-
addCandidate(
|
|
3354
|
+
addCandidate(path11.join(storageRoot, normalized));
|
|
3292
3355
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3293
|
-
addCandidate(
|
|
3356
|
+
addCandidate(path11.join(storageRoot, "facts", normalized));
|
|
3294
3357
|
}
|
|
3295
3358
|
};
|
|
3296
|
-
if (
|
|
3359
|
+
if (path11.isAbsolute(resultPath)) {
|
|
3297
3360
|
addCandidate(resultPath);
|
|
3298
|
-
const relative2 =
|
|
3299
|
-
if (relative2 && !relative2.startsWith("..") && !
|
|
3300
|
-
const normalized = relative2.split(
|
|
3361
|
+
const relative2 = path11.relative(storageRoot, path11.resolve(resultPath));
|
|
3362
|
+
if (relative2 && !relative2.startsWith("..") && !path11.isAbsolute(relative2)) {
|
|
3363
|
+
const normalized = relative2.split(path11.sep).join("/");
|
|
3301
3364
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3302
|
-
addCandidate(
|
|
3365
|
+
addCandidate(path11.join(storageRoot, "facts", normalized));
|
|
3303
3366
|
}
|
|
3304
3367
|
}
|
|
3305
3368
|
} else {
|
|
@@ -3315,9 +3378,9 @@ function normalizeFlatQmdResults(results, config, collection = config.qmdCollect
|
|
|
3315
3378
|
}));
|
|
3316
3379
|
}
|
|
3317
3380
|
function withHotFactsPath(memoryDir, resolved) {
|
|
3318
|
-
const relative2 =
|
|
3381
|
+
const relative2 = path11.relative(path11.resolve(memoryDir), resolved).split(path11.sep).join("/");
|
|
3319
3382
|
if (!/^\d{4}-\d{2}-\d{2}\//.test(relative2) || existsSync(resolved)) return resolved;
|
|
3320
|
-
const hot =
|
|
3383
|
+
const hot = path11.join(path11.resolve(memoryDir), "facts", relative2);
|
|
3321
3384
|
return existsSync(hot) ? hot : resolved;
|
|
3322
3385
|
}
|
|
3323
3386
|
function storageDirOrNull(storage) {
|
|
@@ -3348,7 +3411,7 @@ var QmdResultResolver = class {
|
|
|
3348
3411
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
3349
3412
|
const addStorage = (storage) => {
|
|
3350
3413
|
const storageDir = storageDirOrNull(storage);
|
|
3351
|
-
const storageKey = storageDir ?
|
|
3414
|
+
const storageKey = storageDir ? path11.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
3352
3415
|
if (seenStorageDirs.has(storageKey)) return;
|
|
3353
3416
|
seenStorageDirs.add(storageKey);
|
|
3354
3417
|
storages.push(storage);
|
|
@@ -3378,7 +3441,7 @@ var QmdResultResolver = class {
|
|
|
3378
3441
|
continue;
|
|
3379
3442
|
}
|
|
3380
3443
|
try {
|
|
3381
|
-
const coldRoot =
|
|
3444
|
+
const coldRoot = path11.join(storageDir, "cold");
|
|
3382
3445
|
for (const candidate of qmdResultPathCandidates(coldRoot, parts.relativePath)) {
|
|
3383
3446
|
const memory = await storage.readMemoryByPath(candidate);
|
|
3384
3447
|
if (memory) return memory;
|
|
@@ -3428,9 +3491,9 @@ var QmdResultResolver = class {
|
|
|
3428
3491
|
error: err.message
|
|
3429
3492
|
});
|
|
3430
3493
|
}
|
|
3431
|
-
if (!
|
|
3494
|
+
if (!path11.isAbsolute(fallbackResultPath)) return null;
|
|
3432
3495
|
}
|
|
3433
|
-
if (
|
|
3496
|
+
if (path11.isAbsolute(fallbackResultPath)) {
|
|
3434
3497
|
if (!fallbackStorageDir) {
|
|
3435
3498
|
return await fallbackStorage.readMemoryByPath(fallbackResultPath);
|
|
3436
3499
|
}
|
|
@@ -3487,17 +3550,17 @@ var QmdResultResolver = class {
|
|
|
3487
3550
|
if (!memory && parts && !collectionIsKnownInternal && !collectionIsConfigured) {
|
|
3488
3551
|
memory = await this.readQmdResultMemory(parts.relativePath, fallbackStorage, namespaces, result.namespace);
|
|
3489
3552
|
}
|
|
3490
|
-
const absoluteInsideMemoryRoot =
|
|
3553
|
+
const absoluteInsideMemoryRoot = path11.isAbsolute(result.path) && isPathInsideStorageRoot(path11.resolve(config.memoryDir), path11.resolve(result.path));
|
|
3491
3554
|
const hasExplicitQmdCollection = result.path.trim().startsWith("qmd://");
|
|
3492
3555
|
const unresolvedInternalPath = !memory && (absoluteInsideMemoryRoot || collectionIsKnownInternal && (!preserveUnresolved || hasExplicitQmdCollection) || hasExplicitQmdCollection && collectionIsConfigured);
|
|
3493
|
-
const unresolvedExternalCollection = !memory && (parts !== null && !collectionIsKnownInternal && !collectionIsConfigured ||
|
|
3556
|
+
const unresolvedExternalCollection = !memory && (parts !== null && !collectionIsKnownInternal && !collectionIsConfigured || path11.isAbsolute(result.path) && !isPathInsideStorageRoot(path11.resolve(config.memoryDir), path11.resolve(result.path)));
|
|
3494
3557
|
return memory !== null && !isSupportPassportPrivateMemory(memory) || !memory && !unresolvedInternalPath && (preserveUnresolved || unresolvedExternalCollection);
|
|
3495
3558
|
}
|
|
3496
3559
|
async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
|
|
3497
3560
|
const memory = await this.readQmdResultMemory(result.path, fallbackStorage, recallNamespaces, result.namespace);
|
|
3498
3561
|
if (!memory) return null;
|
|
3499
3562
|
let ownerNamespace = null;
|
|
3500
|
-
if (
|
|
3563
|
+
if (path11.isAbsolute(memory.path)) {
|
|
3501
3564
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(memory.path, fallbackStorage, recallNamespaces);
|
|
3502
3565
|
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
3503
3566
|
if (!ownerNamespace && resolveNamespaceCapabilities(this.getConfig()).namespaces) return null;
|
|
@@ -3518,17 +3581,17 @@ var QmdResultResolver = class {
|
|
|
3518
3581
|
};
|
|
3519
3582
|
}
|
|
3520
3583
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
3521
|
-
const resolvedPath =
|
|
3584
|
+
const resolvedPath = path11.resolve(resultPath);
|
|
3522
3585
|
const config = this.getConfig();
|
|
3523
|
-
const memoryRoot =
|
|
3524
|
-
const namespacesRoot =
|
|
3586
|
+
const memoryRoot = path11.resolve(config.memoryDir);
|
|
3587
|
+
const namespacesRoot = path11.join(memoryRoot, "namespaces");
|
|
3525
3588
|
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
3526
3589
|
const matches = [];
|
|
3527
3590
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
3528
3591
|
const maybeAddStorage = (storage, namespace) => {
|
|
3529
3592
|
const storageDir = storageDirOrNull(storage);
|
|
3530
3593
|
if (!storageDir) return;
|
|
3531
|
-
const candidateRoot =
|
|
3594
|
+
const candidateRoot = path11.resolve(storageDir);
|
|
3532
3595
|
if (seenDirs.has(candidateRoot)) return;
|
|
3533
3596
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
3534
3597
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -3546,7 +3609,7 @@ var QmdResultResolver = class {
|
|
|
3546
3609
|
candidateNamespaces.add(ns);
|
|
3547
3610
|
}
|
|
3548
3611
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
3549
|
-
const relativeToNamespaces =
|
|
3612
|
+
const relativeToNamespaces = path11.relative(namespacesRoot, resolvedPath);
|
|
3550
3613
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
3551
3614
|
if (namespaceSegment) {
|
|
3552
3615
|
candidateNamespaces.add(namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment);
|
|
@@ -4208,7 +4271,7 @@ function fuseDay(date, inputs, options = {}) {
|
|
|
4208
4271
|
|
|
4209
4272
|
// src/wearables/fusion/store.ts
|
|
4210
4273
|
import { createHash as createHash2 } from "crypto";
|
|
4211
|
-
import * as
|
|
4274
|
+
import * as path12 from "path";
|
|
4212
4275
|
var FUSION_KIND = "wearable-fusion";
|
|
4213
4276
|
function hashFusionBody(conversations) {
|
|
4214
4277
|
return createHash2("sha256").update(JSON.stringify(conversations), "utf-8").digest("hex");
|
|
@@ -4395,7 +4458,7 @@ var FusionArtifactStore = class {
|
|
|
4395
4458
|
`invalid wearable fusion date '${String(date)}' \u2014 expected YYYY-MM-DD`
|
|
4396
4459
|
);
|
|
4397
4460
|
}
|
|
4398
|
-
return
|
|
4461
|
+
return path12.join(this.wearablesDir, FUSION_DIR_NAME, `${date}.md`);
|
|
4399
4462
|
}
|
|
4400
4463
|
async writeFusedDay(date, serialized) {
|
|
4401
4464
|
const filePath = this.fusedDayPath(date);
|
|
@@ -4432,7 +4495,7 @@ var FusionArtifactStore = class {
|
|
|
4432
4495
|
}
|
|
4433
4496
|
/** List dates with stored fused artifacts, newest first. */
|
|
4434
4497
|
async listFusedDays() {
|
|
4435
|
-
const fusionDir =
|
|
4498
|
+
const fusionDir = path12.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4436
4499
|
await this.assertPathContained(fusionDir);
|
|
4437
4500
|
let entries;
|
|
4438
4501
|
try {
|
|
@@ -4476,10 +4539,10 @@ var FusionArtifactStore = class {
|
|
|
4476
4539
|
try {
|
|
4477
4540
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4478
4541
|
} catch {
|
|
4479
|
-
rootReal =
|
|
4542
|
+
rootReal = path12.resolve(this.memoryDir);
|
|
4480
4543
|
}
|
|
4481
4544
|
await this.assertNoEscape(rootReal, this.wearablesDir);
|
|
4482
|
-
await this.assertNoEscape(rootReal,
|
|
4545
|
+
await this.assertNoEscape(rootReal, path12.dirname(targetPath));
|
|
4483
4546
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4484
4547
|
await this.assertFusionDirNotSymlinked();
|
|
4485
4548
|
}
|
|
@@ -4493,7 +4556,7 @@ var FusionArtifactStore = class {
|
|
|
4493
4556
|
* (a fresh write creates a real directory lexically under the root).
|
|
4494
4557
|
*/
|
|
4495
4558
|
async assertFusionDirNotSymlinked() {
|
|
4496
|
-
const fusionDir =
|
|
4559
|
+
const fusionDir = path12.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4497
4560
|
let stat4;
|
|
4498
4561
|
try {
|
|
4499
4562
|
stat4 = await this.io.lstat(fusionDir);
|
|
@@ -4629,7 +4692,7 @@ function reconstructFusionInputs(date, dayTranscripts) {
|
|
|
4629
4692
|
|
|
4630
4693
|
// src/meetings/store.ts
|
|
4631
4694
|
import { createHash as createHash3 } from "crypto";
|
|
4632
|
-
import * as
|
|
4695
|
+
import * as path13 from "path";
|
|
4633
4696
|
var MEETINGS_DIR_NAME = "meetings";
|
|
4634
4697
|
var MEETING_KIND = "meeting";
|
|
4635
4698
|
var MEETING_FORMAT_VERSION = 1;
|
|
@@ -4798,7 +4861,7 @@ var MeetingRecordStore = class {
|
|
|
4798
4861
|
constructor(memoryDir, io) {
|
|
4799
4862
|
this.memoryDir = memoryDir;
|
|
4800
4863
|
this.io = io;
|
|
4801
|
-
this.meetingsDir =
|
|
4864
|
+
this.meetingsDir = path13.join(memoryDir, MEETINGS_DIR_NAME);
|
|
4802
4865
|
}
|
|
4803
4866
|
memoryDir;
|
|
4804
4867
|
io;
|
|
@@ -4814,7 +4877,7 @@ var MeetingRecordStore = class {
|
|
|
4814
4877
|
if (idDate !== date) {
|
|
4815
4878
|
throw new Error(`meeting id '${id}' does not belong to date '${date}'`);
|
|
4816
4879
|
}
|
|
4817
|
-
return
|
|
4880
|
+
return path13.join(this.meetingsDir, date, `${id}.md`);
|
|
4818
4881
|
}
|
|
4819
4882
|
/** Idempotently persist a record: skip the write when contentHash is unchanged. */
|
|
4820
4883
|
async saveMeetingRecord(record) {
|
|
@@ -4845,7 +4908,7 @@ var MeetingRecordStore = class {
|
|
|
4845
4908
|
if (!isValidTranscriptDate(date)) {
|
|
4846
4909
|
throw new Error(`invalid meeting date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
4847
4910
|
}
|
|
4848
|
-
const dayDir =
|
|
4911
|
+
const dayDir = path13.join(this.meetingsDir, date);
|
|
4849
4912
|
await this.assertPathContained(dayDir);
|
|
4850
4913
|
let entries;
|
|
4851
4914
|
try {
|
|
@@ -4913,10 +4976,10 @@ var MeetingRecordStore = class {
|
|
|
4913
4976
|
try {
|
|
4914
4977
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4915
4978
|
} catch {
|
|
4916
|
-
rootReal =
|
|
4979
|
+
rootReal = path13.resolve(this.memoryDir);
|
|
4917
4980
|
}
|
|
4918
4981
|
await this.assertNoEscape(rootReal, this.meetingsDir);
|
|
4919
|
-
await this.assertNoEscape(rootReal,
|
|
4982
|
+
await this.assertNoEscape(rootReal, path13.dirname(targetPath));
|
|
4920
4983
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4921
4984
|
await this.assertNotSymlink(this.meetingsDir, "directory");
|
|
4922
4985
|
const dayDir = this.dayDirWithin(targetPath);
|
|
@@ -4926,11 +4989,11 @@ var MeetingRecordStore = class {
|
|
|
4926
4989
|
/** The `<meetings>/<date>` directory on the path to `targetPath`, or null when
|
|
4927
4990
|
* `targetPath` is the meetings root itself. */
|
|
4928
4991
|
dayDirWithin(targetPath) {
|
|
4929
|
-
const rel =
|
|
4930
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
4931
|
-
const first = rel.split(
|
|
4992
|
+
const rel = path13.relative(this.meetingsDir, targetPath);
|
|
4993
|
+
if (rel === "" || rel.startsWith("..") || path13.isAbsolute(rel)) return null;
|
|
4994
|
+
const first = rel.split(path13.sep)[0];
|
|
4932
4995
|
if (first === void 0 || first.length === 0) return null;
|
|
4933
|
-
return
|
|
4996
|
+
return path13.join(this.meetingsDir, first);
|
|
4934
4997
|
}
|
|
4935
4998
|
async assertNotSymlink(target, kind) {
|
|
4936
4999
|
let stat4;
|
|
@@ -4941,7 +5004,7 @@ var MeetingRecordStore = class {
|
|
|
4941
5004
|
throw err;
|
|
4942
5005
|
}
|
|
4943
5006
|
if (stat4.isSymbolicLink) {
|
|
4944
|
-
const label =
|
|
5007
|
+
const label = path13.relative(this.memoryDir, target) || MEETINGS_DIR_NAME;
|
|
4945
5008
|
throw new Error(
|
|
4946
5009
|
`meetings ${kind} '${label}' is a symbolic link \u2014 refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)`
|
|
4947
5010
|
);
|
|
@@ -4965,7 +5028,7 @@ var SORT_STR = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
|
4965
5028
|
|
|
4966
5029
|
// src/storage/supersession-audit.ts
|
|
4967
5030
|
import { readdir as readdir5 } from "fs/promises";
|
|
4968
|
-
import
|
|
5031
|
+
import path14 from "path";
|
|
4969
5032
|
async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody, structuredAttributes) {
|
|
4970
5033
|
let entries;
|
|
4971
5034
|
try {
|
|
@@ -4977,7 +5040,7 @@ async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody,
|
|
|
4977
5040
|
for (const entry of entries) {
|
|
4978
5041
|
if (isMacOsReplicationJunkBasename(entry.name)) continue;
|
|
4979
5042
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
4980
|
-
const memory = await lookup.readMemoryByPath(
|
|
5043
|
+
const memory = await lookup.readMemoryByPath(path14.join(lookup.correctionsDir, entry.name));
|
|
4981
5044
|
if (memory?.frontmatter.category === "correction" && (memory.frontmatter.sourceMemoryId === oldMemoryId || memory.frontmatter.sourceMemoryId === void 0 && memory.frontmatter.lineage?.includes(oldMemoryId)) && memory.frontmatter.lineage?.includes(newMemoryId) && stripAttributesSuffix(memory.content) === auditBody && (structuredAttributes === void 0 || Object.entries(structuredAttributes).every(
|
|
4982
5045
|
([key, value]) => memory.frontmatter.structuredAttributes?.[key] === value
|
|
4983
5046
|
))) {
|
|
@@ -5069,12 +5132,12 @@ Reason: ${reason}`;
|
|
|
5069
5132
|
// src/storage/dropped-extraction-chunk.ts
|
|
5070
5133
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5071
5134
|
import { mkdir } from "fs/promises";
|
|
5072
|
-
import
|
|
5135
|
+
import path15 from "path";
|
|
5073
5136
|
async function saveDroppedExtractionChunk(stateDir, writeSecureFile, bufferKey, reason, turns) {
|
|
5074
|
-
const droppedDir =
|
|
5137
|
+
const droppedDir = path15.join(stateDir, "dropped");
|
|
5075
5138
|
await mkdir(droppedDir, { recursive: true });
|
|
5076
5139
|
const safeKey = bufferKey.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 80) || "default";
|
|
5077
|
-
const filePath =
|
|
5140
|
+
const filePath = path15.join(droppedDir, `${Date.now()}-${randomUUID2().slice(0, 8)}-${safeKey}.json`);
|
|
5078
5141
|
const payload = { bufferKey, reason, droppedAt: (/* @__PURE__ */ new Date()).toISOString(), turns };
|
|
5079
5142
|
await writeSecureFile(filePath, JSON.stringify(payload, null, 2));
|
|
5080
5143
|
return filePath;
|
|
@@ -6080,17 +6143,17 @@ function inferEntityTypeFromContent(content) {
|
|
|
6080
6143
|
}
|
|
6081
6144
|
var KNOWN_ENTITY_FILENAME_PREFIXES = /* @__PURE__ */ new Set(["company", "other", "person", "place", "project", "tool", "topic"]);
|
|
6082
6145
|
function inferEntityTypeFromFilename(pathRel) {
|
|
6083
|
-
const basename =
|
|
6146
|
+
const basename = path16.basename(pathRel, ".md").toLowerCase();
|
|
6084
6147
|
const separator = basename.indexOf("-");
|
|
6085
6148
|
if (separator <= 0) return void 0;
|
|
6086
6149
|
const candidate = basename.slice(0, separator);
|
|
6087
6150
|
return KNOWN_ENTITY_FILENAME_PREFIXES.has(candidate) ? candidate : void 0;
|
|
6088
6151
|
}
|
|
6089
6152
|
function normalizeFrontmatterForPath(frontmatter, pathRel, content = "") {
|
|
6090
|
-
const normalizedPath = pathRel.split(
|
|
6153
|
+
const normalizedPath = pathRel.split(path16.sep).join("/");
|
|
6091
6154
|
let normalizedFrontmatter = frontmatter;
|
|
6092
6155
|
if (normalizedPath === "entities" || normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/")) {
|
|
6093
|
-
const basename =
|
|
6156
|
+
const basename = path16.basename(pathRel, ".md");
|
|
6094
6157
|
const inferredType = inferEntityTypeFromContent(content) || inferEntityTypeFromFilename(pathRel) || "entity";
|
|
6095
6158
|
const existingTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];
|
|
6096
6159
|
normalizedFrontmatter = {
|
|
@@ -6563,9 +6626,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6563
6626
|
this.entitySchemas = entitySchemas;
|
|
6564
6627
|
this.deletionRevisionStore = new DeletionRevisionStore({
|
|
6565
6628
|
baseDir,
|
|
6566
|
-
deletionRevisionMetadataPath:
|
|
6567
|
-
invalidationCommitMetadataPath:
|
|
6568
|
-
deletionRevisionLockPath:
|
|
6629
|
+
deletionRevisionMetadataPath: path16.join(baseDir, ".offline-sync", "deletion-revisions.v1.json"),
|
|
6630
|
+
invalidationCommitMetadataPath: path16.join(baseDir, ".offline-sync", "invalidation-commits.v1.json"),
|
|
6631
|
+
deletionRevisionLockPath: path16.join(baseDir, ".offline-sync", "deletion-revisions.v1.json.lock"),
|
|
6569
6632
|
assertManagedStoragePath: (filePath, method) => this.assertManagedStoragePath(filePath, method)
|
|
6570
6633
|
});
|
|
6571
6634
|
this.casRevisions = new CasRevisionHost(baseDir);
|
|
@@ -6753,8 +6816,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6753
6816
|
}
|
|
6754
6817
|
/** Whether `filePath` resolves to `stateDir` itself or a path contained in it. */
|
|
6755
6818
|
isStateFilePath(filePath) {
|
|
6756
|
-
const rel =
|
|
6757
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
6819
|
+
const rel = path16.relative(this.stateDir, path16.resolve(filePath));
|
|
6820
|
+
return rel === "" || !rel.startsWith("..") && !path16.isAbsolute(rel);
|
|
6758
6821
|
}
|
|
6759
6822
|
// ── Tombstone store (issue #1579) ───────────────────────────────────────
|
|
6760
6823
|
// Instance-scoped (rule 11) + namespace-scoped (rule 42) tombstone index.
|
|
@@ -6869,8 +6932,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6869
6932
|
* /srv/cold/remnic), skipping the patch and stranding a stale hot entry.
|
|
6870
6933
|
*/
|
|
6871
6934
|
isColdOrArchiveTierPath(p) {
|
|
6872
|
-
const rel =
|
|
6873
|
-
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${
|
|
6935
|
+
const rel = path16.relative(this.baseDir, p);
|
|
6936
|
+
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${path16.sep}`) || rel.startsWith(`archive${path16.sep}`);
|
|
6874
6937
|
}
|
|
6875
6938
|
/**
|
|
6876
6939
|
* Mark the secure-store as required for this storage instance.
|
|
@@ -6957,7 +7020,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6957
7020
|
void 0,
|
|
6958
7021
|
this.baseDir
|
|
6959
7022
|
);
|
|
6960
|
-
const rel =
|
|
7023
|
+
const rel = path16.relative(this.baseDir, filePath).split(path16.sep).join("/");
|
|
6961
7024
|
return `${rel}:${version.versionId}`;
|
|
6962
7025
|
} catch (err) {
|
|
6963
7026
|
log.warn(
|
|
@@ -7002,10 +7065,10 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7002
7065
|
_StorageManager.okfConformanceByDir.set(memoryDir, enabled !== false);
|
|
7003
7066
|
}
|
|
7004
7067
|
okfConformanceEnabled() {
|
|
7005
|
-
for (let dir = this.baseDir; ; dir =
|
|
7068
|
+
for (let dir = this.baseDir; ; dir = path16.dirname(dir)) {
|
|
7006
7069
|
const registered = _StorageManager.okfConformanceByDir.get(dir);
|
|
7007
7070
|
if (registered !== void 0) return registered;
|
|
7008
|
-
if (dir ===
|
|
7071
|
+
if (dir === path16.dirname(dir)) return true;
|
|
7009
7072
|
}
|
|
7010
7073
|
}
|
|
7011
7074
|
/**
|
|
@@ -7049,12 +7112,12 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7049
7112
|
}
|
|
7050
7113
|
identityFilePath(workspaceDir, namespace) {
|
|
7051
7114
|
const rawNamespace = typeof namespace === "string" ? namespace.trim() : "";
|
|
7052
|
-
if (!rawNamespace) return
|
|
7115
|
+
if (!rawNamespace) return path16.join(workspaceDir, "IDENTITY.md");
|
|
7053
7116
|
const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
7054
|
-
return
|
|
7117
|
+
return path16.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);
|
|
7055
7118
|
}
|
|
7056
7119
|
versionFilePath(kind) {
|
|
7057
|
-
return
|
|
7120
|
+
return path16.join(this.stateDir, `.${kind}-version.log`);
|
|
7058
7121
|
}
|
|
7059
7122
|
bumpSharedVersion(kind, fallbackMap) {
|
|
7060
7123
|
const filePath = this.versionFilePath(kind);
|
|
@@ -7161,7 +7224,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7161
7224
|
// memories.
|
|
7162
7225
|
// -------------------------------------------------------------------------
|
|
7163
7226
|
get wearablesDir() {
|
|
7164
|
-
return
|
|
7227
|
+
return path16.join(this.baseDir, WEARABLES_DIR_NAME);
|
|
7165
7228
|
}
|
|
7166
7229
|
/**
|
|
7167
7230
|
* Resolve the on-disk path for a source/day transcript. Throws on
|
|
@@ -7177,7 +7240,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7177
7240
|
if (!isValidTranscriptDate(date)) {
|
|
7178
7241
|
throw new Error(`invalid wearable transcript date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
7179
7242
|
}
|
|
7180
|
-
return
|
|
7243
|
+
return path16.join(this.wearablesDir, sourceId, `${date}.md`);
|
|
7181
7244
|
}
|
|
7182
7245
|
async writeWearableDayTranscript(sourceId, date, serialized) {
|
|
7183
7246
|
const targetPath = this.wearableTranscriptPath(sourceId, date);
|
|
@@ -7291,25 +7354,25 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7291
7354
|
});
|
|
7292
7355
|
}
|
|
7293
7356
|
get factsDir() {
|
|
7294
|
-
return
|
|
7357
|
+
return path16.join(this.baseDir, "facts");
|
|
7295
7358
|
}
|
|
7296
7359
|
get correctionsDir() {
|
|
7297
|
-
return
|
|
7360
|
+
return path16.join(this.baseDir, "corrections");
|
|
7298
7361
|
}
|
|
7299
7362
|
get proceduresDir() {
|
|
7300
|
-
return
|
|
7363
|
+
return path16.join(this.baseDir, "procedures");
|
|
7301
7364
|
}
|
|
7302
7365
|
get reasoningTracesDir() {
|
|
7303
|
-
return
|
|
7366
|
+
return path16.join(this.baseDir, "reasoning-traces");
|
|
7304
7367
|
}
|
|
7305
7368
|
get entitiesDir() {
|
|
7306
|
-
return
|
|
7369
|
+
return path16.join(this.baseDir, "entities");
|
|
7307
7370
|
}
|
|
7308
7371
|
resolveEntityFilePath(name) {
|
|
7309
7372
|
if (typeof name !== "string") return null;
|
|
7310
|
-
const filePath =
|
|
7311
|
-
const relative2 =
|
|
7312
|
-
if (relative2 === "" || relative2.startsWith("..") ||
|
|
7373
|
+
const filePath = path16.resolve(this.entitiesDir, `${name}.md`);
|
|
7374
|
+
const relative2 = path16.relative(this.entitiesDir, filePath);
|
|
7375
|
+
if (relative2 === "" || relative2.startsWith("..") || path16.isAbsolute(relative2)) {
|
|
7313
7376
|
return null;
|
|
7314
7377
|
}
|
|
7315
7378
|
return filePath;
|
|
@@ -7320,7 +7383,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7320
7383
|
async readDependencyPropagationQueueFile(filePath) {
|
|
7321
7384
|
const target = await resolveSafeStoragePath(
|
|
7322
7385
|
this.baseDir,
|
|
7323
|
-
|
|
7386
|
+
path16.relative(
|
|
7324
7387
|
this.baseDir,
|
|
7325
7388
|
this.assertManagedStoragePath(filePath, "storage.readDependencyPropagationQueueFile")
|
|
7326
7389
|
)
|
|
@@ -7330,7 +7393,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7330
7393
|
async writeDependencyPropagationQueueFile(filePath, content) {
|
|
7331
7394
|
const target = await resolveSafeStoragePath(
|
|
7332
7395
|
this.baseDir,
|
|
7333
|
-
|
|
7396
|
+
path16.relative(
|
|
7334
7397
|
this.baseDir,
|
|
7335
7398
|
this.assertManagedStoragePath(filePath, "storage.writeDependencyPropagationQueueFile")
|
|
7336
7399
|
)
|
|
@@ -7345,10 +7408,10 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7345
7408
|
});
|
|
7346
7409
|
}
|
|
7347
7410
|
assertManagedStoragePath(filePath, method) {
|
|
7348
|
-
const resolved =
|
|
7349
|
-
const base =
|
|
7350
|
-
const rel =
|
|
7351
|
-
if (rel === "" || rel === ".." || rel.startsWith(`..${
|
|
7411
|
+
const resolved = path16.resolve(filePath);
|
|
7412
|
+
const base = path16.resolve(this.baseDir);
|
|
7413
|
+
const rel = path16.relative(base, resolved);
|
|
7414
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${path16.sep}`) || path16.isAbsolute(rel)) {
|
|
7352
7415
|
throw new Error(`${method}: file path escapes memory dir`);
|
|
7353
7416
|
}
|
|
7354
7417
|
return resolved;
|
|
@@ -7385,7 +7448,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7385
7448
|
async digestOfflineSyncFile(filePath) {
|
|
7386
7449
|
const target = this.assertManagedStoragePath(filePath, "storage.digestOfflineSyncFile");
|
|
7387
7450
|
const st = await stat3(target);
|
|
7388
|
-
const relPath =
|
|
7451
|
+
const relPath = path16.relative(this.baseDir, target).split(path16.sep).join("/");
|
|
7389
7452
|
const cache = await this.loadOfflineSyncDigestCache();
|
|
7390
7453
|
const cached = cache.get(relPath);
|
|
7391
7454
|
if (cached && cached.statBytes === st.size && cached.mtimeMs === st.mtimeMs && cached.ctimeMs === st.ctimeMs && !cached.encrypted) {
|
|
@@ -7470,7 +7533,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7470
7533
|
const cache = this.offlineSyncDigestCache;
|
|
7471
7534
|
if (!cache) return;
|
|
7472
7535
|
const entries = [...cache.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([entryPath, entry]) => ({ path: entryPath, ...entry }));
|
|
7473
|
-
await mkdir2(
|
|
7536
|
+
await mkdir2(path16.dirname(this.offlineSyncDigestCachePath), { recursive: true });
|
|
7474
7537
|
await writeFile2(this.offlineSyncDigestCachePath, `${JSON.stringify({ version: 1, entries })}
|
|
7475
7538
|
`, "utf-8");
|
|
7476
7539
|
}).catch((err) => {
|
|
@@ -7571,7 +7634,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7571
7634
|
}
|
|
7572
7635
|
async appendStorageSecureFileUnlocked(filePath, content) {
|
|
7573
7636
|
const writeKey = this.resolveWriteKey();
|
|
7574
|
-
await mkdir2(
|
|
7637
|
+
await mkdir2(path16.dirname(filePath), { recursive: true });
|
|
7575
7638
|
if (writeKey === null) {
|
|
7576
7639
|
try {
|
|
7577
7640
|
if (await this.isEncryptedFileHeader(filePath)) {
|
|
@@ -7597,13 +7660,13 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7597
7660
|
this.notifyCatalogWriteForPath(filePath);
|
|
7598
7661
|
}
|
|
7599
7662
|
get stateDir() {
|
|
7600
|
-
return
|
|
7663
|
+
return path16.join(this.baseDir, "state");
|
|
7601
7664
|
}
|
|
7602
7665
|
get offlineSyncDigestCachePath() {
|
|
7603
|
-
return
|
|
7666
|
+
return path16.join(this.baseDir, ".offline-sync", "digest-cache.v1.json");
|
|
7604
7667
|
}
|
|
7605
7668
|
get entitySynthesisQueuePath() {
|
|
7606
|
-
return
|
|
7669
|
+
return path16.join(this.stateDir, "entity-synthesis-queue.json");
|
|
7607
7670
|
}
|
|
7608
7671
|
// ── Tombstone store access (issue #1579) ─────────────────────────────────
|
|
7609
7672
|
/**
|
|
@@ -7613,7 +7676,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7613
7676
|
* helpers are injected into the store).
|
|
7614
7677
|
*/
|
|
7615
7678
|
get tombstonesPath() {
|
|
7616
|
-
return
|
|
7679
|
+
return path16.join(this.stateDir, "tombstones.jsonl");
|
|
7617
7680
|
}
|
|
7618
7681
|
/**
|
|
7619
7682
|
* Configure the tombstone invariant for this storage instance. Installed
|
|
@@ -7926,55 +7989,55 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7926
7989
|
return legacyMatches.length > 0 ? [...new Set(legacyMatches.map((content) => ContentHashIndex.computeHash(content)))] : [persistedHash];
|
|
7927
7990
|
}
|
|
7928
7991
|
get questionsDir() {
|
|
7929
|
-
return
|
|
7992
|
+
return path16.join(this.baseDir, "questions");
|
|
7930
7993
|
}
|
|
7931
7994
|
get artifactsDir() {
|
|
7932
|
-
return
|
|
7995
|
+
return path16.join(this.baseDir, "artifacts");
|
|
7933
7996
|
}
|
|
7934
7997
|
get identityDir() {
|
|
7935
|
-
return
|
|
7998
|
+
return path16.join(this.baseDir, "identity");
|
|
7936
7999
|
}
|
|
7937
8000
|
get identityAnchorPath() {
|
|
7938
|
-
return
|
|
8001
|
+
return path16.join(this.identityDir, "identity-anchor.md");
|
|
7939
8002
|
}
|
|
7940
8003
|
get identityIncidentsDir() {
|
|
7941
|
-
return
|
|
8004
|
+
return path16.join(this.identityDir, "incidents");
|
|
7942
8005
|
}
|
|
7943
8006
|
get identityAuditsWeeklyDir() {
|
|
7944
|
-
return
|
|
8007
|
+
return path16.join(this.identityDir, "audits", "weekly");
|
|
7945
8008
|
}
|
|
7946
8009
|
get identityAuditsMonthlyDir() {
|
|
7947
|
-
return
|
|
8010
|
+
return path16.join(this.identityDir, "audits", "monthly");
|
|
7948
8011
|
}
|
|
7949
8012
|
get identityImprovementLoopsPath() {
|
|
7950
|
-
return
|
|
8013
|
+
return path16.join(this.identityDir, "improvement-loops.md");
|
|
7951
8014
|
}
|
|
7952
8015
|
get identityReflectionsPath() {
|
|
7953
|
-
return
|
|
8016
|
+
return path16.join(this.identityDir, "reflections.md");
|
|
7954
8017
|
}
|
|
7955
8018
|
get profilePath() {
|
|
7956
|
-
return
|
|
8019
|
+
return path16.join(this.baseDir, "profile.md");
|
|
7957
8020
|
}
|
|
7958
8021
|
get memoryActionsPath() {
|
|
7959
|
-
return
|
|
8022
|
+
return path16.join(this.stateDir, "memory-actions.jsonl");
|
|
7960
8023
|
}
|
|
7961
8024
|
get memoryLifecycleLedgerPath() {
|
|
7962
|
-
return
|
|
8025
|
+
return path16.join(this.stateDir, "memory-lifecycle-ledger.jsonl");
|
|
7963
8026
|
}
|
|
7964
8027
|
get compressionGuidelinesPath() {
|
|
7965
|
-
return
|
|
8028
|
+
return path16.join(this.stateDir, "compression-guidelines.md");
|
|
7966
8029
|
}
|
|
7967
8030
|
get compressionGuidelineDraftPath() {
|
|
7968
|
-
return
|
|
8031
|
+
return path16.join(this.stateDir, "compression-guidelines.draft.md");
|
|
7969
8032
|
}
|
|
7970
8033
|
get compressionGuidelineStatePath() {
|
|
7971
|
-
return
|
|
8034
|
+
return path16.join(this.stateDir, "compression-guideline-state.json");
|
|
7972
8035
|
}
|
|
7973
8036
|
get compressionGuidelineDraftStatePath() {
|
|
7974
|
-
return
|
|
8037
|
+
return path16.join(this.stateDir, "compression-guideline-draft-state.json");
|
|
7975
8038
|
}
|
|
7976
8039
|
get behaviorSignalsPath() {
|
|
7977
|
-
return
|
|
8040
|
+
return path16.join(this.stateDir, "behavior-signals.jsonl");
|
|
7978
8041
|
}
|
|
7979
8042
|
/**
|
|
7980
8043
|
* In-memory dedup key set for behavior-signals appends (issue #1909),
|
|
@@ -8006,7 +8069,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8006
8069
|
* governance sweeps can treat it uniformly.
|
|
8007
8070
|
*/
|
|
8008
8071
|
get bufferSurpriseLedgerPath() {
|
|
8009
|
-
return
|
|
8072
|
+
return path16.join(this.stateDir, "buffer-surprise-ledger.jsonl");
|
|
8010
8073
|
}
|
|
8011
8074
|
/**
|
|
8012
8075
|
* Entity alias table loaded from THIS store's config/aliases.json.
|
|
@@ -8069,7 +8132,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8069
8132
|
this.loadAliasesSync();
|
|
8070
8133
|
}
|
|
8071
8134
|
loadAliasesSync() {
|
|
8072
|
-
const aliasPath =
|
|
8135
|
+
const aliasPath = path16.join(this.baseDir, "config", "aliases.json");
|
|
8073
8136
|
this.userAliases = {};
|
|
8074
8137
|
const raw = readEntityAliasConfigSync(this.baseDir);
|
|
8075
8138
|
if (raw === void 0) return;
|
|
@@ -8107,9 +8170,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8107
8170
|
await mkdir2(this.baseDir, { recursive: true });
|
|
8108
8171
|
await validateRoots(this.baseDir, this.entitiesDir, this.stateDir, this.archiveDir);
|
|
8109
8172
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8110
|
-
await mkdir2(
|
|
8111
|
-
await mkdir2(
|
|
8112
|
-
await mkdir2(
|
|
8173
|
+
await mkdir2(path16.join(this.factsDir, today), { recursive: true });
|
|
8174
|
+
await mkdir2(path16.join(this.proceduresDir, today), { recursive: true });
|
|
8175
|
+
await mkdir2(path16.join(this.reasoningTracesDir, today), { recursive: true });
|
|
8113
8176
|
await mkdir2(this.correctionsDir, { recursive: true });
|
|
8114
8177
|
await mkdir2(this.entitiesDir, { recursive: true });
|
|
8115
8178
|
await mkdir2(this.stateDir, { recursive: true });
|
|
@@ -8119,7 +8182,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8119
8182
|
await mkdir2(this.identityIncidentsDir, { recursive: true });
|
|
8120
8183
|
await mkdir2(this.identityAuditsWeeklyDir, { recursive: true });
|
|
8121
8184
|
await mkdir2(this.identityAuditsMonthlyDir, { recursive: true });
|
|
8122
|
-
await mkdir2(
|
|
8185
|
+
await mkdir2(path16.join(this.baseDir, "config"), { recursive: true });
|
|
8123
8186
|
await this.entityCanonicalIdMigration.begin(options.waitForEntityMigration !== false, this.entitiesDir);
|
|
8124
8187
|
if (this.hotMemoriesCacheEnabled && this.getMemoryCorpusVersion() === 0) {
|
|
8125
8188
|
this.bumpMemoryCorpusVersion();
|
|
@@ -8142,11 +8205,11 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8142
8205
|
async resolveCategoryWritePath(category, id, today) {
|
|
8143
8206
|
if (category === "correction") {
|
|
8144
8207
|
await mkdir2(this.correctionsDir, { recursive: true });
|
|
8145
|
-
return
|
|
8208
|
+
return path16.join(this.correctionsDir, `${id}.md`);
|
|
8146
8209
|
}
|
|
8147
|
-
const datedDir =
|
|
8210
|
+
const datedDir = path16.join(getCategoryDir(this.baseDir, category), today);
|
|
8148
8211
|
await mkdir2(datedDir, { recursive: true });
|
|
8149
|
-
return
|
|
8212
|
+
return path16.join(datedDir, `${id}.md`);
|
|
8150
8213
|
}
|
|
8151
8214
|
async findExistingTombstoneBlockedMemory(content, category, sourceConnector) {
|
|
8152
8215
|
const identity = buildExplicitCaptureDedupKey(content, category, sourceConnector);
|
|
@@ -8525,7 +8588,7 @@ ${sanitized.text}
|
|
|
8525
8588
|
await this.ensureDirectories();
|
|
8526
8589
|
const now = /* @__PURE__ */ new Date();
|
|
8527
8590
|
const day = now.toISOString().slice(0, 10);
|
|
8528
|
-
const dir =
|
|
8591
|
+
const dir = path16.join(this.artifactsDir, day);
|
|
8529
8592
|
await mkdir2(dir, { recursive: true });
|
|
8530
8593
|
const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
8531
8594
|
const fm = {
|
|
@@ -8552,7 +8615,7 @@ ${sanitized.text}
|
|
|
8552
8615
|
log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
8553
8616
|
return "";
|
|
8554
8617
|
}
|
|
8555
|
-
const filePath =
|
|
8618
|
+
const filePath = path16.join(dir, `${id}.md`);
|
|
8556
8619
|
await this.writeStorageSecureFile(filePath, `${serializeFrontmatter(this.withOkfType(fm))}
|
|
8557
8620
|
|
|
8558
8621
|
${sanitized.text}
|
|
@@ -8607,44 +8670,20 @@ ${sanitized.text}
|
|
|
8607
8670
|
await this.writeStorageSecureFile(this.profilePath, stampedContent);
|
|
8608
8671
|
log.debug("updated profile.md");
|
|
8609
8672
|
}
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
return s.toLowerCase().replace(/[^a-z0-9\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
8673
|
+
async appendToProfile(updates) {
|
|
8674
|
+
await appendToProfileSerialized(this.profileMutationPorts(), updates);
|
|
8613
8675
|
}
|
|
8614
|
-
/**
|
|
8615
|
-
*
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
static isFuzzyDuplicate(newNorm, existingNorms) {
|
|
8619
|
-
for (const existing of existingNorms) {
|
|
8620
|
-
if (newNorm === existing) return true;
|
|
8621
|
-
const shorter = newNorm.length <= existing.length ? newNorm : existing;
|
|
8622
|
-
const longer = newNorm.length > existing.length ? newNorm : existing;
|
|
8623
|
-
if (shorter.length > 20 && shorter.length / longer.length > 0.6 && longer.includes(shorter)) {
|
|
8624
|
-
return true;
|
|
8625
|
-
}
|
|
8626
|
-
}
|
|
8627
|
-
return false;
|
|
8676
|
+
/** Commit an LLM profile consolidation only if the profile is unchanged
|
|
8677
|
+
* since `baseline` was read; see profile-mutation.ts for the race domain. */
|
|
8678
|
+
async commitConsolidatedProfile(baseline, consolidated) {
|
|
8679
|
+
return commitConsolidatedProfileSerialized(this.profileMutationPorts(), baseline, consolidated);
|
|
8628
8680
|
}
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
const existingNorms = existingBulletRaw.map(_StorageManager.normalizeForDedup);
|
|
8636
|
-
const newBullets = updates.filter((u) => {
|
|
8637
|
-
const norm = _StorageManager.normalizeForDedup(u);
|
|
8638
|
-
return !_StorageManager.isFuzzyDuplicate(norm, existingNorms);
|
|
8639
|
-
});
|
|
8640
|
-
if (newBullets.length === 0) return;
|
|
8641
|
-
if (!existing) {
|
|
8642
|
-
const content = ["# Behavioral Profile", "", ...newBullets.map((b) => `- ${b}`), ""].join("\n");
|
|
8643
|
-
await this.writeProfile(content);
|
|
8644
|
-
} else {
|
|
8645
|
-
const withBullets = existing.trimEnd() + "\n" + newBullets.map((b) => `- ${b}`).join("\n") + "\n";
|
|
8646
|
-
await this.writeProfile(withBullets);
|
|
8647
|
-
}
|
|
8681
|
+
profileMutationPorts() {
|
|
8682
|
+
return {
|
|
8683
|
+
baseDir: this.baseDir,
|
|
8684
|
+
readProfile: () => this.readProfile(),
|
|
8685
|
+
writeProfile: (content) => this.writeProfile(content)
|
|
8686
|
+
};
|
|
8648
8687
|
}
|
|
8649
8688
|
/** Check if profile.md exceeds the max line cap and needs LLM consolidation */
|
|
8650
8689
|
async profileNeedsConsolidation(triggerLines) {
|
|
@@ -8846,7 +8885,7 @@ ${sanitized.text}
|
|
|
8846
8885
|
* per-process in-memory cache safe across process boundaries.
|
|
8847
8886
|
*/
|
|
8848
8887
|
invalidateColdMemoriesCache() {
|
|
8849
|
-
const coldRoot =
|
|
8888
|
+
const coldRoot = path16.join(this.baseDir, "cold");
|
|
8850
8889
|
_StorageManager.coldMemoriesCache.delete(coldRoot);
|
|
8851
8890
|
this.bumpColdWriteVersion();
|
|
8852
8891
|
invalidateAllForDir(this.baseDir);
|
|
@@ -8964,7 +9003,7 @@ ${sanitized.text}
|
|
|
8964
9003
|
const correctionPaths = [];
|
|
8965
9004
|
const factPaths = [];
|
|
8966
9005
|
for (const filePath of filePaths) {
|
|
8967
|
-
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${
|
|
9006
|
+
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${path16.sep}`)) {
|
|
8968
9007
|
correctionPaths.push(filePath);
|
|
8969
9008
|
} else {
|
|
8970
9009
|
factPaths.push(filePath);
|
|
@@ -9031,7 +9070,7 @@ ${sanitized.text}
|
|
|
9031
9070
|
const entries = (await readdir6(dir, { withFileTypes: true })).filter((e) => !isMacOsReplicationJunkBasename(e.name));
|
|
9032
9071
|
for (const entry of entries) {
|
|
9033
9072
|
checkCorpusReadAbort(options);
|
|
9034
|
-
const fullPath =
|
|
9073
|
+
const fullPath = path16.join(dir, entry.name);
|
|
9035
9074
|
if (entry.isDirectory()) {
|
|
9036
9075
|
await readDir(fullPath);
|
|
9037
9076
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -9071,7 +9110,7 @@ ${sanitized.text}
|
|
|
9071
9110
|
return this.rememberMemorySnapshot(await this.memoryReadStore.readMemoryByPath(filePath));
|
|
9072
9111
|
}
|
|
9073
9112
|
resolveTierRootDir(tier) {
|
|
9074
|
-
return tier === "cold" ?
|
|
9113
|
+
return tier === "cold" ? path16.join(this.baseDir, "cold") : this.baseDir;
|
|
9075
9114
|
}
|
|
9076
9115
|
resolveMemoryDateDir(memory) {
|
|
9077
9116
|
const preferred = memory.frontmatter.created || memory.frontmatter.updated;
|
|
@@ -9086,13 +9125,13 @@ ${sanitized.text}
|
|
|
9086
9125
|
buildTierMemoryPath(memory, tier) {
|
|
9087
9126
|
const root = this.resolveTierRootDir(tier);
|
|
9088
9127
|
if (this.isArtifactMemory(memory)) {
|
|
9089
|
-
return
|
|
9128
|
+
return path16.join(root, "artifacts", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9090
9129
|
}
|
|
9091
9130
|
if (memory.frontmatter.category === "correction") {
|
|
9092
|
-
return
|
|
9131
|
+
return path16.join(root, "corrections", `${memory.frontmatter.id}.md`);
|
|
9093
9132
|
}
|
|
9094
9133
|
const dir = categoryDirName(memory.frontmatter.category);
|
|
9095
|
-
return
|
|
9134
|
+
return path16.join(root, dir, this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9096
9135
|
}
|
|
9097
9136
|
async writeMemoryFileAtomic(targetPath, memory) {
|
|
9098
9137
|
assertNotOkfReservedBasename(targetPath);
|
|
@@ -9171,8 +9210,8 @@ ${memory.content}
|
|
|
9171
9210
|
memory.frontmatter.entityRef = current.frontmatter.entityRef;
|
|
9172
9211
|
}
|
|
9173
9212
|
durable = true;
|
|
9174
|
-
const sourcePath =
|
|
9175
|
-
const destPath =
|
|
9213
|
+
const sourcePath = path16.resolve(current.path);
|
|
9214
|
+
const destPath = path16.resolve(targetPath);
|
|
9176
9215
|
if (sourcePath !== destPath) {
|
|
9177
9216
|
await recordArchiveDelete2(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));
|
|
9178
9217
|
this.invalidateAllMemoriesCache();
|
|
@@ -9196,8 +9235,8 @@ ${memory.content}
|
|
|
9196
9235
|
}
|
|
9197
9236
|
async migrateMemoryToTier(memory, targetTier) {
|
|
9198
9237
|
const targetPath = this.buildTierMemoryPath(memory, targetTier);
|
|
9199
|
-
const sourcePath =
|
|
9200
|
-
const destPath =
|
|
9238
|
+
const sourcePath = path16.resolve(memory.path);
|
|
9239
|
+
const destPath = path16.resolve(targetPath);
|
|
9201
9240
|
if (sourcePath === destPath) {
|
|
9202
9241
|
return { changed: false, targetPath };
|
|
9203
9242
|
}
|
|
@@ -9207,7 +9246,7 @@ ${memory.content}
|
|
|
9207
9246
|
return { changed, targetPath };
|
|
9208
9247
|
}
|
|
9209
9248
|
get archiveDir() {
|
|
9210
|
-
return
|
|
9249
|
+
return path16.join(this.baseDir, "archive");
|
|
9211
9250
|
}
|
|
9212
9251
|
/**
|
|
9213
9252
|
* Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.
|
|
@@ -9220,7 +9259,7 @@ ${memory.content}
|
|
|
9220
9259
|
try {
|
|
9221
9260
|
const now = lifecycle?.at ?? /* @__PURE__ */ new Date();
|
|
9222
9261
|
const today = now.toISOString().slice(0, 10);
|
|
9223
|
-
const destDir =
|
|
9262
|
+
const destDir = path16.join(this.archiveDir, today);
|
|
9224
9263
|
await mkdir2(destDir, { recursive: true });
|
|
9225
9264
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
9226
9265
|
const updatedFm = canonicalizeEntityRefOption(
|
|
@@ -9236,7 +9275,7 @@ ${memory.content}
|
|
|
9236
9275
|
|
|
9237
9276
|
${current.content}
|
|
9238
9277
|
`;
|
|
9239
|
-
const destPath =
|
|
9278
|
+
const destPath = path16.join(destDir, path16.basename(current.path));
|
|
9240
9279
|
const priorDest = await this.readStorageSecureFile(destPath).catch(() => null);
|
|
9241
9280
|
await recordArchiveWrite(this.baseDir, destPath, () => this.writeStorageSecureFile(destPath, fileContent));
|
|
9242
9281
|
if (typeof current.frontmatter.entityRef === "string") {
|
|
@@ -9460,7 +9499,7 @@ ${memory.content}
|
|
|
9460
9499
|
`;
|
|
9461
9500
|
await this.writeTombstoneBlockedFrontmatter(memory, fileContent, updated, async () => {
|
|
9462
9501
|
this.invalidateAllMemoriesCache();
|
|
9463
|
-
if (memory.path.includes(`${
|
|
9502
|
+
if (memory.path.includes(`${path16.sep}cold${path16.sep}`)) {
|
|
9464
9503
|
this.invalidateColdMemoriesCache();
|
|
9465
9504
|
}
|
|
9466
9505
|
});
|
|
@@ -9472,7 +9511,7 @@ ${memory.content}
|
|
|
9472
9511
|
}
|
|
9473
9512
|
if (mentionReentry && !entityMentionEpoch.neutral(memory.frontmatter, updated)) entityMentionEpoch.bump(this.baseDir);
|
|
9474
9513
|
await this.patchHotMemoriesCache({ addedPath: memory.path });
|
|
9475
|
-
if (memory.path.includes(`${
|
|
9514
|
+
if (memory.path.includes(`${path16.sep}cold${path16.sep}`)) {
|
|
9476
9515
|
this.invalidateColdMemoriesCache();
|
|
9477
9516
|
}
|
|
9478
9517
|
try {
|
|
@@ -9582,7 +9621,7 @@ ${memory.content}
|
|
|
9582
9621
|
return saveDroppedExtractionChunk(this.stateDir, (file, content) => this.writeStorageSecureFile(file, content), bufferKey, reason, turns);
|
|
9583
9622
|
}
|
|
9584
9623
|
async loadMeta() {
|
|
9585
|
-
const metaPath =
|
|
9624
|
+
const metaPath = path16.join(this.stateDir, "meta.json");
|
|
9586
9625
|
try {
|
|
9587
9626
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
9588
9627
|
const parsed = JSON.parse(raw);
|
|
@@ -9615,7 +9654,7 @@ ${memory.content}
|
|
|
9615
9654
|
}
|
|
9616
9655
|
async saveMeta(state) {
|
|
9617
9656
|
await this.ensureDirectories();
|
|
9618
|
-
await this.writeStorageSecureFile(
|
|
9657
|
+
await this.writeStorageSecureFile(path16.join(this.stateDir, "meta.json"), JSON.stringify(state, null, 2));
|
|
9619
9658
|
}
|
|
9620
9659
|
async updateMeta(mutate) {
|
|
9621
9660
|
await updateMetaSerialized(this.stateDir, () => this.loadMeta(), (meta) => this.saveMeta(meta), mutate);
|
|
@@ -9687,7 +9726,7 @@ ${memory.content}
|
|
|
9687
9726
|
},
|
|
9688
9727
|
(payload) => this.appendStorageSecureFile(target, payload),
|
|
9689
9728
|
async () => {
|
|
9690
|
-
await mkdir2(
|
|
9729
|
+
await mkdir2(path16.dirname(target), { recursive: true });
|
|
9691
9730
|
}
|
|
9692
9731
|
);
|
|
9693
9732
|
}
|
|
@@ -9785,7 +9824,7 @@ ${memory.content}
|
|
|
9785
9824
|
async appendReextractJobs(events) {
|
|
9786
9825
|
if (events.length === 0) return 0;
|
|
9787
9826
|
await this.ensureDirectories();
|
|
9788
|
-
const filePath =
|
|
9827
|
+
const filePath = path16.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9789
9828
|
const lines = events.map((event) => JSON.stringify(event)).join("\n") + "\n";
|
|
9790
9829
|
try {
|
|
9791
9830
|
await this.appendStorageSecureFile(filePath, lines);
|
|
@@ -9798,7 +9837,7 @@ ${memory.content}
|
|
|
9798
9837
|
}
|
|
9799
9838
|
async readReextractJobs(limit = 200) {
|
|
9800
9839
|
const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1e3, Math.floor(limit))) : 200;
|
|
9801
|
-
const filePath =
|
|
9840
|
+
const filePath = path16.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9802
9841
|
try {
|
|
9803
9842
|
const raw = await this.readStorageSecureFile(filePath);
|
|
9804
9843
|
const lines = raw.split("\n").filter((line) => line.trim().length > 0);
|
|
@@ -10033,7 +10072,7 @@ ${question}
|
|
|
10033
10072
|
|
|
10034
10073
|
**Context:** ${context}
|
|
10035
10074
|
`;
|
|
10036
|
-
const filePath =
|
|
10075
|
+
const filePath = path16.join(this.questionsDir, `${id}.md`);
|
|
10037
10076
|
await this.writeStorageSecureFile(filePath, content);
|
|
10038
10077
|
log.debug(`wrote question ${id} to ${filePath}`);
|
|
10039
10078
|
this.invalidateQuestionsCache();
|
|
@@ -10092,11 +10131,11 @@ ${question}
|
|
|
10092
10131
|
} catch {
|
|
10093
10132
|
}
|
|
10094
10133
|
const hygiene = opts?.hygiene;
|
|
10095
|
-
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(
|
|
10134
|
+
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(path16.basename(identityPath));
|
|
10096
10135
|
if (rotateEnabled) {
|
|
10097
10136
|
const maxBytes = hygiene.rotateMaxBytes;
|
|
10098
10137
|
if (existing.length > maxBytes) {
|
|
10099
|
-
const archiveDir =
|
|
10138
|
+
const archiveDir = path16.join(workspaceDir, hygiene.archiveDir);
|
|
10100
10139
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
10101
10140
|
filePath: identityPath,
|
|
10102
10141
|
archiveDir,
|
|
@@ -10356,7 +10395,7 @@ ${reflection}
|
|
|
10356
10395
|
if (entries.length === 0) return 0;
|
|
10357
10396
|
const memories = await this.readAllMemories();
|
|
10358
10397
|
const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));
|
|
10359
|
-
const memoryPathMap = new Map(memories.map((m) => [
|
|
10398
|
+
const memoryPathMap = new Map(memories.map((m) => [path16.resolve(m.path), m]));
|
|
10360
10399
|
let updated = 0;
|
|
10361
10400
|
const prevVersion = this.getMemoryCorpusVersion();
|
|
10362
10401
|
let entityRefMoved = false;
|
|
@@ -10364,7 +10403,7 @@ ${reflection}
|
|
|
10364
10403
|
const warm = this.hotMemoriesCacheEnabled && getCachedMemories(this.baseDir, prevVersion, keyId, this.hotCacheTtlMs()) !== null;
|
|
10365
10404
|
const appliedPatches = /* @__PURE__ */ new Map();
|
|
10366
10405
|
for (const entry of entries) {
|
|
10367
|
-
const memory = entry.memoryPath ? memoryPathMap.get(
|
|
10406
|
+
const memory = entry.memoryPath ? memoryPathMap.get(path16.resolve(entry.memoryPath)) : memoryMap.get(entry.memoryId);
|
|
10368
10407
|
if (!memory) continue;
|
|
10369
10408
|
try {
|
|
10370
10409
|
const applied = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {
|
|
@@ -10396,7 +10435,7 @@ ${current.content}
|
|
|
10396
10435
|
if (warm) {
|
|
10397
10436
|
updateCacheOnWrite(this.baseDir, { ...applied.current, frontmatter: applied.newFm }, keyId);
|
|
10398
10437
|
}
|
|
10399
|
-
appliedPatches.set(
|
|
10438
|
+
appliedPatches.set(path16.resolve(memory.path), {
|
|
10400
10439
|
accessCount: entry.newCount,
|
|
10401
10440
|
lastAccessed: entry.lastAccessed
|
|
10402
10441
|
});
|
|
@@ -10414,7 +10453,7 @@ ${current.content}
|
|
|
10414
10453
|
const cur = getCachedMemories(this.baseDir, prevVersion, keyId);
|
|
10415
10454
|
if (cur) {
|
|
10416
10455
|
const reapplied = cur.map((m) => {
|
|
10417
|
-
const patch = appliedPatches.get(
|
|
10456
|
+
const patch = appliedPatches.get(path16.resolve(m.path));
|
|
10418
10457
|
return patch ? {
|
|
10419
10458
|
...m,
|
|
10420
10459
|
frontmatter: { ...m.frontmatter, accessCount: patch.accessCount, lastAccessed: patch.lastAccessed }
|
|
@@ -10444,7 +10483,7 @@ ${current.content}
|
|
|
10444
10483
|
const pathsById = /* @__PURE__ */ new Map();
|
|
10445
10484
|
const filePathsById = /* @__PURE__ */ new Map();
|
|
10446
10485
|
for (const filePath of filePaths) {
|
|
10447
|
-
const memoryId =
|
|
10486
|
+
const memoryId = path16.basename(filePath, ".md");
|
|
10448
10487
|
if (!wantedIds.has(memoryId)) continue;
|
|
10449
10488
|
const paths = filePathsById.get(memoryId) ?? [];
|
|
10450
10489
|
paths.push(filePath);
|
|
@@ -10456,7 +10495,7 @@ ${current.content}
|
|
|
10456
10495
|
const preferredMatches = [];
|
|
10457
10496
|
for (const preferredPath of preferred) {
|
|
10458
10497
|
const directCandidates = new Set(qmdResultPathCandidates(this.baseDir, preferredPath));
|
|
10459
|
-
const directMatch = existingPaths.find((filePath) => directCandidates.has(
|
|
10498
|
+
const directMatch = existingPaths.find((filePath) => directCandidates.has(path16.resolve(filePath)));
|
|
10460
10499
|
if (directMatch) {
|
|
10461
10500
|
preferredMatches.push(directMatch);
|
|
10462
10501
|
continue;
|
|
@@ -10468,7 +10507,7 @@ ${current.content}
|
|
|
10468
10507
|
candidates.add(candidate);
|
|
10469
10508
|
}
|
|
10470
10509
|
}
|
|
10471
|
-
const match = existingPaths.find((filePath) => candidates.has(
|
|
10510
|
+
const match = existingPaths.find((filePath) => candidates.has(path16.resolve(filePath)));
|
|
10472
10511
|
if (match) preferredMatches.push(match);
|
|
10473
10512
|
}
|
|
10474
10513
|
if (preferredMatches.length > 0) {
|
|
@@ -10790,11 +10829,11 @@ ${current.content}
|
|
|
10790
10829
|
}
|
|
10791
10830
|
}
|
|
10792
10831
|
get summariesDir() {
|
|
10793
|
-
return
|
|
10832
|
+
return path16.join(this.baseDir, "summaries");
|
|
10794
10833
|
}
|
|
10795
10834
|
async writeSummary(summary) {
|
|
10796
10835
|
await mkdir2(this.summariesDir, { recursive: true });
|
|
10797
|
-
const filePath =
|
|
10836
|
+
const filePath = path16.join(this.summariesDir, `${summary.id}.json`);
|
|
10798
10837
|
await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));
|
|
10799
10838
|
log.debug(`wrote summary ${summary.id}`);
|
|
10800
10839
|
}
|
|
@@ -10804,7 +10843,7 @@ ${current.content}
|
|
|
10804
10843
|
const summaries = [];
|
|
10805
10844
|
for (const file of files) {
|
|
10806
10845
|
if (isMacOsReplicationJunkBasename(file) || !file.endsWith(".json")) continue;
|
|
10807
|
-
const filePath =
|
|
10846
|
+
const filePath = path16.join(this.summariesDir, file);
|
|
10808
10847
|
const raw = await this.readStorageSecureFile(filePath);
|
|
10809
10848
|
summaries.push(JSON.parse(raw));
|
|
10810
10849
|
}
|
|
@@ -10874,13 +10913,13 @@ ${current.content}
|
|
|
10874
10913
|
return archived;
|
|
10875
10914
|
}
|
|
10876
10915
|
async saveTopics(topics) {
|
|
10877
|
-
const metaPath =
|
|
10916
|
+
const metaPath = path16.join(this.stateDir, "topics.json");
|
|
10878
10917
|
await mkdir2(this.stateDir, { recursive: true });
|
|
10879
10918
|
await this.writeStorageSecureFile(metaPath, JSON.stringify({ topics, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
|
|
10880
10919
|
log.debug(`saved ${topics.length} topic scores`);
|
|
10881
10920
|
}
|
|
10882
10921
|
async loadTopics() {
|
|
10883
|
-
const metaPath =
|
|
10922
|
+
const metaPath = path16.join(this.stateDir, "topics.json");
|
|
10884
10923
|
try {
|
|
10885
10924
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
10886
10925
|
return JSON.parse(raw);
|
|
@@ -11000,4 +11039,4 @@ export {
|
|
|
11000
11039
|
isValidBufferSurpriseEvent,
|
|
11001
11040
|
StorageManager3 as StorageManager
|
|
11002
11041
|
};
|
|
11003
|
-
//# sourceMappingURL=chunk-
|
|
11042
|
+
//# sourceMappingURL=chunk-NHWDTOBN.js.map
|