@remnic/core 10.0.51 → 10.0.53
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 +24 -24
- package/dist/access-authorization-probe.js +25 -25
- package/dist/access-boundary.js +24 -24
- package/dist/access-cli.js +65 -65
- package/dist/access-extraction-force-flush.js +24 -24
- package/dist/access-http-briefing.js +25 -25
- package/dist/access-http-query.js +26 -26
- package/dist/access-http.js +40 -40
- package/dist/access-identity-continuity-surface.js +24 -24
- package/dist/access-lcm-surface.js +24 -24
- package/dist/access-mcp.js +33 -33
- package/dist/access-namespace-preflight.js +24 -24
- package/dist/access-observe-write-surface.js +24 -24
- package/dist/access-operations-batch.js +25 -25
- package/dist/access-operations.js +32 -32
- package/dist/access-recall-concurrency.js +24 -24
- package/dist/access-recall-response.js +24 -24
- package/dist/access-recall-surface.js +24 -24
- package/dist/access-service.js +24 -24
- package/dist/access-surface-catalog.js +26 -26
- package/dist/active-recall.js +9 -9
- package/dist/briefing.js +10 -10
- package/dist/buffer.js +5 -5
- package/dist/causal-consolidation.js +11 -11
- package/dist/{chunk-3NL4ALUP.js → chunk-24SIB3EW.js} +3 -3
- package/dist/{chunk-Y3T5KQCR.js → chunk-2EYCW2ET.js} +2 -2
- package/dist/{chunk-AHGOOZUC.js → chunk-34UVJNSG.js} +2 -2
- package/dist/{chunk-2EXF6IIB.js → chunk-3632XJMR.js} +2 -2
- package/dist/{chunk-KETS5A62.js → chunk-3H3PNQEF.js} +2 -2
- package/dist/{chunk-SFRBUBUZ.js → chunk-3LNAQLW4.js} +3 -3
- package/dist/{chunk-75BK4XGV.js → chunk-4BUJICMI.js} +10 -10
- package/dist/{chunk-KIWO4327.js → chunk-4W5B5Z6P.js} +2 -2
- package/dist/{chunk-B35EQQ7L.js → chunk-53OFDW3P.js} +3 -3
- package/dist/{chunk-2ONKXEC7.js → chunk-5LBBXI2A.js} +2 -2
- package/dist/{chunk-UCLJTGP3.js → chunk-65B5RFKQ.js} +2 -2
- package/dist/{chunk-KAJYSO3U.js → chunk-6CDNOREO.js} +2 -2
- package/dist/{chunk-POJRFSJM.js → chunk-7XGNGLAN.js} +2 -2
- package/dist/{chunk-A6JDT6QF.js → chunk-AO5ZOD32.js} +2 -2
- package/dist/{chunk-RA7YRL6H.js → chunk-AOSCGNIC.js} +3 -3
- package/dist/{chunk-LWMLBVGB.js → chunk-B43P3DTC.js} +2 -2
- package/dist/{chunk-SJD334AG.js → chunk-CA6X37OB.js} +217 -173
- package/dist/chunk-CA6X37OB.js.map +1 -0
- package/dist/{chunk-VUMWVYMR.js → chunk-CIMD2MUR.js} +3 -3
- package/dist/{chunk-XRFLR3XF.js → chunk-DLZGSZVC.js} +22 -9
- package/dist/chunk-DLZGSZVC.js.map +1 -0
- package/dist/{chunk-5CWH2LKL.js → chunk-DOJBV6WR.js} +29 -14
- package/dist/chunk-DOJBV6WR.js.map +1 -0
- package/dist/{chunk-44EUCSG4.js → chunk-FFQNNFHX.js} +2 -2
- package/dist/{chunk-HEF4BRMT.js → chunk-FZLZUDJJ.js} +2 -2
- package/dist/{chunk-L3EFYRYK.js → chunk-GGFQAGOT.js} +7 -7
- package/dist/{chunk-ZLCBLDJO.js → chunk-GIRWNTMV.js} +2 -2
- package/dist/{chunk-EC2KVA27.js → chunk-H4DWSOBQ.js} +169 -105
- package/dist/chunk-H4DWSOBQ.js.map +1 -0
- package/dist/{chunk-SHNM7RIT.js → chunk-HJ4X4BGS.js} +2 -2
- package/dist/{chunk-MUNYUSBU.js → chunk-HJQ4NKKO.js} +2 -2
- package/dist/{chunk-V6Z4NAJZ.js → chunk-HM3ZTDAX.js} +2 -2
- package/dist/{chunk-EZS6QJNC.js → chunk-IFOCK3OJ.js} +2 -2
- package/dist/{chunk-LXXIV7Y2.js → chunk-JEX2JL3U.js} +7 -2
- package/dist/{chunk-LXXIV7Y2.js.map → chunk-JEX2JL3U.js.map} +1 -1
- package/dist/{chunk-DF6ZF2BN.js → chunk-LIVNX7WK.js} +2 -2
- package/dist/{chunk-WY66J4PI.js → chunk-LRVFS4KA.js} +2 -2
- package/dist/{chunk-LMB47UM6.js → chunk-LTDK6HBV.js} +2 -2
- package/dist/{chunk-HCIRR3BA.js → chunk-M4U25HLR.js} +2 -2
- package/dist/{chunk-YK7ZJPQM.js → chunk-MGN2RQRG.js} +2 -2
- package/dist/{chunk-G26YNEOC.js → chunk-NWA6IXR3.js} +1 -1
- package/dist/{chunk-G26YNEOC.js.map → chunk-NWA6IXR3.js.map} +1 -1
- package/dist/{chunk-JIJAWTRK.js → chunk-OCXDZJL4.js} +264 -194
- package/dist/chunk-OCXDZJL4.js.map +1 -0
- package/dist/{chunk-IUQXRRJB.js → chunk-OMWQO7H6.js} +2 -2
- package/dist/{chunk-7VO6E5UD.js → chunk-OVZIYLBZ.js} +6 -2
- package/dist/chunk-OVZIYLBZ.js.map +1 -0
- package/dist/{chunk-SPTPBKZX.js → chunk-OWNAWY6D.js} +2 -2
- package/dist/{chunk-XKDQTDXN.js → chunk-PFUXPTBT.js} +36 -15
- package/dist/chunk-PFUXPTBT.js.map +1 -0
- package/dist/{chunk-DQOGZZJA.js → chunk-QAHP5SBG.js} +3 -3
- package/dist/{chunk-GBGU5OZP.js → chunk-QF5EJ5VP.js} +13 -13
- package/dist/{chunk-FT75AQ74.js → chunk-QS5DUSBM.js} +2 -2
- package/dist/{chunk-72CBJ5VP.js → chunk-R3WZ74B2.js} +3 -3
- package/dist/{chunk-PDTNQLPC.js → chunk-RG3I2663.js} +2 -2
- package/dist/{chunk-CK6GCGMX.js → chunk-RTJJPW3C.js} +2 -2
- package/dist/{chunk-RJDYDF5K.js → chunk-TRAOZ2WP.js} +2 -2
- package/dist/{chunk-6ZAU7LAR.js → chunk-TTTPTQ6S.js} +2 -2
- package/dist/{chunk-JS44PBCM.js → chunk-U2A56LLF.js} +6 -6
- package/dist/{chunk-MC7PXJDP.js → chunk-UBOWDOL5.js} +5 -5
- package/dist/{chunk-4FM35YIA.js → chunk-UQYBPPVC.js} +2 -2
- package/dist/{chunk-OCRLJJOV.js → chunk-V4VCBFAL.js} +3 -3
- package/dist/{chunk-FNNGWN3O.js → chunk-VGE4PUY6.js} +2 -2
- package/dist/{chunk-5DVOBBTV.js → chunk-VV73XT3A.js} +2 -2
- package/dist/{chunk-GE3ZX6YK.js → chunk-W7NKMRAF.js} +2 -2
- package/dist/{chunk-AJJPXUE6.js → chunk-WBN66HPI.js} +2 -2
- package/dist/{chunk-XWJUFER3.js → chunk-WGFEGBFB.js} +2 -2
- package/dist/{chunk-43TUWQNR.js → chunk-XDKEHZUC.js} +2 -2
- package/dist/{chunk-ROAKLYOL.js → chunk-XHEKS4UN.js} +2 -2
- package/dist/{chunk-ZKK3VMWU.js → chunk-XVTB6BZS.js} +2 -2
- package/dist/{chunk-AZLD4CKG.js → chunk-Y56D5FSD.js} +17 -17
- package/dist/{chunk-MPWOAIIH.js → chunk-YDT3OEYF.js} +2 -2
- package/dist/{chunk-IN6U2BS5.js → chunk-YJHOVA42.js} +2 -2
- package/dist/{chunk-TC55M5PO.js → chunk-YLN4ZQV4.js} +2 -2
- package/dist/cli.js +50 -50
- package/dist/coding/export-okf-codegraph.js +9 -9
- package/dist/compounding/engine.js +11 -11
- package/dist/config.js +9 -9
- package/dist/connectors/codex-materialize-runner.js +10 -10
- package/dist/connectors/index.js +10 -10
- package/dist/convergence-refresh.js +12 -12
- package/dist/corpus-watermark.js +12 -12
- package/dist/entity-retrieval.js +10 -10
- package/dist/external-wiki-access.js +25 -25
- package/dist/extraction.js +14 -14
- package/dist/harmonic-retrieval.js +10 -10
- package/dist/index.js +65 -65
- package/dist/location/index.js +12 -12
- package/dist/maintenance/memory-governance.js +10 -10
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -10
- package/dist/maintenance/rebuild-memory-projection-runner.js +12 -12
- package/dist/maintenance/rebuild-memory-projection.js +11 -11
- package/dist/memory-browse-operations.js +25 -25
- package/dist/memory-browse.js +5 -5
- package/dist/namespaces/migrate.js +11 -11
- package/dist/namespaces/search.d.ts.map +1 -1
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.js +10 -10
- package/dist/operator-doctor-corpus.js +13 -13
- package/dist/operator-toolkit.js +18 -18
- package/dist/orchestration/extraction-persist-deps.d.ts +2 -0
- package/dist/orchestration/extraction-persist-deps.d.ts.map +1 -1
- package/dist/orchestration/extraction-persist-promotion.d.ts +40 -10
- package/dist/orchestration/extraction-persist-promotion.d.ts.map +1 -1
- package/dist/orchestration/extraction-persist.d.ts.map +1 -1
- package/dist/orchestration/lifecycle-pending-fallback-drain.d.ts +18 -0
- package/dist/orchestration/lifecycle-pending-fallback-drain.d.ts.map +1 -0
- package/dist/orchestration/maintenance.d.ts +11 -13
- package/dist/orchestration/maintenance.d.ts.map +1 -1
- package/dist/orchestration/maintenance.js +20 -20
- package/dist/orchestration/qmd-maintenance-completion.d.ts +20 -0
- package/dist/orchestration/qmd-maintenance-completion.d.ts.map +1 -0
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +65 -65
- package/dist/qmd.js +2 -2
- package/dist/recall-composition-decision.js +2 -2
- package/dist/recall-navigation-operations.js +25 -25
- package/dist/recall-navigation.js +24 -24
- package/dist/recall-state-view-admission.js +5 -5
- package/dist/recall-why-service.js +5 -5
- package/dist/resume-bundles.js +9 -9
- package/dist/search/factory.js +7 -7
- package/dist/search/index.js +7 -7
- package/dist/search/lancedb-backend.d.ts +3 -0
- package/dist/search/lancedb-backend.d.ts.map +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +3 -0
- package/dist/search/meilisearch-backend.d.ts.map +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/orama-backend.d.ts +3 -0
- package/dist/search/orama-backend.d.ts.map +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +7 -0
- package/dist/search/port.d.ts.map +1 -1
- package/dist/search/port.js +1 -1
- package/dist/search/remote-backend.d.ts +2 -0
- package/dist/search/remote-backend.d.ts.map +1 -1
- package/dist/search/remote-backend.js +2 -2
- package/dist/semantic-consolidation.js +11 -11
- package/dist/semantic-rule-promotion.js +10 -10
- package/dist/semantic-rule-verifier.js +10 -10
- package/dist/source-agent-qualifier.js +13 -13
- package/dist/standup/build.js +10 -10
- package/dist/storage/entity-canonical-id-migration-adapter.d.ts +7 -1
- package/dist/storage/entity-canonical-id-migration-adapter.d.ts.map +1 -1
- package/dist/storage/entity-migration-maintenance-pending.d.ts +31 -0
- package/dist/storage/entity-migration-maintenance-pending.d.ts.map +1 -0
- package/dist/storage.d.ts +2 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +9 -9
- package/dist/support-passport/index.js +27 -27
- package/dist/transfer/export-okf.js +10 -10
- package/dist/verified-recall.js +10 -10
- package/dist/who-knows-cli.js +11 -11
- package/dist/who-knows.js +10 -10
- package/package.json +2 -2
- package/src/namespaces/search.test.ts +121 -0
- package/src/namespaces/search.ts +8 -0
- package/src/orchestration/extraction-persist-deps.ts +3 -0
- package/src/orchestration/extraction-persist-promotion.ts +104 -16
- package/src/orchestration/extraction-persist.ts +66 -77
- package/src/orchestration/lifecycle-pending-fallback-drain.ts +97 -0
- package/src/orchestration/maintenance.test.ts +443 -1
- package/src/orchestration/maintenance.ts +73 -95
- package/src/orchestration/qmd-maintenance-completion.ts +32 -0
- package/src/orchestrator-entity-write-failure.test.ts +370 -0
- package/src/orchestrator.ts +9 -1
- package/src/search/lancedb-backend.ts +29 -12
- package/src/search/meilisearch-backend.test.ts +148 -0
- package/src/search/meilisearch-backend.ts +41 -14
- package/src/search/orama-backend.test.ts +75 -1
- package/src/search/orama-backend.ts +22 -7
- package/src/search/port.ts +7 -0
- package/src/search/remote-backend.ts +4 -0
- package/src/storage/entity-canonical-id-migration-adapter.ts +44 -9
- package/src/storage/entity-migration-maintenance-pending-helpers.test.ts +87 -0
- package/src/storage/entity-migration-maintenance-pending.test.ts +242 -0
- package/src/storage/entity-migration-maintenance-pending.ts +89 -0
- package/src/storage.ts +2 -2
- package/dist/chunk-5CWH2LKL.js.map +0 -1
- package/dist/chunk-7VO6E5UD.js.map +0 -1
- package/dist/chunk-EC2KVA27.js.map +0 -1
- package/dist/chunk-JIJAWTRK.js.map +0 -1
- package/dist/chunk-SJD334AG.js.map +0 -1
- package/dist/chunk-XKDQTDXN.js.map +0 -1
- package/dist/chunk-XRFLR3XF.js.map +0 -1
- /package/dist/{chunk-3NL4ALUP.js.map → chunk-24SIB3EW.js.map} +0 -0
- /package/dist/{chunk-Y3T5KQCR.js.map → chunk-2EYCW2ET.js.map} +0 -0
- /package/dist/{chunk-AHGOOZUC.js.map → chunk-34UVJNSG.js.map} +0 -0
- /package/dist/{chunk-2EXF6IIB.js.map → chunk-3632XJMR.js.map} +0 -0
- /package/dist/{chunk-KETS5A62.js.map → chunk-3H3PNQEF.js.map} +0 -0
- /package/dist/{chunk-SFRBUBUZ.js.map → chunk-3LNAQLW4.js.map} +0 -0
- /package/dist/{chunk-75BK4XGV.js.map → chunk-4BUJICMI.js.map} +0 -0
- /package/dist/{chunk-KIWO4327.js.map → chunk-4W5B5Z6P.js.map} +0 -0
- /package/dist/{chunk-B35EQQ7L.js.map → chunk-53OFDW3P.js.map} +0 -0
- /package/dist/{chunk-2ONKXEC7.js.map → chunk-5LBBXI2A.js.map} +0 -0
- /package/dist/{chunk-UCLJTGP3.js.map → chunk-65B5RFKQ.js.map} +0 -0
- /package/dist/{chunk-KAJYSO3U.js.map → chunk-6CDNOREO.js.map} +0 -0
- /package/dist/{chunk-POJRFSJM.js.map → chunk-7XGNGLAN.js.map} +0 -0
- /package/dist/{chunk-A6JDT6QF.js.map → chunk-AO5ZOD32.js.map} +0 -0
- /package/dist/{chunk-RA7YRL6H.js.map → chunk-AOSCGNIC.js.map} +0 -0
- /package/dist/{chunk-LWMLBVGB.js.map → chunk-B43P3DTC.js.map} +0 -0
- /package/dist/{chunk-VUMWVYMR.js.map → chunk-CIMD2MUR.js.map} +0 -0
- /package/dist/{chunk-44EUCSG4.js.map → chunk-FFQNNFHX.js.map} +0 -0
- /package/dist/{chunk-HEF4BRMT.js.map → chunk-FZLZUDJJ.js.map} +0 -0
- /package/dist/{chunk-L3EFYRYK.js.map → chunk-GGFQAGOT.js.map} +0 -0
- /package/dist/{chunk-ZLCBLDJO.js.map → chunk-GIRWNTMV.js.map} +0 -0
- /package/dist/{chunk-SHNM7RIT.js.map → chunk-HJ4X4BGS.js.map} +0 -0
- /package/dist/{chunk-MUNYUSBU.js.map → chunk-HJQ4NKKO.js.map} +0 -0
- /package/dist/{chunk-V6Z4NAJZ.js.map → chunk-HM3ZTDAX.js.map} +0 -0
- /package/dist/{chunk-EZS6QJNC.js.map → chunk-IFOCK3OJ.js.map} +0 -0
- /package/dist/{chunk-DF6ZF2BN.js.map → chunk-LIVNX7WK.js.map} +0 -0
- /package/dist/{chunk-WY66J4PI.js.map → chunk-LRVFS4KA.js.map} +0 -0
- /package/dist/{chunk-LMB47UM6.js.map → chunk-LTDK6HBV.js.map} +0 -0
- /package/dist/{chunk-HCIRR3BA.js.map → chunk-M4U25HLR.js.map} +0 -0
- /package/dist/{chunk-YK7ZJPQM.js.map → chunk-MGN2RQRG.js.map} +0 -0
- /package/dist/{chunk-IUQXRRJB.js.map → chunk-OMWQO7H6.js.map} +0 -0
- /package/dist/{chunk-SPTPBKZX.js.map → chunk-OWNAWY6D.js.map} +0 -0
- /package/dist/{chunk-DQOGZZJA.js.map → chunk-QAHP5SBG.js.map} +0 -0
- /package/dist/{chunk-GBGU5OZP.js.map → chunk-QF5EJ5VP.js.map} +0 -0
- /package/dist/{chunk-FT75AQ74.js.map → chunk-QS5DUSBM.js.map} +0 -0
- /package/dist/{chunk-72CBJ5VP.js.map → chunk-R3WZ74B2.js.map} +0 -0
- /package/dist/{chunk-PDTNQLPC.js.map → chunk-RG3I2663.js.map} +0 -0
- /package/dist/{chunk-CK6GCGMX.js.map → chunk-RTJJPW3C.js.map} +0 -0
- /package/dist/{chunk-RJDYDF5K.js.map → chunk-TRAOZ2WP.js.map} +0 -0
- /package/dist/{chunk-6ZAU7LAR.js.map → chunk-TTTPTQ6S.js.map} +0 -0
- /package/dist/{chunk-JS44PBCM.js.map → chunk-U2A56LLF.js.map} +0 -0
- /package/dist/{chunk-MC7PXJDP.js.map → chunk-UBOWDOL5.js.map} +0 -0
- /package/dist/{chunk-4FM35YIA.js.map → chunk-UQYBPPVC.js.map} +0 -0
- /package/dist/{chunk-OCRLJJOV.js.map → chunk-V4VCBFAL.js.map} +0 -0
- /package/dist/{chunk-FNNGWN3O.js.map → chunk-VGE4PUY6.js.map} +0 -0
- /package/dist/{chunk-5DVOBBTV.js.map → chunk-VV73XT3A.js.map} +0 -0
- /package/dist/{chunk-GE3ZX6YK.js.map → chunk-W7NKMRAF.js.map} +0 -0
- /package/dist/{chunk-AJJPXUE6.js.map → chunk-WBN66HPI.js.map} +0 -0
- /package/dist/{chunk-XWJUFER3.js.map → chunk-WGFEGBFB.js.map} +0 -0
- /package/dist/{chunk-43TUWQNR.js.map → chunk-XDKEHZUC.js.map} +0 -0
- /package/dist/{chunk-ROAKLYOL.js.map → chunk-XHEKS4UN.js.map} +0 -0
- /package/dist/{chunk-ZKK3VMWU.js.map → chunk-XVTB6BZS.js.map} +0 -0
- /package/dist/{chunk-AZLD4CKG.js.map → chunk-Y56D5FSD.js.map} +0 -0
- /package/dist/{chunk-MPWOAIIH.js.map → chunk-YDT3OEYF.js.map} +0 -0
- /package/dist/{chunk-IN6U2BS5.js.map → chunk-YJHOVA42.js.map} +0 -0
- /package/dist/{chunk-TC55M5PO.js.map → chunk-YLN4ZQV4.js.map} +0 -0
|
@@ -68,10 +68,7 @@ import {
|
|
|
68
68
|
} from "../source-attribution.js";
|
|
69
69
|
import { classifyMemoryKind } from "../himem.js";
|
|
70
70
|
import { shouldPromoteGlobalFactToShared, withholdToolScopedFromSharedNamespace } from "../tool-scoped-memory.js";
|
|
71
|
-
import {
|
|
72
|
-
buildBehaviorSignalsForMemory,
|
|
73
|
-
dedupeBehaviorSignalsByMemoryAndHash,
|
|
74
|
-
} from "../behavior-signals.js";
|
|
71
|
+
import { buildBehaviorSignalsForMemory } from "../behavior-signals.js";
|
|
75
72
|
import { buildProcedurePersistBody } from "../procedural/procedure-types.js";
|
|
76
73
|
import { stripAttributesSuffix } from "../structured-attributes.js";
|
|
77
74
|
import { resolveWriteSubject } from "../memory-subject.js";
|
|
@@ -103,7 +100,7 @@ import type {
|
|
|
103
100
|
} from "../types.js";
|
|
104
101
|
import {
|
|
105
102
|
createBatchPromotedCopyProbe,
|
|
106
|
-
|
|
103
|
+
finalizeExtractionCommittedWrites,
|
|
107
104
|
makeSubjectGuardAllows,
|
|
108
105
|
profileAutoPromotionAllows,
|
|
109
106
|
readActiveMemoriesBothTiers,
|
|
@@ -120,7 +117,7 @@ import {
|
|
|
120
117
|
resolvePersistedMemoryRelativePath,
|
|
121
118
|
} from "../orchestrator.js";
|
|
122
119
|
import type { HarmonicConstructionInput } from "../harmonic-construction.js";
|
|
123
|
-
import { enqueueMergedTargetForHarmonicConstruction
|
|
120
|
+
import { enqueueMergedTargetForHarmonicConstruction } from "./harmonic-construction-persist.js";
|
|
124
121
|
import { applySemanticMergeAtPersist, runMergedTargetPostEffects, writeMergedVerbatimArtifact } from "./semantic-merge-persist.js";
|
|
125
122
|
import { buildMergedTargetPromotionPayload } from "./semantic-merge-promotion-payload.js";
|
|
126
123
|
import { persistMergedTargetThreadEpisode } from "./semantic-merge-commit-effects.js";
|
|
@@ -291,6 +288,7 @@ export class ExtractionPersistCoordinator {
|
|
|
291
288
|
events: [...events],
|
|
292
289
|
});
|
|
293
290
|
};
|
|
291
|
+
|
|
294
292
|
const sharedProfileLayer = scopeProfileWritePlan?.layers.find(
|
|
295
293
|
(layer) =>
|
|
296
294
|
layer.id === "serverShared" &&
|
|
@@ -1106,6 +1104,32 @@ export class ExtractionPersistCoordinator {
|
|
|
1106
1104
|
0,
|
|
1107
1105
|
this.deps.config.extractionMaxProfileUpdatesPerRun,
|
|
1108
1106
|
);
|
|
1107
|
+
const finalizeCommittedWrites = async (scheduleQmd: boolean): Promise<void> => {
|
|
1108
|
+
await finalizeExtractionCommittedWrites({
|
|
1109
|
+
saveContentHashIndexes: () => this.deps.saveContentHashIndexes(),
|
|
1110
|
+
behaviorSignalsByStorage: behaviorSignalsByStorage.values(),
|
|
1111
|
+
harmonic: {
|
|
1112
|
+
enabled: harmonicConstructionEnabled,
|
|
1113
|
+
entries: harmonicFactsByStorage.values(),
|
|
1114
|
+
baseStorageDir: storage.dir,
|
|
1115
|
+
abstractionNodeStoreDir:
|
|
1116
|
+
!scopeProfileWritePlan && harmonicBaseNamespace === this.deps.config.defaultNamespace
|
|
1117
|
+
? this.deps.config.abstractionNodeStoreDir
|
|
1118
|
+
: undefined,
|
|
1119
|
+
sessionKey: sourceContext?.sessionKey,
|
|
1120
|
+
validAt: sourceContext?.validAt,
|
|
1121
|
+
episodeTitle: result.episodeTitle,
|
|
1122
|
+
anchorsEnabled: harmonicAnchorsEnabled,
|
|
1123
|
+
entityMentions: entities,
|
|
1124
|
+
},
|
|
1125
|
+
updateTemporalTagIndexes: (target, ids) =>
|
|
1126
|
+
this.deps.updateTemporalTagIndexes(target, ids),
|
|
1127
|
+
fallbackStorage: storage,
|
|
1128
|
+
persistedIdsByStorage,
|
|
1129
|
+
requestQmdMaintenance: () => this.deps.requestQmdMaintenance(),
|
|
1130
|
+
scheduleQmd,
|
|
1131
|
+
});
|
|
1132
|
+
};
|
|
1109
1133
|
|
|
1110
1134
|
if (
|
|
1111
1135
|
facts.length < result.facts.length ||
|
|
@@ -2583,6 +2607,25 @@ export class ExtractionPersistCoordinator {
|
|
|
2583
2607
|
// so a blocked fact creates no active shared copy / supersession / graph entry.
|
|
2584
2608
|
const tombstoneBlocked = factWrite.tombstoneBlocked;
|
|
2585
2609
|
const postWriteGuard = faithfulnessEnforceStatus === "pending_review" || tombstoneBlocked;
|
|
2610
|
+
// #3231: the fact is durable now. Track it before any post-write step
|
|
2611
|
+
// that can throw, so the batch-end finalization on a failure path still
|
|
2612
|
+
// covers it (a retry exact-dedupes the fact and would not re-queue it).
|
|
2613
|
+
trackBehaviorSignals(
|
|
2614
|
+
targetStorage,
|
|
2615
|
+
buildBehaviorSignalsForMemory({
|
|
2616
|
+
memoryId,
|
|
2617
|
+
category: writeCategory,
|
|
2618
|
+
content: fact.content,
|
|
2619
|
+
namespace: this.deps.storageDirNamespace(targetStorage.dir),
|
|
2620
|
+
confidence: fact.confidence,
|
|
2621
|
+
source: "extraction",
|
|
2622
|
+
}),
|
|
2623
|
+
);
|
|
2624
|
+
trackPersistedId(targetStorage, memoryId, {
|
|
2625
|
+
pendingReview: postWriteGuard,
|
|
2626
|
+
category: writeCategory,
|
|
2627
|
+
harmonicFact,
|
|
2628
|
+
});
|
|
2586
2629
|
// #1645: defer contradiction auto-resolve until tombstone status is
|
|
2587
2630
|
// known (see applyDeferredContradictionResolve).
|
|
2588
2631
|
try {
|
|
@@ -2596,7 +2639,9 @@ export class ExtractionPersistCoordinator {
|
|
|
2596
2639
|
await anchorSnapshots.remove(targetStorage, contradiction!.supersededId);
|
|
2597
2640
|
}
|
|
2598
2641
|
} catch (err) {
|
|
2599
|
-
await
|
|
2642
|
+
await finalizeCommittedWrites(true).catch((finalizeErr) =>
|
|
2643
|
+
log.warn(`committed-write finalization after post-write failure failed: ${finalizeErr}`),
|
|
2644
|
+
);
|
|
2600
2645
|
throw err;
|
|
2601
2646
|
}
|
|
2602
2647
|
if (routedRuleId) {
|
|
@@ -2632,22 +2677,6 @@ export class ExtractionPersistCoordinator {
|
|
|
2632
2677
|
}
|
|
2633
2678
|
}
|
|
2634
2679
|
try {
|
|
2635
|
-
trackBehaviorSignals(
|
|
2636
|
-
targetStorage,
|
|
2637
|
-
buildBehaviorSignalsForMemory({
|
|
2638
|
-
memoryId,
|
|
2639
|
-
category: writeCategory,
|
|
2640
|
-
content: fact.content,
|
|
2641
|
-
namespace: this.deps.storageDirNamespace(targetStorage.dir),
|
|
2642
|
-
confidence: fact.confidence,
|
|
2643
|
-
source: "extraction",
|
|
2644
|
-
}),
|
|
2645
|
-
);
|
|
2646
|
-
trackPersistedId(targetStorage, memoryId, {
|
|
2647
|
-
pendingReview: postWriteGuard,
|
|
2648
|
-
category: writeCategory,
|
|
2649
|
-
harmonicFact,
|
|
2650
|
-
});
|
|
2651
2680
|
await anchorSnapshots.replace(targetStorage, memoryId, writeCategory, memoryPathById);
|
|
2652
2681
|
if (
|
|
2653
2682
|
!postWriteGuard &&
|
|
@@ -2782,9 +2811,12 @@ export class ExtractionPersistCoordinator {
|
|
|
2782
2811
|
);
|
|
2783
2812
|
}
|
|
2784
2813
|
} catch (err) {
|
|
2785
|
-
// PR #2016:
|
|
2786
|
-
//
|
|
2787
|
-
|
|
2814
|
+
// PR #2016 / #3231: finalize deferred side effects for facts already
|
|
2815
|
+
// durable before propagating so hash/behavior/harmonic/temporal/QMD
|
|
2816
|
+
// still land on a partial batch.
|
|
2817
|
+
await finalizeCommittedWrites(true).catch((finalizeErr) =>
|
|
2818
|
+
log.warn(`committed-write finalization after post-write failure failed: ${finalizeErr}`),
|
|
2819
|
+
);
|
|
2788
2820
|
throw err;
|
|
2789
2821
|
}
|
|
2790
2822
|
}
|
|
@@ -2807,7 +2839,6 @@ export class ExtractionPersistCoordinator {
|
|
|
2807
2839
|
durableNonFactTouchRecorded = true;
|
|
2808
2840
|
touchBaseNonFactNamespace();
|
|
2809
2841
|
};
|
|
2810
|
-
// #1955 review: entity fields are screened before entering the index (screenEntityForIndex).
|
|
2811
2842
|
const entityScreenOn = resolveSecurityCapabilities(this.deps.config).injectionScreen;
|
|
2812
2843
|
const entityScreenProfile = resolveSecurityCapabilities(this.deps.config).injectionScreenProfile;
|
|
2813
2844
|
for (const entity of entities) {
|
|
@@ -2829,7 +2860,10 @@ export class ExtractionPersistCoordinator {
|
|
|
2829
2860
|
recordDurableNonFactWrite();
|
|
2830
2861
|
}
|
|
2831
2862
|
} catch (err) {
|
|
2832
|
-
|
|
2863
|
+
await finalizeCommittedWrites(true).catch((finalizeErr) =>
|
|
2864
|
+
log.warn(`committed-write finalization after entity failure failed: ${finalizeErr}`),
|
|
2865
|
+
);
|
|
2866
|
+
throw err;
|
|
2833
2867
|
}
|
|
2834
2868
|
}
|
|
2835
2869
|
// Persist entity relationships (v7.0). #1955 review: source/label/target are screened.
|
|
@@ -2929,28 +2963,9 @@ export class ExtractionPersistCoordinator {
|
|
|
2929
2963
|
touchBaseNonFactNamespace();
|
|
2930
2964
|
}
|
|
2931
2965
|
|
|
2932
|
-
//
|
|
2933
|
-
//
|
|
2934
|
-
|
|
2935
|
-
// this on-disk write is the in-process persisted view — never a cross-restart
|
|
2936
|
-
// trust anchor. A deferred write whose addContentHashDedup threw is still
|
|
2937
|
-
// safe: the fact .md is durable and the next restart's rebuild includes it.
|
|
2938
|
-
await this.deps.saveContentHashIndexes().catch((err) => {
|
|
2939
|
-
log.warn(`content-hash index save failed: ${err}`);
|
|
2940
|
-
});
|
|
2941
|
-
|
|
2942
|
-
for (const {
|
|
2943
|
-
storage: targetStorage,
|
|
2944
|
-
events,
|
|
2945
|
-
} of behaviorSignalsByStorage.values()) {
|
|
2946
|
-
const dedupedSignals = dedupeBehaviorSignalsByMemoryAndHash(events);
|
|
2947
|
-
if (dedupedSignals.length === 0) continue;
|
|
2948
|
-
await targetStorage
|
|
2949
|
-
.appendBehaviorSignals(dedupedSignals)
|
|
2950
|
-
.catch((err) =>
|
|
2951
|
-
log.warn(`appendBehaviorSignals failed (non-fatal): ${err}`),
|
|
2952
|
-
);
|
|
2953
|
-
}
|
|
2966
|
+
// Shared batch-end finalization (hash, behavior, harmonic, temporal).
|
|
2967
|
+
// Failure paths call the same helper with scheduleQmd=true (#3231).
|
|
2968
|
+
await finalizeCommittedWrites(false);
|
|
2954
2969
|
|
|
2955
2970
|
const dedupSuffix = `${dedupedCount > 0 ? ` (${dedupedCount} deduped)` : ""}${semanticMergedCount > 0 ? ` (${semanticMergedCount} merged)` : ""}`;
|
|
2956
2971
|
const gatedSuffix =
|
|
@@ -2962,33 +2977,7 @@ export class ExtractionPersistCoordinator {
|
|
|
2962
2977
|
log.info(
|
|
2963
2978
|
`persisted: ${facts.length - dedupedCount - importanceGatedCount - judgeGatedCount - redactionGatedCount - semanticMergedCount} facts${dedupSuffix}${gatedSuffix}${judgeSuffix}${redactionSuffix}, ${entities.length} entities, ${questions.length} questions, ${profileUpdates.length} profile updates`,
|
|
2964
2979
|
);
|
|
2965
|
-
|
|
2966
|
-
await persistConstructedHarmonicRecords({
|
|
2967
|
-
entries: harmonicFactsByStorage.values(),
|
|
2968
|
-
baseStorageDir: storage.dir,
|
|
2969
|
-
abstractionNodeStoreDir:
|
|
2970
|
-
!scopeProfileWritePlan && harmonicBaseNamespace === this.deps.config.defaultNamespace
|
|
2971
|
-
? this.deps.config.abstractionNodeStoreDir
|
|
2972
|
-
: undefined,
|
|
2973
|
-
sessionKey: sourceContext?.sessionKey,
|
|
2974
|
-
validAt: sourceContext?.validAt,
|
|
2975
|
-
episodeTitle: result.episodeTitle,
|
|
2976
|
-
anchorsEnabled: harmonicAnchorsEnabled,
|
|
2977
|
-
entityMentions: entities,
|
|
2978
|
-
});
|
|
2979
|
-
}
|
|
2980
|
-
// Update temporal + tag indexes (v8.1) — fire-and-forget, fail-open
|
|
2981
|
-
void (async () => {
|
|
2982
|
-
if (persistedIdsByStorage.size === 0) {
|
|
2983
|
-
await this.deps.updateTemporalTagIndexes(storage, []);
|
|
2984
|
-
return;
|
|
2985
|
-
}
|
|
2986
|
-
for (const entry of persistedIdsByStorage.values()) {
|
|
2987
|
-
await this.deps.updateTemporalTagIndexes(entry.storage, entry.ids);
|
|
2988
|
-
}
|
|
2989
|
-
})().catch((err) =>
|
|
2990
|
-
log.debug(`temporal-index update error (non-fatal): ${err}`),
|
|
2991
|
-
);
|
|
2980
|
+
|
|
2992
2981
|
// #1635: surface pending_review ids so the thread episode set excludes them.
|
|
2993
2982
|
this.deps.setLastPersistExtractionPendingReviewIds(pendingReviewPersistedIds);
|
|
2994
2983
|
// Return the persisted fact IDs for threading
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fallback lifecycle pending-append drain for targets with no secure
|
|
3
|
+
* StorageManager. Moved verbatim out of maintenance.ts (issue #2033) so that
|
|
4
|
+
* file stays under the structural size ceiling; behavior is unchanged.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
|
|
10
|
+
import { log } from "../logger.js";
|
|
11
|
+
import {
|
|
12
|
+
drainPendingLifecycleLedgerIfAny,
|
|
13
|
+
pendingLifecycleLedgerDir,
|
|
14
|
+
type LifecyclePendingIo,
|
|
15
|
+
} from "../storage/memory-lifecycle-ledger-access.js";
|
|
16
|
+
import { probeEncryptedRegularFileHeader } from "../secure-store/secure-fs.js";
|
|
17
|
+
import { listContainedSpillFiles } from "../utils/path-containment.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Drain a filesystem-fallback target's pending lifecycle-append spill when no
|
|
21
|
+
* secure StorageManager is available (catalog-disabled namespace; issue
|
|
22
|
+
* #2033). Uses the safe path-scoped PLAINTEXT context this fallback already
|
|
23
|
+
* operates in: a keyless drain can only fold plaintext spills into a plaintext
|
|
24
|
+
* ledger, so it refuses when the ledger or ANY spill is encrypted at rest,
|
|
25
|
+
* leaving those pending for a keyed (catalog-path) drain — exactly mirroring
|
|
26
|
+
* the fallback compaction's encrypted-ledger deferral. Non-fatal; a fast
|
|
27
|
+
* no-op when nothing is pending. The shared spill lister enforces the symlink/
|
|
28
|
+
* containment guard on every spill file it reads or deletes.
|
|
29
|
+
*/
|
|
30
|
+
export async function drainPendingLifecycleAppendsForPath(memoryDir: string): Promise<void> {
|
|
31
|
+
const ledgerPath = path.join(memoryDir, "state", "memory-lifecycle-ledger.jsonl");
|
|
32
|
+
const spillDir = pendingLifecycleLedgerDir(ledgerPath);
|
|
33
|
+
// Enumerate spills through the SAME guarded lister the actual drain uses
|
|
34
|
+
// (listContainedSpillFiles): it rejects a symlinked/non-directory spill dir
|
|
35
|
+
// and skips any symlink/FIFO/device/escaping entry, returning only regular
|
|
36
|
+
// files contained in the dir. Never raw-readdir + open() an untrusted name:
|
|
37
|
+
// opening a FIFO would block until a writer appears and a symlink would
|
|
38
|
+
// redirect the probe outside the dir (#2033). Enumerate BOTH live `*.jsonl`
|
|
39
|
+
// spills and crash-orphaned `*.jsonl.claimed` files: a drain that died
|
|
40
|
+
// between claiming a spill (rename to `.claimed`) and committing it leaves
|
|
41
|
+
// the ONLY copy of those rows as a claimed orphan. Gating solely on live
|
|
42
|
+
// spills would early-return here whenever the pending dir holds nothing but
|
|
43
|
+
// orphans, stranding those rows forever; proceeding lets
|
|
44
|
+
// drainPendingLifecycleLedgerIfAny -> recoverOrphanedClaims restore and
|
|
45
|
+
// re-commit them under the ledger lock (#2033).
|
|
46
|
+
let spillFiles: string[];
|
|
47
|
+
let claimedOrphans: string[];
|
|
48
|
+
try {
|
|
49
|
+
spillFiles = await listContainedSpillFiles(spillDir);
|
|
50
|
+
claimedOrphans = await listContainedSpillFiles(spillDir, ".jsonl.claimed");
|
|
51
|
+
} catch (err) {
|
|
52
|
+
log.debug(`fallback lifecycle pending scan failed (non-fatal) for ${memoryDir}: ${err}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (spillFiles.length === 0 && claimedOrphans.length === 0) return;
|
|
56
|
+
// The pending encryption state is authoritative only UNDER the ledger lock:
|
|
57
|
+
// drainPendingLifecycleLedgerIfAny waits for the lock and re-enumerates the
|
|
58
|
+
// pending dir, so a secure-store writer that spills an encrypted file — or a
|
|
59
|
+
// keyed compaction that rewrites the ledger encrypted — while this fallback
|
|
60
|
+
// waits would defeat any pre-lock probe (#2033). Probe each file at the
|
|
61
|
+
// moment of use inside the held lock instead: readSecure refuses an
|
|
62
|
+
// encrypted spill (the fold reads each spill lazily and propagates the throw
|
|
63
|
+
// BEFORE claiming that spill, leaving it intact) and the append refuses a
|
|
64
|
+
// ledger that became encrypted (the fold rolls the claims back). Either way
|
|
65
|
+
// the plaintext IO
|
|
66
|
+
// never reads or writes ciphertext; the keyed catalog-path drain handles the
|
|
67
|
+
// deferred rows.
|
|
68
|
+
const io: LifecyclePendingIo = {
|
|
69
|
+
writeSecure: async (filePath, payload) => {
|
|
70
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
71
|
+
await writeFile(filePath, payload, "utf-8");
|
|
72
|
+
},
|
|
73
|
+
readSecure: async (filePath) => {
|
|
74
|
+
if (await probeEncryptedRegularFileHeader(filePath)) {
|
|
75
|
+
throw new Error(`fallback lifecycle drain deferred: encrypted spill at ${filePath}`);
|
|
76
|
+
}
|
|
77
|
+
return readFile(filePath, "utf-8");
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
try {
|
|
81
|
+
await drainPendingLifecycleLedgerIfAny(
|
|
82
|
+
ledgerPath,
|
|
83
|
+
io,
|
|
84
|
+
async (payload) => {
|
|
85
|
+
if (await probeEncryptedRegularFileHeader(ledgerPath)) {
|
|
86
|
+
throw new Error(`fallback lifecycle drain deferred: ledger became encrypted at ${ledgerPath}`);
|
|
87
|
+
}
|
|
88
|
+
await appendFile(ledgerPath, payload, "utf-8");
|
|
89
|
+
},
|
|
90
|
+
async () => {
|
|
91
|
+
await mkdir(path.dirname(ledgerPath), { recursive: true });
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
log.debug(`fallback lifecycle pending drain failed (non-fatal) for ${memoryDir}: ${err}`);
|
|
96
|
+
}
|
|
97
|
+
}
|