@remnic/core 9.50.2 → 9.51.0
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.d.ts +13 -11
- package/dist/access-admin-ops-surface.js +41 -39
- package/dist/access-authorization-probe.d.ts +13 -11
- package/dist/access-authorization-probe.js +42 -40
- package/dist/access-boundary.d.ts +13 -11
- package/dist/access-boundary.js +41 -39
- package/dist/access-cli.js +109 -104
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +3 -1
- package/dist/access-extraction-force-flush.d.ts +13 -11
- package/dist/access-extraction-force-flush.js +41 -39
- package/dist/access-health-types.d.ts +3 -1
- package/dist/access-http-lcm-compaction.d.ts +13 -11
- package/dist/access-http-lifecycle-flush.d.ts +13 -11
- package/dist/access-http-offline-stream.d.ts +13 -11
- package/dist/access-http-query.js +41 -39
- package/dist/access-http.d.ts +13 -11
- package/dist/access-http.js +52 -50
- package/dist/access-identity-continuity-surface.d.ts +11 -9
- package/dist/access-identity-continuity-surface.js +41 -39
- package/dist/access-lcm-surface.d.ts +13 -11
- package/dist/access-lcm-surface.js +41 -39
- package/dist/access-mcp.d.ts +13 -11
- package/dist/access-mcp.js +47 -45
- package/dist/access-memory-search-fanout.d.ts +4 -2
- package/dist/{access-namespace-preflight-Dj2QolFE.d.ts → access-namespace-preflight-Ds6CGlCP.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +5 -3
- package/dist/access-namespace-preflight.js +41 -39
- package/dist/access-observe-write-surface.d.ts +13 -11
- package/dist/access-observe-write-surface.js +41 -39
- package/dist/access-offline-manifest.d.ts +11 -9
- package/dist/access-operations-batch.js +43 -41
- package/dist/access-operations.d.ts +13 -11
- package/dist/access-operations.js +46 -44
- package/dist/access-recall-concurrency.d.ts +13 -11
- package/dist/access-recall-concurrency.js +41 -39
- package/dist/access-recall-response.d.ts +13 -11
- package/dist/access-recall-response.js +41 -39
- package/dist/access-recall-surface.d.ts +13 -11
- package/dist/access-recall-surface.js +41 -39
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-DesbnTSa.d.ts → access-service-BY0KJ44c.d.ts} +7 -7
- package/dist/access-service-helpers.d.ts +13 -11
- package/dist/access-service.d.ts +13 -11
- package/dist/access-service.js +41 -39
- package/dist/access-surface-catalog.d.ts +13 -11
- package/dist/access-wearables-meetings-surface.d.ts +5 -3
- package/dist/action-confidence.d.ts +3 -1
- package/dist/active-memory-bridge.d.ts +3 -1
- package/dist/active-recall.d.ts +3 -1
- package/dist/active-recall.js +5 -3
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +3 -1
- package/dist/archive-mutation-version.d.ts +9 -0
- package/dist/archive-mutation-version.js +20 -0
- package/dist/artifact-search.d.ts +3 -1
- package/dist/behavior-learner.d.ts +3 -1
- package/dist/behavior-signals.d.ts +3 -1
- package/dist/bootstrap.d.ts +11 -9
- package/dist/briefing.d.ts +4 -2
- package/dist/briefing.js +10 -9
- package/dist/buffer-surprise-report.d.ts +3 -1
- package/dist/buffer-turn-helpers.d.ts +3 -1
- package/dist/buffer.d.ts +4 -2
- package/dist/buffer.js +5 -5
- package/dist/bulk-import/index.d.ts +5 -3
- package/dist/calibration.d.ts +3 -1
- package/dist/capabilities.d.ts +3 -1
- package/dist/{catalog-D-G7RgXR.d.ts → catalog-D3B4RDy1.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +3 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +3 -1
- package/dist/causal-consolidation.js +13 -12
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +4 -2
- package/dist/causal-trajectory-graph.js +2 -1
- package/dist/causal-trajectory-graph.js.map +1 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-KDG2KTWW.js → chunk-33SV3E43.js} +4 -4
- package/dist/{chunk-2HGUDBRJ.js → chunk-37ZO6LLJ.js} +2 -2
- package/dist/{chunk-QW3WFHKU.js → chunk-45BRYON6.js} +2 -2
- package/dist/{chunk-GZICBRWK.js → chunk-4F6X3RXW.js} +2 -2
- package/dist/{chunk-7BAYBYY5.js → chunk-4PC4PRJE.js} +2 -2
- package/dist/{chunk-VJXY5ZCT.js → chunk-52UKFTUK.js} +2 -2
- package/dist/{chunk-ESG7Z255.js → chunk-5UDMFE3Q.js} +2 -2
- package/dist/{chunk-JPHEOE6Z.js → chunk-6MTSFX7A.js} +15 -15
- package/dist/chunk-6ZN34ISG.js +44 -0
- package/dist/chunk-6ZN34ISG.js.map +1 -0
- package/dist/{chunk-M4MP34AQ.js → chunk-AHZOMHWN.js} +1 -1
- package/dist/{chunk-Z3RHPGSY.js → chunk-AIUBBHSF.js} +3 -3
- package/dist/{chunk-S3AYIQCU.js → chunk-AXIDQG5A.js} +12 -12
- package/dist/{chunk-QN7NTKRC.js → chunk-AZ2QBGYB.js} +1 -1
- package/dist/{chunk-47J4EDGR.js → chunk-AZM4CCAC.js} +8 -8
- package/dist/{chunk-IXXABW5A.js → chunk-BHXYAVUM.js} +11 -5
- package/dist/chunk-BHXYAVUM.js.map +1 -0
- package/dist/{chunk-L2DPF4DF.js → chunk-BIJAWZYW.js} +54 -12
- package/dist/chunk-BIJAWZYW.js.map +1 -0
- package/dist/{chunk-LEJPSMKM.js → chunk-C5QLI33R.js} +3 -3
- package/dist/{chunk-SV3PSA7Y.js → chunk-CV6BBVYV.js} +5 -5
- package/dist/{chunk-V7X767RT.js → chunk-DCZBSE4F.js} +52 -52
- package/dist/chunk-FC67T4E6.js +70 -0
- package/dist/chunk-FC67T4E6.js.map +1 -0
- package/dist/{chunk-7PKFPLLZ.js → chunk-FXTYIA46.js} +2 -2
- package/dist/{chunk-64BHFFKZ.js → chunk-HLYR2TQL.js} +5 -5
- package/dist/{chunk-5C2HNJMO.js → chunk-J5LLX6IL.js} +32 -32
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-PLKFO2HJ.js → chunk-JL43BVDE.js} +2 -2
- package/dist/{chunk-2S72LWKX.js → chunk-JYL3BVVZ.js} +2 -2
- package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
- package/dist/chunk-LXY5VVGM.js +61 -0
- package/dist/chunk-LXY5VVGM.js.map +1 -0
- package/dist/{chunk-PYKKWQZ2.js → chunk-M7BXDKPR.js} +6 -6
- package/dist/{chunk-Z54EM5YZ.js → chunk-MAXVH44E.js} +7 -7
- package/dist/{chunk-LYMNZZIM.js → chunk-NIS256NW.js} +2 -2
- package/dist/{chunk-67QG75MJ.js → chunk-NLK2VZYZ.js} +2 -2
- package/dist/{chunk-A4QMKFFO.js → chunk-O5FFBO2M.js} +14 -28
- package/dist/chunk-O5FFBO2M.js.map +1 -0
- package/dist/{chunk-JYIFGGEM.js → chunk-OUKBMQ2O.js} +2 -2
- package/dist/{chunk-75XOWNRS.js → chunk-OYESWJ43.js} +4 -4
- package/dist/{chunk-TS4AJ2GI.js → chunk-PA45XCUD.js} +3 -3
- package/dist/{chunk-BJYET5TX.js → chunk-PRDJMOST.js} +7 -1
- package/dist/chunk-PRDJMOST.js.map +1 -0
- package/dist/{chunk-4MBPIL4V.js → chunk-PUSLMZBQ.js} +2 -2
- package/dist/{chunk-RVO6TCTU.js → chunk-QCECHYZL.js} +6 -6
- package/dist/{chunk-GFIKG4FR.js → chunk-QGR6OVGT.js} +2 -2
- package/dist/{chunk-NSGU76YO.js → chunk-QHFV6VNU.js} +6 -2
- package/dist/chunk-QHFV6VNU.js.map +1 -0
- package/dist/{chunk-PDEKQWDV.js → chunk-QT2FRYI4.js} +18 -2
- package/dist/chunk-QT2FRYI4.js.map +1 -0
- package/dist/{chunk-HNZKVLAN.js → chunk-S354QO4R.js} +2 -2
- package/dist/{chunk-NO37MR45.js → chunk-SOEN6KCF.js} +2 -2
- package/dist/{chunk-FXX6RQYC.js → chunk-TPTECFWR.js} +2 -2
- package/dist/{chunk-GDDGZVFI.js → chunk-UEVLYVNW.js} +2 -2
- package/dist/{chunk-YQ4IQ2GA.js → chunk-UT5BV5OG.js} +2 -2
- package/dist/{chunk-LAQ33B5D.js → chunk-UU3G6GUP.js} +1 -1
- package/dist/chunk-UU3G6GUP.js.map +1 -0
- package/dist/{chunk-LNTUXKBT.js → chunk-UYYW2KPU.js} +2 -2
- package/dist/{chunk-BOFVT6P3.js → chunk-VBHPOWBJ.js} +175 -98
- package/dist/chunk-VBHPOWBJ.js.map +1 -0
- package/dist/{chunk-QSYL5CXK.js → chunk-VKXWK44Q.js} +3 -3
- package/dist/{chunk-KMWYZTIE.js → chunk-VMMQDEN5.js} +2 -2
- package/dist/{chunk-JB6D7EFB.js → chunk-VVG2BOKA.js} +2 -2
- package/dist/chunk-W5BIQOAJ.js +69 -0
- package/dist/chunk-W5BIQOAJ.js.map +1 -0
- package/dist/{chunk-V5H6OJCR.js → chunk-W5XVQFLM.js} +2 -2
- package/dist/{chunk-OIOZ6MOP.js → chunk-W6FNX2LP.js} +2 -2
- package/dist/{chunk-6QPHF6RR.js → chunk-WQM326GS.js} +2 -2
- package/dist/{chunk-TQFHQPWD.js → chunk-XADV5IZ3.js} +8 -8
- package/dist/{chunk-DATDLJAO.js → chunk-XAPMEU3K.js} +2 -2
- package/dist/chunk-XXSOVESA.js +42 -0
- package/dist/chunk-XXSOVESA.js.map +1 -0
- package/dist/{chunk-IK6X5QPO.js → chunk-ZHY5TMJG.js} +1193 -443
- package/dist/chunk-ZHY5TMJG.js.map +1 -0
- package/dist/{chunk-N3LL5NEU.js → chunk-ZMYDYNI4.js} +2 -2
- package/dist/{cli-D4vvtxjY.d.ts → cli-CnOkH9hA.d.ts} +6 -6
- package/dist/cli.d.ts +15 -13
- package/dist/cli.js +74 -70
- package/dist/coding/pre-action-gate.d.ts +3 -1
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.d.ts +4 -2
- package/dist/compounding/engine.js +10 -9
- package/dist/compounding/preference-consolidator.d.ts +3 -1
- package/dist/compression-optimizer.d.ts +3 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.js +5 -3
- package/dist/connectors/codex-materialize-runner.d.ts +3 -1
- package/dist/connectors/codex-materialize-runner.js +10 -9
- package/dist/connectors/codex-materialize.d.ts +3 -1
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.js +10 -9
- package/dist/consolidation-provenance-check.d.ts +4 -2
- package/dist/consolidation-undo.d.ts +4 -2
- package/dist/contradiction/index.d.ts +4 -2
- package/dist/contradiction-config.d.ts +29 -0
- package/dist/contradiction-config.js +12 -0
- package/dist/contradiction-config.js.map +1 -0
- package/dist/converge-config.d.ts +3 -1
- package/dist/convergence-refresh.d.ts +4 -2
- package/dist/convergence-refresh.js +12 -11
- package/dist/conversation-index/backend.d.ts +3 -1
- package/dist/conversation-index/chunker.d.ts +3 -1
- package/dist/conversation-index/faiss-adapter.d.ts +3 -1
- package/dist/conversation-index/indexer.d.ts +3 -1
- package/dist/conversation-index/search.d.ts +3 -1
- package/dist/corpus-watermark.d.ts +3 -1
- package/dist/corpus-watermark.js +21 -20
- package/dist/day-summary.d.ts +3 -1
- package/dist/delinearize.d.ts +3 -1
- package/dist/dependency-propagation-config.d.ts +3 -1
- package/dist/direct-answer-wiring.d.ts +3 -1
- package/dist/direct-answer.d.ts +3 -1
- package/dist/embedding-fallback.d.ts +3 -1
- package/dist/enrichment/index.d.ts +3 -1
- package/dist/entity-retrieval.d.ts +4 -2
- package/dist/entity-retrieval.js +10 -9
- package/dist/entity-schema.d.ts +3 -1
- package/dist/explicit-capture.d.ts +11 -9
- package/dist/explicit-capture.js +3 -2
- package/dist/external-wiki-access.d.ts +13 -11
- package/dist/external-wiki-access.js +42 -40
- package/dist/external-wiki-collection-registration.d.ts +3 -1
- package/dist/external-wiki-collection.d.ts +3 -1
- package/dist/external-wiki-mcp-tools.d.ts +13 -11
- package/dist/extraction-error-classification.d.ts +3 -1
- package/dist/extraction-faithfulness.d.ts +3 -1
- package/dist/extraction-judge-telemetry.d.ts +3 -1
- package/dist/extraction-judge-training.d.ts +3 -1
- package/dist/extraction-judge.d.ts +3 -1
- package/dist/extraction-liveness.d.ts +3 -1
- package/dist/extraction-normalization.d.ts +3 -1
- package/dist/extraction-prompt.d.ts +3 -1
- package/dist/extraction-source-grounding-rules.d.ts +3 -1
- package/dist/extraction-source-grounding.d.ts +3 -1
- package/dist/extraction.d.ts +3 -1
- package/dist/extraction.js +22 -21
- package/dist/fallback-llm.d.ts +3 -1
- package/dist/graph-444E-DrF.d.ts +349 -0
- package/dist/graph-dashboard-diff.d.ts +4 -2
- package/dist/graph-dashboard-key.d.ts +4 -2
- package/dist/graph-dashboard-parser.d.ts +4 -2
- package/dist/{graph-edge-decay-Z6ENALU2.js → graph-edge-decay-65KMOJWY.js} +4 -3
- package/dist/graph-edge-decay-65KMOJWY.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +4 -2
- package/dist/graph-path-reconstruction.d.ts +10 -0
- package/dist/graph-path-reconstruction.js +12 -0
- package/dist/graph-path-reconstruction.js.map +1 -0
- package/dist/graph-path-scoring-config.d.ts +8 -0
- package/dist/graph-path-scoring-config.js +10 -0
- package/dist/graph-path-scoring-config.js.map +1 -0
- package/dist/graph-path-scoring.d.ts +36 -0
- package/dist/graph-path-scoring.js +11 -0
- package/dist/graph-path-scoring.js.map +1 -0
- package/dist/graph-snapshot.d.ts +4 -2
- package/dist/graph-snapshot.js +3 -2
- package/dist/graph.d.ts +5 -318
- package/dist/graph.js +5 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +3 -1
- package/dist/importers/index.d.ts +3 -1
- package/dist/in-flight-reads.d.ts +3 -1
- package/dist/index.d.ts +22 -20
- package/dist/index.js +149 -144
- package/dist/intent.d.ts +3 -1
- package/dist/lcm/engine.d.ts +3 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +3 -1
- package/dist/lcm/index.js +6 -6
- package/dist/lcm/tools.d.ts +3 -1
- package/dist/lifecycle.d.ts +3 -1
- package/dist/live-connectors-runner.d.ts +3 -1
- package/dist/local-llm.d.ts +3 -1
- package/dist/local-model-endpoint.d.ts +3 -1
- package/dist/maintenance/memory-governance.d.ts +3 -1
- package/dist/maintenance/memory-governance.js +10 -9
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +10 -9
- package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-projection.js +11 -10
- package/dist/{maintenance-ClmUVpGI.d.ts → maintenance-CKwxpdRx.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +13 -11
- package/dist/memory-action-policy.d.ts +3 -1
- package/dist/memory-cache.d.ts +3 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +3 -1
- package/dist/memory-projection-store.d.ts +3 -1
- package/dist/memory-provenance.d.ts +3 -1
- package/dist/memory-snapshot.d.ts +3 -1
- package/dist/memory-worth-outcomes.d.ts +4 -2
- package/dist/models-json.d.ts +3 -1
- package/dist/namespaces/migrate.d.ts +5 -3
- package/dist/namespaces/migrate.js +20 -19
- package/dist/namespaces/principal.d.ts +3 -1
- package/dist/namespaces/search.d.ts +3 -1
- package/dist/namespaces/search.js +7 -7
- package/dist/namespaces/storage.d.ts +5 -3
- package/dist/namespaces/storage.js +10 -9
- package/dist/native-knowledge.d.ts +3 -1
- package/dist/offline-sync-impression-drain.d.ts +3 -1
- package/dist/operator-doctor-corpus.d.ts +3 -1
- package/dist/operator-doctor-corpus.js +22 -21
- package/dist/operator-doctor-replica.d.ts +3 -1
- package/dist/operator-toolkit.d.ts +6 -4
- package/dist/operator-toolkit.js +33 -29
- package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
- package/dist/orchestration/maintenance.d.ts +6 -4
- package/dist/orchestration/maintenance.js +15 -14
- package/dist/{orchestrator-qJ07zI8H.d.ts → orchestrator-BshGam-o.d.ts} +45 -19
- package/dist/orchestrator.d.ts +11 -9
- package/dist/orchestrator.js +109 -104
- package/dist/patterns-cli.d.ts +3 -1
- package/dist/{pipeline-WFCxhHOn.d.ts → pipeline-D21Rs6gW.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +3 -1
- package/dist/proactive-contention.d.ts +3 -1
- package/dist/provenance.d.ts +3 -1
- package/dist/{qmd-5tzkQ44y.d.ts → qmd-Dhle1P4X.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +4 -2
- package/dist/qmd-recall-cache.d.ts +3 -1
- package/dist/qmd.d.ts +4 -2
- package/dist/qmd.js +4 -4
- package/dist/recall-concurrency-config.d.ts +3 -1
- package/dist/recall-disclosure-escalation.d.ts +3 -1
- package/dist/recall-explain-renderer.d.ts +3 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +3 -1
- package/dist/recall-planner-llm.d.ts +3 -1
- package/dist/recall-planner-llm.js +3 -3
- package/dist/recall-state.d.ts +7 -1
- package/dist/recall-state.js +1 -1
- package/dist/recall-tag-filter.d.ts +3 -1
- package/dist/recall-timings.d.ts +3 -1
- package/dist/recall-xray-cli.d.ts +3 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +3 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +7 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +3 -1
- package/dist/reconcile/manifest.d.ts +3 -1
- package/dist/reconcile/plan.d.ts +3 -1
- package/dist/replay/normalizers/chatgpt.d.ts +3 -1
- package/dist/replay/normalizers/claude.d.ts +3 -1
- package/dist/replay/normalizers/openclaw.d.ts +3 -1
- package/dist/replay/normalizers/shared.d.ts +3 -1
- package/dist/replay/runner.d.ts +3 -1
- package/dist/replay/types.d.ts +3 -1
- package/dist/replica-divergence.d.ts +3 -1
- package/dist/replica-peers-config.d.ts +3 -1
- package/dist/resolve-auth-token.d.ts +3 -1
- package/dist/resume-bundles.js +6 -4
- package/dist/retrieval-agents.d.ts +4 -2
- package/dist/retrieval-tiers.d.ts +3 -1
- package/dist/routing/engine.d.ts +3 -1
- package/dist/routing/store.d.ts +3 -1
- package/dist/salvage-envelope.d.ts +3 -1
- package/dist/{scope-profiles--vfXPl3X.d.ts → scope-profiles-NzGPDXLn.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +3 -1
- package/dist/search/factory.d.ts +3 -1
- package/dist/search/factory.js +6 -6
- package/dist/search/index.d.ts +3 -1
- package/dist/search/index.js +12 -12
- package/dist/search/lancedb-backend.d.ts +3 -1
- package/dist/search/meilisearch-backend.d.ts +3 -1
- package/dist/search/noop-backend.d.ts +3 -1
- package/dist/search/orama-backend.d.ts +3 -1
- package/dist/search/port.d.ts +3 -1
- package/dist/search/remote-backend.d.ts +3 -1
- package/dist/{semantic-consolidation-BBDuP9nJ.d.ts → semantic-consolidation-DLDKvyy5.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +4 -2
- package/dist/semantic-consolidation.js +11 -10
- package/dist/semantic-rule-promotion.js +10 -9
- package/dist/semantic-rule-verifier.d.ts +3 -1
- package/dist/semantic-rule-verifier.js +10 -9
- package/dist/{service-B8DtbpCM.d.ts → service-BIgVM7fL.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +3 -1
- package/dist/session-observer-state.d.ts +3 -1
- package/dist/shared-context/manager.d.ts +3 -1
- package/dist/signal.d.ts +3 -1
- package/dist/source-agent-qualifier.d.ts +3 -1
- package/dist/source-agent-qualifier.js +18 -17
- package/dist/{storage-BkYN1RIy.d.ts → storage-CVfGWqCI.d.ts} +7 -6
- package/dist/storage.d.ts +4 -2
- package/dist/storage.js +9 -8
- package/dist/summarizer.d.ts +3 -1
- package/dist/summary-snapshot.d.ts +3 -1
- package/dist/temporal-supersession.d.ts +4 -2
- package/dist/temporal-timeline-recall.d.ts +3 -1
- package/dist/temporal-validity.d.ts +3 -1
- package/dist/threading.d.ts +3 -1
- package/dist/tier-migration.d.ts +4 -2
- package/dist/tier-routing.d.ts +3 -1
- package/dist/topics.d.ts +3 -1
- package/dist/transcript.d.ts +3 -1
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/trust-score-stage.d.ts +3 -1
- package/dist/trust-score.d.ts +3 -1
- package/dist/{types-u2s9j1uD.d.ts → types-CkiDUorT.d.ts} +10 -16
- package/dist/types.d.ts +3 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +3 -1
- package/dist/verified-recall.js +10 -9
- package/dist/write-envelope.d.ts +3 -1
- package/package.json +2 -2
- package/src/archive-mutation-version.ts +59 -0
- package/src/config.test.ts +45 -0
- package/src/config.ts +10 -30
- package/src/contradiction/contradiction.test.ts +86 -1
- package/src/contradiction-config.ts +92 -0
- package/src/graph-path-reconstruction.ts +91 -0
- package/src/graph-path-scoring-config.ts +55 -0
- package/src/graph-path-scoring.test.ts +238 -0
- package/src/graph-path-scoring.ts +77 -0
- package/src/graph.test.ts +225 -5
- package/src/graph.ts +72 -5
- package/src/orchestration/contradiction-linking-coordinator.ts +246 -76
- package/src/orchestration/contradiction-localization.integration.test.ts +1953 -0
- package/src/orchestration/extraction-anchor-snapshot.ts +83 -0
- package/src/orchestration/extraction-persist-deps.ts +8 -2
- package/src/orchestration/extraction-persist.ts +43 -34
- package/src/orchestration/graph-path-state-loader.test.ts +801 -0
- package/src/orchestration/graph-path-state-loader.ts +318 -0
- package/src/orchestration/graph-recall-coordinator.integration.test.ts +1163 -0
- package/src/orchestration/graph-recall-coordinator.ts +206 -29
- package/src/orchestration/graph-recall-seam.ts +19 -0
- package/src/orchestration/recall-internal-deps.ts +7 -13
- package/src/orchestration/recall-internal.ts +5 -0
- package/src/orchestration/recall-introspection.ts +9 -1
- package/src/orchestration/recall-search-pipeline.ts +8 -13
- package/src/orchestration/update-localization.test.ts +784 -0
- package/src/orchestration/update-localization.ts +173 -0
- package/src/orchestrator.ts +19 -18
- package/src/recall-state.test.ts +29 -1
- package/src/recall-state.ts +13 -0
- package/src/recall-xray-renderer.test.ts +45 -0
- package/src/recall-xray-renderer.ts +16 -0
- package/src/recall-xray.ts +13 -0
- package/src/storage/supersession-side-effects.ts +97 -0
- package/src/storage/tombstone-blocked-capture-sync.ts +13 -5
- package/src/storage-contract/cache-coherence.test.ts +299 -0
- package/src/storage.ts +86 -88
- package/src/types.ts +12 -15
- package/dist/chunk-A4QMKFFO.js.map +0 -1
- package/dist/chunk-BJYET5TX.js.map +0 -1
- package/dist/chunk-BOFVT6P3.js.map +0 -1
- package/dist/chunk-IK6X5QPO.js.map +0 -1
- package/dist/chunk-IXXABW5A.js.map +0 -1
- package/dist/chunk-L2DPF4DF.js.map +0 -1
- package/dist/chunk-LAQ33B5D.js.map +0 -1
- package/dist/chunk-NSGU76YO.js.map +0 -1
- package/dist/chunk-PDEKQWDV.js.map +0 -1
- /package/dist/{graph-edge-decay-Z6ENALU2.js.map → archive-mutation-version.js.map} +0 -0
- /package/dist/{chunk-KDG2KTWW.js.map → chunk-33SV3E43.js.map} +0 -0
- /package/dist/{chunk-2HGUDBRJ.js.map → chunk-37ZO6LLJ.js.map} +0 -0
- /package/dist/{chunk-QW3WFHKU.js.map → chunk-45BRYON6.js.map} +0 -0
- /package/dist/{chunk-GZICBRWK.js.map → chunk-4F6X3RXW.js.map} +0 -0
- /package/dist/{chunk-7BAYBYY5.js.map → chunk-4PC4PRJE.js.map} +0 -0
- /package/dist/{chunk-VJXY5ZCT.js.map → chunk-52UKFTUK.js.map} +0 -0
- /package/dist/{chunk-ESG7Z255.js.map → chunk-5UDMFE3Q.js.map} +0 -0
- /package/dist/{chunk-JPHEOE6Z.js.map → chunk-6MTSFX7A.js.map} +0 -0
- /package/dist/{chunk-M4MP34AQ.js.map → chunk-AHZOMHWN.js.map} +0 -0
- /package/dist/{chunk-Z3RHPGSY.js.map → chunk-AIUBBHSF.js.map} +0 -0
- /package/dist/{chunk-S3AYIQCU.js.map → chunk-AXIDQG5A.js.map} +0 -0
- /package/dist/{chunk-QN7NTKRC.js.map → chunk-AZ2QBGYB.js.map} +0 -0
- /package/dist/{chunk-47J4EDGR.js.map → chunk-AZM4CCAC.js.map} +0 -0
- /package/dist/{chunk-LEJPSMKM.js.map → chunk-C5QLI33R.js.map} +0 -0
- /package/dist/{chunk-SV3PSA7Y.js.map → chunk-CV6BBVYV.js.map} +0 -0
- /package/dist/{chunk-V7X767RT.js.map → chunk-DCZBSE4F.js.map} +0 -0
- /package/dist/{chunk-7PKFPLLZ.js.map → chunk-FXTYIA46.js.map} +0 -0
- /package/dist/{chunk-64BHFFKZ.js.map → chunk-HLYR2TQL.js.map} +0 -0
- /package/dist/{chunk-5C2HNJMO.js.map → chunk-J5LLX6IL.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-PLKFO2HJ.js.map → chunk-JL43BVDE.js.map} +0 -0
- /package/dist/{chunk-2S72LWKX.js.map → chunk-JYL3BVVZ.js.map} +0 -0
- /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-PYKKWQZ2.js.map → chunk-M7BXDKPR.js.map} +0 -0
- /package/dist/{chunk-Z54EM5YZ.js.map → chunk-MAXVH44E.js.map} +0 -0
- /package/dist/{chunk-LYMNZZIM.js.map → chunk-NIS256NW.js.map} +0 -0
- /package/dist/{chunk-67QG75MJ.js.map → chunk-NLK2VZYZ.js.map} +0 -0
- /package/dist/{chunk-JYIFGGEM.js.map → chunk-OUKBMQ2O.js.map} +0 -0
- /package/dist/{chunk-75XOWNRS.js.map → chunk-OYESWJ43.js.map} +0 -0
- /package/dist/{chunk-TS4AJ2GI.js.map → chunk-PA45XCUD.js.map} +0 -0
- /package/dist/{chunk-4MBPIL4V.js.map → chunk-PUSLMZBQ.js.map} +0 -0
- /package/dist/{chunk-RVO6TCTU.js.map → chunk-QCECHYZL.js.map} +0 -0
- /package/dist/{chunk-GFIKG4FR.js.map → chunk-QGR6OVGT.js.map} +0 -0
- /package/dist/{chunk-HNZKVLAN.js.map → chunk-S354QO4R.js.map} +0 -0
- /package/dist/{chunk-NO37MR45.js.map → chunk-SOEN6KCF.js.map} +0 -0
- /package/dist/{chunk-FXX6RQYC.js.map → chunk-TPTECFWR.js.map} +0 -0
- /package/dist/{chunk-GDDGZVFI.js.map → chunk-UEVLYVNW.js.map} +0 -0
- /package/dist/{chunk-YQ4IQ2GA.js.map → chunk-UT5BV5OG.js.map} +0 -0
- /package/dist/{chunk-LNTUXKBT.js.map → chunk-UYYW2KPU.js.map} +0 -0
- /package/dist/{chunk-QSYL5CXK.js.map → chunk-VKXWK44Q.js.map} +0 -0
- /package/dist/{chunk-KMWYZTIE.js.map → chunk-VMMQDEN5.js.map} +0 -0
- /package/dist/{chunk-JB6D7EFB.js.map → chunk-VVG2BOKA.js.map} +0 -0
- /package/dist/{chunk-V5H6OJCR.js.map → chunk-W5XVQFLM.js.map} +0 -0
- /package/dist/{chunk-OIOZ6MOP.js.map → chunk-W6FNX2LP.js.map} +0 -0
- /package/dist/{chunk-6QPHF6RR.js.map → chunk-WQM326GS.js.map} +0 -0
- /package/dist/{chunk-TQFHQPWD.js.map → chunk-XADV5IZ3.js.map} +0 -0
- /package/dist/{chunk-DATDLJAO.js.map → chunk-XAPMEU3K.js.map} +0 -0
- /package/dist/{chunk-N3LL5NEU.js.map → chunk-ZMYDYNI4.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage/tombstone-blocked-capture-mutation.ts","../src/storage/tombstone-blocked-capture-sync.ts","../src/storage/tombstone-blocked-capture-index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\nimport { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { withHeldFileLock } from \"../utils/serialize-mutations.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nconst TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS = 60_000;\nconst CAPTURE_WRITE_LOCK_MAX_ATTEMPTS = 3;\nconst CAPTURE_WRITE_LOCK_RETRY_BASE_MS = 25;\nconst CAPTURE_WRITE_LOCK_BUSY_MESSAGE = \"tombstone-blocked capture write lock remained busy\";\n\nexport function isTombstoneBlockedCaptureWriteLockBusy(error: unknown): boolean {\n return error instanceof Error && error.message === CAPTURE_WRITE_LOCK_BUSY_MESSAGE;\n}\n\nexport function normalizeExplicitCaptureContent(value: string): string {\n return value.toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\nexport function buildExplicitCaptureDedupKey(\n content: string,\n category: string,\n sourceConnector: string | undefined\n): string {\n const encode = (label: string, value: string): string => `${label} ${value.length} ${value}`;\n return [\n encode(\"category\", category),\n encode(\"connector\", sourceConnector?.trim() ?? \"\"),\n encode(\"content\", normalizeExplicitCaptureContent(content)),\n ].join(\" \");\n}\n\nexport function buildCapturePathLockIdentity(pathname: string): string {\n return `path ${pathname.length} ${pathname}`;\n}\n\nexport function captureIdentityHash(memory: MemoryFile): string {\n return createHash(\"sha256\")\n .update(\n buildExplicitCaptureDedupKey(memory.content, memory.frontmatter.category, memory.frontmatter.sourceConnector)\n )\n .digest(\"hex\");\n}\n\nexport type TombstoneBlockedCaptureWriteLockOptions = {\n readonly stateDir: string;\n readonly withHeldFileLock?: typeof withHeldFileLock;\n};\n\nexport class TombstoneBlockedCaptureWriteLock {\n private readonly context = new AsyncLocalStorage<ReadonlySet<string>>();\n\n constructor(private readonly options: TombstoneBlockedCaptureWriteLockOptions) {}\n\n private captureWriteLockPathForHash(identityHash: string): string {\n const filename =\n identityHash.length === 0 ? \"explicit-capture-write.lock\" : `explicit-capture-write-${identityHash}.lock`;\n return path.join(this.options.stateDir, \"tombstone-blocked-capture\", filename);\n }\n\n private async withSingleCaptureWriteLock<T>(lockPath: string, task: () => Promise<T>): Promise<T> {\n await mkdir(path.dirname(lockPath), { recursive: true });\n const retry = Symbol(\"retry\");\n const permanentFailure = Symbol(\"permanent-failure\");\n const runWithHeldFileLock = this.options.withHeldFileLock ?? withHeldFileLock;\n for (let attempt = 0; attempt < CAPTURE_WRITE_LOCK_MAX_ATTEMPTS; attempt += 1) {\n const result = await runWithHeldFileLock<T | typeof retry | typeof permanentFailure>(\n lockPath,\n {\n staleMs: TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS,\n maxWaitMs: 1_000,\n pollMs: 25,\n },\n async (acquired, controller) => {\n if (acquired) return await task();\n return controller.failure === \"error\" ? permanentFailure : retry;\n }\n );\n if (result === permanentFailure) {\n throw new Error(\"tombstone-blocked capture write lock acquisition failed\");\n }\n if (result !== retry) return result;\n if (attempt === CAPTURE_WRITE_LOCK_MAX_ATTEMPTS - 1) break;\n const delayState = Promise.withResolvers<void>();\n setTimeout(delayState.resolve, CAPTURE_WRITE_LOCK_RETRY_BASE_MS * 2 ** attempt);\n await delayState.promise;\n }\n throw new Error(CAPTURE_WRITE_LOCK_BUSY_MESSAGE);\n }\n private async withPhysicalCaptureWriteLocks<T>(\n task: () => Promise<T>,\n identityHashes: readonly string[]\n ): Promise<T> {\n const lockPaths = [...new Set(identityHashes.map((hash) => this.captureWriteLockPathForHash(hash)))];\n const acquire = async (index: number): Promise<T> => {\n if (index === lockPaths.length) return await task();\n return await this.withSingleCaptureWriteLock(lockPaths[index], () => acquire(index + 1));\n };\n return await acquire(0);\n }\n\n async withCaptureWriteLock<T>(task: () => Promise<T>, identity?: string | readonly string[]): Promise<T> {\n const identities =\n Array.isArray(identity) && identity.length > 0 ? identity : [typeof identity === \"string\" ? identity : \"\"];\n return await this.withCaptureWriteLocks(task, identities, []);\n }\n\n async withCaptureWriteLockHashes<T>(task: () => Promise<T>, identityHashes: readonly string[]): Promise<T> {\n return await this.withCaptureWriteLocks(task, [], identityHashes);\n }\n\n async withCaptureWriteLockAndHashes<T>(\n task: () => Promise<T>,\n identity: string | readonly string[] | undefined,\n identityHashes: readonly string[]\n ): Promise<T> {\n const identities =\n Array.isArray(identity) && identity.length > 0 ? identity : [typeof identity === \"string\" ? identity : \"\"];\n return await this.withCaptureWriteLocks(task, identities, identityHashes);\n }\n\n private async withCaptureWriteLocks<T>(\n task: () => Promise<T>,\n identities: readonly string[],\n identityHashes: readonly string[]\n ): Promise<T> {\n const current = this.context.getStore();\n const hashToken = (key: string): string =>\n `\\u0000${key.length === 0 ? \"\" : createHash(\"sha256\").update(key).digest(\"hex\")}`;\n const identityHash = (key: string): string =>\n key.length === 0 ? \"\" : createHash(\"sha256\").update(key).digest(\"hex\");\n const identityKeys = [...new Set(identities)];\n const hashes = [...new Set(identityHashes)];\n const requested = [\n ...identityKeys\n .filter((key) => !current || (!current.has(key) && !current.has(hashToken(key))))\n .map((key) => ({ hash: identityHash(key), pathLock: key.startsWith(\"path \") })),\n ...hashes.filter((hash) => !current || !current.has(`\\u0000${hash}`)).map((hash) => ({ hash, pathLock: false })),\n ]\n .filter((entry, index, entries) => entries.findIndex((candidate) => candidate.hash === entry.hash) === index)\n .sort(\n (left, right) =>\n Number(left.pathLock) - Number(right.pathLock) ||\n this.captureWriteLockPathForHash(left.hash).localeCompare(this.captureWriteLockPathForHash(right.hash))\n );\n const physicalMissing = requested.map((entry) => entry.hash);\n if (current && requested.length > 0) {\n const held = [...current]\n .filter((token) => token.startsWith(\"\\u0000\"))\n .map((token) => {\n const hash = token.slice(1);\n const pathLock = [...current].some(\n (key) => !key.startsWith(\"\\u0000\") && key.startsWith(\"path \") && hashToken(key) === token\n );\n return { hash, pathLock };\n });\n const requestedFirst = requested[0];\n const heldLast = held\n .sort(\n (left, right) =>\n Number(left.pathLock) - Number(right.pathLock) ||\n this.captureWriteLockPathForHash(left.hash).localeCompare(this.captureWriteLockPathForHash(right.hash))\n )\n .at(-1);\n if (\n heldLast &&\n requestedFirst &&\n (Number(requestedFirst.pathLock) < Number(heldLast.pathLock) ||\n (requestedFirst.pathLock === heldLast.pathLock &&\n this.captureWriteLockPathForHash(requestedFirst.hash) < this.captureWriteLockPathForHash(heldLast.hash)))\n ) {\n throw new Error(CAPTURE_WRITE_LOCK_BUSY_MESSAGE);\n }\n }\n const next = new Set(current);\n for (const key of identityKeys) {\n next.add(key);\n next.add(hashToken(key));\n }\n for (const hash of hashes) next.add(`\\u0000${hash}`);\n const run = () => this.context.run(next, task);\n if (physicalMissing.length === 0) return await run();\n return await this.withPhysicalCaptureWriteLocks(run, physicalMissing);\n }\n}\n\nexport type TombstoneBlockedMutationHost = {\n readCurrent: () => Promise<MemoryFile | null>;\n isBlocked: (memory: MemoryFile | null) => boolean;\n isQueuedReview: (memory: MemoryFile | null) => boolean;\n memoryIdentity: (memory: MemoryFile) => string;\n prepareWrite: () => Promise<string>;\n commitWrite: (marker: string) => Promise<void>;\n discardWrite: (marker: string) => Promise<void>;\n markUntrusted: () => void;\n writeStorageSecureFile: (pathname: string, fileContent: string) => Promise<void>;\n withCaptureWriteLock: (task: () => Promise<void>, identity: string | readonly string[]) => Promise<void>;\n logWarning: (message: string) => void;\n};\n\nexport type TombstoneBlockedMutation = {\n blocked: boolean;\n pathname: string;\n fileContent: string;\n identity: string | readonly string[];\n updateIndex: (rebuildMarker?: string, current?: MemoryFile | null) => Promise<void>;\n beforeIndexUpdate?: () => Promise<void>;\n coordinate?: boolean;\n};\n\nexport async function runTombstoneBlockedMutation(\n host: TombstoneBlockedMutationHost,\n mutation: TombstoneBlockedMutation\n): Promise<void> {\n let lockIdentity: string | readonly string[] = mutation.identity;\n for (;;) {\n let retryIdentity: string | undefined;\n const mutate = async (): Promise<void> => {\n const current = await host.readCurrent();\n const currentBlocked = host.isBlocked(current);\n const currentQueuedReview = host.isQueuedReview(current);\n if (current !== null && (mutation.coordinate === true || currentBlocked || currentQueuedReview)) {\n const currentIdentity = host.memoryIdentity(current);\n const heldIdentities = Array.isArray(lockIdentity) ? lockIdentity : [lockIdentity];\n if (!heldIdentities.includes(currentIdentity)) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n const rebuildMarker = mutation.blocked || currentBlocked ? await host.prepareWrite() : undefined;\n try {\n await host.writeStorageSecureFile(mutation.pathname, mutation.fileContent);\n } catch (err) {\n if (rebuildMarker) {\n try {\n await host.discardWrite(rebuildMarker);\n } catch (cleanupError) {\n host.markUntrusted();\n host.logWarning(`storage.tombstoneBlocked failed to clear write marker: ${cleanupError}`);\n }\n }\n throw err;\n }\n if (rebuildMarker) {\n try {\n await host.commitWrite(rebuildMarker);\n } catch (err) {\n host.markUntrusted();\n host.logWarning(`storage.tombstoneBlocked committed write marker failed: ${err}`);\n }\n }\n if (rebuildMarker) await mutation.beforeIndexUpdate?.();\n await mutation.updateIndex(rebuildMarker, currentBlocked && current !== null ? current : undefined);\n };\n await host.withCaptureWriteLock(mutate, lockIdentity);\n if (retryIdentity === undefined) return;\n const identities = Array.isArray(lockIdentity) ? [...lockIdentity, retryIdentity] : [lockIdentity, retryIdentity];\n lockIdentity = [...new Set(identities)];\n }\n}\n\nexport function tombstoneBlocked(frontmatter: MemoryFrontmatter): boolean {\n return frontmatter.status === \"pending_review\" && Boolean(frontmatter.blockedBy);\n}\n\nexport function isQueuedReviewFrontmatter(frontmatter: MemoryFrontmatter): boolean {\n return frontmatter.status === \"pending_review\" && (frontmatter.tags ?? []).includes(\"queued-review\");\n}\n\nexport function isQueuedReviewMemory(memory: MemoryFile | null): memory is MemoryFile {\n return memory !== null && isQueuedReviewFrontmatter(memory.frontmatter);\n}\n","import { createHash, randomUUID, type Hash } from \"node:crypto\";\nimport { unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { log } from \"../logger.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nimport { markProjectedMemoryPathInvalid } from \"../memory-projection-store.js\";\nimport { RECALL_FALLBACK_DIRS } from \"../utils/category-dir.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport { pathMayCarryEntityRefs, requestEntityCanonicalIdReconcile } from \"./entity-canonical-id-references.js\";\nimport { withRawEntityPageMutation } from \"./entity-canonical-id-lock.js\";\nimport { readMaybeEncryptedFileFromChunks, writeMaybeEncryptedFileFromChunks } from \"../secure-store/secure-fs.js\";\nimport {\n buildExplicitCaptureDedupKey,\n buildCapturePathLockIdentity,\n captureIdentityHash,\n tombstoneBlocked,\n isQueuedReviewMemory,\n runTombstoneBlockedMutation,\n type TombstoneBlockedMutationHost,\n} from \"./tombstone-blocked-capture-mutation.js\";\nimport { TombstoneBlockedCaptureIndex } from \"./tombstone-blocked-capture-index.js\";\nimport type { TombstoneBlockedCaptureIndexOptions } from \"./tombstone-blocked-capture-index.js\";\n\nconst OFFLINE_SYNC_BUFFER_LIMIT_BYTES = 1_048_576;\nconst OFFLINE_SYNC_STAGE_READ_BYTES = 64 * 1024;\nconst OFFLINE_SYNC_FRONTMATTER_DELIMITER = Buffer.from(\"\\n---\\n\", \"utf8\");\n\nconst CASED_CHARACTER = /\\p{Cased}/u;\nconst CASE_IGNORABLE_CHARACTER = /\\p{Case_Ignorable}/u;\n\ntype StreamedOfflineSyncIdentity = {\n identityHash: string;\n};\n\ntype PreparedOfflineSyncChunks = {\n after: MemoryFile | null;\n chunks: AsyncIterable<Buffer>;\n stagePath?: string;\n streamedIdentity?: StreamedOfflineSyncIdentity;\n};\n\ntype ExplicitContentNormalizerSink = {\n write: (chunk: string) => void;\n beginConditionalSigma: () => void;\n resolveConditionalSigma: (useFinalSigma: boolean) => void;\n};\n\nfunction createExplicitContentNormalizer(sink: ExplicitContentNormalizerSink): {\n push: (text: string) => void;\n finish: () => void;\n} {\n let started = false;\n let pendingSpace = false;\n let output = \"\";\n let precededByCased = false;\n let pendingSigma = false;\n const flush = () => {\n if (output.length > 0) {\n sink.write(output);\n output = \"\";\n }\n };\n const emit = (text: string) => {\n for (const character of text) {\n if (/\\s/u.test(character)) {\n if (started) pendingSpace = true;\n continue;\n }\n if (pendingSpace) {\n output += \" \";\n pendingSpace = false;\n }\n output += character;\n started = true;\n if (output.length >= OFFLINE_SYNC_STAGE_READ_BYTES) flush();\n }\n };\n const resolveSigma = (followedByCased: boolean) => {\n flush();\n sink.resolveConditionalSigma(!followedByCased);\n pendingSigma = false;\n };\n const push = (text: string) => {\n for (const character of text) {\n const caseIgnorable = CASE_IGNORABLE_CHARACTER.test(character);\n const cased = CASED_CHARACTER.test(character);\n if (pendingSigma) {\n if (caseIgnorable) {\n emit(character.toLowerCase());\n continue;\n }\n resolveSigma(cased);\n }\n if (character === \"Σ\" && precededByCased) {\n flush();\n sink.beginConditionalSigma();\n pendingSigma = true;\n precededByCased = true;\n continue;\n }\n emit(character.toLowerCase());\n if (!caseIgnorable) precededByCased = cased;\n }\n };\n return {\n push,\n finish() {\n if (pendingSigma) resolveSigma(false);\n flush();\n },\n };\n}\n\nasync function forEachStagedTextChunk(\n stagePath: string,\n offset: number,\n onText: (text: string) => void,\n key: Buffer | null,\n memoryDir: string\n): Promise<void> {\n const decoder = new TextDecoder(\"utf-8\");\n let remaining = offset;\n for await (const chunk of readMaybeEncryptedFileFromChunks(stagePath, key, memoryDir)) {\n const textChunk = remaining >= chunk.length ? null : chunk.subarray(remaining);\n remaining = Math.max(0, remaining - chunk.length);\n if (textChunk === null || textChunk.length === 0) continue;\n const text = decoder.decode(textChunk, { stream: true });\n if (text.length > 0) onText(text);\n }\n const finalText = decoder.decode();\n if (finalText.length > 0) onText(finalText);\n}\n\nasync function findStagedBodyOffset(stagePath: string, key: Buffer | null, memoryDir: string): Promise<number | null> {\n let scannedBytes = 0;\n let tail = Buffer.alloc(0);\n for await (const chunk of readMaybeEncryptedFileFromChunks(stagePath, key, memoryDir)) {\n const window = tail.length > 0 ? Buffer.concat([tail, chunk]) : chunk;\n const windowStart = scannedBytes - tail.length;\n for (let searchFrom = 0; ; ) {\n const delimiterStart = window.indexOf(OFFLINE_SYNC_FRONTMATTER_DELIMITER, searchFrom);\n if (delimiterStart < 0) break;\n if (windowStart + delimiterStart >= 4) {\n return windowStart + delimiterStart + OFFLINE_SYNC_FRONTMATTER_DELIMITER.length;\n }\n searchFrom = delimiterStart + 1;\n }\n scannedBytes += chunk.length;\n const tailLength = Math.min(OFFLINE_SYNC_FRONTMATTER_DELIMITER.length - 1, window.length);\n tail = Buffer.from(window.subarray(window.length - tailLength));\n }\n return null;\n}\n\nasync function readStagedPrefix(\n stagePath: string,\n byteLimit: number,\n key: Buffer | null,\n memoryDir: string\n): Promise<Buffer> {\n const chunks: Buffer[] = [];\n let bytesRead = 0;\n for await (const chunk of readMaybeEncryptedFileFromChunks(stagePath, key, memoryDir)) {\n const length = Math.min(chunk.length, byteLimit - bytesRead);\n if (length > 0) chunks.push(chunk.subarray(0, length));\n bytesRead += length;\n if (bytesRead >= byteLimit) break;\n }\n return Buffer.concat(chunks, bytesRead);\n}\n\nexport type OfflineSyncMemoryParser = (filePath: string, content: Buffer) => MemoryFile | null;\n\nexport function parseTombstoneBlockedOfflineSyncMemory(\n filePath: string,\n content: Buffer,\n memoryDir: string,\n parseFrontmatter: (raw: string) => { frontmatter: MemoryFrontmatter; content: string } | null,\n normalizeFrontmatterForPath: (frontmatter: MemoryFrontmatter, pathRel: string, content?: string) => MemoryFrontmatter,\n toMemoryPathRel: (baseDir: string, filePath: string) => string\n): MemoryFile | null {\n const parsed = parseFrontmatter(content.toString(\"utf8\"));\n if (!parsed) return null;\n return {\n path: filePath,\n frontmatter: normalizeFrontmatterForPath(parsed.frontmatter, toMemoryPathRel(memoryDir, filePath), parsed.content),\n content: parsed.content,\n };\n}\n\nexport abstract class TombstoneBlockedCaptureIndexHost {\n private tombstoneBlockedCaptureIndex: TombstoneBlockedCaptureIndex | null = null;\n protected abstract tombstoneBlockedCaptureIndexOptions(): TombstoneBlockedCaptureIndexOptions;\n protected abstract writeStorageSecureFile(\n filePath: string,\n content: string | Buffer,\n forceEncrypt?: boolean\n ): Promise<void>;\n protected abstract assertManagedStoragePath(filePath: string, method: string): string;\n protected abstract notifyCatalogWriteForPath(filePath: string): void;\n protected abstract readMemoryByPath(filePath: string): Promise<MemoryFile | null>;\n protected abstract invalidateAllMemoriesCache(): void;\n protected abstract invalidateKnowledgeIndexCache(): void;\n protected abstract invalidateColdMemoriesCache(): void;\n protected abstract bumpArtifactWriteVersion(): number;\n protected abstract bumpMemoryStatusVersion(): void;\n protected abstract bumpMemoryCorpusVersion(): void;\n protected abstract markFactHashIndexNotAuthoritative(): void;\n protected abstract deleteManagedStorageFile(filePath: string, deletionMtimeMs?: number | null): Promise<boolean>;\n protected abstract writeManagedStorageFile(filePath: string, write: () => Promise<void>): Promise<void>;\n\n private async writeStorageSecureFileChunks(filePath: string, chunks: AsyncIterable<Buffer>): Promise<void> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n await writeMaybeEncryptedFileFromChunks(\n filePath,\n chunks,\n options.secureStoreWriteKeyProvider(),\n {},\n options.memoryDir\n );\n this.notifyCatalogWriteForPath(filePath);\n }\n\n protected getTombstoneBlockedCaptureIndex(): TombstoneBlockedCaptureIndex {\n if (this.tombstoneBlockedCaptureIndex === null) {\n this.tombstoneBlockedCaptureIndex = new TombstoneBlockedCaptureIndex(this.tombstoneBlockedCaptureIndexOptions());\n }\n return this.tombstoneBlockedCaptureIndex;\n }\n async withTombstoneBlockedCaptureWriteLock<T>(\n task: () => Promise<T>,\n identity?: string | readonly string[]\n ): Promise<T> {\n return await this.getTombstoneBlockedCaptureIndex().withCaptureWriteLock(task, identity);\n }\n\n protected async withTombstoneBlockedCaptureWriteLockAndHashes<T>(\n task: () => Promise<T>,\n identity: string | readonly string[] | undefined,\n identityHashes: readonly string[]\n ): Promise<T> {\n return await this.getTombstoneBlockedCaptureIndex().withCaptureWriteLockAndHashes(task, identity, identityHashes);\n }\n\n private async writeTombstoneBlockedMutation(\n blocked: boolean,\n pathname: string,\n fileContent: string,\n identity: string | readonly string[],\n updateIndex: (rebuildMarker?: string, current?: MemoryFile | null) => Promise<void>,\n beforeIndexUpdate?: () => Promise<void>,\n coordinate = false\n ): Promise<void> {\n const host: TombstoneBlockedMutationHost = {\n readCurrent: () => this.readMemoryByPath(pathname),\n isBlocked: (memory) => this.isTombstoneBlockedMemory(memory),\n isQueuedReview: (memory) => isQueuedReviewMemory(memory),\n memoryIdentity: (memory) => this.offlineSyncMemoryIdentity(memory),\n prepareWrite: () => this.getTombstoneBlockedCaptureIndex().prepareWrite(),\n commitWrite: (marker) => this.getTombstoneBlockedCaptureIndex().commitWrite(marker),\n discardWrite: (marker) => this.getTombstoneBlockedCaptureIndex().discardWrite(marker),\n markUntrusted: () => this.getTombstoneBlockedCaptureIndex().markUntrusted(),\n writeStorageSecureFile: (target, content) => this.writeStorageSecureFile(target, content),\n withCaptureWriteLock: (task, lockIdentity) => this.withTombstoneBlockedCaptureWriteLock(task, lockIdentity),\n logWarning: (message) => log.warn(message),\n };\n await runTombstoneBlockedMutation(host, {\n blocked,\n pathname,\n fileContent,\n identity,\n updateIndex,\n beforeIndexUpdate,\n coordinate,\n });\n }\n\n protected async writeTombstoneBlockedMemory(\n pathname: string,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n beforeIndexUpdate?: () => Promise<void>\n ): Promise<void> {\n await this.writeTombstoneBlockedMutation(\n tombstoneBlocked(frontmatter),\n pathname,\n fileContent,\n [\n buildCapturePathLockIdentity(pathname),\n buildExplicitCaptureDedupKey(content, frontmatter.category, frontmatter.sourceConnector),\n ],\n (rebuildMarker) =>\n this.getTombstoneBlockedCaptureIndex().addWrittenMemory(pathname, frontmatter, content, rebuildMarker),\n beforeIndexUpdate\n );\n }\n\n protected async withTombstoneBlockedMemoryPathLock<T>(\n pathname: string,\n task: (current: MemoryFile | null) => Promise<T>,\n additionalPathnames: readonly string[] = []\n ): Promise<T> {\n let lockIdentities = [pathname, ...additionalPathnames].map(buildCapturePathLockIdentity);\n for (;;) {\n let retryIdentity: string | undefined;\n let result: T | undefined;\n await this.withTombstoneBlockedCaptureWriteLock(async () => {\n const current = await this.readMemoryByPath(pathname);\n if (current !== null) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (!lockIdentities.includes(currentIdentity)) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n result = await task(current);\n }, lockIdentities);\n if (retryIdentity !== undefined) {\n lockIdentities = [...new Set([...lockIdentities, retryIdentity])];\n continue;\n }\n return result!;\n }\n }\n\n protected async writeTombstoneBlockedChunk(\n pathname: string,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n findDuplicate: () => Promise<MemoryFile | null>,\n afterWrite: (current: MemoryFile | null) => Promise<void>\n ): Promise<string> {\n const incomingIdentity = buildExplicitCaptureDedupKey(content, frontmatter.category, frontmatter.sourceConnector);\n let lockIdentities = [buildCapturePathLockIdentity(pathname), incomingIdentity];\n for (;;) {\n let retryIdentity: string | undefined;\n let result = frontmatter.id;\n await this.withTombstoneBlockedCaptureWriteLock(async () => {\n const current = await this.readMemoryByPath(pathname);\n if (current !== null) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (!lockIdentities.includes(currentIdentity)) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n if (tombstoneBlocked(frontmatter)) {\n const duplicate = await findDuplicate();\n if (duplicate) {\n result = duplicate.frontmatter.id;\n return;\n }\n }\n await this.writeTombstoneBlockedMemory(pathname, fileContent, frontmatter, content);\n await afterWrite(current);\n }, lockIdentities);\n if (retryIdentity === undefined) return result;\n lockIdentities = [...new Set([...lockIdentities, retryIdentity])];\n }\n }\n\n protected async writeTombstoneBlockedUpdate(\n before: MemoryFile,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n beforeIndexUpdate?: () => Promise<void>\n ): Promise<void> {\n await this.writeTombstoneBlockedMutation(\n tombstoneBlocked(before.frontmatter) || tombstoneBlocked(frontmatter),\n before.path,\n fileContent,\n [\n buildCapturePathLockIdentity(before.path),\n this.offlineSyncMemoryIdentity(before),\n buildExplicitCaptureDedupKey(content, frontmatter.category, frontmatter.sourceConnector),\n ],\n (rebuildMarker, current) =>\n this.getTombstoneBlockedCaptureIndex().syncUpdatedMemory(\n current ?? before,\n frontmatter,\n content,\n rebuildMarker\n ),\n beforeIndexUpdate,\n true\n );\n }\n\n protected async writeTombstoneBlockedFrontmatter(\n before: MemoryFile,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n beforeIndexUpdate?: () => Promise<void>\n ): Promise<void> {\n await this.writeTombstoneBlockedMutation(\n tombstoneBlocked(before.frontmatter) || tombstoneBlocked(frontmatter),\n before.path,\n fileContent,\n [\n buildCapturePathLockIdentity(before.path),\n this.offlineSyncMemoryIdentity(before),\n buildExplicitCaptureDedupKey(before.content, frontmatter.category, frontmatter.sourceConnector),\n ],\n (rebuildMarker, current) =>\n this.getTombstoneBlockedCaptureIndex().syncUpdatedFrontmatter(current ?? before, frontmatter, rebuildMarker),\n beforeIndexUpdate,\n true\n );\n }\n\n private isTombstoneBlockedMemory(memory: MemoryFile | null): memory is MemoryFile {\n return memory !== null && memory.frontmatter.status === \"pending_review\" && Boolean(memory.frontmatter.blockedBy);\n }\n\n private offlineSyncMemoryIdentity(memory: MemoryFile): string {\n return buildExplicitCaptureDedupKey(\n memory.content,\n memory.frontmatter.category,\n memory.frontmatter.sourceConnector\n );\n }\n private async isDuplicateTombstoneBlockedOfflineSync(\n target: string,\n incoming: MemoryFile,\n streamedIdentity?: StreamedOfflineSyncIdentity\n ): Promise<boolean> {\n const before = await this.readMemoryByPath(target);\n const duplicate = streamedIdentity\n ? true\n : await this.getTombstoneBlockedCaptureIndex().has(\n incoming.content,\n incoming.frontmatter.category,\n incoming.frontmatter.sourceConnector\n );\n if (!duplicate) return false;\n const incomingIdentity = streamedIdentity?.identityHash ?? this.offlineSyncMemoryIdentity(incoming);\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const existing = [...(await options.readAllMemories()), ...(await options.readAllColdMemories())];\n const exactMatch = existing.some(\n (memory) =>\n this.isTombstoneBlockedMemory(memory) &&\n (streamedIdentity ? captureIdentityHash(memory) : this.offlineSyncMemoryIdentity(memory)) === incomingIdentity\n );\n if (!exactMatch) return false;\n if (before === null) return true;\n if (!this.isTombstoneBlockedMemory(before)) return false;\n const beforeIdentity = streamedIdentity ? captureIdentityHash(before) : this.offlineSyncMemoryIdentity(before);\n if (beforeIdentity !== incomingIdentity) return false;\n return streamedIdentity\n ? isDeepStrictEqual(before.frontmatter, incoming.frontmatter)\n : before.content === incoming.content && isDeepStrictEqual(before.frontmatter, incoming.frontmatter);\n }\n\n private async invalidateAfterOfflineSyncMutation(filePath: string, ownedMarker?: string): Promise<void> {\n this.invalidateAllMemoriesCache();\n this.invalidateKnowledgeIndexCache();\n this.markFactHashIndexNotAuthoritative();\n if (filePath.includes(`${path.sep}cold${path.sep}`)) {\n this.invalidateColdMemoriesCache();\n }\n await this.rebuildTombstoneBlockedCaptureAfterInvalidationForPath(filePath, ownedMarker);\n if (filePath.includes(`${path.sep}artifacts${path.sep}`)) {\n this.bumpArtifactWriteVersion();\n }\n this.bumpMemoryStatusVersion();\n }\n\n protected async runTombstoneBlockedArchive(\n memory: MemoryFile,\n task: (current: MemoryFile, markDurable: () => void) => Promise<string | null>\n ): Promise<string | null> {\n let archivedPath: string | null = null;\n const archived = await this.runTombstoneBlockedInvalidation(memory, async (current, rebuildMarker, markDurable) => {\n let archiveDurable = false;\n const markArchiveDurable = () => {\n archiveDurable = true;\n markDurable();\n };\n archivedPath = await task(current, markArchiveDurable);\n if (rebuildMarker !== undefined && (archivedPath !== null || archiveDurable)) {\n await this.rebuildTombstoneBlockedCaptureAfterInvalidation(rebuildMarker);\n } else if (rebuildMarker !== undefined) {\n const index = this.getTombstoneBlockedCaptureIndex();\n try {\n await index.discardWrite(rebuildMarker);\n } catch {\n index.markUntrusted();\n }\n }\n return archivedPath !== null;\n });\n return archived ? archivedPath : null;\n }\n\n protected async runTombstoneBlockedInvalidation(\n memory: MemoryFile,\n task: (current: MemoryFile, rebuildMarker: string | undefined, markDurable: () => void) => Promise<boolean>,\n propagateErrors = false,\n coordinate = false\n ): Promise<boolean> {\n let lockIdentities = [\n buildCapturePathLockIdentity(memory.path),\n ...(coordinate || this.isTombstoneBlockedMemory(memory) || isQueuedReviewMemory(memory)\n ? [this.offlineSyncMemoryIdentity(memory)]\n : []),\n ];\n for (;;) {\n const attempt = async () => {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const current =\n (await this.readMemoryByPath(memory.path)) ??\n (await options.readAllMemories()).find((candidate) => candidate.frontmatter.id === memory.frontmatter.id) ??\n (await options.readAllColdMemories()).find((candidate) => candidate.frontmatter.id === memory.frontmatter.id);\n if (!current) return { result: false };\n const blocked = this.isTombstoneBlockedMemory(current);\n const queuedReview = isQueuedReviewMemory(current);\n if (blocked || queuedReview) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (!lockIdentities.includes(currentIdentity)) return { retryIdentity: currentIdentity };\n }\n const blockedIndex = blocked ? this.getTombstoneBlockedCaptureIndex() : null;\n let rebuildMarker: string | undefined;\n let durable = false;\n try {\n if (blockedIndex) rebuildMarker = await blockedIndex.prepareWrite();\n const result = await task(current, rebuildMarker, () => {\n durable = true;\n });\n if (!result && rebuildMarker && !durable && blockedIndex) {\n try {\n await blockedIndex.discardWrite(rebuildMarker);\n } catch {\n blockedIndex.markUntrusted();\n }\n }\n return { result };\n } catch (error) {\n if (rebuildMarker && !durable && blockedIndex) {\n try {\n await blockedIndex.discardWrite(rebuildMarker);\n } catch {\n blockedIndex.markUntrusted();\n }\n }\n if (propagateErrors) throw error;\n return { result: false };\n }\n };\n const result = await this.withTombstoneBlockedCaptureWriteLock(attempt, lockIdentities);\n if (result.retryIdentity !== undefined) {\n lockIdentities = [...new Set([...lockIdentities, result.retryIdentity])];\n continue;\n }\n return result.result;\n }\n }\n async deleteMemoryForMaintenance(\n memory: MemoryFile,\n shouldDelete: (current: MemoryFile) => boolean = () => true\n ): Promise<MemoryFile | null> {\n let deleted: MemoryFile | null = null;\n const removed = await this.runTombstoneBlockedInvalidation(\n memory,\n async (current, rebuildMarker, markDurable) => {\n if (!shouldDelete(current)) return false;\n if (!(await this.deleteManagedStorageFile(current.path))) return false;\n markDurable();\n deleted = current;\n const memoryDir = this.tombstoneBlockedCaptureIndexOptions().memoryDir;\n markProjectedMemoryPathInvalid(memoryDir, current.frontmatter.id);\n this.invalidateAllMemoriesCache();\n if (current.path.includes(`${path.sep}cold${path.sep}`)) {\n this.invalidateColdMemoriesCache();\n }\n await this.rebuildTombstoneBlockedCaptureAfterInvalidation(rebuildMarker);\n this.bumpMemoryCorpusVersion();\n this.bumpMemoryStatusVersion();\n return true;\n },\n true,\n true\n );\n return removed ? deleted : null;\n }\n\n protected async runTombstoneBlockedOfflineSyncMutation(\n target: string,\n after: MemoryFile | null,\n write: () => Promise<void>,\n coordinate = false,\n streamedIdentity?: StreamedOfflineSyncIdentity\n ): Promise<void> {\n for (;;) {\n const before = await this.readMemoryByPath(target);\n const targetIdentity = before === null ? undefined : this.offlineSyncMemoryIdentity(before);\n const afterIdentity = after === null || streamedIdentity ? undefined : this.offlineSyncMemoryIdentity(after);\n const mustCoordinate =\n coordinate || targetIdentity !== undefined || afterIdentity !== undefined || streamedIdentity !== undefined;\n const identities = [\n ...(mustCoordinate ? [buildCapturePathLockIdentity(target)] : []),\n ...(targetIdentity === undefined ? [] : [targetIdentity]),\n ...(afterIdentity === undefined ? [] : [afterIdentity]),\n ];\n let retryIdentity: string | undefined;\n const mutate = async (): Promise<void> => {\n const current = await this.readMemoryByPath(target);\n if (current !== null) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (currentIdentity !== targetIdentity) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n if (\n this.isTombstoneBlockedMemory(after) &&\n (await this.isDuplicateTombstoneBlockedOfflineSync(target, after, streamedIdentity))\n ) {\n return;\n }\n const affectsBlockedIndex =\n coordinate || this.isTombstoneBlockedMemory(current) || this.isTombstoneBlockedMemory(after);\n const marker = affectsBlockedIndex ? await this.getTombstoneBlockedCaptureIndex().prepareWrite() : undefined;\n let durable = false;\n try {\n await write();\n durable = true;\n if (marker) {\n try {\n await this.getTombstoneBlockedCaptureIndex().commitWrite(marker);\n } catch (err) {\n this.getTombstoneBlockedCaptureIndex().markUntrusted();\n log.warn(`storage.offlineSyncFile committed write marker failed: ${err}`);\n }\n }\n await this.invalidateAfterOfflineSyncMutation(target, marker);\n } catch (err) {\n if (marker && !durable) {\n try {\n await this.getTombstoneBlockedCaptureIndex().discardWrite(marker);\n } catch (cleanupError) {\n this.getTombstoneBlockedCaptureIndex().markUntrusted();\n log.warn(`storage.offlineSyncFile failed to clear write marker: ${cleanupError}`);\n }\n }\n throw err;\n }\n };\n if (!mustCoordinate) {\n await mutate();\n } else if (streamedIdentity) {\n await this.withTombstoneBlockedCaptureWriteLockAndHashes(mutate, identities, [streamedIdentity.identityHash]);\n } else {\n await this.withTombstoneBlockedCaptureWriteLock(mutate, identities);\n }\n if (retryIdentity !== undefined) continue;\n return;\n }\n }\n\n protected async writeTombstoneBlockedOfflineSyncFile(target: string, content: Buffer): Promise<void> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const after = options.parseMemory?.(target, content) ?? null;\n await withRawEntityPageMutation(path.dirname(options.stateDir), target, async () => {\n await this.runTombstoneBlockedOfflineSyncMutation(\n target,\n after,\n () => this.writeManagedStorageFile(target, () => this.writeStorageSecureFile(target, content))\n );\n });\n }\n\n private async prepareTombstoneBlockedOfflineSyncChunks(\n target: string,\n chunks: AsyncIterable<Buffer>\n ): Promise<PreparedOfflineSyncChunks> {\n const parseMemory = this.tombstoneBlockedCaptureIndexOptions().parseMemory;\n if (!parseMemory) return { after: null, chunks };\n\n const iterator = chunks[Symbol.asyncIterator]();\n const buffered: Buffer[] = [];\n let bufferedBytes = 0;\n let firstOverflow: Buffer | undefined;\n for (;;) {\n const next = await iterator.next();\n if (next.done) break;\n if (bufferedBytes + next.value.length > OFFLINE_SYNC_BUFFER_LIMIT_BYTES) {\n firstOverflow = next.value;\n break;\n }\n bufferedBytes += next.value.length;\n buffered.push(next.value);\n }\n const overflow = firstOverflow;\n if (overflow === undefined) {\n let after: MemoryFile | null = null;\n try {\n after = parseMemory(target, Buffer.concat(buffered));\n } catch {\n after = null;\n }\n const replay = (async function* (): AsyncIterable<Buffer> {\n for (const chunk of buffered) yield chunk;\n })();\n return { after, chunks: replay };\n }\n\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const stagePath = path.join(\n options.stateDir,\n \"tombstone-blocked-capture\",\n \"offline-sync-staging\",\n `${randomUUID()}.stage`\n );\n const stagedChunks = (async function* (): AsyncIterable<Buffer> {\n for (const chunk of buffered) yield chunk;\n yield overflow;\n for (;;) {\n const next = await iterator.next();\n if (next.done) break;\n yield next.value;\n }\n })();\n try {\n await writeMaybeEncryptedFileFromChunks(\n stagePath,\n stagedChunks,\n options.secureStoreWriteKeyProvider(),\n { atomic: false },\n options.memoryDir\n );\n return await this.describeStagedOfflineSyncChunks(target, stagePath, parseMemory);\n } catch (err) {\n await unlink(stagePath).catch(() => {});\n throw err;\n }\n }\n\n private async describeStagedOfflineSyncChunks(\n target: string,\n stagePath: string,\n parseMemory: OfflineSyncMemoryParser\n ): Promise<PreparedOfflineSyncChunks> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const key = options.secureStoreKeyProvider();\n const bodyOffset = await findStagedBodyOffset(stagePath, key, options.memoryDir);\n if (bodyOffset === null) {\n return { after: null, chunks: this.readStagedOfflineSyncChunks(stagePath), stagePath };\n }\n const prefix = await readStagedPrefix(stagePath, bodyOffset, key, options.memoryDir);\n let after: MemoryFile | null = null;\n try {\n after = parseMemory(target, prefix.subarray(0, bodyOffset));\n } catch {\n after = null;\n }\n if (after === null) {\n return { after: null, chunks: this.readStagedOfflineSyncChunks(stagePath), stagePath };\n }\n const streamedIdentity = await this.computeStagedOfflineSyncIdentity(stagePath, bodyOffset, after);\n return {\n after,\n chunks: this.readStagedOfflineSyncChunks(stagePath),\n stagePath,\n streamedIdentity,\n };\n }\n\n private async computeStagedOfflineSyncIdentity(\n stagePath: string,\n bodyOffset: number,\n after: MemoryFile\n ): Promise<StreamedOfflineSyncIdentity> {\n let normalizedLength = 0;\n const countNormalizer = createExplicitContentNormalizer({\n write: (chunk) => {\n normalizedLength += chunk.length;\n },\n beginConditionalSigma: () => {\n normalizedLength += 1;\n },\n resolveConditionalSigma: () => {},\n });\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const key = options.secureStoreKeyProvider();\n await forEachStagedTextChunk(stagePath, bodyOffset, (text) => countNormalizer.push(text), key, options.memoryDir);\n countNormalizer.finish();\n\n const category = after.frontmatter.category;\n const connector = after.frontmatter.sourceConnector?.trim() ?? \"\";\n const encode = (label: string, value: string): string => `${label} ${value.length} ${value}`;\n const identityPrefix = [\n encode(\"category\", category),\n encode(\"connector\", connector),\n `content ${normalizedLength} `,\n ].join(\" \");\n let identityHash = createHash(\"sha256\");\n let normalSigmaIdentityHash: Hash | undefined;\n identityHash.update(identityPrefix);\n const identityNormalizer = createExplicitContentNormalizer({\n write: (chunk) => {\n identityHash.update(chunk);\n normalSigmaIdentityHash?.update(chunk);\n },\n beginConditionalSigma: () => {\n normalSigmaIdentityHash = identityHash.copy().update(\"σ\");\n identityHash.update(\"ς\");\n },\n resolveConditionalSigma: (useFinalSigma) => {\n if (!useFinalSigma) {\n if (normalSigmaIdentityHash === undefined) throw new Error(\"conditional sigma hash state is missing\");\n identityHash = normalSigmaIdentityHash;\n }\n normalSigmaIdentityHash = undefined;\n },\n });\n await forEachStagedTextChunk(\n stagePath,\n bodyOffset,\n (text) => identityNormalizer.push(text),\n key,\n options.memoryDir\n );\n identityNormalizer.finish();\n return {\n identityHash: identityHash.digest(\"hex\"),\n };\n }\n\n private async *readStagedOfflineSyncChunks(stagePath: string): AsyncIterable<Buffer> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n for await (const chunk of readMaybeEncryptedFileFromChunks(\n stagePath,\n options.secureStoreKeyProvider(),\n options.memoryDir\n )) {\n yield chunk;\n }\n }\n\n protected async writeTombstoneBlockedOfflineSyncFileChunks(\n target: string,\n chunks: AsyncIterable<Buffer>\n ): Promise<void> {\n const coordinate = this.getTombstoneBlockedCaptureIndex().shouldRebuildAfterInvalidationForPath(target);\n const prepared: PreparedOfflineSyncChunks = coordinate\n ? await this.prepareTombstoneBlockedOfflineSyncChunks(target, chunks)\n : { after: null, chunks };\n const streamedIdentity = prepared.streamedIdentity;\n const baseDir = path.dirname(this.tombstoneBlockedCaptureIndexOptions().stateDir);\n try {\n await withRawEntityPageMutation(baseDir, target, async () => {\n await this.runTombstoneBlockedOfflineSyncMutation(\n target,\n prepared.after,\n () => this.writeManagedStorageFile(target, () => this.writeStorageSecureFileChunks(target, prepared.chunks)),\n coordinate,\n streamedIdentity\n );\n });\n } finally {\n if (prepared.stagePath !== undefined) await unlink(prepared.stagePath).catch(() => {});\n }\n }\n\n async writeOfflineSyncFile(filePath: string, content: Buffer): Promise<void> {\n const target = this.assertManagedStoragePath(filePath, \"storage.writeOfflineSyncFile\");\n await this.writeTombstoneBlockedOfflineSyncFile(target, content);\n await this.requestSyncReconcileIfMigrationPath(target);\n }\n\n async writeOfflineSyncFileChunks(filePath: string, chunks: AsyncIterable<Buffer>): Promise<void> {\n const target = this.assertManagedStoragePath(filePath, \"storage.writeOfflineSyncFileChunks\");\n await this.writeTombstoneBlockedOfflineSyncFileChunks(target, chunks);\n await this.requestSyncReconcileIfMigrationPath(target);\n }\n\n /**\n * Opaque replicated bytes can restore legacy memory references or entity\n * relationship targets. Other sync traffic must not request reconciliation.\n */\n private async requestSyncReconcileIfMigrationPath(target: string): Promise<void> {\n const stateDir = this.tombstoneBlockedCaptureIndexOptions().stateDir;\n if (!pathMayCarryEntityRefs(path.dirname(stateDir), target)) return;\n await requestEntityCanonicalIdReconcile(stateDir);\n }\n\n async deleteOfflineSyncFile(filePath: string, deletionMtimeMs?: number | null): Promise<void> {\n const target = this.assertManagedStoragePath(filePath, \"storage.deleteOfflineSyncFile\");\n await this.deleteTombstoneBlockedOfflineSyncFile(target, deletionMtimeMs);\n await this.requestSyncReconcileIfMigrationPath(target);\n }\n\n protected async deleteTombstoneBlockedOfflineSyncFile(\n target: string,\n deletionMtimeMs?: number | null\n ): Promise<void> {\n const stateDir = this.tombstoneBlockedCaptureIndexOptions().stateDir;\n await withRawEntityPageMutation(path.dirname(stateDir), target, async () => {\n await this.runTombstoneBlockedOfflineSyncMutation(target, null, async () => {\n await this.deleteManagedStorageFile(target, deletionMtimeMs);\n });\n });\n }\n\n async checkTombstoneBlockedExplicitCapture(\n ...args: [string, string, string?]\n ): Promise<{ has: boolean; authoritative: boolean }> {\n return this.getTombstoneBlockedCaptureIndex().check(...args);\n }\n\n async hasTombstoneBlockedExplicitCapture(...args: [string, string, string?]): Promise<boolean> {\n return this.getTombstoneBlockedCaptureIndex().has(...args);\n }\n\n async isTombstoneBlockedExplicitCaptureIndexAuthoritative(): Promise<boolean> {\n return this.getTombstoneBlockedCaptureIndex().isAuthoritative();\n }\n\n protected async rebuildTombstoneBlockedCaptureAfterInvalidationForPath(\n filePath: string,\n ownedMarker?: string\n ): Promise<void> {\n const index = this.getTombstoneBlockedCaptureIndex();\n if (index.shouldRebuildAfterInvalidationForPath(filePath)) {\n await this.rebuildTombstoneBlockedCaptureAfterInvalidation(ownedMarker);\n }\n }\n protected async rebuildTombstoneBlockedCaptureAfterInvalidation(ownedMarker?: string): Promise<void> {\n await this.getTombstoneBlockedCaptureIndex().rebuildAfterInvalidation(ownedMarker);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, readdir, rename, stat, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { log } from \"../logger.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nimport { RECALL_FALLBACK_DIRS } from \"../utils/category-dir.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport { withHeldFileLock } from \"../utils/serialize-mutations.js\";\nimport {\n CONTENT_HASH_INDEX_RETRY_MAX_DELAY_MS,\n ContentHashIndex,\n type ContentHashIndexLockOptions,\n} from \"./content-hash-index.js\";\nimport {\n buildExplicitCaptureDedupKey,\n TombstoneBlockedCaptureWriteLock,\n} from \"./tombstone-blocked-capture-mutation.js\";\nimport type { OfflineSyncMemoryParser } from \"./tombstone-blocked-capture-sync.js\";\nexport {\n buildExplicitCaptureDedupKey,\n isTombstoneBlockedCaptureWriteLockBusy,\n normalizeExplicitCaptureContent,\n} from \"./tombstone-blocked-capture-mutation.js\";\nexport {\n parseTombstoneBlockedOfflineSyncMemory,\n type OfflineSyncMemoryParser,\n TombstoneBlockedCaptureIndexHost,\n} from \"./tombstone-blocked-capture-sync.js\";\n\nconst REBUILD_MAX_ATTEMPTS = 3;\nconst execFileAsync = promisify(execFile);\nconst REBUILD_RETRY_BASE_MS = 50;\n\nconst ABANDONED_MARKER_MIN_AGE_MS = 60_000;\nconst MARKER_PROCESS_START_TOLERANCE_MS = 2_000;\nconst DOTNET_UNIX_EPOCH_TICKS = 621_355_968_000_000_000;\nconst MARKER_PROCESS_STARTED_AT_MS = Date.now() - process.uptime() * 1000;\n\n\ntype RebuildMarker = {\n path: string;\n committed: boolean;\n pid?: number;\n ownerId?: string;\n createdAt?: number;\n processStartedAtMs?: number;\n malformed?: boolean;\n};\n\n\nexport type TombstoneBlockedCaptureIndexOptions = {\n readonly stateDir: string;\n readonly memoryDir: string;\n readonly secureStoreKeyProvider: () => Buffer | null;\n readonly secureStoreWriteKeyProvider: () => Buffer | null;\n readonly lockOptions: () => ContentHashIndexLockOptions;\n readonly readAllMemories: () => Promise<MemoryFile[]>;\n readonly readAllColdMemories: () => Promise<MemoryFile[]>;\n readonly parseMemory?: OfflineSyncMemoryParser;\n readonly withHeldFileLock?: typeof withHeldFileLock;\n};\n\n/**\n * Durable targeted deduplication for tombstone-blocked explicit captures.\n *\n * The active fact-hash index intentionally excludes blocked rows. This small\n * companion index keeps the blocked identity visible without making every\n * authoritative active-index miss scan the full corpus.\n */\nexport class TombstoneBlockedCaptureIndex {\n private readonly options: TombstoneBlockedCaptureIndexOptions;\n private index: ContentHashIndex | null = null;\n private loadPromise: Promise<ContentHashIndex> | null = null;\n private refreshPromise: Promise<ContentHashIndex> | null = null;\n private authoritative = false;\n private readonly captureWriteLock: TombstoneBlockedCaptureWriteLock;\n\n constructor(options: TombstoneBlockedCaptureIndexOptions) {\n this.options = options;\n this.captureWriteLock = new TombstoneBlockedCaptureWriteLock(options);\n }\n\n private createIndex(): ContentHashIndex {\n return new ContentHashIndex(\n path.join(this.options.stateDir, \"tombstone-blocked-capture\"),\n this.options.secureStoreKeyProvider,\n this.options.secureStoreWriteKeyProvider,\n this.options.memoryDir,\n this.options.lockOptions()\n );\n }\n\n private indexPath(): string {\n return path.join(this.options.stateDir, \"tombstone-blocked-capture\", \"fact-hashes.txt\");\n }\n\n private rebuildMarkerPath(): string {\n return path.join(this.options.stateDir, \"tombstone-blocked-capture\", \"rebuild-required\");\n }\n\n private async readRebuildMarkers(): Promise<RebuildMarker[]> {\n try {\n const entries = (await readdir(this.rebuildMarkerPath())).filter((entry) => !entry.startsWith(\".\"));\n return (\n await Promise.all(\n entries.map(async (entry) => {\n const markerPath = path.join(this.rebuildMarkerPath(), entry);\n try {\n const raw = (await readFile(markerPath, \"utf8\")).trim();\n if (raw === \"committed\") return { path: markerPath, committed: true };\n let value: Record<string, unknown>;\n let malformed = false;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n malformed = true;\n value = {};\n } else {\n value = parsed as Record<string, unknown>;\n }\n } catch {\n malformed = true;\n value = {};\n }\n const state = value.state;\n if (state !== \"pending\" && state !== \"committed\") malformed = true;\n const markerStat = await stat(markerPath).catch(() => null);\n // A torn payload can lose its JSON metadata, but the atomic\n // marker filename and filesystem mtime still identify its owner\n // and age. Preserve both so stale malformed markers can be\n // reaped without treating a fresh pre-commit gap as abandoned.\n const createdAt =\n typeof value.createdAt === \"number\" && Number.isFinite(value.createdAt)\n ? value.createdAt\n : markerStat?.mtimeMs;\n if (typeof value.pid !== \"number\" || !Number.isInteger(value.pid)) malformed = true;\n const ownerId =\n typeof value.ownerId === \"string\" && value.ownerId.length > 0\n ? value.ownerId\n : path.basename(markerPath);\n if (typeof value.ownerId !== \"string\" || value.ownerId.length === 0) malformed = true;\n const processStartedAtMs =\n typeof value.processStartedAtMs === \"number\" &&\n Number.isFinite(value.processStartedAtMs) &&\n value.processStartedAtMs > 0\n ? value.processStartedAtMs\n : undefined;\n return {\n path: markerPath,\n committed: state === \"committed\",\n ...(typeof value.pid === \"number\" && Number.isInteger(value.pid) ? { pid: value.pid } : {}),\n ...(ownerId.length > 0 ? { ownerId } : {}),\n ...(typeof createdAt === \"number\" && Number.isFinite(createdAt) ? { createdAt } : {}),\n ...(processStartedAtMs === undefined ? {} : { processStartedAtMs }),\n ...(malformed ? { malformed: true } : {}),\n };\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return null;\n throw err;\n }\n })\n )\n ).filter((marker): marker is RebuildMarker => marker !== null);\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return [];\n throw err;\n }\n }\n private async isAbandonedMarker(marker: RebuildMarker): Promise<boolean> {\n if (marker.committed || marker.createdAt === undefined) return false;\n if (Date.now() - marker.createdAt < ABANDONED_MARKER_MIN_AGE_MS) return false;\n if (marker.malformed) return true;\n return marker.pid !== undefined && !(await this.isProcessAlive(marker.pid, marker.processStartedAtMs));\n }\n\n private async isProcessAlive(pid: number, processStartedAtMs?: number): Promise<boolean> {\n try {\n process.kill(pid, 0);\n } catch (err) {\n return !isErrnoCode(err, \"ESRCH\");\n }\n if (processStartedAtMs === undefined) return true;\n const runningStartedAtMs = await this.readProcessStartedAtMs(pid);\n if (runningStartedAtMs === null) return true;\n return runningStartedAtMs <= processStartedAtMs + MARKER_PROCESS_START_TOLERANCE_MS;\n }\n private async readProcessStartedAtMs(pid: number): Promise<number | null> {\n try {\n if (process.platform === \"win32\") {\n const { stdout } = await execFileAsync(\n \"powershell.exe\",\n [\n \"-NoLogo\",\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-Command\",\n `(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().Ticks`,\n ],\n { encoding: \"utf8\", timeout: 1_000 }\n );\n const ticks = Number(stdout.trim());\n return Number.isFinite(ticks) ? (ticks - DOTNET_UNIX_EPOCH_TICKS) / 10_000 : null;\n }\n const { stdout } = await execFileAsync(\"ps\", [\"-p\", String(pid), \"-o\", \"lstart=\"], {\n encoding: \"utf8\",\n timeout: 1_000,\n });\n const output = stdout.trim();\n if (!output) return null;\n const startedAtMs = Date.parse(output);\n return Number.isFinite(startedAtMs) ? startedAtMs : null;\n } catch {\n return null;\n }\n }\n\n private async getClearableRebuildMarkerPaths(markers: readonly RebuildMarker[]): Promise<string[]> {\n const paths = await Promise.all(\n markers.map(async (marker) => (marker.committed || (await this.isAbandonedMarker(marker)) ? marker.path : null))\n );\n return paths.filter((markerPath): markerPath is string => markerPath !== null);\n }\n\n private async getRebuildMarkers(): Promise<RebuildMarker[]> {\n return await this.readRebuildMarkers();\n }\n\n // A pending marker protects the pre-commit gap; only committed markers are safe for another writer to clear.\n private async writeMarkerAtomically(markerPath: string, payload: string): Promise<void> {\n const temporaryPath = `${markerPath}.tmp-${process.pid}-${randomUUID()}`;\n try {\n await writeFile(temporaryPath, payload, \"utf8\");\n await rename(temporaryPath, markerPath);\n } finally {\n await unlink(temporaryPath).catch((err: unknown) => {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n });\n }\n }\n\n private async markRebuildRequired(committed = false): Promise<string> {\n const markerDir = this.rebuildMarkerPath();\n await mkdir(markerDir, { recursive: true });\n const ownerId = randomUUID();\n const markerPath = path.join(markerDir, ownerId);\n await this.writeMarkerAtomically(\n markerPath,\n `${JSON.stringify({\n state: committed ? \"committed\" : \"pending\",\n pid: process.pid,\n ownerId,\n createdAt: Date.now(),\n processStartedAtMs: MARKER_PROCESS_STARTED_AT_MS,\n })}\\n`\n );\n return markerPath;\n }\n\n private async markRebuildCommitted(markerPath: string): Promise<void> {\n await this.writeMarkerAtomically(\n markerPath,\n `${JSON.stringify({\n state: \"committed\",\n pid: process.pid,\n ownerId: path.basename(markerPath),\n createdAt: Date.now(),\n processStartedAtMs: MARKER_PROCESS_STARTED_AT_MS,\n })}\\n`\n );\n }\n\n private async clearRebuildRequired(markerPaths: readonly string[]): Promise<void> {\n await Promise.all(\n markerPaths.map(async (markerPath) => {\n try {\n await unlink(markerPath);\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n }\n })\n );\n }\n\n private async hasRebuildRequired(excludedMarkers: readonly string[] = []): Promise<boolean> {\n const excluded = new Set(excludedMarkers);\n return (await this.getRebuildMarkers()).some((marker) => !excluded.has(marker.path));\n }\n\n private async setAuthoritative(rebuilt: boolean): Promise<void> {\n this.authoritative = rebuilt && !(await this.getRebuildMarkers()).some((marker) => !marker.committed);\n }\n private isBlocked(memory: MemoryFile): boolean {\n return memory.frontmatter.status === \"pending_review\" && Boolean(memory.frontmatter.blockedBy);\n }\n\n private async rebuild(index: ContentHashIndex): Promise<boolean> {\n return await index.rebuildUnderLock(async () => {\n index.clear();\n const existing = [...(await this.options.readAllMemories()), ...(await this.options.readAllColdMemories())];\n for (const memory of existing) {\n if (!this.isBlocked(memory)) continue;\n index.add(\n buildExplicitCaptureDedupKey(memory.content, memory.frontmatter.category, memory.frontmatter.sourceConnector)\n );\n }\n });\n }\n\n private async hasPersistedIndexOrMarkers(): Promise<boolean> {\n try {\n await stat(this.indexPath());\n return true;\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return (await this.readRebuildMarkers()).length > 0;\n }\n }\n\n private async getIndex(): Promise<ContentHashIndex> {\n if (this.index) return this.index;\n if (!this.loadPromise) {\n const index = this.createIndex();\n this.loadPromise = (async () => {\n await index.load();\n const rebuildMarkers = await this.getRebuildMarkers();\n const clearableRebuildMarkers = await this.getClearableRebuildMarkerPaths(rebuildMarkers);\n let persisted = true;\n try {\n await stat(this.indexPath());\n if (rebuildMarkers.length > 0) persisted = false;\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) persisted = false;\n else throw err;\n }\n if (!persisted) {\n const lockOptions = this.options.lockOptions();\n const maxAttempts = lockOptions.retryMaxAttempts ?? REBUILD_MAX_ATTEMPTS;\n const baseMs = lockOptions.retryBaseMs ?? REBUILD_RETRY_BASE_MS;\n let rebuilt = false;\n for (let attempt = 0; attempt < maxAttempts; attempt += 1) {\n rebuilt = await this.rebuild(index);\n if (rebuilt || attempt === maxAttempts - 1) break;\n const wait = Math.min(baseMs * 2 ** attempt, CONTENT_HASH_INDEX_RETRY_MAX_DELAY_MS);\n const delayState = Promise.withResolvers<void>();\n setTimeout(delayState.resolve, wait);\n await delayState.promise;\n }\n if (!rebuilt) {\n throw new Error(\"tombstone-blocked capture index rebuild lock unavailable\");\n }\n await this.clearRebuildRequired(clearableRebuildMarkers);\n }\n await this.setAuthoritative(true);\n this.index = index;\n return index;\n })().catch((err) => {\n this.loadPromise = null;\n throw err;\n });\n }\n return this.loadPromise;\n }\n\n async withCaptureWriteLock<T>(task: () => Promise<T>, identity?: string | readonly string[]): Promise<T> {\n return await this.captureWriteLock.withCaptureWriteLock(task, identity);\n }\n\n async withCaptureWriteLockHashes<T>(task: () => Promise<T>, identityHashes: readonly string[]): Promise<T> {\n return await this.captureWriteLock.withCaptureWriteLockHashes(task, identityHashes);\n }\n async withCaptureWriteLockAndHashes<T>(\n task: () => Promise<T>,\n identity: string | readonly string[] | undefined,\n identityHashes: readonly string[]\n ): Promise<T> {\n return await this.captureWriteLock.withCaptureWriteLockAndHashes(task, identity, identityHashes);\n }\n\n private async reload(): Promise<ContentHashIndex> {\n if (!this.refreshPromise) {\n this.refreshPromise = (async () => {\n this.index = null;\n this.loadPromise = null;\n return await this.getIndex();\n })().finally(() => {\n this.refreshPromise = null;\n });\n }\n return this.refreshPromise;\n }\n\n /** Return blocked-row membership and authority from one index snapshot. */\n async check(\n content: string,\n category: string,\n sourceConnector?: string\n ): Promise<{ has: boolean; authoritative: boolean }> {\n const key = buildExplicitCaptureDedupKey(content, category, sourceConnector);\n let index = await this.getIndex();\n if ((await this.hasRebuildRequired()) || !(await index.isDiskFingerprintCurrent())) {\n index = await this.reload();\n }\n return { has: index.has(key), authoritative: this.authoritative };\n }\n\n /** Return whether a blocked row matches this explicit-capture identity. */\n async has(content: string, category: string, sourceConnector?: string): Promise<boolean> {\n return (await this.check(content, category, sourceConnector)).has;\n }\n\n /** Return whether the in-memory index is safe to answer an authoritative miss. */\n async isAuthoritative(): Promise<boolean> {\n const index = await this.getIndex();\n if ((await this.hasRebuildRequired()) || !(await index.isDiskFingerprintCurrent())) {\n await this.reload();\n }\n return this.authoritative;\n }\n\n /** Reserve durable rebuild intent before a blocked memory file is committed. */\n async prepareWrite(): Promise<string> {\n return this.markRebuildRequired();\n }\n\n /** Mark a prepared write committed once its memory file is durable. */\n async commitWrite(rebuildMarker: string): Promise<void> {\n await this.markRebuildCommitted(rebuildMarker);\n }\n\n /** Drop a pending marker when the protected memory write never commits. */\n async discardWrite(rebuildMarker: string): Promise<void> {\n await this.clearRebuildRequired([rebuildMarker]);\n }\n\n /** Add a newly persisted blocked row to the durable targeted index. */\n async add(memory: MemoryFile, rebuildMarker?: string): Promise<void> {\n if (!this.isBlocked(memory)) return;\n let index = await this.getIndex();\n if (\n (await this.hasRebuildRequired(rebuildMarker ? [rebuildMarker] : [])) ||\n !(await index.isDiskFingerprintCurrent())\n ) {\n index = await this.reload();\n }\n index.add(\n buildExplicitCaptureDedupKey(memory.content, memory.frontmatter.category, memory.frontmatter.sourceConnector)\n );\n const marker = rebuildMarker ?? (await this.markRebuildRequired(true));\n if (rebuildMarker) await this.markRebuildCommitted(rebuildMarker);\n await index.saveMergingWithDisk();\n await index.flushReconcileRetry();\n if (index.hasPendingChanges) {\n this.markUntrusted();\n return;\n }\n await this.clearRebuildRequired([marker]);\n await this.setAuthoritative(true);\n }\n\n /** Rebuild the index after a blocked row changes or is removed. */\n async rebuildIfLoaded(ownedMarker?: string): Promise<void> {\n const index = this.index ?? ((await this.hasPersistedIndexOrMarkers()) ? this.getIndex() : null);\n if (!index) return;\n const rebuildMarkers = await this.getRebuildMarkers();\n const rebuildMarker = await this.markRebuildRequired(true);\n const clearableRebuildMarkers = await this.getClearableRebuildMarkerPaths(rebuildMarkers);\n const rebuilt = await this.rebuild(await index);\n if (rebuilt) {\n await this.clearRebuildRequired([\n ...clearableRebuildMarkers,\n ...(ownedMarker === undefined || clearableRebuildMarkers.includes(ownedMarker) ? [] : [ownedMarker]),\n rebuildMarker,\n ]);\n }\n await this.setAuthoritative(rebuilt);\n }\n\n /** Rebuild when either side of a write is blocked and its identity changed. */\n async sync(before: MemoryFile, after: MemoryFile, rebuildMarker?: string): Promise<void> {\n const beforeBlocked = this.isBlocked(before);\n const afterBlocked = this.isBlocked(after);\n if (!beforeBlocked && !afterBlocked) return;\n const beforeKey = buildExplicitCaptureDedupKey(\n before.content,\n before.frontmatter.category,\n before.frontmatter.sourceConnector\n );\n const afterKey = buildExplicitCaptureDedupKey(\n after.content,\n after.frontmatter.category,\n after.frontmatter.sourceConnector\n );\n if (beforeBlocked && afterBlocked && beforeKey === afterKey) {\n if (rebuildMarker) {\n await this.markRebuildCommitted(rebuildMarker);\n await this.clearRebuildRequired([rebuildMarker]);\n }\n return;\n }\n const existingMarkers = await this.getRebuildMarkers();\n const marker = rebuildMarker ?? (await this.markRebuildRequired(true));\n const clearableExistingMarkers = await this.getClearableRebuildMarkerPaths(existingMarkers);\n if (rebuildMarker) await this.markRebuildCommitted(rebuildMarker);\n const rebuilt = await this.rebuild(await this.getIndex());\n if (rebuilt) {\n await this.clearRebuildRequired([\n ...clearableExistingMarkers,\n marker,\n ]);\n }\n await this.setAuthoritative(rebuilt);\n }\n markUntrusted(): void {\n this.authoritative = false;\n }\n\n private async failOpen(operation: string, action: () => Promise<void>): Promise<void> {\n try {\n await action();\n } catch (err) {\n this.markUntrusted();\n log.warn(`storage.${operation} completed but failed to update tombstone-blocked capture index: ${err}`);\n }\n }\n\n async addWrittenMemory(\n pathname: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n rebuildMarker?: string\n ): Promise<void> {\n await this.failOpen(\"writeMemory\", () => this.add({ path: pathname, frontmatter, content }, rebuildMarker));\n }\n\n async rebuildAfterInvalidation(ownedMarker?: string): Promise<void> {\n await this.failOpen(\"invalidateMemory\", () => this.rebuildIfLoaded(ownedMarker));\n }\n\n async syncUpdatedMemory(\n before: MemoryFile,\n frontmatter: MemoryFrontmatter,\n content: string,\n rebuildMarker?: string\n ): Promise<void> {\n await this.failOpen(\"updateMemory\", () => this.sync(before, { ...before, frontmatter, content }, rebuildMarker));\n }\n\n async syncUpdatedFrontmatter(\n before: MemoryFile,\n frontmatter: MemoryFrontmatter,\n rebuildMarker?: string\n ): Promise<void> {\n await this.failOpen(\"writeMemoryFrontmatter\", () => this.sync(before, { ...before, frontmatter }, rebuildMarker));\n }\n shouldRebuildAfterInvalidationForPath(filePath: string): boolean {\n const relative = path.relative(path.resolve(this.options.memoryDir), path.resolve(filePath));\n const category = relative.split(path.sep)[0];\n return category === \"cold\" || RECALL_FALLBACK_DIRS.includes(category);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB,OAAO,UAAU;AAGjB,IAAM,wCAAwC;AAC9C,IAAM,kCAAkC;AACxC,IAAM,mCAAmC;AACzC,IAAM,kCAAkC;AAEjC,SAAS,uCAAuC,OAAyB;AAC9E,SAAO,iBAAiB,SAAS,MAAM,YAAY;AACrD;AAEO,SAAS,gCAAgC,OAAuB;AACrE,SAAO,MAAM,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACvD;AAEO,SAAS,6BACd,SACA,UACA,iBACQ;AACR,QAAM,SAAS,CAAC,OAAe,UAA0B,GAAG,KAAK,IAAI,MAAM,MAAM,IAAI,KAAK;AAC1F,SAAO;AAAA,IACL,OAAO,YAAY,QAAQ;AAAA,IAC3B,OAAO,aAAa,iBAAiB,KAAK,KAAK,EAAE;AAAA,IACjD,OAAO,WAAW,gCAAgC,OAAO,CAAC;AAAA,EAC5D,EAAE,KAAK,GAAG;AACZ;AAEO,SAAS,6BAA6B,UAA0B;AACrE,SAAO,QAAQ,SAAS,MAAM,IAAI,QAAQ;AAC5C;AAEO,SAAS,oBAAoB,QAA4B;AAC9D,SAAO,WAAW,QAAQ,EACvB;AAAA,IACC,6BAA6B,OAAO,SAAS,OAAO,YAAY,UAAU,OAAO,YAAY,eAAe;AAAA,EAC9G,EACC,OAAO,KAAK;AACjB;AAOO,IAAM,mCAAN,MAAuC;AAAA,EAG5C,YAA6B,SAAkD;AAAlD;AAAA,EAAmD;AAAA,EAAnD;AAAA,EAFZ,UAAU,IAAI,kBAAuC;AAAA,EAI9D,4BAA4B,cAA8B;AAChE,UAAM,WACJ,aAAa,WAAW,IAAI,gCAAgC,0BAA0B,YAAY;AACpG,WAAO,KAAK,KAAK,KAAK,QAAQ,UAAU,6BAA6B,QAAQ;AAAA,EAC/E;AAAA,EAEA,MAAc,2BAA8B,UAAkB,MAAoC;AAChG,UAAM,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,UAAM,QAAQ,uBAAO,OAAO;AAC5B,UAAM,mBAAmB,uBAAO,mBAAmB;AACnD,UAAM,sBAAsB,KAAK,QAAQ,oBAAoB;AAC7D,aAAS,UAAU,GAAG,UAAU,iCAAiC,WAAW,GAAG;AAC7E,YAAM,SAAS,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,UACE,SAAS;AAAA,UACT,WAAW;AAAA,UACX,QAAQ;AAAA,QACV;AAAA,QACA,OAAO,UAAU,eAAe;AAC9B,cAAI,SAAU,QAAO,MAAM,KAAK;AAChC,iBAAO,WAAW,YAAY,UAAU,mBAAmB;AAAA,QAC7D;AAAA,MACF;AACA,UAAI,WAAW,kBAAkB;AAC/B,cAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AACA,UAAI,WAAW,MAAO,QAAO;AAC7B,UAAI,YAAY,kCAAkC,EAAG;AACrD,YAAM,aAAa,QAAQ,cAAoB;AAC/C,iBAAW,WAAW,SAAS,mCAAmC,KAAK,OAAO;AAC9E,YAAM,WAAW;AAAA,IACnB;AACA,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACjD;AAAA,EACA,MAAc,8BACZ,MACA,gBACY;AACZ,UAAM,YAAY,CAAC,GAAG,IAAI,IAAI,eAAe,IAAI,CAAC,SAAS,KAAK,4BAA4B,IAAI,CAAC,CAAC,CAAC;AACnG,UAAM,UAAU,OAAO,UAA8B;AACnD,UAAI,UAAU,UAAU,OAAQ,QAAO,MAAM,KAAK;AAClD,aAAO,MAAM,KAAK,2BAA2B,UAAU,KAAK,GAAG,MAAM,QAAQ,QAAQ,CAAC,CAAC;AAAA,IACzF;AACA,WAAO,MAAM,QAAQ,CAAC;AAAA,EACxB;AAAA,EAEA,MAAM,qBAAwB,MAAwB,UAAmD;AACvG,UAAM,aACJ,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,IAAI,WAAW,CAAC,OAAO,aAAa,WAAW,WAAW,EAAE;AAC3G,WAAO,MAAM,KAAK,sBAAsB,MAAM,YAAY,CAAC,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,2BAA8B,MAAwB,gBAA+C;AACzG,WAAO,MAAM,KAAK,sBAAsB,MAAM,CAAC,GAAG,cAAc;AAAA,EAClE;AAAA,EAEA,MAAM,8BACJ,MACA,UACA,gBACY;AACZ,UAAM,aACJ,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,IAAI,WAAW,CAAC,OAAO,aAAa,WAAW,WAAW,EAAE;AAC3G,WAAO,MAAM,KAAK,sBAAsB,MAAM,YAAY,cAAc;AAAA,EAC1E;AAAA,EAEA,MAAc,sBACZ,MACA,YACA,gBACY;AACZ,UAAM,UAAU,KAAK,QAAQ,SAAS;AACtC,UAAM,YAAY,CAAC,QACjB,KAAS,IAAI,WAAW,IAAI,KAAK,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,KAAK,CAAC;AACjF,UAAM,eAAe,CAAC,QACpB,IAAI,WAAW,IAAI,KAAK,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,KAAK;AACvE,UAAM,eAAe,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC;AAC5C,UAAM,SAAS,CAAC,GAAG,IAAI,IAAI,cAAc,CAAC;AAC1C,UAAM,YAAY;AAAA,MAChB,GAAG,aACA,OAAO,CAAC,QAAQ,CAAC,WAAY,CAAC,QAAQ,IAAI,GAAG,KAAK,CAAC,QAAQ,IAAI,UAAU,GAAG,CAAC,CAAE,EAC/E,IAAI,CAAC,SAAS,EAAE,MAAM,aAAa,GAAG,GAAG,UAAU,IAAI,WAAW,OAAO,EAAE,EAAE;AAAA,MAChF,GAAG,OAAO,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,IAAI,KAAS,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,UAAU,MAAM,EAAE;AAAA,IACjH,EACG,OAAO,CAAC,OAAO,OAAO,YAAY,QAAQ,UAAU,CAAC,cAAc,UAAU,SAAS,MAAM,IAAI,MAAM,KAAK,EAC3G;AAAA,MACC,CAAC,MAAM,UACL,OAAO,KAAK,QAAQ,IAAI,OAAO,MAAM,QAAQ,KAC7C,KAAK,4BAA4B,KAAK,IAAI,EAAE,cAAc,KAAK,4BAA4B,MAAM,IAAI,CAAC;AAAA,IAC1G;AACF,UAAM,kBAAkB,UAAU,IAAI,CAAC,UAAU,MAAM,IAAI;AAC3D,QAAI,WAAW,UAAU,SAAS,GAAG;AACnC,YAAM,OAAO,CAAC,GAAG,OAAO,EACrB,OAAO,CAAC,UAAU,MAAM,WAAW,IAAQ,CAAC,EAC5C,IAAI,CAAC,UAAU;AACd,cAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,cAAM,WAAW,CAAC,GAAG,OAAO,EAAE;AAAA,UAC5B,CAAC,QAAQ,CAAC,IAAI,WAAW,IAAQ,KAAK,IAAI,WAAW,OAAO,KAAK,UAAU,GAAG,MAAM;AAAA,QACtF;AACA,eAAO,EAAE,MAAM,SAAS;AAAA,MAC1B,CAAC;AACH,YAAM,iBAAiB,UAAU,CAAC;AAClC,YAAM,WAAW,KACd;AAAA,QACC,CAAC,MAAM,UACL,OAAO,KAAK,QAAQ,IAAI,OAAO,MAAM,QAAQ,KAC7C,KAAK,4BAA4B,KAAK,IAAI,EAAE,cAAc,KAAK,4BAA4B,MAAM,IAAI,CAAC;AAAA,MAC1G,EACC,GAAG,EAAE;AACR,UACE,YACA,mBACC,OAAO,eAAe,QAAQ,IAAI,OAAO,SAAS,QAAQ,KACxD,eAAe,aAAa,SAAS,YACpC,KAAK,4BAA4B,eAAe,IAAI,IAAI,KAAK,4BAA4B,SAAS,IAAI,IAC1G;AACA,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AAAA,IACF;AACA,UAAM,OAAO,IAAI,IAAI,OAAO;AAC5B,eAAW,OAAO,cAAc;AAC9B,WAAK,IAAI,GAAG;AACZ,WAAK,IAAI,UAAU,GAAG,CAAC;AAAA,IACzB;AACA,eAAW,QAAQ,OAAQ,MAAK,IAAI,KAAS,IAAI,EAAE;AACnD,UAAM,MAAM,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI;AAC7C,QAAI,gBAAgB,WAAW,EAAG,QAAO,MAAM,IAAI;AACnD,WAAO,MAAM,KAAK,8BAA8B,KAAK,eAAe;AAAA,EACtE;AACF;AA0BA,eAAsB,4BACpB,MACA,UACe;AACf,MAAI,eAA2C,SAAS;AACxD,aAAS;AACP,QAAI;AACJ,UAAM,SAAS,YAA2B;AACxC,YAAM,UAAU,MAAM,KAAK,YAAY;AACvC,YAAM,iBAAiB,KAAK,UAAU,OAAO;AAC7C,YAAM,sBAAsB,KAAK,eAAe,OAAO;AACvD,UAAI,YAAY,SAAS,SAAS,eAAe,QAAQ,kBAAkB,sBAAsB;AAC/F,cAAM,kBAAkB,KAAK,eAAe,OAAO;AACnD,cAAM,iBAAiB,MAAM,QAAQ,YAAY,IAAI,eAAe,CAAC,YAAY;AACjF,YAAI,CAAC,eAAe,SAAS,eAAe,GAAG;AAC7C,0BAAgB;AAChB;AAAA,QACF;AAAA,MACF;AACA,YAAM,gBAAgB,SAAS,WAAW,iBAAiB,MAAM,KAAK,aAAa,IAAI;AACvF,UAAI;AACF,cAAM,KAAK,uBAAuB,SAAS,UAAU,SAAS,WAAW;AAAA,MAC3E,SAAS,KAAK;AACZ,YAAI,eAAe;AACjB,cAAI;AACF,kBAAM,KAAK,aAAa,aAAa;AAAA,UACvC,SAAS,cAAc;AACrB,iBAAK,cAAc;AACnB,iBAAK,WAAW,0DAA0D,YAAY,EAAE;AAAA,UAC1F;AAAA,QACF;AACA,cAAM;AAAA,MACR;AACA,UAAI,eAAe;AACjB,YAAI;AACF,gBAAM,KAAK,YAAY,aAAa;AAAA,QACtC,SAAS,KAAK;AACZ,eAAK,cAAc;AACnB,eAAK,WAAW,2DAA2D,GAAG,EAAE;AAAA,QAClF;AAAA,MACF;AACA,UAAI,cAAe,OAAM,SAAS,oBAAoB;AACtD,YAAM,SAAS,YAAY,eAAe,kBAAkB,YAAY,OAAO,UAAU,MAAS;AAAA,IACpG;AACA,UAAM,KAAK,qBAAqB,QAAQ,YAAY;AACpD,QAAI,kBAAkB,OAAW;AACjC,UAAM,aAAa,MAAM,QAAQ,YAAY,IAAI,CAAC,GAAG,cAAc,aAAa,IAAI,CAAC,cAAc,aAAa;AAChH,mBAAe,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC;AAAA,EACxC;AACF;AAEO,SAAS,iBAAiB,aAAyC;AACxE,SAAO,YAAY,WAAW,oBAAoB,QAAQ,YAAY,SAAS;AACjF;AAEO,SAAS,0BAA0B,aAAyC;AACjF,SAAO,YAAY,WAAW,qBAAqB,YAAY,QAAQ,CAAC,GAAG,SAAS,eAAe;AACrG;AAEO,SAAS,qBAAqB,QAAiD;AACpF,SAAO,WAAW,QAAQ,0BAA0B,OAAO,WAAW;AACxE;;;AC/QA,SAAS,cAAAA,aAAY,cAAAC,mBAA6B;AAClD,SAAS,UAAAC,eAAc;AACvB,OAAOC,WAAU;AACjB,SAAS,yBAAyB;;;ACHlC,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,SAAAC,QAAO,UAAU,SAAS,QAAQ,MAAM,QAAQ,iBAAiB;AAC1E,OAAOC,WAAU;AACjB,SAAS,iBAAiB;AA2B1B,IAAM,uBAAuB;AAC7B,IAAM,gBAAgB,UAAU,QAAQ;AACxC,IAAM,wBAAwB;AAE9B,IAAM,8BAA8B;AACpC,IAAM,oCAAoC;AAC1C,IAAM,0BAA0B;AAChC,IAAM,+BAA+B,KAAK,IAAI,IAAI,QAAQ,OAAO,IAAI;AAiC9D,IAAM,+BAAN,MAAmC;AAAA,EACvB;AAAA,EACT,QAAiC;AAAA,EACjC,cAAgD;AAAA,EAChD,iBAAmD;AAAA,EACnD,gBAAgB;AAAA,EACP;AAAA,EAEjB,YAAY,SAA8C;AACxD,SAAK,UAAU;AACf,SAAK,mBAAmB,IAAI,iCAAiC,OAAO;AAAA,EACtE;AAAA,EAEQ,cAAgC;AACtC,WAAO,IAAI;AAAA,MACTC,MAAK,KAAK,KAAK,QAAQ,UAAU,2BAA2B;AAAA,MAC5D,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ,YAAY;AAAA,IAC3B;AAAA,EACF;AAAA,EAEQ,YAAoB;AAC1B,WAAOA,MAAK,KAAK,KAAK,QAAQ,UAAU,6BAA6B,iBAAiB;AAAA,EACxF;AAAA,EAEQ,oBAA4B;AAClC,WAAOA,MAAK,KAAK,KAAK,QAAQ,UAAU,6BAA6B,kBAAkB;AAAA,EACzF;AAAA,EAEA,MAAc,qBAA+C;AAC3D,QAAI;AACF,YAAM,WAAW,MAAM,QAAQ,KAAK,kBAAkB,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,WAAW,GAAG,CAAC;AAClG,cACE,MAAM,QAAQ;AAAA,QACZ,QAAQ,IAAI,OAAO,UAAU;AAC3B,gBAAM,aAAaA,MAAK,KAAK,KAAK,kBAAkB,GAAG,KAAK;AAC5D,cAAI;AACF,kBAAM,OAAO,MAAM,SAAS,YAAY,MAAM,GAAG,KAAK;AACtD,gBAAI,QAAQ,YAAa,QAAO,EAAE,MAAM,YAAY,WAAW,KAAK;AACpE,gBAAI;AACJ,gBAAI,YAAY;AAChB,gBAAI;AACF,oBAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,kBAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAClE,4BAAY;AACZ,wBAAQ,CAAC;AAAA,cACX,OAAO;AACL,wBAAQ;AAAA,cACV;AAAA,YACF,QAAQ;AACN,0BAAY;AACZ,sBAAQ,CAAC;AAAA,YACX;AACA,kBAAM,QAAQ,MAAM;AACpB,gBAAI,UAAU,aAAa,UAAU,YAAa,aAAY;AAC9D,kBAAM,aAAa,MAAM,KAAK,UAAU,EAAE,MAAM,MAAM,IAAI;AAK1D,kBAAM,YACJ,OAAO,MAAM,cAAc,YAAY,OAAO,SAAS,MAAM,SAAS,IAClE,MAAM,YACN,YAAY;AAClB,gBAAI,OAAO,MAAM,QAAQ,YAAY,CAAC,OAAO,UAAU,MAAM,GAAG,EAAG,aAAY;AAC/E,kBAAM,UACJ,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,SAAS,IACxD,MAAM,UACNA,MAAK,SAAS,UAAU;AAC9B,gBAAI,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,WAAW,EAAG,aAAY;AACjF,kBAAM,qBACJ,OAAO,MAAM,uBAAuB,YACpC,OAAO,SAAS,MAAM,kBAAkB,KACxC,MAAM,qBAAqB,IACvB,MAAM,qBACN;AACN,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,WAAW,UAAU;AAAA,cACrB,GAAI,OAAO,MAAM,QAAQ,YAAY,OAAO,UAAU,MAAM,GAAG,IAAI,EAAE,KAAK,MAAM,IAAI,IAAI,CAAC;AAAA,cACzF,GAAI,QAAQ,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,cACxC,GAAI,OAAO,cAAc,YAAY,OAAO,SAAS,SAAS,IAAI,EAAE,UAAU,IAAI,CAAC;AAAA,cACnF,GAAI,uBAAuB,SAAY,CAAC,IAAI,EAAE,mBAAmB;AAAA,cACjE,GAAI,YAAY,EAAE,WAAW,KAAK,IAAI,CAAC;AAAA,YACzC;AAAA,UACF,SAAS,KAAK;AACZ,gBAAI,YAAY,KAAK,QAAQ,EAAG,QAAO;AACvC,kBAAM;AAAA,UACR;AAAA,QACF,CAAC;AAAA,MACH,GACA,OAAO,CAAC,WAAoC,WAAW,IAAI;AAAA,IAC/D,SAAS,KAAK;AACZ,UAAI,YAAY,KAAK,QAAQ,EAAG,QAAO,CAAC;AACxC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,MAAc,kBAAkB,QAAyC;AACvE,QAAI,OAAO,aAAa,OAAO,cAAc,OAAW,QAAO;AAC/D,QAAI,KAAK,IAAI,IAAI,OAAO,YAAY,4BAA6B,QAAO;AACxE,QAAI,OAAO,UAAW,QAAO;AAC7B,WAAO,OAAO,QAAQ,UAAa,CAAE,MAAM,KAAK,eAAe,OAAO,KAAK,OAAO,kBAAkB;AAAA,EACtG;AAAA,EAEA,MAAc,eAAe,KAAa,oBAA+C;AACvF,QAAI;AACF,cAAQ,KAAK,KAAK,CAAC;AAAA,IACrB,SAAS,KAAK;AACZ,aAAO,CAAC,YAAY,KAAK,OAAO;AAAA,IAClC;AACA,QAAI,uBAAuB,OAAW,QAAO;AAC7C,UAAM,qBAAqB,MAAM,KAAK,uBAAuB,GAAG;AAChE,QAAI,uBAAuB,KAAM,QAAO;AACxC,WAAO,sBAAsB,qBAAqB;AAAA,EACpD;AAAA,EACA,MAAc,uBAAuB,KAAqC;AACxE,QAAI;AACF,UAAI,QAAQ,aAAa,SAAS;AAChC,cAAM,EAAE,QAAAC,QAAO,IAAI,MAAM;AAAA,UACvB;AAAA,UACA;AAAA,YACE;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,oBAAoB,GAAG;AAAA,UACzB;AAAA,UACA,EAAE,UAAU,QAAQ,SAAS,IAAM;AAAA,QACrC;AACA,cAAM,QAAQ,OAAOA,QAAO,KAAK,CAAC;AAClC,eAAO,OAAO,SAAS,KAAK,KAAK,QAAQ,2BAA2B,MAAS;AAAA,MAC/E;AACA,YAAM,EAAE,OAAO,IAAI,MAAM,cAAc,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,MAAM,SAAS,GAAG;AAAA,QACjF,UAAU;AAAA,QACV,SAAS;AAAA,MACX,CAAC;AACD,YAAM,SAAS,OAAO,KAAK;AAC3B,UAAI,CAAC,OAAQ,QAAO;AACpB,YAAM,cAAc,KAAK,MAAM,MAAM;AACrC,aAAO,OAAO,SAAS,WAAW,IAAI,cAAc;AAAA,IACtD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,+BAA+B,SAAsD;AACjG,UAAM,QAAQ,MAAM,QAAQ;AAAA,MAC1B,QAAQ,IAAI,OAAO,WAAY,OAAO,aAAc,MAAM,KAAK,kBAAkB,MAAM,IAAK,OAAO,OAAO,IAAK;AAAA,IACjH;AACA,WAAO,MAAM,OAAO,CAAC,eAAqC,eAAe,IAAI;AAAA,EAC/E;AAAA,EAEA,MAAc,oBAA8C;AAC1D,WAAO,MAAM,KAAK,mBAAmB;AAAA,EACvC;AAAA;AAAA,EAGA,MAAc,sBAAsB,YAAoB,SAAgC;AACtF,UAAM,gBAAgB,GAAG,UAAU,QAAQ,QAAQ,GAAG,IAAI,WAAW,CAAC;AACtE,QAAI;AACF,YAAM,UAAU,eAAe,SAAS,MAAM;AAC9C,YAAM,OAAO,eAAe,UAAU;AAAA,IACxC,UAAE;AACA,YAAM,OAAO,aAAa,EAAE,MAAM,CAAC,QAAiB;AAClD,YAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,YAAY,OAAwB;AACpE,UAAM,YAAY,KAAK,kBAAkB;AACzC,UAAMC,OAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAC1C,UAAM,UAAU,WAAW;AAC3B,UAAM,aAAaF,MAAK,KAAK,WAAW,OAAO;AAC/C,UAAM,KAAK;AAAA,MACT;AAAA,MACA,GAAG,KAAK,UAAU;AAAA,QAChB,OAAO,YAAY,cAAc;AAAA,QACjC,KAAK,QAAQ;AAAA,QACb;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,QACpB,oBAAoB;AAAA,MACtB,CAAC,CAAC;AAAA;AAAA,IACJ;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,qBAAqB,YAAmC;AACpE,UAAM,KAAK;AAAA,MACT;AAAA,MACA,GAAG,KAAK,UAAU;AAAA,QAChB,OAAO;AAAA,QACP,KAAK,QAAQ;AAAA,QACb,SAASA,MAAK,SAAS,UAAU;AAAA,QACjC,WAAW,KAAK,IAAI;AAAA,QACpB,oBAAoB;AAAA,MACtB,CAAC,CAAC;AAAA;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,MAAc,qBAAqB,aAA+C;AAChF,UAAM,QAAQ;AAAA,MACZ,YAAY,IAAI,OAAO,eAAe;AACpC,YAAI;AACF,gBAAM,OAAO,UAAU;AAAA,QACzB,SAAS,KAAK;AACZ,cAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AAAA,QACzC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,kBAAqC,CAAC,GAAqB;AAC1F,UAAM,WAAW,IAAI,IAAI,eAAe;AACxC,YAAQ,MAAM,KAAK,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,IAAI,OAAO,IAAI,CAAC;AAAA,EACrF;AAAA,EAEA,MAAc,iBAAiB,SAAiC;AAC9D,SAAK,gBAAgB,WAAW,EAAE,MAAM,KAAK,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,SAAS;AAAA,EACtG;AAAA,EACQ,UAAU,QAA6B;AAC7C,WAAO,OAAO,YAAY,WAAW,oBAAoB,QAAQ,OAAO,YAAY,SAAS;AAAA,EAC/F;AAAA,EAEA,MAAc,QAAQ,OAA2C;AAC/D,WAAO,MAAM,MAAM,iBAAiB,YAAY;AAC9C,YAAM,MAAM;AACZ,YAAM,WAAW,CAAC,GAAI,MAAM,KAAK,QAAQ,gBAAgB,GAAI,GAAI,MAAM,KAAK,QAAQ,oBAAoB,CAAE;AAC1G,iBAAW,UAAU,UAAU;AAC7B,YAAI,CAAC,KAAK,UAAU,MAAM,EAAG;AAC7B,cAAM;AAAA,UACJ,6BAA6B,OAAO,SAAS,OAAO,YAAY,UAAU,OAAO,YAAY,eAAe;AAAA,QAC9G;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,6BAA+C;AAC3D,QAAI;AACF,YAAM,KAAK,KAAK,UAAU,CAAC;AAC3B,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,UAAI,CAAC,YAAY,KAAK,QAAQ,EAAG,OAAM;AACvC,cAAQ,MAAM,KAAK,mBAAmB,GAAG,SAAS;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,MAAc,WAAsC;AAClD,QAAI,KAAK,MAAO,QAAO,KAAK;AAC5B,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,QAAQ,KAAK,YAAY;AAC/B,WAAK,eAAe,YAAY;AAC9B,cAAM,MAAM,KAAK;AACjB,cAAM,iBAAiB,MAAM,KAAK,kBAAkB;AACpD,cAAM,0BAA0B,MAAM,KAAK,+BAA+B,cAAc;AACxF,YAAI,YAAY;AAChB,YAAI;AACF,gBAAM,KAAK,KAAK,UAAU,CAAC;AAC3B,cAAI,eAAe,SAAS,EAAG,aAAY;AAAA,QAC7C,SAAS,KAAK;AACZ,cAAI,YAAY,KAAK,QAAQ,EAAG,aAAY;AAAA,cACvC,OAAM;AAAA,QACb;AACA,YAAI,CAAC,WAAW;AACd,gBAAM,cAAc,KAAK,QAAQ,YAAY;AAC7C,gBAAM,cAAc,YAAY,oBAAoB;AACpD,gBAAM,SAAS,YAAY,eAAe;AAC1C,cAAI,UAAU;AACd,mBAAS,UAAU,GAAG,UAAU,aAAa,WAAW,GAAG;AACzD,sBAAU,MAAM,KAAK,QAAQ,KAAK;AAClC,gBAAI,WAAW,YAAY,cAAc,EAAG;AAC5C,kBAAM,OAAO,KAAK,IAAI,SAAS,KAAK,SAAS,qCAAqC;AAClF,kBAAM,aAAa,QAAQ,cAAoB;AAC/C,uBAAW,WAAW,SAAS,IAAI;AACnC,kBAAM,WAAW;AAAA,UACnB;AACA,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,0DAA0D;AAAA,UAC5E;AACA,gBAAM,KAAK,qBAAqB,uBAAuB;AAAA,QACzD;AACA,cAAM,KAAK,iBAAiB,IAAI;AAChC,aAAK,QAAQ;AACb,eAAO;AAAA,MACT,GAAG,EAAE,MAAM,CAAC,QAAQ;AAClB,aAAK,cAAc;AACnB,cAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,qBAAwB,MAAwB,UAAmD;AACvG,WAAO,MAAM,KAAK,iBAAiB,qBAAqB,MAAM,QAAQ;AAAA,EACxE;AAAA,EAEA,MAAM,2BAA8B,MAAwB,gBAA+C;AACzG,WAAO,MAAM,KAAK,iBAAiB,2BAA2B,MAAM,cAAc;AAAA,EACpF;AAAA,EACA,MAAM,8BACJ,MACA,UACA,gBACY;AACZ,WAAO,MAAM,KAAK,iBAAiB,8BAA8B,MAAM,UAAU,cAAc;AAAA,EACjG;AAAA,EAEA,MAAc,SAAoC;AAChD,QAAI,CAAC,KAAK,gBAAgB;AACxB,WAAK,kBAAkB,YAAY;AACjC,aAAK,QAAQ;AACb,aAAK,cAAc;AACnB,eAAO,MAAM,KAAK,SAAS;AAAA,MAC7B,GAAG,EAAE,QAAQ,MAAM;AACjB,aAAK,iBAAiB;AAAA,MACxB,CAAC;AAAA,IACH;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,MACJ,SACA,UACA,iBACmD;AACnD,UAAM,MAAM,6BAA6B,SAAS,UAAU,eAAe;AAC3E,QAAI,QAAQ,MAAM,KAAK,SAAS;AAChC,QAAK,MAAM,KAAK,mBAAmB,KAAM,CAAE,MAAM,MAAM,yBAAyB,GAAI;AAClF,cAAQ,MAAM,KAAK,OAAO;AAAA,IAC5B;AACA,WAAO,EAAE,KAAK,MAAM,IAAI,GAAG,GAAG,eAAe,KAAK,cAAc;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,IAAI,SAAiB,UAAkB,iBAA4C;AACvF,YAAQ,MAAM,KAAK,MAAM,SAAS,UAAU,eAAe,GAAG;AAAA,EAChE;AAAA;AAAA,EAGA,MAAM,kBAAoC;AACxC,UAAM,QAAQ,MAAM,KAAK,SAAS;AAClC,QAAK,MAAM,KAAK,mBAAmB,KAAM,CAAE,MAAM,MAAM,yBAAyB,GAAI;AAClF,YAAM,KAAK,OAAO;AAAA,IACpB;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,eAAgC;AACpC,WAAO,KAAK,oBAAoB;AAAA,EAClC;AAAA;AAAA,EAGA,MAAM,YAAY,eAAsC;AACtD,UAAM,KAAK,qBAAqB,aAAa;AAAA,EAC/C;AAAA;AAAA,EAGA,MAAM,aAAa,eAAsC;AACvD,UAAM,KAAK,qBAAqB,CAAC,aAAa,CAAC;AAAA,EACjD;AAAA;AAAA,EAGA,MAAM,IAAI,QAAoB,eAAuC;AACnE,QAAI,CAAC,KAAK,UAAU,MAAM,EAAG;AAC7B,QAAI,QAAQ,MAAM,KAAK,SAAS;AAChC,QACG,MAAM,KAAK,mBAAmB,gBAAgB,CAAC,aAAa,IAAI,CAAC,CAAC,KACnE,CAAE,MAAM,MAAM,yBAAyB,GACvC;AACA,cAAQ,MAAM,KAAK,OAAO;AAAA,IAC5B;AACA,UAAM;AAAA,MACJ,6BAA6B,OAAO,SAAS,OAAO,YAAY,UAAU,OAAO,YAAY,eAAe;AAAA,IAC9G;AACA,UAAM,SAAS,iBAAkB,MAAM,KAAK,oBAAoB,IAAI;AACpE,QAAI,cAAe,OAAM,KAAK,qBAAqB,aAAa;AAChE,UAAM,MAAM,oBAAoB;AAChC,UAAM,MAAM,oBAAoB;AAChC,QAAI,MAAM,mBAAmB;AAC3B,WAAK,cAAc;AACnB;AAAA,IACF;AACA,UAAM,KAAK,qBAAqB,CAAC,MAAM,CAAC;AACxC,UAAM,KAAK,iBAAiB,IAAI;AAAA,EAClC;AAAA;AAAA,EAGA,MAAM,gBAAgB,aAAqC;AACzD,UAAM,QAAQ,KAAK,UAAW,MAAM,KAAK,2BAA2B,IAAK,KAAK,SAAS,IAAI;AAC3F,QAAI,CAAC,MAAO;AACZ,UAAM,iBAAiB,MAAM,KAAK,kBAAkB;AACpD,UAAM,gBAAgB,MAAM,KAAK,oBAAoB,IAAI;AACzD,UAAM,0BAA0B,MAAM,KAAK,+BAA+B,cAAc;AACxF,UAAM,UAAU,MAAM,KAAK,QAAQ,MAAM,KAAK;AAC9C,QAAI,SAAS;AACX,YAAM,KAAK,qBAAqB;AAAA,QAC9B,GAAG;AAAA,QACH,GAAI,gBAAgB,UAAa,wBAAwB,SAAS,WAAW,IAAI,CAAC,IAAI,CAAC,WAAW;AAAA,QAClG;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,KAAK,iBAAiB,OAAO;AAAA,EACrC;AAAA;AAAA,EAGA,MAAM,KAAK,QAAoB,OAAmB,eAAuC;AACvF,UAAM,gBAAgB,KAAK,UAAU,MAAM;AAC3C,UAAM,eAAe,KAAK,UAAU,KAAK;AACzC,QAAI,CAAC,iBAAiB,CAAC,aAAc;AACrC,UAAM,YAAY;AAAA,MAChB,OAAO;AAAA,MACP,OAAO,YAAY;AAAA,MACnB,OAAO,YAAY;AAAA,IACrB;AACA,UAAM,WAAW;AAAA,MACf,MAAM;AAAA,MACN,MAAM,YAAY;AAAA,MAClB,MAAM,YAAY;AAAA,IACpB;AACA,QAAI,iBAAiB,gBAAgB,cAAc,UAAU;AAC3D,UAAI,eAAe;AACjB,cAAM,KAAK,qBAAqB,aAAa;AAC7C,cAAM,KAAK,qBAAqB,CAAC,aAAa,CAAC;AAAA,MACjD;AACA;AAAA,IACF;AACA,UAAM,kBAAkB,MAAM,KAAK,kBAAkB;AACrD,UAAM,SAAS,iBAAkB,MAAM,KAAK,oBAAoB,IAAI;AACpE,UAAM,2BAA2B,MAAM,KAAK,+BAA+B,eAAe;AAC1F,QAAI,cAAe,OAAM,KAAK,qBAAqB,aAAa;AAChE,UAAM,UAAU,MAAM,KAAK,QAAQ,MAAM,KAAK,SAAS,CAAC;AACxD,QAAI,SAAS;AACX,YAAM,KAAK,qBAAqB;AAAA,QAC9B,GAAG;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,KAAK,iBAAiB,OAAO;AAAA,EACrC;AAAA,EACA,gBAAsB;AACpB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,MAAc,SAAS,WAAmB,QAA4C;AACpF,QAAI;AACF,YAAM,OAAO;AAAA,IACf,SAAS,KAAK;AACZ,WAAK,cAAc;AACnB,UAAI,KAAK,WAAW,SAAS,oEAAoE,GAAG,EAAE;AAAA,IACxG;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,UACA,aACA,SACA,eACe;AACf,UAAM,KAAK,SAAS,eAAe,MAAM,KAAK,IAAI,EAAE,MAAM,UAAU,aAAa,QAAQ,GAAG,aAAa,CAAC;AAAA,EAC5G;AAAA,EAEA,MAAM,yBAAyB,aAAqC;AAClE,UAAM,KAAK,SAAS,oBAAoB,MAAM,KAAK,gBAAgB,WAAW,CAAC;AAAA,EACjF;AAAA,EAEA,MAAM,kBACJ,QACA,aACA,SACA,eACe;AACf,UAAM,KAAK,SAAS,gBAAgB,MAAM,KAAK,KAAK,QAAQ,EAAE,GAAG,QAAQ,aAAa,QAAQ,GAAG,aAAa,CAAC;AAAA,EACjH;AAAA,EAEA,MAAM,uBACJ,QACA,aACA,eACe;AACf,UAAM,KAAK,SAAS,0BAA0B,MAAM,KAAK,KAAK,QAAQ,EAAE,GAAG,QAAQ,YAAY,GAAG,aAAa,CAAC;AAAA,EAClH;AAAA,EACA,sCAAsC,UAA2B;AAC/D,UAAM,WAAWA,MAAK,SAASA,MAAK,QAAQ,KAAK,QAAQ,SAAS,GAAGA,MAAK,QAAQ,QAAQ,CAAC;AAC3F,UAAM,WAAW,SAAS,MAAMA,MAAK,GAAG,EAAE,CAAC;AAC3C,WAAO,aAAa,UAAU,qBAAqB,SAAS,QAAQ;AAAA,EACtE;AACF;;;ADzhBA,IAAM,kCAAkC;AACxC,IAAM,gCAAgC,KAAK;AAC3C,IAAM,qCAAqC,OAAO,KAAK,WAAW,MAAM;AAExE,IAAM,kBAAkB;AACxB,IAAM,2BAA2B;AAmBjC,SAAS,gCAAgC,MAGvC;AACA,MAAI,UAAU;AACd,MAAI,eAAe;AACnB,MAAI,SAAS;AACb,MAAI,kBAAkB;AACtB,MAAI,eAAe;AACnB,QAAM,QAAQ,MAAM;AAClB,QAAI,OAAO,SAAS,GAAG;AACrB,WAAK,MAAM,MAAM;AACjB,eAAS;AAAA,IACX;AAAA,EACF;AACA,QAAM,OAAO,CAAC,SAAiB;AAC7B,eAAW,aAAa,MAAM;AAC5B,UAAI,MAAM,KAAK,SAAS,GAAG;AACzB,YAAI,QAAS,gBAAe;AAC5B;AAAA,MACF;AACA,UAAI,cAAc;AAChB,kBAAU;AACV,uBAAe;AAAA,MACjB;AACA,gBAAU;AACV,gBAAU;AACV,UAAI,OAAO,UAAU,8BAA+B,OAAM;AAAA,IAC5D;AAAA,EACF;AACA,QAAM,eAAe,CAAC,oBAA6B;AACjD,UAAM;AACN,SAAK,wBAAwB,CAAC,eAAe;AAC7C,mBAAe;AAAA,EACjB;AACA,QAAM,OAAO,CAAC,SAAiB;AAC7B,eAAW,aAAa,MAAM;AAC5B,YAAM,gBAAgB,yBAAyB,KAAK,SAAS;AAC7D,YAAM,QAAQ,gBAAgB,KAAK,SAAS;AAC5C,UAAI,cAAc;AAChB,YAAI,eAAe;AACjB,eAAK,UAAU,YAAY,CAAC;AAC5B;AAAA,QACF;AACA,qBAAa,KAAK;AAAA,MACpB;AACA,UAAI,cAAc,YAAO,iBAAiB;AACxC,cAAM;AACN,aAAK,sBAAsB;AAC3B,uBAAe;AACf,0BAAkB;AAClB;AAAA,MACF;AACA,WAAK,UAAU,YAAY,CAAC;AAC5B,UAAI,CAAC,cAAe,mBAAkB;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AACP,UAAI,aAAc,cAAa,KAAK;AACpC,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,eAAe,uBACb,WACA,QACA,QACA,KACA,WACe;AACf,QAAM,UAAU,IAAI,YAAY,OAAO;AACvC,MAAI,YAAY;AAChB,mBAAiB,SAAS,iCAAiC,WAAW,KAAK,SAAS,GAAG;AACrF,UAAM,YAAY,aAAa,MAAM,SAAS,OAAO,MAAM,SAAS,SAAS;AAC7E,gBAAY,KAAK,IAAI,GAAG,YAAY,MAAM,MAAM;AAChD,QAAI,cAAc,QAAQ,UAAU,WAAW,EAAG;AAClD,UAAM,OAAO,QAAQ,OAAO,WAAW,EAAE,QAAQ,KAAK,CAAC;AACvD,QAAI,KAAK,SAAS,EAAG,QAAO,IAAI;AAAA,EAClC;AACA,QAAM,YAAY,QAAQ,OAAO;AACjC,MAAI,UAAU,SAAS,EAAG,QAAO,SAAS;AAC5C;AAEA,eAAe,qBAAqB,WAAmB,KAAoB,WAA2C;AACpH,MAAI,eAAe;AACnB,MAAI,OAAO,OAAO,MAAM,CAAC;AACzB,mBAAiB,SAAS,iCAAiC,WAAW,KAAK,SAAS,GAAG;AACrF,UAAM,SAAS,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI;AAChE,UAAM,cAAc,eAAe,KAAK;AACxC,aAAS,aAAa,OAAO;AAC3B,YAAM,iBAAiB,OAAO,QAAQ,oCAAoC,UAAU;AACpF,UAAI,iBAAiB,EAAG;AACxB,UAAI,cAAc,kBAAkB,GAAG;AACrC,eAAO,cAAc,iBAAiB,mCAAmC;AAAA,MAC3E;AACA,mBAAa,iBAAiB;AAAA,IAChC;AACA,oBAAgB,MAAM;AACtB,UAAM,aAAa,KAAK,IAAI,mCAAmC,SAAS,GAAG,OAAO,MAAM;AACxF,WAAO,OAAO,KAAK,OAAO,SAAS,OAAO,SAAS,UAAU,CAAC;AAAA,EAChE;AACA,SAAO;AACT;AAEA,eAAe,iBACb,WACA,WACA,KACA,WACiB;AACjB,QAAM,SAAmB,CAAC;AAC1B,MAAI,YAAY;AAChB,mBAAiB,SAAS,iCAAiC,WAAW,KAAK,SAAS,GAAG;AACrF,UAAM,SAAS,KAAK,IAAI,MAAM,QAAQ,YAAY,SAAS;AAC3D,QAAI,SAAS,EAAG,QAAO,KAAK,MAAM,SAAS,GAAG,MAAM,CAAC;AACrD,iBAAa;AACb,QAAI,aAAa,UAAW;AAAA,EAC9B;AACA,SAAO,OAAO,OAAO,QAAQ,SAAS;AACxC;AAIO,SAAS,uCACd,UACA,SACA,WACA,kBACA,6BACA,iBACmB;AACnB,QAAM,SAAS,iBAAiB,QAAQ,SAAS,MAAM,CAAC;AACxD,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa,4BAA4B,OAAO,aAAa,gBAAgB,WAAW,QAAQ,GAAG,OAAO,OAAO;AAAA,IACjH,SAAS,OAAO;AAAA,EAClB;AACF;AAEO,IAAe,mCAAf,MAAgD;AAAA,EAC7C,+BAAoE;AAAA,EAoB5E,MAAc,6BAA6B,UAAkB,QAA8C;AACzG,UAAM,UAAU,KAAK,oCAAoC;AACzD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,QAAQ,4BAA4B;AAAA,MACpC,CAAC;AAAA,MACD,QAAQ;AAAA,IACV;AACA,SAAK,0BAA0B,QAAQ;AAAA,EACzC;AAAA,EAEU,kCAAgE;AACxE,QAAI,KAAK,iCAAiC,MAAM;AAC9C,WAAK,+BAA+B,IAAI,6BAA6B,KAAK,oCAAoC,CAAC;AAAA,IACjH;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EACA,MAAM,qCACJ,MACA,UACY;AACZ,WAAO,MAAM,KAAK,gCAAgC,EAAE,qBAAqB,MAAM,QAAQ;AAAA,EACzF;AAAA,EAEA,MAAgB,8CACd,MACA,UACA,gBACY;AACZ,WAAO,MAAM,KAAK,gCAAgC,EAAE,8BAA8B,MAAM,UAAU,cAAc;AAAA,EAClH;AAAA,EAEA,MAAc,8BACZ,SACA,UACA,aACA,UACA,aACA,mBACA,aAAa,OACE;AACf,UAAM,OAAqC;AAAA,MACzC,aAAa,MAAM,KAAK,iBAAiB,QAAQ;AAAA,MACjD,WAAW,CAAC,WAAW,KAAK,yBAAyB,MAAM;AAAA,MAC3D,gBAAgB,CAAC,WAAW,qBAAqB,MAAM;AAAA,MACvD,gBAAgB,CAAC,WAAW,KAAK,0BAA0B,MAAM;AAAA,MACjE,cAAc,MAAM,KAAK,gCAAgC,EAAE,aAAa;AAAA,MACxE,aAAa,CAAC,WAAW,KAAK,gCAAgC,EAAE,YAAY,MAAM;AAAA,MAClF,cAAc,CAAC,WAAW,KAAK,gCAAgC,EAAE,aAAa,MAAM;AAAA,MACpF,eAAe,MAAM,KAAK,gCAAgC,EAAE,cAAc;AAAA,MAC1E,wBAAwB,CAAC,QAAQ,YAAY,KAAK,uBAAuB,QAAQ,OAAO;AAAA,MACxF,sBAAsB,CAAC,MAAM,iBAAiB,KAAK,qCAAqC,MAAM,YAAY;AAAA,MAC1G,YAAY,CAAC,YAAY,IAAI,KAAK,OAAO;AAAA,IAC3C;AACA,UAAM,4BAA4B,MAAM;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAgB,4BACd,UACA,aACA,aACA,SACA,mBACe;AACf,UAAM,KAAK;AAAA,MACT,iBAAiB,WAAW;AAAA,MAC5B;AAAA,MACA;AAAA,MACA;AAAA,QACE,6BAA6B,QAAQ;AAAA,QACrC,6BAA6B,SAAS,YAAY,UAAU,YAAY,eAAe;AAAA,MACzF;AAAA,MACA,CAAC,kBACC,KAAK,gCAAgC,EAAE,iBAAiB,UAAU,aAAa,SAAS,aAAa;AAAA,MACvG;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,mCACd,UACA,MACA,sBAAyC,CAAC,GAC9B;AACZ,QAAI,iBAAiB,CAAC,UAAU,GAAG,mBAAmB,EAAE,IAAI,4BAA4B;AACxF,eAAS;AACP,UAAI;AACJ,UAAI;AACJ,YAAM,KAAK,qCAAqC,YAAY;AAC1D,cAAM,UAAU,MAAM,KAAK,iBAAiB,QAAQ;AACpD,YAAI,YAAY,MAAM;AACpB,gBAAM,kBAAkB,KAAK,0BAA0B,OAAO;AAC9D,cAAI,CAAC,eAAe,SAAS,eAAe,GAAG;AAC7C,4BAAgB;AAChB;AAAA,UACF;AAAA,QACF;AACA,iBAAS,MAAM,KAAK,OAAO;AAAA,MAC7B,GAAG,cAAc;AACjB,UAAI,kBAAkB,QAAW;AAC/B,yBAAiB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,gBAAgB,aAAa,CAAC,CAAC;AAChE;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAgB,2BACd,UACA,aACA,aACA,SACA,eACA,YACiB;AACjB,UAAM,mBAAmB,6BAA6B,SAAS,YAAY,UAAU,YAAY,eAAe;AAChH,QAAI,iBAAiB,CAAC,6BAA6B,QAAQ,GAAG,gBAAgB;AAC9E,eAAS;AACP,UAAI;AACJ,UAAI,SAAS,YAAY;AACzB,YAAM,KAAK,qCAAqC,YAAY;AAC1D,cAAM,UAAU,MAAM,KAAK,iBAAiB,QAAQ;AACpD,YAAI,YAAY,MAAM;AACpB,gBAAM,kBAAkB,KAAK,0BAA0B,OAAO;AAC9D,cAAI,CAAC,eAAe,SAAS,eAAe,GAAG;AAC7C,4BAAgB;AAChB;AAAA,UACF;AAAA,QACF;AACA,YAAI,iBAAiB,WAAW,GAAG;AACjC,gBAAM,YAAY,MAAM,cAAc;AACtC,cAAI,WAAW;AACb,qBAAS,UAAU,YAAY;AAC/B;AAAA,UACF;AAAA,QACF;AACA,cAAM,KAAK,4BAA4B,UAAU,aAAa,aAAa,OAAO;AAClF,cAAM,WAAW,OAAO;AAAA,MAC1B,GAAG,cAAc;AACjB,UAAI,kBAAkB,OAAW,QAAO;AACxC,uBAAiB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,gBAAgB,aAAa,CAAC,CAAC;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAgB,4BACd,QACA,aACA,aACA,SACA,mBACe;AACf,UAAM,KAAK;AAAA,MACT,iBAAiB,OAAO,WAAW,KAAK,iBAAiB,WAAW;AAAA,MACpE,OAAO;AAAA,MACP;AAAA,MACA;AAAA,QACE,6BAA6B,OAAO,IAAI;AAAA,QACxC,KAAK,0BAA0B,MAAM;AAAA,QACrC,6BAA6B,SAAS,YAAY,UAAU,YAAY,eAAe;AAAA,MACzF;AAAA,MACA,CAAC,eAAe,YACd,KAAK,gCAAgC,EAAE;AAAA,QACrC,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,iCACd,QACA,aACA,aACA,mBACe;AACf,UAAM,KAAK;AAAA,MACT,iBAAiB,OAAO,WAAW,KAAK,iBAAiB,WAAW;AAAA,MACpE,OAAO;AAAA,MACP;AAAA,MACA;AAAA,QACE,6BAA6B,OAAO,IAAI;AAAA,QACxC,KAAK,0BAA0B,MAAM;AAAA,QACrC,6BAA6B,OAAO,SAAS,YAAY,UAAU,YAAY,eAAe;AAAA,MAChG;AAAA,MACA,CAAC,eAAe,YACd,KAAK,gCAAgC,EAAE,uBAAuB,WAAW,QAAQ,aAAa,aAAa;AAAA,MAC7G;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,yBAAyB,QAAiD;AAChF,WAAO,WAAW,QAAQ,OAAO,YAAY,WAAW,oBAAoB,QAAQ,OAAO,YAAY,SAAS;AAAA,EAClH;AAAA,EAEQ,0BAA0B,QAA4B;AAC5D,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,YAAY;AAAA,MACnB,OAAO,YAAY;AAAA,IACrB;AAAA,EACF;AAAA,EACA,MAAc,uCACZ,QACA,UACA,kBACkB;AAClB,UAAM,SAAS,MAAM,KAAK,iBAAiB,MAAM;AACjD,UAAM,YAAY,mBACd,OACA,MAAM,KAAK,gCAAgC,EAAE;AAAA,MAC3C,SAAS;AAAA,MACT,SAAS,YAAY;AAAA,MACrB,SAAS,YAAY;AAAA,IACvB;AACJ,QAAI,CAAC,UAAW,QAAO;AACvB,UAAM,mBAAmB,kBAAkB,gBAAgB,KAAK,0BAA0B,QAAQ;AAClG,UAAM,UAAU,KAAK,oCAAoC;AACzD,UAAM,WAAW,CAAC,GAAI,MAAM,QAAQ,gBAAgB,GAAI,GAAI,MAAM,QAAQ,oBAAoB,CAAE;AAChG,UAAM,aAAa,SAAS;AAAA,MAC1B,CAAC,WACC,KAAK,yBAAyB,MAAM,MACnC,mBAAmB,oBAAoB,MAAM,IAAI,KAAK,0BAA0B,MAAM,OAAO;AAAA,IAClG;AACA,QAAI,CAAC,WAAY,QAAO;AACxB,QAAI,WAAW,KAAM,QAAO;AAC5B,QAAI,CAAC,KAAK,yBAAyB,MAAM,EAAG,QAAO;AACnD,UAAM,iBAAiB,mBAAmB,oBAAoB,MAAM,IAAI,KAAK,0BAA0B,MAAM;AAC7G,QAAI,mBAAmB,iBAAkB,QAAO;AAChD,WAAO,mBACH,kBAAkB,OAAO,aAAa,SAAS,WAAW,IAC1D,OAAO,YAAY,SAAS,WAAW,kBAAkB,OAAO,aAAa,SAAS,WAAW;AAAA,EACvG;AAAA,EAEA,MAAc,mCAAmC,UAAkB,aAAqC;AACtG,SAAK,2BAA2B;AAChC,SAAK,8BAA8B;AACnC,SAAK,kCAAkC;AACvC,QAAI,SAAS,SAAS,GAAGG,MAAK,GAAG,OAAOA,MAAK,GAAG,EAAE,GAAG;AACnD,WAAK,4BAA4B;AAAA,IACnC;AACA,UAAM,KAAK,uDAAuD,UAAU,WAAW;AACvF,QAAI,SAAS,SAAS,GAAGA,MAAK,GAAG,YAAYA,MAAK,GAAG,EAAE,GAAG;AACxD,WAAK,yBAAyB;AAAA,IAChC;AACA,SAAK,wBAAwB;AAAA,EAC/B;AAAA,EAEA,MAAgB,2BACd,QACA,MACwB;AACxB,QAAI,eAA8B;AAClC,UAAM,WAAW,MAAM,KAAK,gCAAgC,QAAQ,OAAO,SAAS,eAAe,gBAAgB;AACjH,UAAI,iBAAiB;AACrB,YAAM,qBAAqB,MAAM;AAC/B,yBAAiB;AACjB,oBAAY;AAAA,MACd;AACA,qBAAe,MAAM,KAAK,SAAS,kBAAkB;AACrD,UAAI,kBAAkB,WAAc,iBAAiB,QAAQ,iBAAiB;AAC5E,cAAM,KAAK,gDAAgD,aAAa;AAAA,MAC1E,WAAW,kBAAkB,QAAW;AACtC,cAAM,QAAQ,KAAK,gCAAgC;AACnD,YAAI;AACF,gBAAM,MAAM,aAAa,aAAa;AAAA,QACxC,QAAQ;AACN,gBAAM,cAAc;AAAA,QACtB;AAAA,MACF;AACA,aAAO,iBAAiB;AAAA,IAC1B,CAAC;AACD,WAAO,WAAW,eAAe;AAAA,EACnC;AAAA,EAEA,MAAgB,gCACd,QACA,MACA,kBAAkB,OAClB,aAAa,OACK;AAClB,QAAI,iBAAiB;AAAA,MACnB,6BAA6B,OAAO,IAAI;AAAA,MACxC,GAAI,cAAc,KAAK,yBAAyB,MAAM,KAAK,qBAAqB,MAAM,IAClF,CAAC,KAAK,0BAA0B,MAAM,CAAC,IACvC,CAAC;AAAA,IACP;AACA,eAAS;AACP,YAAM,UAAU,YAAY;AAC1B,cAAM,UAAU,KAAK,oCAAoC;AACzD,cAAM,UACH,MAAM,KAAK,iBAAiB,OAAO,IAAI,MACvC,MAAM,QAAQ,gBAAgB,GAAG,KAAK,CAAC,cAAc,UAAU,YAAY,OAAO,OAAO,YAAY,EAAE,MACvG,MAAM,QAAQ,oBAAoB,GAAG,KAAK,CAAC,cAAc,UAAU,YAAY,OAAO,OAAO,YAAY,EAAE;AAC9G,YAAI,CAAC,QAAS,QAAO,EAAE,QAAQ,MAAM;AACrC,cAAM,UAAU,KAAK,yBAAyB,OAAO;AACrD,cAAM,eAAe,qBAAqB,OAAO;AACjD,YAAI,WAAW,cAAc;AAC3B,gBAAM,kBAAkB,KAAK,0BAA0B,OAAO;AAC9D,cAAI,CAAC,eAAe,SAAS,eAAe,EAAG,QAAO,EAAE,eAAe,gBAAgB;AAAA,QACzF;AACA,cAAM,eAAe,UAAU,KAAK,gCAAgC,IAAI;AACxE,YAAI;AACJ,YAAI,UAAU;AACd,YAAI;AACF,cAAI,aAAc,iBAAgB,MAAM,aAAa,aAAa;AAClE,gBAAMC,UAAS,MAAM,KAAK,SAAS,eAAe,MAAM;AACtD,sBAAU;AAAA,UACZ,CAAC;AACD,cAAI,CAACA,WAAU,iBAAiB,CAAC,WAAW,cAAc;AACxD,gBAAI;AACF,oBAAM,aAAa,aAAa,aAAa;AAAA,YAC/C,QAAQ;AACN,2BAAa,cAAc;AAAA,YAC7B;AAAA,UACF;AACA,iBAAO,EAAE,QAAAA,QAAO;AAAA,QAClB,SAAS,OAAO;AACd,cAAI,iBAAiB,CAAC,WAAW,cAAc;AAC7C,gBAAI;AACF,oBAAM,aAAa,aAAa,aAAa;AAAA,YAC/C,QAAQ;AACN,2BAAa,cAAc;AAAA,YAC7B;AAAA,UACF;AACA,cAAI,gBAAiB,OAAM;AAC3B,iBAAO,EAAE,QAAQ,MAAM;AAAA,QACzB;AAAA,MACF;AACA,YAAM,SAAS,MAAM,KAAK,qCAAqC,SAAS,cAAc;AACtF,UAAI,OAAO,kBAAkB,QAAW;AACtC,yBAAiB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,gBAAgB,OAAO,aAAa,CAAC,CAAC;AACvE;AAAA,MACF;AACA,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAAA,EACA,MAAM,2BACJ,QACA,eAAiD,MAAM,MAC3B;AAC5B,QAAI,UAA6B;AACjC,UAAM,UAAU,MAAM,KAAK;AAAA,MACzB;AAAA,MACA,OAAO,SAAS,eAAe,gBAAgB;AAC7C,YAAI,CAAC,aAAa,OAAO,EAAG,QAAO;AACnC,YAAI,CAAE,MAAM,KAAK,yBAAyB,QAAQ,IAAI,EAAI,QAAO;AACjE,oBAAY;AACZ,kBAAU;AACV,cAAM,YAAY,KAAK,oCAAoC,EAAE;AAC7D,uCAA+B,WAAW,QAAQ,YAAY,EAAE;AAChE,aAAK,2BAA2B;AAChC,YAAI,QAAQ,KAAK,SAAS,GAAGD,MAAK,GAAG,OAAOA,MAAK,GAAG,EAAE,GAAG;AACvD,eAAK,4BAA4B;AAAA,QACnC;AACA,cAAM,KAAK,gDAAgD,aAAa;AACxE,aAAK,wBAAwB;AAC7B,aAAK,wBAAwB;AAC7B,eAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,WAAO,UAAU,UAAU;AAAA,EAC7B;AAAA,EAEA,MAAgB,uCACd,QACA,OACA,OACA,aAAa,OACb,kBACe;AACf,eAAS;AACP,YAAM,SAAS,MAAM,KAAK,iBAAiB,MAAM;AACjD,YAAM,iBAAiB,WAAW,OAAO,SAAY,KAAK,0BAA0B,MAAM;AAC1F,YAAM,gBAAgB,UAAU,QAAQ,mBAAmB,SAAY,KAAK,0BAA0B,KAAK;AAC3G,YAAM,iBACJ,cAAc,mBAAmB,UAAa,kBAAkB,UAAa,qBAAqB;AACpG,YAAM,aAAa;AAAA,QACjB,GAAI,iBAAiB,CAAC,6BAA6B,MAAM,CAAC,IAAI,CAAC;AAAA,QAC/D,GAAI,mBAAmB,SAAY,CAAC,IAAI,CAAC,cAAc;AAAA,QACvD,GAAI,kBAAkB,SAAY,CAAC,IAAI,CAAC,aAAa;AAAA,MACvD;AACA,UAAI;AACJ,YAAM,SAAS,YAA2B;AACxC,cAAM,UAAU,MAAM,KAAK,iBAAiB,MAAM;AAClD,YAAI,YAAY,MAAM;AACpB,gBAAM,kBAAkB,KAAK,0BAA0B,OAAO;AAC9D,cAAI,oBAAoB,gBAAgB;AACtC,4BAAgB;AAChB;AAAA,UACF;AAAA,QACF;AACA,YACE,KAAK,yBAAyB,KAAK,KAClC,MAAM,KAAK,uCAAuC,QAAQ,OAAO,gBAAgB,GAClF;AACA;AAAA,QACF;AACA,cAAM,sBACJ,cAAc,KAAK,yBAAyB,OAAO,KAAK,KAAK,yBAAyB,KAAK;AAC7F,cAAM,SAAS,sBAAsB,MAAM,KAAK,gCAAgC,EAAE,aAAa,IAAI;AACnG,YAAI,UAAU;AACd,YAAI;AACF,gBAAM,MAAM;AACZ,oBAAU;AACV,cAAI,QAAQ;AACV,gBAAI;AACF,oBAAM,KAAK,gCAAgC,EAAE,YAAY,MAAM;AAAA,YACjE,SAAS,KAAK;AACZ,mBAAK,gCAAgC,EAAE,cAAc;AACrD,kBAAI,KAAK,0DAA0D,GAAG,EAAE;AAAA,YAC1E;AAAA,UACF;AACA,gBAAM,KAAK,mCAAmC,QAAQ,MAAM;AAAA,QAC9D,SAAS,KAAK;AACZ,cAAI,UAAU,CAAC,SAAS;AACtB,gBAAI;AACF,oBAAM,KAAK,gCAAgC,EAAE,aAAa,MAAM;AAAA,YAClE,SAAS,cAAc;AACrB,mBAAK,gCAAgC,EAAE,cAAc;AACrD,kBAAI,KAAK,yDAAyD,YAAY,EAAE;AAAA,YAClF;AAAA,UACF;AACA,gBAAM;AAAA,QACR;AAAA,MACF;AACA,UAAI,CAAC,gBAAgB;AACnB,cAAM,OAAO;AAAA,MACf,WAAW,kBAAkB;AAC3B,cAAM,KAAK,8CAA8C,QAAQ,YAAY,CAAC,iBAAiB,YAAY,CAAC;AAAA,MAC9G,OAAO;AACL,cAAM,KAAK,qCAAqC,QAAQ,UAAU;AAAA,MACpE;AACA,UAAI,kBAAkB,OAAW;AACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,qCAAqC,QAAgB,SAAgC;AACnG,UAAM,UAAU,KAAK,oCAAoC;AACzD,UAAM,QAAQ,QAAQ,cAAc,QAAQ,OAAO,KAAK;AACxD,UAAM,0BAA0BA,MAAK,QAAQ,QAAQ,QAAQ,GAAG,QAAQ,YAAY;AAClF,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,QACA,MAAM,KAAK,wBAAwB,QAAQ,MAAM,KAAK,uBAAuB,QAAQ,OAAO,CAAC;AAAA,MAC/F;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,yCACZ,QACA,QACoC;AACpC,UAAM,cAAc,KAAK,oCAAoC,EAAE;AAC/D,QAAI,CAAC,YAAa,QAAO,EAAE,OAAO,MAAM,OAAO;AAE/C,UAAM,WAAW,OAAO,OAAO,aAAa,EAAE;AAC9C,UAAM,WAAqB,CAAC;AAC5B,QAAI,gBAAgB;AACpB,QAAI;AACJ,eAAS;AACP,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAI,KAAK,KAAM;AACf,UAAI,gBAAgB,KAAK,MAAM,SAAS,iCAAiC;AACvE,wBAAgB,KAAK;AACrB;AAAA,MACF;AACA,uBAAiB,KAAK,MAAM;AAC5B,eAAS,KAAK,KAAK,KAAK;AAAA,IAC1B;AACA,UAAM,WAAW;AACjB,QAAI,aAAa,QAAW;AAC1B,UAAI,QAA2B;AAC/B,UAAI;AACF,gBAAQ,YAAY,QAAQ,OAAO,OAAO,QAAQ,CAAC;AAAA,MACrD,QAAQ;AACN,gBAAQ;AAAA,MACV;AACA,YAAM,UAAU,mBAA0C;AACxD,mBAAW,SAAS,SAAU,OAAM;AAAA,MACtC,GAAG;AACH,aAAO,EAAE,OAAO,QAAQ,OAAO;AAAA,IACjC;AAEA,UAAM,UAAU,KAAK,oCAAoC;AACzD,UAAM,YAAYA,MAAK;AAAA,MACrB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,GAAGE,YAAW,CAAC;AAAA,IACjB;AACA,UAAM,gBAAgB,mBAA0C;AAC9D,iBAAW,SAAS,SAAU,OAAM;AACpC,YAAM;AACN,iBAAS;AACP,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAI,KAAK,KAAM;AACf,cAAM,KAAK;AAAA,MACb;AAAA,IACF,GAAG;AACH,QAAI;AACF,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,QAAQ,4BAA4B;AAAA,QACpC,EAAE,QAAQ,MAAM;AAAA,QAChB,QAAQ;AAAA,MACV;AACA,aAAO,MAAM,KAAK,gCAAgC,QAAQ,WAAW,WAAW;AAAA,IAClF,SAAS,KAAK;AACZ,YAAMC,QAAO,SAAS,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACtC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,gCACZ,QACA,WACA,aACoC;AACpC,UAAM,UAAU,KAAK,oCAAoC;AACzD,UAAM,MAAM,QAAQ,uBAAuB;AAC3C,UAAM,aAAa,MAAM,qBAAqB,WAAW,KAAK,QAAQ,SAAS;AAC/E,QAAI,eAAe,MAAM;AACvB,aAAO,EAAE,OAAO,MAAM,QAAQ,KAAK,4BAA4B,SAAS,GAAG,UAAU;AAAA,IACvF;AACA,UAAM,SAAS,MAAM,iBAAiB,WAAW,YAAY,KAAK,QAAQ,SAAS;AACnF,QAAI,QAA2B;AAC/B,QAAI;AACF,cAAQ,YAAY,QAAQ,OAAO,SAAS,GAAG,UAAU,CAAC;AAAA,IAC5D,QAAQ;AACN,cAAQ;AAAA,IACV;AACA,QAAI,UAAU,MAAM;AAClB,aAAO,EAAE,OAAO,MAAM,QAAQ,KAAK,4BAA4B,SAAS,GAAG,UAAU;AAAA,IACvF;AACA,UAAM,mBAAmB,MAAM,KAAK,iCAAiC,WAAW,YAAY,KAAK;AACjG,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,KAAK,4BAA4B,SAAS;AAAA,MAClD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,iCACZ,WACA,YACA,OACsC;AACtC,QAAI,mBAAmB;AACvB,UAAM,kBAAkB,gCAAgC;AAAA,MACtD,OAAO,CAAC,UAAU;AAChB,4BAAoB,MAAM;AAAA,MAC5B;AAAA,MACA,uBAAuB,MAAM;AAC3B,4BAAoB;AAAA,MACtB;AAAA,MACA,yBAAyB,MAAM;AAAA,MAAC;AAAA,IAClC,CAAC;AACD,UAAM,UAAU,KAAK,oCAAoC;AACzD,UAAM,MAAM,QAAQ,uBAAuB;AAC3C,UAAM,uBAAuB,WAAW,YAAY,CAAC,SAAS,gBAAgB,KAAK,IAAI,GAAG,KAAK,QAAQ,SAAS;AAChH,oBAAgB,OAAO;AAEvB,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,YAAY,MAAM,YAAY,iBAAiB,KAAK,KAAK;AAC/D,UAAM,SAAS,CAAC,OAAe,UAA0B,GAAG,KAAK,IAAI,MAAM,MAAM,IAAI,KAAK;AAC1F,UAAM,iBAAiB;AAAA,MACrB,OAAO,YAAY,QAAQ;AAAA,MAC3B,OAAO,aAAa,SAAS;AAAA,MAC7B,WAAW,gBAAgB;AAAA,IAC7B,EAAE,KAAK,GAAG;AACV,QAAI,eAAeC,YAAW,QAAQ;AACtC,QAAI;AACJ,iBAAa,OAAO,cAAc;AAClC,UAAM,qBAAqB,gCAAgC;AAAA,MACzD,OAAO,CAAC,UAAU;AAChB,qBAAa,OAAO,KAAK;AACzB,iCAAyB,OAAO,KAAK;AAAA,MACvC;AAAA,MACA,uBAAuB,MAAM;AAC3B,kCAA0B,aAAa,KAAK,EAAE,OAAO,QAAG;AACxD,qBAAa,OAAO,QAAG;AAAA,MACzB;AAAA,MACA,yBAAyB,CAAC,kBAAkB;AAC1C,YAAI,CAAC,eAAe;AAClB,cAAI,4BAA4B,OAAW,OAAM,IAAI,MAAM,yCAAyC;AACpG,yBAAe;AAAA,QACjB;AACA,kCAA0B;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,CAAC,SAAS,mBAAmB,KAAK,IAAI;AAAA,MACtC;AAAA,MACA,QAAQ;AAAA,IACV;AACA,uBAAmB,OAAO;AAC1B,WAAO;AAAA,MACL,cAAc,aAAa,OAAO,KAAK;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,OAAe,4BAA4B,WAA0C;AACnF,UAAM,UAAU,KAAK,oCAAoC;AACzD,qBAAiB,SAAS;AAAA,MACxB;AAAA,MACA,QAAQ,uBAAuB;AAAA,MAC/B,QAAQ;AAAA,IACV,GAAG;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAgB,2CACd,QACA,QACe;AACf,UAAM,aAAa,KAAK,gCAAgC,EAAE,sCAAsC,MAAM;AACtG,UAAM,WAAsC,aACxC,MAAM,KAAK,yCAAyC,QAAQ,MAAM,IAClE,EAAE,OAAO,MAAM,OAAO;AAC1B,UAAM,mBAAmB,SAAS;AAClC,UAAM,UAAUJ,MAAK,QAAQ,KAAK,oCAAoC,EAAE,QAAQ;AAChF,QAAI;AACF,YAAM,0BAA0B,SAAS,QAAQ,YAAY;AAC3D,cAAM,KAAK;AAAA,UACT;AAAA,UACA,SAAS;AAAA,UACT,MAAM,KAAK,wBAAwB,QAAQ,MAAM,KAAK,6BAA6B,QAAQ,SAAS,MAAM,CAAC;AAAA,UAC3G;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,UAAE;AACA,UAAI,SAAS,cAAc,OAAW,OAAMG,QAAO,SAAS,SAAS,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACvF;AAAA,EACF;AAAA,EAEA,MAAM,qBAAqB,UAAkB,SAAgC;AAC3E,UAAM,SAAS,KAAK,yBAAyB,UAAU,8BAA8B;AACrF,UAAM,KAAK,qCAAqC,QAAQ,OAAO;AAC/D,UAAM,KAAK,oCAAoC,MAAM;AAAA,EACvD;AAAA,EAEA,MAAM,2BAA2B,UAAkB,QAA8C;AAC/F,UAAM,SAAS,KAAK,yBAAyB,UAAU,oCAAoC;AAC3F,UAAM,KAAK,2CAA2C,QAAQ,MAAM;AACpE,UAAM,KAAK,oCAAoC,MAAM;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,oCAAoC,QAA+B;AAC/E,UAAM,WAAW,KAAK,oCAAoC,EAAE;AAC5D,QAAI,CAAC,uBAAuBH,MAAK,QAAQ,QAAQ,GAAG,MAAM,EAAG;AAC7D,UAAM,kCAAkC,QAAQ;AAAA,EAClD;AAAA,EAEA,MAAM,sBAAsB,UAAkB,iBAAgD;AAC5F,UAAM,SAAS,KAAK,yBAAyB,UAAU,+BAA+B;AACtF,UAAM,KAAK,sCAAsC,QAAQ,eAAe;AACxE,UAAM,KAAK,oCAAoC,MAAM;AAAA,EACvD;AAAA,EAEA,MAAgB,sCACd,QACA,iBACe;AACf,UAAM,WAAW,KAAK,oCAAoC,EAAE;AAC5D,UAAM,0BAA0BA,MAAK,QAAQ,QAAQ,GAAG,QAAQ,YAAY;AAC1E,YAAM,KAAK,uCAAuC,QAAQ,MAAM,YAAY;AAC1E,cAAM,KAAK,yBAAyB,QAAQ,eAAe;AAAA,MAC7D,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,wCACD,MACgD;AACnD,WAAO,KAAK,gCAAgC,EAAE,MAAM,GAAG,IAAI;AAAA,EAC7D;AAAA,EAEA,MAAM,sCAAsC,MAAmD;AAC7F,WAAO,KAAK,gCAAgC,EAAE,IAAI,GAAG,IAAI;AAAA,EAC3D;AAAA,EAEA,MAAM,sDAAwE;AAC5E,WAAO,KAAK,gCAAgC,EAAE,gBAAgB;AAAA,EAChE;AAAA,EAEA,MAAgB,uDACd,UACA,aACe;AACf,UAAM,QAAQ,KAAK,gCAAgC;AACnD,QAAI,MAAM,sCAAsC,QAAQ,GAAG;AACzD,YAAM,KAAK,gDAAgD,WAAW;AAAA,IACxE;AAAA,EACF;AAAA,EACA,MAAgB,gDAAgD,aAAqC;AACnG,UAAM,KAAK,gCAAgC,EAAE,yBAAyB,WAAW;AAAA,EACnF;AACF;","names":["createHash","randomUUID","unlink","path","mkdir","path","path","stdout","mkdir","path","result","randomUUID","unlink","createHash"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graph.ts"],"sourcesContent":["/**\n * Multi-Graph Memory (MAGMA/SYNAPSE-inspired, v8.2)\n *\n * Maintains three typed edge graphs:\n * entity.jsonl — memories sharing a named entity (entityRef)\n * time.jsonl — consecutive memories in the same thread/session\n * causal.jsonl — memories linked by causal language heuristics\n *\n * Stored under `<memoryDir>/state/graphs/`.\n * All writes are fail-open: errors are caught/logged, never thrown.\n */\n\nimport { appendFile, mkdir, readFile, stat } from \"node:fs/promises\";\nimport * as path from \"node:path\";\n\nimport { readEdgeConfidence } from \"./graph-edge-reinforcement.js\";\nimport { emitGraphEvent } from \"./graph-events.js\";\nimport type { GraphConstructionCapabilitySet } from \"./capabilities.js\";\n\nexport type GraphType = \"entity\" | \"time\" | \"causal\";\n\nexport interface GraphEdge {\n from: string; // relative memory path (e.g. \"facts/2026-02-22/abc.md\")\n to: string; // relative memory path\n type: GraphType;\n weight: number; // 1.0 default, decay applied during traversal\n label: string; // entity name, threadId, or matched causal phrase\n ts: string; // ISO timestamp of edge creation\n\n // Issue #681 — edge confidence + reinforcement (PR 1/3: schema + primitive only).\n // Both fields are optional so existing edges without confidence still validate.\n // Treat a missing `confidence` as 1.0 (legacy behavior) at read sites.\n // PR 2/3 wires the maintenance decay job; PR 3/3 weights PageRank traversal by confidence.\n confidence?: number; // [0, 1]; missing = 1.0\n lastReinforcedAt?: string; // ISO timestamp of most recent reinforcement\n}\n\nexport interface GraphConfig {\n multiGraphMemoryEnabled: boolean;\n entityGraphEnabled: boolean;\n timeGraphEnabled: boolean;\n causalGraphEnabled: boolean;\n maxGraphTraversalSteps: number;\n graphActivationDecay: number;\n maxEntityGraphEdgesPerMemory: number;\n graphLateralInhibitionEnabled: boolean;\n graphLateralInhibitionBeta: number;\n graphLateralInhibitionTopM: number;\n /**\n * Issue #681 PR 3/3 — minimum edge confidence required for traversal.\n * Edges with confidence below this floor are pruned. Legacy edges\n * (no `confidence` field) are treated as 1.0 and always pass.\n * Range `[0, 1]`. Default 0.2.\n */\n graphTraversalConfidenceFloor: number;\n /**\n * Issue #681 PR 3/3 — number of PageRank-style refinement iterations\n * applied on top of BFS activation. Set to 0 to disable refinement\n * and return raw BFS scores. Default 8.\n */\n graphTraversalPageRankIterations: number;\n /**\n * Issue #1904 — incremental GraphIndex edge cache. When true (the default,\n * and the value when omitted), a single-writer edge append is pushed into the\n * warm edge cache in place (revalidated by file size for cross-process\n * coherence) instead of nulling the cache and paying a full 6 MB re-read +\n * parse on the next traversal. Set false to restore the pre-#1904\n * null-on-every-write behavior. Optional here (unlike the required\n * PluginConfig field parseConfig always sets) so GraphConfig can still be\n * constructed directly with a partial config; only an explicit `false` opts\n * out, so an omitted field keeps the incremental default.\n */\n graphEdgeCacheIncrementalEnabled?: boolean;\n}\n\n/** Default minimum edge confidence required for traversal (issue #681 PR 3/3). */\nexport const DEFAULT_GRAPH_TRAVERSAL_CONFIDENCE_FLOOR = 0.2;\n/** Default PageRank-style refinement iteration count (issue #681 PR 3/3). */\nexport const DEFAULT_GRAPH_TRAVERSAL_PAGERANK_ITERATIONS = 8;\n\n// Causal signal phrases — order matters (most specific first)\nexport const CAUSAL_PHRASES = [\"as a result\", \"led to\", \"because of\", \"therefore\", \"caused\", \"because\"];\n\nexport function graphsDir(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"graphs\");\n}\n\nexport function graphFilePath(memoryDir: string, type: GraphType): string {\n return path.join(graphsDir(memoryDir), `${type}.jsonl`);\n}\n\nexport async function ensureGraphsDir(memoryDir: string): Promise<void> {\n await mkdir(graphsDir(memoryDir), { recursive: true });\n}\n\n// ---------------------------------------------------------------------------\n// Per-graph-file write lock (gotcha #40 promise-chain pattern).\n//\n// Both the append path (`appendEdge`) and the rewrite path used by the\n// decay maintenance job must serialize on the same lock keyed by the\n// JSONL file path. Without this, an extraction can append a new edge\n// between the decay job's read-snapshot and rewrite, silently dropping\n// the appended edge during active traffic (issue #729 / Codex P1).\n// ---------------------------------------------------------------------------\nconst graphWriteLocks = new Map<string, Promise<void>>();\n\n/**\n * Run `fn` while holding the write lock for the given graph JSONL file.\n *\n * The lock is keyed by absolute file path so concurrent writes to\n * different graph types proceed independently. The chain recovers from\n * rejection (gotcha #40) so a single I/O failure does not poison all\n * future writers, but the original error is still surfaced to the\n * caller of `withGraphWriteLock`.\n */\nexport function withGraphWriteLock<T>(filePath: string, fn: () => Promise<T>): Promise<T> {\n const prev = graphWriteLocks.get(filePath) ?? Promise.resolve();\n const next = prev.then(fn, fn);\n graphWriteLocks.set(\n filePath,\n next.then(\n () => undefined,\n () => undefined\n )\n );\n return next;\n}\n\nexport async function appendEdge(memoryDir: string, edge: GraphEdge): Promise<void> {\n await ensureGraphsDir(memoryDir);\n const filePath = graphFilePath(memoryDir, edge.type);\n const line = `${JSON.stringify(edge)}\\n`;\n await withGraphWriteLock(filePath, async () => {\n await appendFile(filePath, line, \"utf8\");\n });\n // Emit edge-added event for SSE subscribers (issue #691 PR 5/5).\n // Fail-open: emitGraphEvent catches listener errors so a bad SSE client\n // can never surface into the extraction pipeline.\n emitGraphEvent(memoryDir, \"edge-added\", {\n source: edge.from,\n target: edge.to,\n kind: edge.type,\n weight: edge.weight,\n label: edge.label,\n confidence: typeof edge.confidence === \"number\" ? edge.confidence : 1.0,\n });\n}\n\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return typeof err === \"object\" && err !== null && \"code\" in err;\n}\n\nfunction parseEdgesJsonl(raw: string, expectedType: GraphType): GraphEdge[] {\n const edges: GraphEdge[] = [];\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (isValidGraphEdge(parsed, expectedType)) {\n edges.push(parsed);\n }\n } catch {\n // skip corrupt lines — fail-open for partial JSONL recovery\n }\n }\n return edges;\n}\n\n/**\n * Read all edges of a given type from the JSONL file.\n * Returns [] if the file doesn't exist or any read error occurs (fail-open).\n *\n * Production traversal callers (recall/PageRank) depend on this fail-open\n * posture so a temporarily missing or unreadable graph file never blocks\n * a recall. Maintenance jobs that need to distinguish ENOENT from real\n * I/O failures must use {@link readEdgesStrict} instead.\n */\nexport async function readEdges(memoryDir: string, type: GraphType): Promise<GraphEdge[]> {\n const filePath = graphFilePath(memoryDir, type);\n try {\n const raw = await readFile(filePath, \"utf8\");\n return parseEdgesJsonl(raw, type);\n } catch {\n return [];\n }\n}\n\n/**\n * Same as {@link readEdges} but only swallows `ENOENT`; all other read\n * errors (`EACCES`, `EIO`, …) are propagated. Used by the graph-edge\n * decay maintenance job so I/O outages surface as a failed run instead\n * of being silently reported as \"no edges to decay\" (issue #729 /\n * Codex P1, line 120).\n */\nexport async function readEdgesStrict(memoryDir: string, type: GraphType): Promise<GraphEdge[]> {\n const filePath = graphFilePath(memoryDir, type);\n try {\n const raw = await readFile(filePath, \"utf8\");\n return parseEdgesJsonl(raw, type);\n } catch (err) {\n if (isNodeError(err) && err.code === \"ENOENT\") {\n return [];\n }\n throw err;\n }\n}\n\n/**\n * Read edges from all enabled graph types.\n */\nexport async function readAllEdges(\n memoryDir: string,\n graphCaps: Pick<GraphConstructionCapabilitySet, \"entityGraph\" | \"timeGraph\" | \"causalGraph\">,\n): Promise<GraphEdge[]> {\n const parts: GraphEdge[][] = await Promise.all([\n graphCaps.entityGraph ? readEdges(memoryDir, \"entity\") : Promise.resolve([]),\n graphCaps.timeGraph ? readEdges(memoryDir, \"time\") : Promise.resolve([]),\n graphCaps.causalGraph ? readEdges(memoryDir, \"causal\") : Promise.resolve([]),\n ]);\n return parts.flat();\n}\n\nexport interface GraphHealthFileStats {\n type: GraphType;\n filePath: string;\n exists: boolean;\n totalLines: number;\n validEdges: number;\n corruptLines: number;\n uniqueNodes: number;\n}\n\nexport interface GraphHealthReport {\n generatedAt: string;\n enabledTypes: GraphType[];\n totals: {\n totalLines: number;\n validEdges: number;\n corruptLines: number;\n uniqueNodes: number;\n };\n files: GraphHealthFileStats[];\n repairGuidance?: string[];\n}\n\nfunction isValidGraphEdge(raw: unknown, expectedType: GraphType): raw is GraphEdge {\n if (!raw || typeof raw !== \"object\") return false;\n const edge = raw as Record<string, unknown>;\n return (\n edge.type === expectedType &&\n typeof edge.from === \"string\" &&\n edge.from.length > 0 &&\n typeof edge.to === \"string\" &&\n edge.to.length > 0 &&\n typeof edge.weight === \"number\" &&\n Number.isFinite(edge.weight) &&\n typeof edge.label === \"string\" &&\n typeof edge.ts === \"string\"\n );\n}\n\nexport async function analyzeGraphHealth(\n memoryDir: string,\n options?: {\n entityGraphEnabled?: boolean;\n timeGraphEnabled?: boolean;\n causalGraphEnabled?: boolean;\n includeRepairGuidance?: boolean;\n }\n): Promise<GraphHealthReport> {\n const enabledTypes: GraphType[] = [];\n if (options?.entityGraphEnabled !== false) enabledTypes.push(\"entity\");\n if (options?.timeGraphEnabled !== false) enabledTypes.push(\"time\");\n if (options?.causalGraphEnabled !== false) enabledTypes.push(\"causal\");\n\n const files: GraphHealthFileStats[] = [];\n const globalNodes = new Set<string>();\n\n for (const type of enabledTypes) {\n const filePath = graphFilePath(memoryDir, type);\n let exists = true;\n let totalLines = 0;\n let validEdges = 0;\n let corruptLines = 0;\n const nodes = new Set<string>();\n\n try {\n const raw = await readFile(filePath, \"utf8\");\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n totalLines += 1;\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isValidGraphEdge(parsed, type)) {\n corruptLines += 1;\n continue;\n }\n validEdges += 1;\n nodes.add(parsed.from);\n nodes.add(parsed.to);\n globalNodes.add(parsed.from);\n globalNodes.add(parsed.to);\n } catch {\n corruptLines += 1;\n }\n }\n } catch {\n exists = false;\n }\n\n files.push({\n type,\n filePath,\n exists,\n totalLines,\n validEdges,\n corruptLines,\n uniqueNodes: nodes.size,\n });\n }\n\n const totals = files.reduce(\n (acc, item) => {\n acc.totalLines += item.totalLines;\n acc.validEdges += item.validEdges;\n acc.corruptLines += item.corruptLines;\n return acc;\n },\n {\n totalLines: 0,\n validEdges: 0,\n corruptLines: 0,\n uniqueNodes: globalNodes.size,\n }\n );\n totals.uniqueNodes = globalNodes.size;\n\n const report: GraphHealthReport = {\n generatedAt: new Date().toISOString(),\n enabledTypes,\n totals,\n files,\n };\n\n if (options?.includeRepairGuidance === true) {\n const guidance: string[] = [];\n if (totals.corruptLines > 0) {\n guidance.push(\n \"Corrupt graph lines detected: back up memory/state/graphs, then rebuild graphs from clean memory replay/extraction runs.\"\n );\n }\n if (totals.validEdges === 0) {\n guidance.push(\n \"No valid edges detected yet: run normal extraction traffic (or replay ingestion) to seed graph files.\"\n );\n }\n if (guidance.length > 0) report.repairGuidance = guidance;\n }\n\n return report;\n}\n\n/**\n * Detect causal signal phrases in text. Returns the first matched phrase, or null.\n */\nexport function detectCausalPhrase(text: string): string | null {\n const lower = text.toLowerCase();\n for (const phrase of CAUSAL_PHRASES) {\n if (lower.includes(phrase)) return phrase;\n }\n return null;\n}\n\n/**\n * GraphIndex — builds and updates the three memory graphs.\n *\n * Usage (orchestrator):\n * this.graphIndex = new GraphIndex(config.memoryDir, config);\n *\n * // After each memory write:\n * await this.graphIndex.onMemoryWritten(memoryPath, frontmatter, threadId, recentInThread);\n */\n/**\n * Identity of one graph JSONL file used to validate the incremental edge cache\n * (issue #1904). An absent file (ENOENT) is recorded as the all-zero sentinel\n * `{ size: 0, mtimeMs: 0, ino: 0 }` so a later peer creation (ino becomes\n * non-zero) is detected as a change.\n */\ninterface GraphFileMeta {\n size: number;\n mtimeMs: number;\n ino: number;\n}\n\nexport class GraphIndex {\n private readonly memoryDir: string;\n private readonly cfg: GraphConfig;\n\n // Cache for readAllEdges() result. With 30k+ entity edges (6 MB JSONL) the\n // file read + JSON parse takes 2-4 s per call. This instance-level cache\n // eliminates that overhead on every spreadingActivation() call; it is\n // invalidated (set to null) in onMemoryWritten() so new edges appear promptly.\n private edgeCache: {\n allEdges: GraphEdge[];\n loadedAt: number;\n // Per-file identity of each enabled graph file observed at load (issue\n // #1904). An incremental push is trusted only when every file's identity is\n // explained entirely by OUR own append: size grows by exactly the bytes we\n // appended and the inode is unchanged (a local append keeps the inode; an\n // external atomic temp+rename rewrite — e.g. the edge-decay job — changes\n // it). Untouched files must match size AND mtime AND inode exactly. This\n // closes the size-only holes Codex flagged: a peer append racing cache\n // construction, and an equal-length atomic rewrite (e.g. confidence\n // 0.9->0.8) that preserves byte length. Any divergence forces a full reload.\n meta: Partial<Record<GraphType, GraphFileMeta>>;\n } | null = null;\n private static readonly EDGE_CACHE_TTL_MS = 300_000; // 5 minutes\n\n constructor(memoryDir: string, cfg: GraphConfig) {\n this.memoryDir = memoryDir;\n this.cfg = cfg;\n }\n\n /** Clear the edge cache so the next spreadingActivation() re-reads from disk.\n * Call after any code path that appends edges outside of onMemoryWritten(). */\n invalidateEdgeCache(): void {\n this.edgeCache = null;\n }\n\n private async loadEdgesCached(): Promise<GraphEdge[]> {\n if (this.edgeCache && Date.now() - this.edgeCache.loadedAt < GraphIndex.EDGE_CACHE_TTL_MS) {\n return this.edgeCache.allEdges;\n }\n // Consistent snapshot (issue #1904, Codex): capture file identity BEFORE and\n // AFTER reading edges and retry if it changed, so `allEdges` and the recorded\n // `meta` baseline reflect the SAME on-disk state. Without this a peer append\n // landing mid-read would leave the cache holding edges that exclude the peer\n // edge while the baseline already counts its bytes — a later local append\n // would then pass the size-delta check and silently omit the peer edge.\n let allEdges: GraphEdge[] = [];\n let meta = await this.readEnabledGraphFileMeta();\n let stable = false;\n for (let attempt = 0; attempt < 3; attempt++) {\n const before = meta;\n allEdges = await readAllEdges(this.memoryDir, {\n entityGraph: this.cfg.entityGraphEnabled,\n timeGraph: this.cfg.timeGraphEnabled,\n causalGraph: this.cfg.causalGraphEnabled,\n });\n meta = await this.readEnabledGraphFileMeta();\n if (this.graphFileMetaEqual(before, meta)) {\n stable = true;\n break;\n }\n // A write landed during the read; the just-captured `meta` is the new\n // baseline for the next attempt's before-snapshot.\n }\n if (stable) {\n this.edgeCache = { allEdges, loadedAt: Date.now(), meta };\n } else {\n // Contended: a peer kept writing across every attempt, so the final\n // allEdges/meta pair is not guaranteed consistent. Serve THIS read's edges\n // (best effort) but do NOT poison the cache — leave it null so the next\n // call re-reads, instead of installing a baseline that could hide a peer\n // edge for the TTL (Codex).\n this.edgeCache = null;\n }\n return allEdges;\n }\n\n /**\n * Identity ({ size, mtimeMs, ino }) of each ENABLED graph file (issue #1904).\n * Missing files (ENOENT) and any stat error map to the all-zero sentinel so\n * the baseline is fail-open: a later revalidation sees a mismatch (or a peer\n * creation flipping ino from 0 to non-zero) and forces a full reload rather\n * than trusting a stale incremental push.\n */\n private async readEnabledGraphFileMeta(): Promise<Partial<Record<GraphType, GraphFileMeta>>> {\n const enabled: GraphType[] = [];\n if (this.cfg.entityGraphEnabled) enabled.push(\"entity\");\n if (this.cfg.timeGraphEnabled) enabled.push(\"time\");\n if (this.cfg.causalGraphEnabled) enabled.push(\"causal\");\n const meta: Partial<Record<GraphType, GraphFileMeta>> = {};\n for (const type of enabled) {\n try {\n const st = await stat(graphFilePath(this.memoryDir, type));\n meta[type] = { size: st.size, mtimeMs: st.mtimeMs, ino: Number(st.ino) };\n } catch {\n meta[type] = { size: 0, mtimeMs: 0, ino: 0 };\n }\n }\n return meta;\n }\n\n /** True iff both metadata maps carry identical identity for every key. */\n private graphFileMetaEqual(\n a: Partial<Record<GraphType, GraphFileMeta>>,\n b: Partial<Record<GraphType, GraphFileMeta>>,\n ): boolean {\n const types: GraphType[] = [\"entity\", \"time\", \"causal\"];\n for (const type of types) {\n const x = a[type];\n const y = b[type];\n if (!x && !y) continue;\n if (!x || !y) return false;\n if (x.size !== y.size || x.mtimeMs !== y.mtimeMs || x.ino !== y.ino) return false;\n }\n return true;\n }\n\n /**\n * Re-stat every graph file whose identity the cache just committed and return\n * false if any has moved since (issue #1904, Codex). Closes the validation→\n * in-place-push TOCTOU window: a peer process (concurrent CLI / daemon /\n * decay job) can append between edgeFilesUnchangedExceptOurAppends()'s final\n * stat and the allEdges.push(...). Without this re-check the cache would be\n * accepted with identity predating the peer write and miss the peer edge for\n * the TTL. A residual infinitesimal window (peer writes during this re-stat)\n * remains and is TTL-bounded.\n */\n private async edgeCacheIdentityUnchangedSinceCommit(): Promise<boolean> {\n if (!this.edgeCache) return false;\n for (const type of Object.keys(this.edgeCache.meta) as GraphType[]) {\n const committed = this.edgeCache.meta[type];\n if (!committed) continue;\n let cur: GraphFileMeta;\n try {\n const st = await stat(graphFilePath(this.memoryDir, type));\n cur = { size: st.size, mtimeMs: st.mtimeMs, ino: Number(st.ino) };\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") {\n cur = { size: 0, mtimeMs: 0, ino: 0 };\n } else {\n return false;\n }\n }\n if (\n cur.size !== committed.size ||\n cur.mtimeMs !== committed.mtimeMs ||\n cur.ino !== committed.ino\n ) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Called after a memory is written to disk.\n *\n * @param memoryPath - relative path from memoryDir (e.g. \"facts/2026-02-22/abc.md\")\n * @param entityRef - entityRef frontmatter field (if any)\n * @param content - full memory text (for causal detection)\n * @param created - ISO timestamp of this memory\n * @param threadId - current thread ID (for time graph)\n * @param recentInThread - paths of the N most-recent memories in this thread (for time graph)\n * @param entitySiblings - paths of other memories that share the same entityRef (for entity graph)\n */\n async onMemoryWritten(opts: {\n memoryPath: string;\n entityRef?: string;\n content: string;\n created: string;\n threadId?: string;\n recentInThread?: string[];\n entitySiblings?: string[];\n causalPredecessor?: string;\n /**\n * Optional frozen gate overrides (from GraphConstructionCapabilitySet).\n * When provided, these take precedence over `this.cfg` so the caller's\n * operation-scoped snapshot is the single source of truth (#1566).\n */\n graphCapsOverride?: {\n entityGraph: boolean;\n timeGraph: boolean;\n causalGraph: boolean;\n multiGraphMemory: boolean;\n };\n }): Promise<void> {\n const g = opts.graphCapsOverride;\n const multiGraphOn = g ? g.multiGraphMemory : this.cfg.multiGraphMemoryEnabled;\n if (!multiGraphOn) return;\n const entityOn = g ? g.entityGraph : this.cfg.entityGraphEnabled;\n const timeOn = g ? g.timeGraph : this.cfg.timeGraphEnabled;\n const causalOn = g ? g.causalGraph : this.cfg.causalGraphEnabled;\n const ts = new Date().toISOString();\n // Collect the edges appended this call so a coherent single-writer push can\n // extend the warm edge cache in place instead of nulling it (issue #1904).\n const appended: GraphEdge[] = [];\n\n try {\n // Entity graph\n if (entityOn && opts.entityRef && opts.entitySiblings?.length) {\n const siblings = opts.entitySiblings.slice(0, this.cfg.maxEntityGraphEdgesPerMemory);\n for (const sibling of siblings) {\n const edge: GraphEdge = {\n from: opts.memoryPath,\n to: sibling,\n type: \"entity\",\n weight: 1.0,\n label: opts.entityRef,\n ts,\n };\n appended.push(edge);\n await appendEdge(this.memoryDir, edge);\n }\n }\n\n // Time graph — link to most recent memory in same thread\n if (timeOn && opts.threadId && opts.recentInThread?.length) {\n const predecessor = opts.recentInThread[opts.recentInThread.length - 1];\n if (predecessor && predecessor !== opts.memoryPath) {\n const edge: GraphEdge = {\n from: predecessor,\n to: opts.memoryPath,\n type: \"time\",\n weight: 1.0,\n label: opts.threadId,\n ts,\n };\n appended.push(edge);\n await appendEdge(this.memoryDir, edge);\n }\n }\n\n // Causal graph\n if (causalOn && opts.causalPredecessor) {\n const phrase = detectCausalPhrase(opts.content);\n if (phrase) {\n const edge: GraphEdge = {\n from: opts.causalPredecessor,\n to: opts.memoryPath,\n type: \"causal\",\n weight: 1.0,\n label: phrase,\n ts,\n };\n appended.push(edge);\n await appendEdge(this.memoryDir, edge);\n }\n }\n } catch (err) {\n // Fail-open: graph write errors must never surface to caller\n const { log } = await import(\"./logger.js\");\n log.warn(`[graph] onMemoryWritten error: ${err}`);\n } finally {\n // Edge-cache coherence (issue #1904). Legacy behavior nulled the cache on\n // every write, paying a 2-4 s full re-read + parse on the next traversal.\n if (!this.edgeCache || Date.now() - this.edgeCache.loadedAt >= GraphIndex.EDGE_CACHE_TTL_MS) {\n // Nothing warm, or the entry is past its 5-min TTL backstop — reload.\n this.edgeCache = null;\n } else if (this.cfg.graphEdgeCacheIncrementalEnabled === false) {\n // Rollback lever: restore the pre-#1904 null-on-every-write behavior.\n this.edgeCache = null;\n } else {\n // Trust an in-place push ONLY when WE are the sole writer since load:\n // every enabled graph file's on-disk size must equal our baseline plus\n // exactly the bytes we appended to it. A divergence means a peer process\n // (backup daemon / CLI / decay job) also wrote — force a full reload for\n // cross-process coherence. Any stat error fails open to a full reload.\n try {\n if (await this.edgeFilesUnchangedExceptOurAppends(appended)) {\n if (appended.length > 0) {\n this.edgeCache.allEdges.push(...appended);\n // Close the validation→push TOCTOU window (#1904, Codex): a peer\n // process can append between the validation stat above and this\n // in-place push. Re-verify every committed identity; if any file\n // moved, the cache would miss the peer edge for the TTL, so null\n // it and let the next traversal reload. (Skipped when this call\n // pushed nothing — no new window was opened, and the validation\n // already confirmed no peer wrote.)\n if (this.edgeCache && !(await this.edgeCacheIdentityUnchangedSinceCommit())) {\n this.edgeCache = null;\n }\n }\n } else {\n this.edgeCache = null;\n }\n } catch {\n this.edgeCache = null;\n }\n }\n }\n }\n\n /**\n * Cross-process coherence check for the incremental edge cache (issue #1904).\n *\n * Returns true iff every ENABLED graph file's current identity is explained\n * ENTIRELY by THIS call's own append — no other process wrote to any graph\n * file since load. Per file:\n * - inode must be unchanged. A local append (`appendFile`) keeps the inode;\n * an external atomic temp+rename rewrite (e.g. the edge-decay job) changes\n * it, so an inode change — even one that preserves byte length, such as\n * decaying confidence 0.9->0.8 — forces a reload (Codex).\n * - a file WE appended to (delta > 0): size must equal baseline + our exact\n * appended bytes. If it was absent at load (sentinel ino 0), our append\n * created it, so we accept size === delta and adopt the new identity.\n * - a file we did NOT touch (delta 0): size AND mtime must be unchanged, so\n * an in-place equal-length rewrite (mtime bump) or a peer append (size\n * bump) both force a reload.\n * On success it commits the new identity baseline so the next append\n * revalidates against post-this-write truth. Fail-open: an unreadable file\n * (non-ENOENT) returns false, forcing a full reload.\n */\n private async edgeFilesUnchangedExceptOurAppends(appended: GraphEdge[]): Promise<boolean> {\n if (!this.edgeCache) return false;\n const expectedDelta: Partial<Record<GraphType, number>> = {};\n for (const edge of appended) {\n const bytes = Buffer.byteLength(`${JSON.stringify(edge)}\\n`, \"utf8\");\n expectedDelta[edge.type] = (expectedDelta[edge.type] ?? 0) + bytes;\n }\n const enabled: GraphType[] = [];\n if (this.cfg.entityGraphEnabled) enabled.push(\"entity\");\n if (this.cfg.timeGraphEnabled) enabled.push(\"time\");\n if (this.cfg.causalGraphEnabled) enabled.push(\"causal\");\n const observed: Partial<Record<GraphType, GraphFileMeta>> = {};\n for (const type of enabled) {\n let cur: GraphFileMeta;\n try {\n const st = await stat(graphFilePath(this.memoryDir, type));\n cur = { size: st.size, mtimeMs: st.mtimeMs, ino: Number(st.ino) };\n } catch (err) {\n // An absent graph file (ENOENT) is the normal partially-populated state\n // (e.g. entity edges written before any causal edge): treat it as the\n // all-zero sentinel so the incremental cache stays warm. Only a genuine\n // stat failure forces a full reload (#1904, Codex).\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") {\n cur = { size: 0, mtimeMs: 0, ino: 0 };\n } else {\n return false;\n }\n }\n const base = this.edgeCache.meta[type] ?? { size: 0, mtimeMs: 0, ino: 0 };\n const delta = expectedDelta[type] ?? 0;\n if (delta > 0) {\n if (base.ino === 0) {\n // File was absent at load; our append created it. Accept iff its whole\n // size is exactly our appended bytes (nothing else wrote it).\n if (cur.ino === 0 || cur.size !== delta) return false;\n } else {\n // Existing file: our append keeps the inode and grows size by exactly\n // our bytes. An atomic rewrite (ino change) or a peer append (size\n // mismatch) both fail here.\n if (cur.ino !== base.ino || cur.size !== base.size + delta) return false;\n }\n } else {\n // Untouched file: identity must be byte-for-byte unchanged.\n if (cur.ino !== base.ino || cur.size !== base.size || cur.mtimeMs !== base.mtimeMs) {\n return false;\n }\n }\n observed[type] = cur;\n }\n this.edgeCache.meta = observed;\n return true;\n }\n\n /**\n * Spreading activation BFS (SYNAPSE-inspired).\n *\n * Starting from `seeds`, traverse the combined graph for up to `maxSteps` hops.\n * Each candidate gets an activation score = edge.weight × edgeConfidence × decay^hop.\n *\n * Issue #681 PR 3/3 — confidence-aware traversal:\n * - Each edge's `weight` is multiplied by its `confidence` (legacy edges\n * missing `confidence` are treated as 1.0, preserving prior behavior).\n * - Edges with `confidence < graphTraversalConfidenceFloor` are pruned and\n * contribute neither activation nor downstream neighbors.\n * - When `graphTraversalPageRankIterations > 0`, an additional PageRank-\n * style refinement pass redistributes activation along confidence-weighted\n * edges, sharpening the ranking among multi-hop candidates.\n * - Per-result provenance includes the highest-confidence edge that landed\n * on each candidate, so the X-ray surface can attribute pruning and\n * ranking decisions back to specific edges.\n *\n * @param seeds - initial memory paths to expand from (e.g. QMD top results)\n * @param maxSteps - max BFS hops (from config: maxGraphTraversalSteps)\n * @returns Array of {path, score, edgeConfidence, ...} sorted descending, not including seed paths\n */\n async spreadingActivation(\n seeds: string[],\n maxSteps?: number,\n opts?: {\n /**\n * Issue #681 — when `true`, bypasses the configured\n * `graphTraversalConfidenceFloor` and includes low-confidence\n * edges in traversal. Equivalent to forcing the floor to `0`.\n * Default `false` (floor from config is applied).\n */\n includeLowConfidence?: boolean;\n /** Absolute deadline in ms-since-epoch for post-retrieval assembly. */\n deadlineAtMs?: number;\n }\n ): Promise<\n Array<{\n path: string;\n score: number;\n seed: string;\n hopDepth: number;\n decayedWeight: number;\n graphType: \"entity\" | \"time\" | \"causal\";\n /**\n * Confidence of the edge that produced this candidate's recorded\n * provenance (the strongest edge along the chosen entry path).\n * In `[0, 1]`. Legacy edges without `confidence` surface as 1.0.\n */\n edgeConfidence: number;\n }>\n > {\n if (!this.cfg.multiGraphMemoryEnabled) return [];\n const steps = maxSteps ?? this.cfg.maxGraphTraversalSteps;\n const decay = this.cfg.graphActivationDecay;\n // When `includeLowConfidence` is set, use floor=0 so all edges\n // participate in traversal regardless of their decay state.\n // Otherwise clamp the configured floor into [0, 1] so misconfiguration\n // cannot (a) admit edges with negative confidence or (b) reject every\n // edge.\n const floor =\n opts?.includeLowConfidence === true ? 0 : clampConfidenceFloor(this.cfg.graphTraversalConfidenceFloor);\n const iterations = clampPageRankIterations(this.cfg.graphTraversalPageRankIterations);\n const deadlineAtMs = opts?.deadlineAtMs;\n const deadlineExpired = (): boolean =>\n typeof deadlineAtMs === \"number\" && Date.now() >= deadlineAtMs;\n\n try {\n if (deadlineExpired()) return [];\n const allEdges = await this.loadEdgesCached();\n if (deadlineExpired()) return [];\n\n // Build adjacency index: from → edges, to → edges (bidirectional for entity/time, directional for causal).\n // Edges below the confidence floor are pruned at index time so neither\n // direct activation nor downstream BFS expansion can re-introduce them.\n const adj = new Map<string, GraphEdge[]>();\n for (let i = 0; i < allEdges.length; i += 1) {\n if ((i & 1023) === 0 && deadlineExpired()) return [];\n const edge = allEdges[i];\n const conf = readEdgeConfidence(edge);\n if (conf < floor) continue;\n if (!adj.has(edge.from)) adj.set(edge.from, []);\n adj.get(edge.from)!.push(edge);\n // Entity and time edges are bidirectional\n if (edge.type !== \"causal\") {\n if (!adj.has(edge.to)) adj.set(edge.to, []);\n adj.get(edge.to)!.push({ ...edge, from: edge.to, to: edge.from });\n }\n }\n\n const seedSet = new Set(seeds);\n const scores = new Map<string, number>(); // candidate path → accumulated activation score\n const provenance = new Map<\n string,\n {\n seed: string;\n hopDepth: number;\n decayedWeight: number;\n graphType: \"entity\" | \"time\" | \"causal\";\n edgeConfidence: number;\n }\n >();\n let frontier = new Map<string, { node: string; seed: string; activation: number }>();\n const reachedBySeed = new Map<string, Set<string>>();\n for (const seed of seeds) {\n frontier.set(`${seed}\\0${seed}`, { node: seed, seed, activation: 1 });\n reachedBySeed.set(seed, new Set([seed]));\n }\n const finalizeScores = () =>\n Array.from(scores.entries())\n .map(([p, score]) => ({\n path: p,\n score,\n seed: provenance.get(p)?.seed ?? \"\",\n hopDepth: provenance.get(p)?.hopDepth ?? 0,\n decayedWeight: provenance.get(p)?.decayedWeight ?? 0,\n graphType: provenance.get(p)?.graphType ?? \"entity\",\n edgeConfidence: provenance.get(p)?.edgeConfidence ?? 1,\n }))\n .sort((a, b) => b.score - a.score);\n\n for (let hop = 0; hop < steps && frontier.size > 0; hop++) {\n if (deadlineExpired()) return finalizeScores();\n const nextFrontier = new Map<string, { node: string; seed: string; activation: number }>();\n\n for (const { node, seed: sourceSeed, activation } of frontier.values()) {\n const edges = adj.get(node) ?? [];\n for (let i = 0; i < edges.length; i += 1) {\n if ((i & 1023) === 0 && deadlineExpired()) return finalizeScores();\n const edge = edges[i];\n const neighbor = edge.to === node ? edge.from : edge.to;\n const conf = readEdgeConfidence(edge);\n // Defense in depth: the adjacency build already drops sub-floor\n // edges, but if a synthesized reverse edge ever bypassed that\n // path, this guard keeps spreading activation honest.\n if (conf < floor) continue;\n const score = activation * edge.weight * conf * decay;\n const reachedForSeed = reachedBySeed.get(sourceSeed);\n if (reachedForSeed?.has(neighbor)) {\n continue;\n }\n\n if (!seedSet.has(neighbor)) {\n const existing = scores.get(neighbor) ?? 0;\n scores.set(neighbor, existing + score);\n\n const prev = provenance.get(neighbor);\n if (!prev || hop + 1 < prev.hopDepth || (hop + 1 === prev.hopDepth && score > prev.decayedWeight)) {\n provenance.set(neighbor, {\n seed: sourceSeed,\n hopDepth: hop + 1,\n decayedWeight: score,\n graphType: edge.type,\n edgeConfidence: conf,\n });\n }\n\n if (hop + 1 < steps) {\n const frontierKey = `${sourceSeed}\\0${neighbor}`;\n const existingFrontier = nextFrontier.get(frontierKey);\n if (existingFrontier) {\n existingFrontier.activation += score;\n } else {\n nextFrontier.set(frontierKey, {\n node: neighbor,\n seed: sourceSeed,\n activation: score,\n });\n }\n }\n }\n }\n }\n\n for (const { node, seed } of nextFrontier.values()) {\n reachedBySeed.get(seed)?.add(node);\n }\n frontier = nextFrontier;\n }\n\n // Issue #681 PR 3/3 — optional PageRank-style refinement.\n // Redistributes a node's accumulated activation along its outgoing\n // edges, weighted by edge confidence. Damping is fixed at the\n // canonical 0.85 so the ranking stays comparable across queries;\n // the `iterations` knob bounds compute, not behavior shape.\n if (!deadlineExpired() && iterations > 0 && scores.size > 1) {\n applyPageRankRefinement(scores, adj, {\n iterations,\n floor,\n damping: 0.85,\n deadlineAtMs,\n });\n }\n\n // Apply lateral inhibition if enabled (Synapse-inspired competitive suppression)\n if (deadlineExpired()) return finalizeScores();\n if (this.cfg.graphLateralInhibitionEnabled && scores.size > 1) {\n const inhibited = applyLateralInhibition(scores, {\n beta: this.cfg.graphLateralInhibitionBeta,\n topM: this.cfg.graphLateralInhibitionTopM,\n });\n for (const [k, v] of inhibited) {\n scores.set(k, v);\n }\n }\n\n return finalizeScores();\n } catch (err) {\n const { log } = await import(\"./logger.js\");\n log.warn(`[graph] spreadingActivation error: ${err}`);\n return [];\n }\n }\n}\n\n/**\n * Clamp `graphTraversalConfidenceFloor` into the legal range `[0, 1]`.\n * Non-finite or non-numeric values fall back to the documented default\n * so misconfiguration cannot silently disable the floor or reject every edge.\n *\n * Exported for tests; call sites in `spreadingActivation` use it to make\n * the contract explicit at every boundary.\n */\nexport function clampConfidenceFloor(raw: unknown): number {\n if (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n return DEFAULT_GRAPH_TRAVERSAL_CONFIDENCE_FLOOR;\n }\n if (raw < 0) return 0;\n if (raw > 1) return 1;\n return raw;\n}\n\n/**\n * Clamp `graphTraversalPageRankIterations` into a non-negative integer.\n * Negative or non-finite values fall back to 0 (disable refinement) so\n * misconfiguration cannot stall recall in an unbounded loop.\n */\nexport function clampPageRankIterations(raw: unknown): number {\n if (typeof raw !== \"number\" || !Number.isFinite(raw)) return 0;\n if (raw <= 0) return 0;\n return Math.floor(raw);\n}\n\n/**\n * PageRank-style refinement on top of the BFS activation map.\n *\n * Each iteration redistributes a fraction of every node's score along\n * its outgoing edges, scaled by edge confidence. Confidence below\n * `floor` is filtered out before redistribution, mirroring the BFS\n * pruning rule. Mutates `scores` in place.\n *\n * Exported for tests; in production, call sites pass the same adjacency\n * map already used by BFS so behavior stays consistent.\n */\nexport function applyPageRankRefinement(\n scores: Map<string, number>,\n adj: Map<string, GraphEdge[]>,\n opts: { iterations: number; floor: number; damping: number; deadlineAtMs?: number }\n): void {\n const { iterations, floor, damping, deadlineAtMs } = opts;\n if (iterations <= 0 || scores.size === 0) return;\n const safeDamping = Math.min(1, Math.max(0, damping));\n const deadlineExpired = (): boolean =>\n typeof deadlineAtMs === \"number\" && Date.now() >= deadlineAtMs;\n\n // Pre-compute confidence-weighted out-edge totals for normalization.\n // Done once per refinement, not per iteration, since adjacency is\n // immutable inside the loop.\n //\n // Codex P1 (#735): the denominator MUST be computed over the same\n // eligible-neighbor set the iteration redistributes into — i.e.\n // edges whose neighbor is in `scores`. Counting edges-to-seeds (or\n // edges-to-unseen-nodes) in the denominator while dropping their\n // flow during iteration leaks `safeDamping × score` every pass and\n // collapses leaf candidates' scores instead of just re-ranking them.\n const eligible = (edge: GraphEdge, fromNode: string): boolean => {\n if (readEdgeConfidence(edge) < floor) return false;\n const neighbor = edge.to === fromNode ? edge.from : edge.to;\n return scores.has(neighbor);\n };\n const outboundTotal = new Map<string, number>();\n for (const [node, edges] of adj.entries()) {\n if (deadlineExpired()) return;\n if (!scores.has(node)) continue; // only candidate nodes redistribute\n let sum = 0;\n for (const edge of edges) {\n if (!eligible(edge, node)) continue;\n sum += readEdgeConfidence(edge) * edge.weight;\n }\n if (sum > 0) outboundTotal.set(node, sum);\n }\n\n for (let i = 0; i < iterations; i += 1) {\n if (deadlineExpired()) return;\n const next = new Map<string, number>();\n // Teleport / damping floor: every node retains `(1 - damping) * score`\n // of its current activation so dangling nodes do not bleed to zero.\n for (const [node, score] of scores) {\n next.set(node, (1 - safeDamping) * score);\n }\n for (const [node, score] of scores) {\n const outEdges = adj.get(node);\n const total = outboundTotal.get(node);\n // Dangling-node fallback: when a candidate has zero eligible\n // outflow (no in-scores neighbors above the floor), the\n // `safeDamping × score` portion would otherwise evaporate. Keep\n // it on `node` so total mass is conserved and the score reflects\n // the candidate's standing rather than its in-degree topology.\n if (!outEdges || outEdges.length === 0 || !total || total <= 0) {\n next.set(node, (next.get(node) ?? 0) + safeDamping * score);\n continue;\n }\n for (let edgeIndex = 0; edgeIndex < outEdges.length; edgeIndex += 1) {\n if ((edgeIndex & 1023) === 0 && deadlineExpired()) return;\n const edge = outEdges[edgeIndex];\n if (!eligible(edge, node)) continue;\n const conf = readEdgeConfidence(edge);\n const neighbor = edge.to === node ? edge.from : edge.to;\n const flow = safeDamping * score * ((conf * edge.weight) / total);\n next.set(neighbor, (next.get(neighbor) ?? 0) + flow);\n }\n }\n for (const [node, score] of next) {\n scores.set(node, score);\n }\n }\n}\n\n/**\n * Lateral inhibition (Synapse-inspired).\n *\n * For each node, the top-M higher-activation competitors exert inhibition\n * proportional to their activation difference. Output is clamped to [0, ∞).\n *\n * No sigmoid is applied here — downstream `normalizeGraphActivationScore`\n * already applies x/(1+x) soft squash, so adding a sigmoid would double-\n * normalize and cap graph influence at ~50%.\n *\n * Formula: u_hat_i = max(0, u_i - beta * sum_{k in top-M where u_k > u_i}(u_k - u_i))\n *\n * When beta=0 or topM=0, returns original scores unchanged (no-op).\n */\nexport function applyLateralInhibition(\n scores: Map<string, number>,\n opts: { beta: number; topM: number }\n): Map<string, number> {\n const { beta, topM } = opts;\n if (beta === 0 || topM === 0) return new Map(scores);\n\n const sorted = Array.from(scores.entries()).sort((a, b) => b[1] - a[1]);\n const topCompetitors = sorted.slice(0, topM);\n\n const result = new Map<string, number>();\n for (const [node, u] of scores) {\n let inhibition = 0;\n for (const [, uK] of topCompetitors) {\n if (uK > u) {\n inhibition += uK - u;\n }\n }\n result.set(node, Math.max(0, u - beta * inhibition));\n }\n\n return result;\n}\n"],"mappings":"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","names":[]}
|