@remnic/core 9.54.4 → 9.54.6
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 +24 -23
- package/dist/access-admin-ops-surface.js +55 -50
- package/dist/access-authorization-probe.d.ts +25 -22
- package/dist/access-authorization-probe.js +58 -51
- package/dist/access-boundary.d.ts +26 -23
- package/dist/access-boundary.js +59 -52
- package/dist/access-cli.js +115 -107
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +19 -18
- package/dist/access-extraction-force-flush.js +55 -50
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +22 -21
- package/dist/access-http-lifecycle-flush.d.ts +22 -21
- package/dist/access-http-offline-stream.d.ts +19 -18
- package/dist/access-http-query.js +55 -50
- package/dist/access-http.d.ts +55 -36
- package/dist/access-http.js +76 -65
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +55 -50
- package/dist/access-lcm-surface.d.ts +21 -20
- package/dist/access-lcm-surface.js +55 -50
- package/dist/access-mcp.d.ts +22 -21
- package/dist/access-mcp.js +63 -57
- package/dist/access-memory-search-fanout.d.ts +22 -2
- package/dist/access-memory-search-fanout.js +1 -1
- package/dist/{access-namespace-preflight-C7n4tgWC.d.ts → access-namespace-preflight-CCNn_6NE.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +55 -50
- package/dist/access-observe-write-surface.d.ts +22 -21
- package/dist/access-observe-write-surface.js +55 -50
- package/dist/access-offline-manifest.d.ts +10 -9
- package/dist/access-offline-manifest.js +12 -10
- package/dist/access-operations-batch.js +57 -52
- package/dist/access-operations.d.ts +23 -22
- package/dist/access-operations.js +61 -55
- package/dist/access-recall-concurrency.d.ts +21 -20
- package/dist/access-recall-concurrency.js +55 -50
- package/dist/access-recall-response.d.ts +19 -18
- package/dist/access-recall-response.js +55 -50
- package/dist/access-recall-surface.d.ts +19 -18
- package/dist/access-recall-surface.js +55 -50
- package/dist/access-schema.d.ts +2 -2
- package/dist/access-schema.js +5 -4
- package/dist/{access-service-CXvbxLK-.d.ts → access-service-DkSdXK4S.d.ts} +1314 -83
- package/dist/access-service-helpers.d.ts +22 -21
- package/dist/access-service.d.ts +31 -30
- package/dist/access-service.js +55 -50
- package/dist/access-surface-catalog.d.ts +22 -21
- package/dist/access-surface-catalog.js +209 -2
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +14 -1
- package/dist/active-memory-bridge.js +6 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +4 -2
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/admin-console/public/what-helps-me/app.js +1594 -0
- package/dist/admin-console/public/what-helps-me/index.html +339 -0
- package/dist/admin-console/public/what-helps-me/model.js +685 -0
- package/dist/admin-console/public/what-helps-me/what-helps-me.css +1296 -0
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-TDHLZPVP.js → auto-sync-NR3GPCOA.js} +4 -4
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +33 -12
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +3 -3
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-BOOxl-I2.d.ts → catalog-DGFf8mD9.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +34 -13
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-ZYLC7NFO.js → chunk-26ZXBTYN.js} +4 -4
- package/dist/chunk-26ZXBTYN.js.map +1 -0
- package/dist/{chunk-LLJMAULE.js → chunk-2FKEIPIT.js} +5 -5
- package/dist/{chunk-3CSX3ETE.js → chunk-2LWQSV6A.js} +23 -11
- package/dist/chunk-2LWQSV6A.js.map +1 -0
- package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
- package/dist/chunk-37DZZFFM.js +502 -0
- package/dist/chunk-37DZZFFM.js.map +1 -0
- package/dist/chunk-3HSRWJTC.js +9 -0
- package/dist/chunk-3HSRWJTC.js.map +1 -0
- package/dist/{chunk-XUAMCLY4.js → chunk-3TIZPSJC.js} +17 -13
- package/dist/chunk-3TIZPSJC.js.map +1 -0
- package/dist/{chunk-PDDTI7IC.js → chunk-43SEBY2M.js} +1 -1
- package/dist/{chunk-HWRD23DW.js → chunk-46SZBVDS.js} +3 -3
- package/dist/{chunk-6HPHEFXT.js → chunk-5FD7JMTX.js} +2 -2
- package/dist/{chunk-7BZOBA5J.js → chunk-5NB726GV.js} +70 -16
- package/dist/chunk-5NB726GV.js.map +1 -0
- package/dist/chunk-62OKGIJA.js +39 -0
- package/dist/chunk-62OKGIJA.js.map +1 -0
- package/dist/{chunk-IBKR2TFR.js → chunk-6CYHUWCO.js} +2 -2
- package/dist/{chunk-YN6ASZUG.js → chunk-6QPI2ITJ.js} +5 -5
- package/dist/{chunk-UU3G6GUP.js → chunk-76JJSXK7.js} +1 -1
- package/dist/chunk-76JJSXK7.js.map +1 -0
- package/dist/{chunk-PX2LSHYM.js → chunk-7BD6O7ZV.js} +189 -4
- package/dist/chunk-7BD6O7ZV.js.map +1 -0
- package/dist/chunk-7TBXNYLO.js +346 -0
- package/dist/chunk-7TBXNYLO.js.map +1 -0
- package/dist/{chunk-NH5IR2WM.js → chunk-BRR5EUTF.js} +6 -2
- package/dist/chunk-BRR5EUTF.js.map +1 -0
- package/dist/{chunk-NIS256NW.js → chunk-CIAI24TQ.js} +3 -3
- package/dist/{chunk-T2JHZWH6.js → chunk-D3LBIUWV.js} +11703 -7573
- package/dist/chunk-D3LBIUWV.js.map +1 -0
- package/dist/{chunk-7FGL6CGA.js → chunk-DVYRD4HY.js} +2 -2
- package/dist/{chunk-G7Z6EENO.js → chunk-EKTP7MNS.js} +4 -4
- package/dist/{chunk-S75M5ZRK.js → chunk-F2JRDPON.js} +16 -1
- package/dist/chunk-F2JRDPON.js.map +1 -0
- package/dist/{chunk-RZ4XGKOJ.js → chunk-FFRTNF3L.js} +8 -8
- package/dist/{chunk-VKXWK44Q.js → chunk-FONWBCVY.js} +3 -3
- package/dist/{chunk-DZD576ZU.js → chunk-FPLM2TKD.js} +2 -2
- package/dist/{chunk-ZPJ4QSGP.js → chunk-FTPONF6B.js} +2 -2
- package/dist/{chunk-LJS7KUPV.js → chunk-FWX7W5PM.js} +2 -2
- package/dist/{chunk-UTRO5UJU.js → chunk-G6DFSS6A.js} +5 -1
- package/dist/chunk-G6DFSS6A.js.map +1 -0
- package/dist/{chunk-6LAPLZOS.js → chunk-GJ776BC2.js} +8 -3
- package/dist/chunk-GJ776BC2.js.map +1 -0
- package/dist/{chunk-G4T7L557.js → chunk-GN3WRFJY.js} +6 -6
- package/dist/{chunk-QT2FRYI4.js → chunk-H7NAZ3UB.js} +2 -2
- package/dist/{chunk-APPFNGX6.js → chunk-HBUFQRIM.js} +2 -2
- package/dist/{chunk-UU7TRFNE.js → chunk-HGJ6NJ4E.js} +2 -2
- package/dist/{chunk-WB7JSQCP.js → chunk-HIEWDJ2O.js} +5 -2
- package/dist/{chunk-WB7JSQCP.js.map → chunk-HIEWDJ2O.js.map} +1 -1
- package/dist/{chunk-UES4BHA2.js → chunk-I3MSGFGD.js} +17 -6
- package/dist/chunk-I3MSGFGD.js.map +1 -0
- package/dist/{chunk-C4ZNGVK3.js → chunk-IKP5OYQQ.js} +2 -2
- package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
- package/dist/{chunk-RDJRFDJY.js → chunk-IQ4NVWEF.js} +2 -2
- package/dist/{chunk-CGVHPCP2.js → chunk-JYG4OLWH.js} +2 -2
- package/dist/{chunk-WOPA3SGI.js → chunk-K26NWEOC.js} +8 -8
- package/dist/{chunk-K4QS7LXU.js → chunk-K2UGPTYY.js} +485 -44
- package/dist/chunk-K2UGPTYY.js.map +1 -0
- package/dist/{chunk-L6CQ7WIW.js → chunk-KFBOPMF6.js} +11 -11
- package/dist/chunk-KFBOPMF6.js.map +1 -0
- package/dist/{chunk-G7A5HLUS.js → chunk-KJH6W2I7.js} +2 -2
- package/dist/{chunk-IXEBUYO4.js → chunk-KM55SMLG.js} +11 -2
- package/dist/{chunk-IXEBUYO4.js.map → chunk-KM55SMLG.js.map} +1 -1
- package/dist/{chunk-HOIRB77A.js → chunk-L6Z5OAS4.js} +2 -2
- package/dist/chunk-LC2BDILZ.js +57 -0
- package/dist/chunk-LC2BDILZ.js.map +1 -0
- package/dist/{chunk-227UFSEQ.js → chunk-LEPOP46W.js} +4 -4
- package/dist/{chunk-6R4G7N4S.js → chunk-M4YHAODQ.js} +388 -748
- package/dist/chunk-M4YHAODQ.js.map +1 -0
- package/dist/{chunk-3JLPGJ43.js → chunk-MIH3CJPN.js} +5 -5
- package/dist/{chunk-QHFV6VNU.js → chunk-MK5VEWCR.js} +2 -2
- package/dist/chunk-NISZQW72.js +140 -0
- package/dist/chunk-NISZQW72.js.map +1 -0
- package/dist/{chunk-GUKBW4HL.js → chunk-NQMSEB5D.js} +6 -6
- package/dist/{chunk-G2LUMAUF.js → chunk-OCIP6YMD.js} +12 -5
- package/dist/chunk-OCIP6YMD.js.map +1 -0
- package/dist/{chunk-47P3RYZP.js → chunk-PG4QBPVG.js} +21 -11
- package/dist/chunk-PG4QBPVG.js.map +1 -0
- package/dist/{chunk-WRJVB3C2.js → chunk-PO7NXBG2.js} +2 -2
- package/dist/{chunk-QWGE2PUH.js → chunk-PT54WISF.js} +190 -56
- package/dist/chunk-PT54WISF.js.map +1 -0
- package/dist/{chunk-AZM4CCAC.js → chunk-QZLDRQ4I.js} +8 -8
- package/dist/{chunk-THPPCISA.js → chunk-RBII7637.js} +5 -5
- package/dist/{chunk-JDZPNCMA.js → chunk-RUNORG2P.js} +6 -3
- package/dist/chunk-RUNORG2P.js.map +1 -0
- package/dist/{chunk-JV5YUBIZ.js → chunk-RZQ6W2W4.js} +50 -44
- package/dist/chunk-RZQ6W2W4.js.map +1 -0
- package/dist/{chunk-RUMNY5DT.js → chunk-SMNYAMJD.js} +6 -2
- package/dist/chunk-SMNYAMJD.js.map +1 -0
- package/dist/{chunk-MKQBXQKU.js → chunk-TB6CBZ5V.js} +22 -15
- package/dist/chunk-TB6CBZ5V.js.map +1 -0
- package/dist/{chunk-VMMQDEN5.js → chunk-TO7ZTWJW.js} +2 -2
- package/dist/{chunk-K2TDK7GG.js → chunk-TWTUGCTY.js} +2 -2
- package/dist/{chunk-HLYR2TQL.js → chunk-UCTS3DDH.js} +2 -2
- package/dist/{chunk-JYIJNNN3.js → chunk-UG6VXIOK.js} +2 -2
- package/dist/{chunk-WM65LU67.js → chunk-UKYS3NU5.js} +2 -2
- package/dist/{chunk-WDBX6VER.js → chunk-UPLZNJKN.js} +5 -5
- package/dist/{chunk-C23BYTJV.js → chunk-UW5NPZJ2.js} +40 -12
- package/dist/chunk-UW5NPZJ2.js.map +1 -0
- package/dist/{chunk-2GFK22OZ.js → chunk-V6ERBR7U.js} +2 -2
- package/dist/{chunk-CYF6WVE7.js → chunk-W5ZKPI34.js} +139 -158
- package/dist/chunk-W5ZKPI34.js.map +1 -0
- package/dist/chunk-XX4HPFFM.js +370 -0
- package/dist/chunk-XX4HPFFM.js.map +1 -0
- package/dist/{chunk-ZMYDYNI4.js → chunk-XZHE2DEN.js} +4 -4
- package/dist/chunk-YXQEKCZM.js +223 -0
- package/dist/chunk-YXQEKCZM.js.map +1 -0
- package/dist/{chunk-GYPQL6XN.js → chunk-Z4N7SVVF.js} +35 -47
- package/dist/chunk-Z4N7SVVF.js.map +1 -0
- package/dist/{chunk-MAXVH44E.js → chunk-Z54EM5YZ.js} +7 -7
- package/dist/{chunk-YGLY6QFV.js → chunk-ZRZVLB7O.js} +2 -2
- package/dist/{chunk-4IIFL7GC.js → chunk-ZUKIUXHQ.js} +10 -10
- package/dist/{cli-DVUFIa5E.d.ts → cli-Bze8S0Qs.d.ts} +5 -5
- package/dist/cli.d.ts +22 -21
- package/dist/cli.js +90 -80
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +33 -12
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +4 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +33 -12
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +32 -12
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/contradiction/index.js +3 -1
- package/dist/contradiction-scan-JDTBXRGW.js +20 -0
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +35 -14
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +25 -24
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-XzF76C9n.d.ts → dependency-propagation-delivery-CzEfB31P.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +33 -12
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/explicit-capture.js +7 -4
- package/dist/external-wiki-access.d.ts +22 -21
- package/dist/external-wiki-access.js +56 -51
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +22 -21
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-faithfulness.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-judge.js +2 -2
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +35 -19
- package/dist/fallback-llm.d.ts +14 -1
- package/dist/fallback-llm.js +1 -1
- package/dist/{first-start-migration-626C5554.js → first-start-migration-CRZCZAJN.js} +11 -3
- package/dist/first-start-migration-CRZCZAJN.js.map +1 -0
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +314 -308
- package/dist/index.js +304 -133
- package/dist/inline-script.d.ts +3 -0
- package/dist/inline-script.js +8 -0
- package/dist/inline-script.js.map +1 -0
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +6 -6
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +2 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +33 -12
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +33 -12
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +34 -13
- package/dist/{maintenance-BJzNIKBE.d.ts → maintenance-C8aRWfhq.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +22 -21
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-mutations.js +2 -2
- package/dist/memory-projection-store.d.ts +6 -2
- package/dist/memory-projection-store.js +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +24 -23
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +33 -12
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-file-io.d.ts +20 -0
- package/dist/offline-sync-file-io.js +18 -0
- package/dist/offline-sync-file-io.js.map +1 -0
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/offline-sync-impression-drain.js +5 -5
- package/dist/offline-sync.d.ts +8 -6
- package/dist/offline-sync.js +2 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +26 -25
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +39 -36
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +38 -18
- package/dist/{orchestrator-BiXgBJBQ.d.ts → orchestrator-D85CzDDY.d.ts} +11 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +117 -109
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-sz_dcuLg.d.ts → pipeline-DPcUifCO.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/public-http-D-SyWNj6.d.ts +25 -0
- package/dist/{purge-533FZLS4.js → purge-GB7PZHT2.js} +2 -2
- package/dist/{qmd-eAWObK4M.d.ts → qmd-dFCHp1r0.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/recall-concurrency-config.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-planner-llm.js +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +2 -1
- package/dist/reconcile/manifest.d.ts +2 -1
- package/dist/reconcile/manifest.js +6 -5
- package/dist/reconcile/plan.d.ts +2 -1
- package/dist/reconcile/plan.js +3 -2
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +5 -3
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/schemas.d.ts +38 -38
- package/dist/{scope-profiles-BBQsXuyj.d.ts → scope-profiles-DICK7GtN.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +6 -6
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +12 -12
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-HD8RkzVA.d.ts → semantic-consolidation-BP7NAX0N.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +34 -13
- package/dist/semantic-rule-promotion.js +33 -12
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +33 -12
- package/dist/{service-DIrtHHEg.d.ts → service-DT-pJyda.d.ts} +660 -660
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +31 -15
- package/dist/{storage-DqCzXi56.d.ts → storage-qOnaJ1Lw.d.ts} +49 -13
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +33 -12
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +518 -0
- package/dist/support-passport/index.js +357 -0
- package/dist/support-passport/index.js.map +1 -0
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +2 -2
- package/dist/tier-routing.js +7 -1
- package/dist/{tier-stats-2JCZYEF7.js → tier-stats-EXYSKSVN.js} +8 -2
- package/dist/{tier-stats-2JCZYEF7.js.map → tier-stats-EXYSKSVN.js.map} +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -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/transfer/types.d.ts +36 -36
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-d_j4vC6N.d.ts → types-ed-SvS2t.d.ts} +8 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +2 -2
- package/dist/verified-recall.js +33 -12
- package/dist/write-envelope.d.ts +1 -1
- package/dist/write-rate-limiter.d.ts +11 -5
- package/dist/write-rate-limiter.js +1 -1
- package/package.json +12 -2
- package/scripts/build-with-heap.mjs +11 -1
- package/src/access-authorization-probe.ts +20 -2
- package/src/access-boundary.ts +32 -0
- package/src/access-http.test.ts +1971 -643
- package/src/access-http.ts +81 -74
- package/src/access-mcp.ts +3 -1
- package/src/access-memory-search-fanout.ts +24 -1
- package/src/access-offline-manifest.ts +5 -0
- package/src/access-operations.ts +2 -0
- package/src/access-service-namespace.test.ts +14 -0
- package/src/access-service-observe-scope.test.ts +2 -0
- package/src/access-service-offline-file-content.test.ts +211 -0
- package/src/access-service.ts +628 -884
- package/src/access-surface-catalog.test.ts +40 -10
- package/src/access-surface-catalog.ts +15 -0
- package/src/active-memory-bridge.test.ts +151 -0
- package/src/active-memory-bridge.ts +95 -21
- package/src/briefing.test.ts +38 -0
- package/src/briefing.ts +3 -3
- package/src/cli.ts +6 -1
- package/src/config.ts +18 -9
- package/src/connectors/codex-materialize-runner.ts +2 -0
- package/src/contradiction/contradiction-scan.ts +2 -0
- package/src/contradiction/contradiction.test.ts +42 -0
- package/src/correction/correction-access-wiring.ts +8 -2
- package/src/correction/correction-storage-integration.test.ts +7 -0
- package/src/explicit-capture.test.ts +24 -0
- package/src/explicit-capture.ts +2 -0
- package/src/fallback-llm.test.ts +54 -0
- package/src/fallback-llm.ts +54 -9
- package/src/index.ts +3 -0
- package/src/inline-script.ts +6 -0
- package/src/local-llm-headers-timeout.test.ts +42 -0
- package/src/local-llm.ts +8 -8
- package/src/maintenance/first-start-migration.ts +2 -1
- package/src/maintenance/memory-governance.test.ts +25 -0
- package/src/maintenance/memory-governance.ts +4 -1
- package/src/maintenance/pattern-reinforcement.test.ts +20 -0
- package/src/maintenance/pattern-reinforcement.ts +2 -1
- package/src/maintenance/rebuild-memory-projection.ts +8 -8
- package/src/mcp-read-only-tools.ts +3 -0
- package/src/memory-projection-store.ts +25 -27
- package/src/offline-sync-file-io.ts +68 -0
- package/src/offline-sync.ts +43 -57
- package/src/orchestration/consolidation-run.ts +5 -4
- package/src/orchestration/contradiction-linking-coordinator.ts +7 -0
- package/src/orchestration/contradiction-localization.integration.test.ts +115 -0
- package/src/orchestration/lifecycle-policy-coordinator.ts +2 -1
- package/src/orchestration/qmd-result-resolver.test.ts +215 -14
- package/src/orchestration/qmd-result-resolver.ts +142 -82
- package/src/orchestration/recall-search-pipeline.test.ts +41 -0
- package/src/orchestration/recall-search-pipeline.ts +12 -0
- package/src/orchestration/semantic-consolidation-coordinator.ts +2 -1
- package/src/orchestration/tier-migration-coordinator.ts +23 -56
- package/src/orchestration/workspace-ops.test.ts +37 -0
- package/src/orchestration/workspace-ops.ts +5 -29
- package/src/orchestrator.ts +7 -8
- package/src/relay/mission-access.test.ts +11 -11
- package/src/relay/mission-ui.test.ts +3 -1
- package/src/storage/supersession-audit.ts +7 -1
- package/src/storage/supersession-side-effects.ts +17 -5
- package/src/storage/tombstone-blocked-capture-sync.ts +31 -0
- package/src/storage-contract/failure-semantics.test.ts +102 -0
- package/src/storage.ts +18 -19
- package/src/support-passport/access-http-base.ts +143 -0
- package/src/support-passport/access-http.ts +172 -0
- package/src/support-passport/access-operations.ts +272 -0
- package/src/support-passport/access-service-base.test.ts +193 -0
- package/src/support-passport/access-service-base.ts +176 -0
- package/src/support-passport/access-surface.test.ts +283 -0
- package/src/support-passport/access-surface.ts +286 -0
- package/src/support-passport/card-projection.test.ts +137 -0
- package/src/support-passport/card-projection.ts +348 -0
- package/src/support-passport/card-replacement.ts +126 -0
- package/src/support-passport/card-service-commit-forwarding.test.ts +160 -0
- package/src/support-passport/card-service.test.ts +2964 -0
- package/src/support-passport/card-service.ts +1184 -0
- package/src/support-passport/card-state.ts +158 -0
- package/src/support-passport/config-model-routing.test.ts +37 -0
- package/src/support-passport/config.test.ts +34 -0
- package/src/support-passport/config.ts +41 -0
- package/src/support-passport/contracts.test.ts +156 -0
- package/src/support-passport/contracts.ts +149 -0
- package/src/support-passport/errors.ts +30 -0
- package/src/support-passport/generated-batch.test.ts +185 -0
- package/src/support-passport/generated-batch.ts +338 -0
- package/src/support-passport/grant-contracts.ts +183 -0
- package/src/support-passport/grant-generated-batch-scope.test.ts +201 -0
- package/src/support-passport/grant-service-cache.test.ts +148 -0
- package/src/support-passport/grant-service-cancellation.test.ts +83 -0
- package/src/support-passport/grant-service-marker-cache.test.ts +62 -0
- package/src/support-passport/grant-service.test.ts +3496 -0
- package/src/support-passport/grant-service.ts +513 -0
- package/src/support-passport/grant-store-commit-hook.test.ts +123 -0
- package/src/support-passport/grant-store-order.test.ts +60 -0
- package/src/support-passport/grant-store-path-safety.test.ts +30 -0
- package/src/support-passport/grant-store-recovery.test.ts +448 -0
- package/src/support-passport/grant-store.ts +906 -0
- package/src/support-passport/index.ts +17 -0
- package/src/support-passport/mcp-tools.test.ts +222 -0
- package/src/support-passport/mcp-tools.ts +187 -0
- package/src/support-passport/model-adapter.test.ts +840 -0
- package/src/support-passport/model-adapter.ts +602 -0
- package/src/support-passport/model-audit-pinned-write.test.ts +59 -0
- package/src/support-passport/model-audit.ts +152 -0
- package/src/support-passport/model-bridge.test.ts +456 -0
- package/src/support-passport/model-bridge.ts +439 -0
- package/src/support-passport/model-contracts.ts +124 -0
- package/src/support-passport/model-service.test.ts +1731 -0
- package/src/support-passport/model-service.ts +399 -0
- package/src/support-passport/offline-sync-guard.ts +230 -0
- package/src/support-passport/owner-http.test.ts +671 -0
- package/src/support-passport/owner-lock.ts +70 -0
- package/src/support-passport/private-file.test.ts +99 -0
- package/src/support-passport/private-file.ts +498 -0
- package/src/support-passport/public-http.test.ts +476 -0
- package/src/support-passport/public-http.ts +601 -0
- package/src/support-passport/ui.test.ts +181 -0
- package/src/tier-routing.ts +28 -17
- package/src/training-export/converter.test.ts +24 -0
- package/src/training-export/converter.ts +2 -0
- package/src/types.ts +8 -1
- package/src/wearables/service.test.ts +13 -0
- package/src/wearables/service.ts +2 -0
- package/src/write-rate-limiter.test.ts +30 -6
- package/src/write-rate-limiter.ts +29 -18
- package/dist/chunk-3CSX3ETE.js.map +0 -1
- package/dist/chunk-47P3RYZP.js.map +0 -1
- package/dist/chunk-6LAPLZOS.js.map +0 -1
- package/dist/chunk-6R4G7N4S.js.map +0 -1
- package/dist/chunk-7BZOBA5J.js.map +0 -1
- package/dist/chunk-C23BYTJV.js.map +0 -1
- package/dist/chunk-CYF6WVE7.js.map +0 -1
- package/dist/chunk-G2LUMAUF.js.map +0 -1
- package/dist/chunk-GYPQL6XN.js.map +0 -1
- package/dist/chunk-JDZPNCMA.js.map +0 -1
- package/dist/chunk-JV5YUBIZ.js.map +0 -1
- package/dist/chunk-K4QS7LXU.js.map +0 -1
- package/dist/chunk-L6CQ7WIW.js.map +0 -1
- package/dist/chunk-MKQBXQKU.js.map +0 -1
- package/dist/chunk-NH5IR2WM.js.map +0 -1
- package/dist/chunk-PX2LSHYM.js.map +0 -1
- package/dist/chunk-QWGE2PUH.js.map +0 -1
- package/dist/chunk-RUMNY5DT.js.map +0 -1
- package/dist/chunk-S75M5ZRK.js.map +0 -1
- package/dist/chunk-T2JHZWH6.js.map +0 -1
- package/dist/chunk-UES4BHA2.js.map +0 -1
- package/dist/chunk-UTRO5UJU.js.map +0 -1
- package/dist/chunk-UU3G6GUP.js.map +0 -1
- package/dist/chunk-XUAMCLY4.js.map +0 -1
- package/dist/chunk-ZYLC7NFO.js.map +0 -1
- package/dist/contradiction-scan-HYLIRMJ2.js +0 -14
- package/dist/first-start-migration-626C5554.js.map +0 -1
- /package/dist/{auto-sync-TDHLZPVP.js.map → auto-sync-NR3GPCOA.js.map} +0 -0
- /package/dist/{chunk-LLJMAULE.js.map → chunk-2FKEIPIT.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-PDDTI7IC.js.map → chunk-43SEBY2M.js.map} +0 -0
- /package/dist/{chunk-HWRD23DW.js.map → chunk-46SZBVDS.js.map} +0 -0
- /package/dist/{chunk-6HPHEFXT.js.map → chunk-5FD7JMTX.js.map} +0 -0
- /package/dist/{chunk-IBKR2TFR.js.map → chunk-6CYHUWCO.js.map} +0 -0
- /package/dist/{chunk-YN6ASZUG.js.map → chunk-6QPI2ITJ.js.map} +0 -0
- /package/dist/{chunk-NIS256NW.js.map → chunk-CIAI24TQ.js.map} +0 -0
- /package/dist/{chunk-7FGL6CGA.js.map → chunk-DVYRD4HY.js.map} +0 -0
- /package/dist/{chunk-G7Z6EENO.js.map → chunk-EKTP7MNS.js.map} +0 -0
- /package/dist/{chunk-RZ4XGKOJ.js.map → chunk-FFRTNF3L.js.map} +0 -0
- /package/dist/{chunk-VKXWK44Q.js.map → chunk-FONWBCVY.js.map} +0 -0
- /package/dist/{chunk-DZD576ZU.js.map → chunk-FPLM2TKD.js.map} +0 -0
- /package/dist/{chunk-ZPJ4QSGP.js.map → chunk-FTPONF6B.js.map} +0 -0
- /package/dist/{chunk-LJS7KUPV.js.map → chunk-FWX7W5PM.js.map} +0 -0
- /package/dist/{chunk-G4T7L557.js.map → chunk-GN3WRFJY.js.map} +0 -0
- /package/dist/{chunk-QT2FRYI4.js.map → chunk-H7NAZ3UB.js.map} +0 -0
- /package/dist/{chunk-APPFNGX6.js.map → chunk-HBUFQRIM.js.map} +0 -0
- /package/dist/{chunk-UU7TRFNE.js.map → chunk-HGJ6NJ4E.js.map} +0 -0
- /package/dist/{chunk-C4ZNGVK3.js.map → chunk-IKP5OYQQ.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
- /package/dist/{chunk-RDJRFDJY.js.map → chunk-IQ4NVWEF.js.map} +0 -0
- /package/dist/{chunk-CGVHPCP2.js.map → chunk-JYG4OLWH.js.map} +0 -0
- /package/dist/{chunk-WOPA3SGI.js.map → chunk-K26NWEOC.js.map} +0 -0
- /package/dist/{chunk-G7A5HLUS.js.map → chunk-KJH6W2I7.js.map} +0 -0
- /package/dist/{chunk-HOIRB77A.js.map → chunk-L6Z5OAS4.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-LEPOP46W.js.map} +0 -0
- /package/dist/{chunk-3JLPGJ43.js.map → chunk-MIH3CJPN.js.map} +0 -0
- /package/dist/{chunk-QHFV6VNU.js.map → chunk-MK5VEWCR.js.map} +0 -0
- /package/dist/{chunk-GUKBW4HL.js.map → chunk-NQMSEB5D.js.map} +0 -0
- /package/dist/{chunk-WRJVB3C2.js.map → chunk-PO7NXBG2.js.map} +0 -0
- /package/dist/{chunk-AZM4CCAC.js.map → chunk-QZLDRQ4I.js.map} +0 -0
- /package/dist/{chunk-THPPCISA.js.map → chunk-RBII7637.js.map} +0 -0
- /package/dist/{chunk-VMMQDEN5.js.map → chunk-TO7ZTWJW.js.map} +0 -0
- /package/dist/{chunk-K2TDK7GG.js.map → chunk-TWTUGCTY.js.map} +0 -0
- /package/dist/{chunk-HLYR2TQL.js.map → chunk-UCTS3DDH.js.map} +0 -0
- /package/dist/{chunk-JYIJNNN3.js.map → chunk-UG6VXIOK.js.map} +0 -0
- /package/dist/{chunk-WM65LU67.js.map → chunk-UKYS3NU5.js.map} +0 -0
- /package/dist/{chunk-WDBX6VER.js.map → chunk-UPLZNJKN.js.map} +0 -0
- /package/dist/{chunk-2GFK22OZ.js.map → chunk-V6ERBR7U.js.map} +0 -0
- /package/dist/{chunk-ZMYDYNI4.js.map → chunk-XZHE2DEN.js.map} +0 -0
- /package/dist/{chunk-MAXVH44E.js.map → chunk-Z54EM5YZ.js.map} +0 -0
- /package/dist/{chunk-YGLY6QFV.js.map → chunk-ZRZVLB7O.js.map} +0 -0
- /package/dist/{chunk-4IIFL7GC.js.map → chunk-ZUKIUXHQ.js.map} +0 -0
- /package/dist/{contradiction-scan-HYLIRMJ2.js.map → contradiction-scan-JDTBXRGW.js.map} +0 -0
- /package/dist/{purge-533FZLS4.js.map → purge-GB7PZHT2.js.map} +0 -0
|
@@ -33,6 +33,7 @@ import { evaluateMemoryActionPolicy } from "../memory-action-policy.js";
|
|
|
33
33
|
import { NamespaceStorageRouter } from "../namespaces/storage.js";
|
|
34
34
|
import { namespaceCollectionName } from "../namespaces/search.js";
|
|
35
35
|
import { parseMemoryActionEligibilityContext } from "../schemas.js";
|
|
36
|
+
import { isSupportPassportPrivateMemory } from "../support-passport/card-projection.js";
|
|
36
37
|
import type { SearchBackend } from "../search/port.js";
|
|
37
38
|
import { type AccessTrackingEntry, type MemoryActionEvent, type MemoryFile, type PluginConfig, confidenceTier } from "../types.js";
|
|
38
39
|
import { RECALL_FALLBACK_DIRS } from "../utils/category-dir.js";
|
|
@@ -371,41 +372,16 @@ export class WorkspaceOpsCoordinator {
|
|
|
371
372
|
const fullPath = path.join(dateDir, entry.name);
|
|
372
373
|
try {
|
|
373
374
|
assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const fmBlock = fmMatch[1];
|
|
378
|
-
const content = fmMatch[2].trim();
|
|
379
|
-
const fm: Record<string, string> = {};
|
|
380
|
-
for (const line of fmBlock.split("\n")) {
|
|
381
|
-
const colonIdx = line.indexOf(":");
|
|
382
|
-
if (colonIdx === -1) continue;
|
|
383
|
-
fm[line.slice(0, colonIdx).trim()] = line
|
|
384
|
-
.slice(colonIdx + 1)
|
|
385
|
-
.trim();
|
|
386
|
-
}
|
|
387
|
-
const created = fm.created || "unknown";
|
|
388
|
-
const createdAt = parseFiniteDate(created);
|
|
375
|
+
const memory = await storage.readMemoryByPath(fullPath);
|
|
376
|
+
if (!memory || isSupportPassportPrivateMemory(memory)) continue;
|
|
377
|
+
const createdAt = parseFiniteDate(memory.frontmatter.created);
|
|
389
378
|
if (
|
|
390
379
|
createdAt &&
|
|
391
380
|
formatDateInTimeZone(createdAt, timeZone) !== targetLocalDate
|
|
392
381
|
) {
|
|
393
382
|
continue;
|
|
394
383
|
}
|
|
395
|
-
facts.push(
|
|
396
|
-
path: fullPath,
|
|
397
|
-
frontmatter: {
|
|
398
|
-
id: fm.id || path.basename(entry.name, ".md"),
|
|
399
|
-
category: (fm.category as any) || "fact",
|
|
400
|
-
created,
|
|
401
|
-
updated: fm.updated || created,
|
|
402
|
-
source: fm.source || "unknown",
|
|
403
|
-
confidence: parseFloat(fm.confidence || "0.8"),
|
|
404
|
-
confidenceTier: (fm.confidenceTier as any) || "implied",
|
|
405
|
-
tags: [],
|
|
406
|
-
},
|
|
407
|
-
content,
|
|
408
|
-
});
|
|
384
|
+
facts.push(memory);
|
|
409
385
|
} catch {
|
|
410
386
|
// Skip unreadable files
|
|
411
387
|
}
|
package/src/orchestrator.ts
CHANGED
|
@@ -1116,6 +1116,13 @@ export class Orchestrator {
|
|
|
1116
1116
|
return this.storageRouter.storageFor(ns);
|
|
1117
1117
|
}
|
|
1118
1118
|
|
|
1119
|
+
filterPrivateSearchResults = (
|
|
1120
|
+
results: QmdSearchResult[], namespaces: readonly string[] = [], preserveUnresolved = false,
|
|
1121
|
+
visibilityCache?: Map<string, boolean>,
|
|
1122
|
+
) => this.qmdResultResolver.filterPrivateSearchResults(
|
|
1123
|
+
results, this.storage, namespaces, preserveUnresolved, visibilityCache,
|
|
1124
|
+
);
|
|
1125
|
+
|
|
1119
1126
|
private configuredNamespaceList(): string[] {
|
|
1120
1127
|
// #1521: delegates to the scope-module resolver. The inline derivation is
|
|
1121
1128
|
// retired so the adHocNamespaceResolutions ratchet no longer counts this
|
|
@@ -3784,14 +3791,6 @@ export class Orchestrator {
|
|
|
3784
3791
|
.filter((id): id is string => id !== null);
|
|
3785
3792
|
}
|
|
3786
3793
|
|
|
3787
|
-
// ---------------------------------------------------------------------------
|
|
3788
|
-
// Contradiction Detection (Phase 2B)
|
|
3789
|
-
// ---------------------------------------------------------------------------
|
|
3790
|
-
|
|
3791
|
-
// ---------------------------------------------------------------------------
|
|
3792
|
-
// Feedback (v2.2)
|
|
3793
|
-
// ---------------------------------------------------------------------------
|
|
3794
|
-
|
|
3795
3794
|
async recordMemoryFeedback(
|
|
3796
3795
|
memoryId: string,
|
|
3797
3796
|
vote: "up" | "down",
|
|
@@ -367,25 +367,25 @@ test("Relay write quota releases the exact reservation when timestamps collide",
|
|
|
367
367
|
adminConsoleEnabled: false,
|
|
368
368
|
});
|
|
369
369
|
const internals = server as unknown as {
|
|
370
|
-
writeLimiter: {
|
|
371
|
-
|
|
370
|
+
writeLimiter: {
|
|
371
|
+
slotsFor(principal?: string): ReadonlyArray<{ readonly recordedAt: number }>;
|
|
372
|
+
inFlightFor(principal?: string): number;
|
|
373
|
+
};
|
|
374
|
+
reserveWriteRateLimitSlot: () => { commit(): void; release(): void };
|
|
372
375
|
};
|
|
373
376
|
const originalNow = Date.now;
|
|
374
377
|
try {
|
|
375
378
|
Date.now = () => 1_754_000_000_000;
|
|
376
|
-
const
|
|
379
|
+
const committed = internals.reserveWriteRateLimitSlot();
|
|
380
|
+
committed.commit();
|
|
377
381
|
const committedSlot = internals.writeLimiter.slotsFor()[0];
|
|
378
|
-
const
|
|
379
|
-
const failedSlot = internals.writeLimiter.slotsFor()[1];
|
|
382
|
+
const failed = internals.reserveWriteRateLimitSlot();
|
|
380
383
|
assert.ok(committedSlot);
|
|
381
|
-
assert.
|
|
382
|
-
assert.notEqual(committedSlot, failedSlot);
|
|
384
|
+
assert.equal(internals.writeLimiter.inFlightFor(), 1);
|
|
383
385
|
|
|
384
|
-
|
|
386
|
+
failed.release();
|
|
385
387
|
assert.deepEqual(internals.writeLimiter.slotsFor(), [committedSlot]);
|
|
386
|
-
|
|
387
|
-
releaseCommitted();
|
|
388
|
-
assert.deepEqual(internals.writeLimiter.slotsFor(), []);
|
|
388
|
+
assert.equal(internals.writeLimiter.inFlightFor(), 0);
|
|
389
389
|
} finally {
|
|
390
390
|
Date.now = originalNow;
|
|
391
391
|
}
|
|
@@ -62,7 +62,9 @@ test("Relay Mission Control serves both aliases from one exact static allow-list
|
|
|
62
62
|
});
|
|
63
63
|
assert.equal(authorizedShell.status, 200);
|
|
64
64
|
assert.equal(authorizedShell.headers.get("cache-control"), "private, no-store");
|
|
65
|
-
|
|
65
|
+
const authorizedShellText = await authorizedShell.text();
|
|
66
|
+
assert.match(authorizedShellText, /Object\.defineProperty\(window,key/);
|
|
67
|
+
assert.match(authorizedShellText, /\}\)\("relay-token",document\.currentScript\)/);
|
|
66
68
|
|
|
67
69
|
const expectedAssets = new Map([
|
|
68
70
|
["relay.css", /^text\/css/],
|
|
@@ -2,6 +2,7 @@ import { readdir } from "node:fs/promises";
|
|
|
2
2
|
import type { Dirent } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
|
+
import { stripAttributesSuffix } from "../structured-attributes.js";
|
|
5
6
|
import type { MemoryFile } from "../types.js";
|
|
6
7
|
import { isErrnoCode } from "../utils/errno.js";
|
|
7
8
|
|
|
@@ -15,6 +16,7 @@ export async function hasSupersessionAudit(
|
|
|
15
16
|
oldMemoryId: string,
|
|
16
17
|
newMemoryId: string,
|
|
17
18
|
auditBody: string,
|
|
19
|
+
structuredAttributes?: Record<string, string>
|
|
18
20
|
): Promise<boolean> {
|
|
19
21
|
let entries: Dirent[];
|
|
20
22
|
try {
|
|
@@ -32,7 +34,11 @@ export async function hasSupersessionAudit(
|
|
|
32
34
|
(memory.frontmatter.sourceMemoryId === oldMemoryId ||
|
|
33
35
|
(memory.frontmatter.sourceMemoryId === undefined && memory.frontmatter.lineage?.includes(oldMemoryId))) &&
|
|
34
36
|
memory.frontmatter.lineage?.includes(newMemoryId) &&
|
|
35
|
-
memory.content === auditBody
|
|
37
|
+
stripAttributesSuffix(memory.content) === auditBody &&
|
|
38
|
+
(structuredAttributes === undefined ||
|
|
39
|
+
Object.entries(structuredAttributes).every(
|
|
40
|
+
([key, value]) => memory.frontmatter.structuredAttributes?.[key] === value
|
|
41
|
+
))
|
|
36
42
|
) {
|
|
37
43
|
return true;
|
|
38
44
|
}
|
|
@@ -31,6 +31,8 @@ export interface SupersessionSideEffectOptions {
|
|
|
31
31
|
exactReplay: boolean;
|
|
32
32
|
currentBefore: MemoryFile;
|
|
33
33
|
updatedFm: MemoryFrontmatter;
|
|
34
|
+
actor?: string;
|
|
35
|
+
audit?: SupersessionAuditOptions;
|
|
34
36
|
citationTemplate: string;
|
|
35
37
|
correctionsDir: string;
|
|
36
38
|
readMemoryByPath: (filePath: string) => Promise<MemoryFile | null>;
|
|
@@ -44,10 +46,17 @@ export interface SupersessionSideEffectOptions {
|
|
|
44
46
|
appendTombstone: (input: TombstoneInput) => Promise<string | null>;
|
|
45
47
|
writeSealedMemory: (
|
|
46
48
|
envelope: SealedMemoryEnvelope,
|
|
47
|
-
extras: { lineage: [string, string]; sourceMemoryId: string }
|
|
49
|
+
extras: { actor?: string; lineage: [string, string]; sourceMemoryId: string }
|
|
48
50
|
) => Promise<unknown>;
|
|
49
51
|
}
|
|
50
52
|
|
|
53
|
+
export interface SupersessionAuditOptions {
|
|
54
|
+
content: string;
|
|
55
|
+
tags?: string[];
|
|
56
|
+
structuredAttributes?: Record<string, string>;
|
|
57
|
+
source?: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
51
60
|
export async function runSupersessionSideEffects(options: SupersessionSideEffectOptions): Promise<boolean> {
|
|
52
61
|
const {
|
|
53
62
|
oldMemoryId,
|
|
@@ -90,7 +99,7 @@ export async function runSupersessionSideEffects(options: SupersessionSideEffect
|
|
|
90
99
|
}
|
|
91
100
|
}
|
|
92
101
|
|
|
93
|
-
const auditBody = `Superseded: ${currentBefore.content}\n\nReason: ${reason}`;
|
|
102
|
+
const auditBody = `Superseded: ${options.audit?.content ?? currentBefore.content}\n\nReason: ${reason}`;
|
|
94
103
|
const auditExists = await hasSupersessionAudit(
|
|
95
104
|
{
|
|
96
105
|
correctionsDir: options.correctionsDir,
|
|
@@ -98,7 +107,8 @@ export async function runSupersessionSideEffects(options: SupersessionSideEffect
|
|
|
98
107
|
},
|
|
99
108
|
oldMemoryId,
|
|
100
109
|
newMemoryId,
|
|
101
|
-
auditBody
|
|
110
|
+
auditBody,
|
|
111
|
+
options.audit?.structuredAttributes
|
|
102
112
|
);
|
|
103
113
|
if (!auditExists) {
|
|
104
114
|
const auditEnvelope = composeMemoryEnvelope(
|
|
@@ -106,11 +116,13 @@ export async function runSupersessionSideEffects(options: SupersessionSideEffect
|
|
|
106
116
|
content: auditBody,
|
|
107
117
|
category: "correction",
|
|
108
118
|
confidence: 1,
|
|
109
|
-
tags: ["supersession", "auto-resolved"],
|
|
119
|
+
tags: options.audit?.tags ?? ["supersession", "auto-resolved"],
|
|
120
|
+
structuredAttributes: options.audit?.structuredAttributes,
|
|
110
121
|
},
|
|
111
|
-
{ source: "contradiction-detection" }
|
|
122
|
+
{ source: options.audit?.source ?? "contradiction-detection" }
|
|
112
123
|
);
|
|
113
124
|
await options.writeSealedMemory(auditEnvelope, {
|
|
125
|
+
actor: options.actor,
|
|
114
126
|
lineage: [oldMemoryId, newMemoryId],
|
|
115
127
|
sourceMemoryId: oldMemoryId,
|
|
116
128
|
});
|
|
@@ -11,6 +11,7 @@ import { pathMayCarryEntityRefs, requestEntityCanonicalIdReconcile } from "./ent
|
|
|
11
11
|
import { withRawEntityPageMutation } from "./entity-canonical-id-lock.js";
|
|
12
12
|
import { readMaybeEncryptedFileFromChunks, writeMaybeEncryptedFileFromChunks } from "../secure-store/secure-fs.js";
|
|
13
13
|
import * as archiveMutation from "../archive-mutation-version.js";
|
|
14
|
+
import { invalidationCommitFingerprint } from "./deletion-revision-store.js";
|
|
14
15
|
import {
|
|
15
16
|
buildExplicitCaptureDedupKey,
|
|
16
17
|
buildCapturePathLockIdentity,
|
|
@@ -236,6 +237,36 @@ export abstract class TombstoneBlockedCaptureIndexHost {
|
|
|
236
237
|
return await this.getTombstoneBlockedCaptureIndex().withCaptureWriteLock(task, identity);
|
|
237
238
|
}
|
|
238
239
|
|
|
240
|
+
/** Read selected memories while their mutation locks remain held. */
|
|
241
|
+
async readMemorySnapshotsIfUnchanged(expected: readonly MemoryFile[]): Promise<MemoryFile[] | null> {
|
|
242
|
+
return await this.withMemorySnapshotsIfUnchanged(expected, async (memories) => memories);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async withMemorySnapshotsIfUnchanged<T>(
|
|
246
|
+
expected: readonly MemoryFile[],
|
|
247
|
+
task: (memories: MemoryFile[]) => Promise<T>,
|
|
248
|
+
): Promise<T | null> {
|
|
249
|
+
if (expected.length === 0) return await task([]);
|
|
250
|
+
const pathnames = [...new Set(expected.map((memory) => memory.path))];
|
|
251
|
+
if (pathnames.length !== expected.length) return null;
|
|
252
|
+
return await this.withTombstoneBlockedCaptureWriteLock(async () => {
|
|
253
|
+
const current = await Promise.all(pathnames.map((pathname) => this.readMemoryByPath(pathname)));
|
|
254
|
+
for (let index = 0; index < expected.length; index += 1) {
|
|
255
|
+
const actual = current[index];
|
|
256
|
+
const snapshot = expected[index];
|
|
257
|
+
if (
|
|
258
|
+
!actual ||
|
|
259
|
+
!snapshot ||
|
|
260
|
+
actual.frontmatter.id !== snapshot.frontmatter.id ||
|
|
261
|
+
invalidationCommitFingerprint(actual) !== invalidationCommitFingerprint(snapshot)
|
|
262
|
+
) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return await task(current as MemoryFile[]);
|
|
267
|
+
}, pathnames.map(buildCapturePathLockIdentity));
|
|
268
|
+
}
|
|
269
|
+
|
|
239
270
|
protected async withTombstoneBlockedCaptureWriteLockAndHashes<T>(
|
|
240
271
|
task: () => Promise<T>,
|
|
241
272
|
identity: string | readonly string[] | undefined,
|
|
@@ -52,6 +52,108 @@ test("failure-semantics: getMemoryById on empty store returns null (not throw)",
|
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
test("failure-semantics: selected memory snapshots reject a changed member", async () => {
|
|
56
|
+
const { storage, cleanup } = await makeStorage();
|
|
57
|
+
try {
|
|
58
|
+
const first = await storage.writeMemory("preference", "First source");
|
|
59
|
+
const second = await storage.writeMemory("preference", "Second source");
|
|
60
|
+
const firstSnapshot = await storage.readMemoryByPath(first.memory.path);
|
|
61
|
+
const secondSnapshot = await storage.readMemoryByPath(second.memory.path);
|
|
62
|
+
assert.ok(firstSnapshot);
|
|
63
|
+
assert.ok(secondSnapshot);
|
|
64
|
+
assert.equal(await storage.updateMemory(second.id, "Changed source"), true);
|
|
65
|
+
|
|
66
|
+
assert.equal(await storage.readMemorySnapshotsIfUnchanged([firstSnapshot, secondSnapshot]), null);
|
|
67
|
+
assert.deepEqual(
|
|
68
|
+
(await storage.readMemorySnapshotsIfUnchanged([firstSnapshot]))?.map((memory) => memory.frontmatter.id),
|
|
69
|
+
[first.id]
|
|
70
|
+
);
|
|
71
|
+
} finally {
|
|
72
|
+
await cleanup();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("failure-semantics: selected memory snapshots block member writes until every read completes", async () => {
|
|
77
|
+
const { storage, cleanup } = await makeStorage();
|
|
78
|
+
const secondReadStarted = Promise.withResolvers<void>();
|
|
79
|
+
const releaseSecondRead = Promise.withResolvers<void>();
|
|
80
|
+
try {
|
|
81
|
+
const first = await storage.writeMemory("preference", "First source");
|
|
82
|
+
const second = await storage.writeMemory("preference", "Second source");
|
|
83
|
+
const firstSnapshot = await storage.readMemoryByPath(first.memory.path);
|
|
84
|
+
const secondSnapshot = await storage.readMemoryByPath(second.memory.path);
|
|
85
|
+
assert.ok(firstSnapshot);
|
|
86
|
+
assert.ok(secondSnapshot);
|
|
87
|
+
const readMemoryByPath = storage.readMemoryByPath.bind(storage);
|
|
88
|
+
let pauseSecond = true;
|
|
89
|
+
storage.readMemoryByPath = async (filePath) => {
|
|
90
|
+
const memory = await readMemoryByPath(filePath);
|
|
91
|
+
if (pauseSecond && filePath === second.memory.path) {
|
|
92
|
+
pauseSecond = false;
|
|
93
|
+
secondReadStarted.resolve();
|
|
94
|
+
await releaseSecondRead.promise;
|
|
95
|
+
}
|
|
96
|
+
return memory;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const snapshotPromise = storage.readMemorySnapshotsIfUnchanged([firstSnapshot, secondSnapshot]);
|
|
100
|
+
await secondReadStarted.promise;
|
|
101
|
+
let writeSettled = false;
|
|
102
|
+
const writePromise = storage.updateMemory(first.id, "Changed source").finally(() => {
|
|
103
|
+
writeSettled = true;
|
|
104
|
+
});
|
|
105
|
+
await new Promise<void>((resolve) => setImmediate(resolve));
|
|
106
|
+
assert.equal(writeSettled, false);
|
|
107
|
+
|
|
108
|
+
releaseSecondRead.resolve();
|
|
109
|
+
assert.deepEqual(
|
|
110
|
+
(await snapshotPromise)?.map((memory) => memory.frontmatter.id),
|
|
111
|
+
[first.id, second.id]
|
|
112
|
+
);
|
|
113
|
+
assert.equal(await writePromise, true);
|
|
114
|
+
} finally {
|
|
115
|
+
releaseSecondRead.resolve();
|
|
116
|
+
await cleanup();
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("failure-semantics: selected memory snapshot tasks hold every member lock", async () => {
|
|
121
|
+
const { storage, cleanup } = await makeStorage();
|
|
122
|
+
const taskStarted = Promise.withResolvers<void>();
|
|
123
|
+
const releaseTask = Promise.withResolvers<void>();
|
|
124
|
+
try {
|
|
125
|
+
const first = await storage.writeMemory("preference", "First source");
|
|
126
|
+
const second = await storage.writeMemory("preference", "Second source");
|
|
127
|
+
const firstSnapshot = await storage.readMemoryByPath(first.memory.path);
|
|
128
|
+
const secondSnapshot = await storage.readMemoryByPath(second.memory.path);
|
|
129
|
+
assert.ok(firstSnapshot);
|
|
130
|
+
assert.ok(secondSnapshot);
|
|
131
|
+
|
|
132
|
+
const snapshotTask = storage.withMemorySnapshotsIfUnchanged(
|
|
133
|
+
[firstSnapshot, secondSnapshot],
|
|
134
|
+
async (memories) => {
|
|
135
|
+
taskStarted.resolve();
|
|
136
|
+
await releaseTask.promise;
|
|
137
|
+
return memories.map((memory) => memory.frontmatter.id);
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
await taskStarted.promise;
|
|
141
|
+
let writeSettled = false;
|
|
142
|
+
const writePromise = storage.updateMemoryIfUnchanged(firstSnapshot, "Changed source").finally(() => {
|
|
143
|
+
writeSettled = true;
|
|
144
|
+
});
|
|
145
|
+
await new Promise<void>((resolve) => setImmediate(resolve));
|
|
146
|
+
assert.equal(writeSettled, false);
|
|
147
|
+
|
|
148
|
+
releaseTask.resolve();
|
|
149
|
+
assert.deepEqual(await snapshotTask, [first.id, second.id]);
|
|
150
|
+
assert.equal(await writePromise, true);
|
|
151
|
+
} finally {
|
|
152
|
+
releaseTask.resolve();
|
|
153
|
+
await cleanup();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
55
157
|
test("failure-semantics: readMemoryByPath on a non-existent file returns null (not throw)", async () => {
|
|
56
158
|
const { storage, baseDir, cleanup } = await makeStorage();
|
|
57
159
|
try {
|
package/src/storage.ts
CHANGED
|
@@ -137,7 +137,7 @@ import {
|
|
|
137
137
|
type TombstoneStats,
|
|
138
138
|
} from "./lifecycle/tombstones.js";
|
|
139
139
|
import { supersessionKeysForFact } from "./temporal-supersession.js";
|
|
140
|
-
import { runSupersessionSideEffects } from "./storage/supersession-side-effects.js";
|
|
140
|
+
import { runSupersessionSideEffects, type SupersessionAuditOptions } from "./storage/supersession-side-effects.js";
|
|
141
141
|
import type {
|
|
142
142
|
AccessTrackingEntry,
|
|
143
143
|
BufferState,
|
|
@@ -233,6 +233,7 @@ import {
|
|
|
233
233
|
} from "./memory-projection-store.js";
|
|
234
234
|
import { inferMemoryStatus, isArchivedMemoryPath, toMemoryPathRel } from "./memory-lifecycle-ledger-utils.js";
|
|
235
235
|
import { normalizeProjectionPreview, normalizeProjectionTags } from "./memory-projection-format.js";
|
|
236
|
+
import { isSupportPassportPrivateMemory } from "./support-passport/card-projection.js";
|
|
236
237
|
import { parseFlexibleIsoTimestamp } from "./utils/iso-timestamp.js";
|
|
237
238
|
import {
|
|
238
239
|
composeMemoryEnvelope,
|
|
@@ -3682,7 +3683,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3682
3683
|
category: MemoryCategory,
|
|
3683
3684
|
content: string,
|
|
3684
3685
|
options: WriteMemoryOptions = {}
|
|
3685
|
-
)
|
|
3686
|
+
) {
|
|
3686
3687
|
await this.ensureDirectories();
|
|
3687
3688
|
const rawEntityRef = options.entityRef;
|
|
3688
3689
|
let refIds = typeof options.entityRef === "string" ? this.currentHistoricalIds() : null;
|
|
@@ -3883,6 +3884,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3883
3884
|
tombstoneBlocked: true,
|
|
3884
3885
|
blockedBy: duplicateBlocked.frontmatter.blockedBy,
|
|
3885
3886
|
duplicateOf: duplicateBlocked.frontmatter.id,
|
|
3887
|
+
memory: duplicateBlocked,
|
|
3886
3888
|
};
|
|
3887
3889
|
}
|
|
3888
3890
|
await this.patchHotMemoriesCache({ addedPath: filePath }, "memory-create");
|
|
@@ -3937,7 +3939,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3937
3939
|
}
|
|
3938
3940
|
}
|
|
3939
3941
|
log.debug(`wrote memory ${id} to ${filePath}`);
|
|
3940
|
-
return { id, tombstoneBlocked, ...(fm.blockedBy ? { blockedBy: fm.blockedBy } : {}) };
|
|
3942
|
+
return { id, tombstoneBlocked, ...(fm.blockedBy ? { blockedBy: fm.blockedBy } : {}), memory: { path: filePath, frontmatter: fm, content: sanitized.text } };
|
|
3941
3943
|
}
|
|
3942
3944
|
|
|
3943
3945
|
/**
|
|
@@ -3959,7 +3961,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
3959
3961
|
* `envelope.sourceReason` is access-layer metadata with no frontmatter
|
|
3960
3962
|
* field and is deliberately not persisted here.
|
|
3961
3963
|
*/
|
|
3962
|
-
async writeSealedMemory(envelope: SealedMemoryEnvelope, extras: SealedWriteExtras = {})
|
|
3964
|
+
async writeSealedMemory(envelope: SealedMemoryEnvelope, extras: SealedWriteExtras = {}) {
|
|
3963
3965
|
if (!isSealedMemoryEnvelope(envelope)) {
|
|
3964
3966
|
throw new Error(
|
|
3965
3967
|
"writeSealedMemory: value is not a valid sealed memory envelope (fails the composeMemoryEnvelope contract)"
|
|
@@ -6636,21 +6638,18 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6636
6638
|
return updated;
|
|
6637
6639
|
}
|
|
6638
6640
|
|
|
6639
|
-
/**
|
|
6640
|
-
* Get a memory by its ID.
|
|
6641
|
-
*/
|
|
6642
6641
|
async getMemoryById(id: string): Promise<MemoryFile | null> {
|
|
6643
6642
|
const memories = await this.readAllMemories();
|
|
6644
6643
|
return memories.find((m) => m.frontmatter.id === id) ?? null;
|
|
6645
6644
|
}
|
|
6646
6645
|
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6646
|
+
async getMemoryByIdIncludingArchived(id: string): Promise<MemoryFile | null> {
|
|
6647
|
+
const active = await this.getMemoryById(id);
|
|
6648
|
+
return active ?? (await this.readAllColdMemories()).find((memory) => memory.frontmatter.id === id) ??
|
|
6649
|
+
(await this.readArchivedMemories()).find((memory) => memory.frontmatter.id === id) ?? null;
|
|
6650
|
+
}
|
|
6651
|
+
|
|
6652
|
+
/** Resolve existing active memory IDs through a lightweight directory scan. */
|
|
6654
6653
|
async findExistingMemoryPaths(
|
|
6655
6654
|
ids: string[],
|
|
6656
6655
|
preferredPaths: Map<string, string[]> = new Map()
|
|
@@ -6751,6 +6750,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6751
6750
|
lastAccessed: memory.frontmatter.lastAccessed,
|
|
6752
6751
|
tags: normalizeProjectionTags(memory.frontmatter.tags),
|
|
6753
6752
|
preview: normalizeProjectionPreview(memory.content),
|
|
6753
|
+
privateRecord: isSupportPassportPrivateMemory(memory),
|
|
6754
6754
|
};
|
|
6755
6755
|
}
|
|
6756
6756
|
|
|
@@ -6916,9 +6916,9 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
6916
6916
|
reason: string,
|
|
6917
6917
|
supersessionMetadata?: Pick<MemoryFrontmatter, "supersessionCause" | "invalidatedBy">,
|
|
6918
6918
|
options: {
|
|
6919
|
-
requireActive?: boolean;
|
|
6920
|
-
acceptExactReplay?: boolean;
|
|
6919
|
+
actor?: string; requireActive?: boolean; acceptExactReplay?: boolean;
|
|
6921
6920
|
expectedSnapshot?: Pick<MemoryFile, "content" | "frontmatter"> & Partial<Pick<MemoryFile, "path">>;
|
|
6921
|
+
audit?: SupersessionAuditOptions;
|
|
6922
6922
|
} = {},
|
|
6923
6923
|
): Promise<boolean> {
|
|
6924
6924
|
const matchesSupersession = (memory: MemoryFile): boolean =>
|
|
@@ -7061,6 +7061,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
7061
7061
|
exactReplay,
|
|
7062
7062
|
currentBefore,
|
|
7063
7063
|
updatedFm,
|
|
7064
|
+
actor: options.actor, audit: options.audit,
|
|
7064
7065
|
citationTemplate: this.citationTemplate,
|
|
7065
7066
|
correctionsDir: this.correctionsDir,
|
|
7066
7067
|
readMemoryByPath: (filePath) => this.readMemoryByPath(filePath),
|
|
@@ -7093,7 +7094,7 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
7093
7094
|
memoryId: oldMemoryId,
|
|
7094
7095
|
eventType: "superseded",
|
|
7095
7096
|
timestamp: supersededAt,
|
|
7096
|
-
actor: "storage.supersedeMemory",
|
|
7097
|
+
actor: options.actor ?? "storage.supersedeMemory",
|
|
7097
7098
|
reasonCode: reason,
|
|
7098
7099
|
before: exactReplay ? { ...beforeState, status: "active" } : beforeState,
|
|
7099
7100
|
after: afterState,
|
|
@@ -7107,14 +7108,12 @@ export class StorageManager extends TombstoneBlockedCaptureIndexHost {
|
|
|
7107
7108
|
writeSealedMemory: (envelope, extras) => this.writeSealedMemory(envelope, extras),
|
|
7108
7109
|
});
|
|
7109
7110
|
return sideEffectsComplete || options.acceptExactReplay !== true;
|
|
7110
|
-
|
|
7111
7111
|
} catch (err) {
|
|
7112
7112
|
log.error(`failed to supersede memory ${oldMemoryId}:`, err);
|
|
7113
7113
|
return false;
|
|
7114
7114
|
}
|
|
7115
7115
|
}
|
|
7116
7116
|
|
|
7117
|
-
|
|
7118
7117
|
private get summariesDir(): string {
|
|
7119
7118
|
return path.join(this.baseDir, "summaries");
|
|
7120
7119
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { EngramAccessForbiddenError } from "../access-errors.js";
|
|
5
|
+
import type { EngramAccessService } from "../access-service.js";
|
|
6
|
+
import { enforceNamespaceAllowList, tokenCapabilityStore } from "../access-token-capabilities.js";
|
|
7
|
+
import type { WriteRateLimitReservation } from "../write-rate-limiter.js";
|
|
8
|
+
import { handleSupportPassportOwnerHttp } from "./access-http.js";
|
|
9
|
+
import { buildSupportPassportPublicRequestHandler } from "./public-http.js";
|
|
10
|
+
|
|
11
|
+
const SUPPORT_PASSPORT_QUOTA_LIMITED_WRITE_TOOLS = new Set([
|
|
12
|
+
"engram.support_passport_draft_create",
|
|
13
|
+
"remnic.support_passport_draft_create",
|
|
14
|
+
"engram.support_passport_drafts_generate",
|
|
15
|
+
"remnic.support_passport_drafts_generate",
|
|
16
|
+
"engram.support_passport_card_replace",
|
|
17
|
+
"remnic.support_passport_card_replace",
|
|
18
|
+
"engram.support_passport_card_approve",
|
|
19
|
+
"remnic.support_passport_card_approve",
|
|
20
|
+
"engram.support_passport_card_reject",
|
|
21
|
+
"remnic.support_passport_card_reject",
|
|
22
|
+
"engram.support_passport_card_withdraw",
|
|
23
|
+
"remnic.support_passport_card_withdraw",
|
|
24
|
+
"engram.support_passport_grant_create",
|
|
25
|
+
"remnic.support_passport_grant_create",
|
|
26
|
+
"engram.support_passport_grant_revoke",
|
|
27
|
+
"remnic.support_passport_grant_revoke",
|
|
28
|
+
]);
|
|
29
|
+
const SUPPORT_PASSPORT_ADMIN_CONSOLE_ASSETS = new Map<string, string>([
|
|
30
|
+
["what-helps-me.css", "text/css; charset=utf-8"],
|
|
31
|
+
["model.js", "application/javascript; charset=utf-8"],
|
|
32
|
+
["app.js", "application/javascript; charset=utf-8"],
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
export abstract class SupportPassportAccessHttpBase {
|
|
36
|
+
private supportPassportPublicHandler: ReturnType<typeof buildSupportPassportPublicRequestHandler> | undefined;
|
|
37
|
+
protected abstract readonly service: EngramAccessService;
|
|
38
|
+
protected abstract readonly adminConsolePublicDir: string;
|
|
39
|
+
protected abstract resolveRequestPrincipal(req: IncomingMessage): string | undefined;
|
|
40
|
+
protected abstract readJsonBody(req: IncomingMessage, maxBodyBytes?: number): Promise<Record<string, unknown>>;
|
|
41
|
+
protected abstract respondJson(res: ServerResponse, status: number, payload: unknown): void;
|
|
42
|
+
protected abstract reserveWriteRateLimitSlot(req?: IncomingMessage): WriteRateLimitReservation;
|
|
43
|
+
protected abstract respondAdminConsoleShell(
|
|
44
|
+
req: IncomingMessage,
|
|
45
|
+
res: ServerResponse,
|
|
46
|
+
pathname: string,
|
|
47
|
+
relativePath?: string,
|
|
48
|
+
allowPrefill?: boolean,
|
|
49
|
+
): Promise<void>;
|
|
50
|
+
protected abstract respondStatic(res: ServerResponse, filePath: string, contentType: string): Promise<void>;
|
|
51
|
+
|
|
52
|
+
protected handleSupportPassportOwnerRequest(
|
|
53
|
+
req: IncomingMessage,
|
|
54
|
+
res: ServerResponse,
|
|
55
|
+
pathname: string,
|
|
56
|
+
hasQuery: boolean,
|
|
57
|
+
abortSignal: AbortSignal
|
|
58
|
+
): Promise<boolean> {
|
|
59
|
+
return handleSupportPassportOwnerHttp({
|
|
60
|
+
req,
|
|
61
|
+
res,
|
|
62
|
+
pathname,
|
|
63
|
+
hasQuery,
|
|
64
|
+
service: this.service,
|
|
65
|
+
principal: this.resolveRequestPrincipal(req),
|
|
66
|
+
abortSignal,
|
|
67
|
+
readJsonBody: () => this.readJsonBody(req),
|
|
68
|
+
respondJson: (status, payload) => {
|
|
69
|
+
res.setHeader("cache-control", "private, no-store");
|
|
70
|
+
res.setHeader("vary", "Authorization");
|
|
71
|
+
this.respondJson(res, status, payload);
|
|
72
|
+
},
|
|
73
|
+
reserveWriteRateLimitSlot: () => this.reserveWriteRateLimitSlot(req),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
protected handleSupportPassportPublicRequest(req: IncomingMessage, res: ServerResponse): Promise<boolean> {
|
|
78
|
+
this.supportPassportPublicHandler ??= buildSupportPassportPublicRequestHandler(this.service, {
|
|
79
|
+
trustedProxyAddresses: this.service.configRef?.supportPassport?.trustedProxyAddresses ?? [],
|
|
80
|
+
});
|
|
81
|
+
return this.supportPassportPublicHandler(req, res, {
|
|
82
|
+
authorized: false,
|
|
83
|
+
tokenAuthorized: false,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected async enforceSupportPassportAuthorizationProbe(req: IncomingMessage): Promise<void> {
|
|
88
|
+
const principal = this.resolveRequestPrincipal(req)?.trim();
|
|
89
|
+
if (!principal) {
|
|
90
|
+
throw new EngramAccessForbiddenError("A trusted principal is required for support passport access.");
|
|
91
|
+
}
|
|
92
|
+
const owner = await this.service.getWritableStorageForNamespace(undefined, principal);
|
|
93
|
+
enforceNamespaceAllowList(
|
|
94
|
+
tokenCapabilityStore.getStore(),
|
|
95
|
+
owner.namespace,
|
|
96
|
+
this.service.configRef.defaultNamespace
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
protected isSupportPassportQuotaLimitedWriteTool(toolName: string): boolean {
|
|
101
|
+
return SUPPORT_PASSPORT_QUOTA_LIMITED_WRITE_TOOLS.has(toolName);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
protected async handleSupportPassportUi(
|
|
105
|
+
req: IncomingMessage,
|
|
106
|
+
res: ServerResponse,
|
|
107
|
+
pathname: string
|
|
108
|
+
): Promise<boolean> {
|
|
109
|
+
if (req.method !== "GET") return false;
|
|
110
|
+
const isSupportPassportPath =
|
|
111
|
+
pathname === "/remnic/ui/what-helps-me" ||
|
|
112
|
+
pathname === "/engram/ui/what-helps-me" ||
|
|
113
|
+
pathname.startsWith("/remnic/ui/what-helps-me/") ||
|
|
114
|
+
pathname.startsWith("/engram/ui/what-helps-me/");
|
|
115
|
+
if (!isSupportPassportPath) return false;
|
|
116
|
+
if (!this.service.supportPassportEnabled) {
|
|
117
|
+
this.respondJson(res, 404, { error: "not_found" });
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
if (pathname === "/remnic/ui/what-helps-me" || pathname === "/engram/ui/what-helps-me") {
|
|
121
|
+
const search = new URL(req.url ?? pathname, "http://placeholder").search;
|
|
122
|
+
res.statusCode = 301;
|
|
123
|
+
res.setHeader("location", `${pathname}/${search}`);
|
|
124
|
+
res.end();
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (pathname === "/remnic/ui/what-helps-me/" || pathname === "/engram/ui/what-helps-me/") {
|
|
128
|
+
const helperRequest = new URL(req.url ?? pathname, "http://placeholder").searchParams.has("grant");
|
|
129
|
+
res.setHeader("content-security-policy", "frame-ancestors 'none'");
|
|
130
|
+
res.setHeader("x-frame-options", "DENY");
|
|
131
|
+
await this.respondAdminConsoleShell(req, res, pathname, "what-helps-me/index.html", !helperRequest);
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
const fileName = pathname.split("/").at(-1) ?? "";
|
|
135
|
+
const assetType = SUPPORT_PASSPORT_ADMIN_CONSOLE_ASSETS.get(fileName);
|
|
136
|
+
if (assetType && pathname.split("/").length === 5) {
|
|
137
|
+
await this.respondStatic(res, path.join(this.adminConsolePublicDir, "what-helps-me", fileName), assetType);
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
this.respondJson(res, 404, { error: "not_found" });
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
}
|