@remnic/core 9.65.2 → 9.65.4
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 +44 -44
- package/dist/access-admin-ops-surface.js +21 -19
- package/dist/access-authorization-probe.d.ts +38 -38
- package/dist/access-authorization-probe.js +22 -20
- package/dist/access-boundary.d.ts +40 -40
- package/dist/access-boundary.js +21 -19
- package/dist/access-cli.js +62 -60
- 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 +25 -25
- package/dist/access-extraction-force-flush.js +21 -19
- package/dist/access-health-types.d.ts +3 -1
- package/dist/access-http-lcm-compaction.d.ts +39 -39
- package/dist/access-http-lifecycle-flush.d.ts +39 -39
- package/dist/access-http-offline-stream.d.ts +25 -25
- package/dist/access-http-query.d.ts +4 -2
- package/dist/access-http-query.js +23 -21
- package/dist/access-http.d.ts +51 -44
- package/dist/access-http.js +37 -35
- package/dist/access-identity-continuity-surface.d.ts +12 -12
- package/dist/access-identity-continuity-surface.js +21 -19
- package/dist/access-lcm-surface.d.ts +27 -27
- package/dist/access-lcm-surface.js +21 -19
- package/dist/access-mcp-admin-tools.d.ts +9 -1
- package/dist/access-mcp-admin-tools.js +3 -1
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +39 -39
- package/dist/access-mcp.js +31 -29
- package/dist/access-memory-search-fanout.d.ts +4 -2
- package/dist/{access-namespace-preflight-Dhvcl-T0.d.ts → access-namespace-preflight-D_6mo8ms.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +5 -3
- package/dist/access-namespace-preflight.js +21 -19
- package/dist/access-observe-write-surface.d.ts +39 -39
- package/dist/access-observe-write-surface.js +21 -19
- package/dist/access-offline-manifest.d.ts +12 -12
- package/dist/access-offline-manifest.js +3 -3
- package/dist/access-operations-batch.js +25 -23
- package/dist/access-operations.d.ts +40 -40
- package/dist/access-operations.js +28 -26
- package/dist/access-recall-concurrency.d.ts +40 -40
- package/dist/access-recall-concurrency.js +21 -19
- package/dist/access-recall-response.d.ts +24 -24
- package/dist/access-recall-response.js +21 -19
- package/dist/access-recall-surface.d.ts +24 -24
- package/dist/access-recall-surface.js +21 -19
- package/dist/access-schema.d.ts +45 -45
- package/dist/{access-service-Bke1alZO.d.ts → access-service-DqPa3hy4.d.ts} +219 -75
- package/dist/access-service-helpers.d.ts +40 -40
- package/dist/access-service.d.ts +47 -47
- package/dist/access-service.js +21 -19
- package/dist/access-surface-catalog.d.ts +40 -40
- package/dist/access-surface-catalog.js +27 -21
- package/dist/access-surface-catalog.js.map +1 -1
- 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 +10 -1
- package/dist/active-recall.js.map +1 -1
- package/dist/ambient-provenance.d.ts +3 -1
- package/dist/artifact-search.d.ts +3 -1
- package/dist/{auto-sync-H64ZCNIR.js → auto-sync-XVMLL2RH.js} +5 -5
- package/dist/behavior-learner.d.ts +3 -1
- package/dist/behavior-signals.d.ts +3 -1
- package/dist/bootstrap.d.ts +12 -12
- package/dist/briefing-window.d.ts +4 -2
- package/dist/briefing.d.ts +4 -2
- package/dist/briefing.js +4 -4
- 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/bulk-import/index.d.ts +5 -3
- package/dist/calibration.d.ts +3 -1
- package/dist/capabilities.d.ts +3 -1
- package/dist/{catalog-DV6qnbr7.d.ts → catalog-DO_7zfkv.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +3 -1
- package/dist/causal-consolidation.js +12 -9
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/chunk-236PXYG7.js +232 -0
- package/dist/chunk-236PXYG7.js.map +1 -0
- package/dist/{chunk-YB42WZCY.js → chunk-2IXQSGCU.js} +2 -2
- package/dist/{chunk-PE255F4T.js → chunk-2MVTAIL3.js} +2 -2
- package/dist/{chunk-LGO6A7GJ.js → chunk-3JZBPTLD.js} +338 -80
- package/dist/chunk-3JZBPTLD.js.map +1 -0
- package/dist/{chunk-GDFVPUJ5.js → chunk-3NH3VP3U.js} +2 -2
- package/dist/{chunk-TBOJ76ER.js → chunk-AB3A7EFH.js} +18 -2
- package/dist/{chunk-TBOJ76ER.js.map → chunk-AB3A7EFH.js.map} +1 -1
- package/dist/{chunk-GNCCUR6K.js → chunk-AXGFOFNY.js} +2 -2
- package/dist/{chunk-SB7D4BT7.js → chunk-AZLLH6YA.js} +1554 -114
- package/dist/chunk-AZLLH6YA.js.map +1 -0
- package/dist/{chunk-5YQ63T4B.js → chunk-BK5G2MHO.js} +2 -2
- package/dist/{chunk-LZH5FR2W.js → chunk-CQBIN77D.js} +2 -2
- package/dist/{chunk-35NN3ZFA.js → chunk-CTVWELNK.js} +21 -3
- package/dist/chunk-CTVWELNK.js.map +1 -0
- package/dist/{chunk-NKKD4ZAU.js → chunk-DORFF5N5.js} +2 -2
- package/dist/{chunk-BWLRUMOG.js → chunk-DPNXADEI.js} +441 -2
- package/dist/chunk-DPNXADEI.js.map +1 -0
- package/dist/{chunk-SQI57UCJ.js → chunk-DUEDOYZD.js} +2 -2
- package/dist/{chunk-5NM4OH4P.js → chunk-DUZARALI.js} +3 -3
- package/dist/{chunk-2E36UXVW.js → chunk-ECLJ4LA2.js} +2 -2
- package/dist/{chunk-TZNQUNKL.js → chunk-FC7TIRFS.js} +15 -1
- package/dist/chunk-FC7TIRFS.js.map +1 -0
- package/dist/{chunk-IID2CMUU.js → chunk-GHD2LLG4.js} +2 -2
- package/dist/{chunk-ZQHI2BZB.js → chunk-HF5BUTI6.js} +2 -2
- package/dist/{chunk-3DVBKTSO.js → chunk-HSZMX3ZJ.js} +4 -4
- package/dist/{chunk-S2DPMJXH.js → chunk-I23ZHYSL.js} +2 -2
- package/dist/{chunk-ODZG724P.js → chunk-I2HTKOOP.js} +2 -2
- package/dist/chunk-I32NKXE2.js +879 -0
- package/dist/chunk-I32NKXE2.js.map +1 -0
- package/dist/{chunk-NTWN6HB2.js → chunk-IURMJBGP.js} +2 -2
- package/dist/{chunk-OCZIYAE5.js → chunk-IWKGOCL6.js} +3 -3
- package/dist/{chunk-UXO5IMBK.js → chunk-J3ATBB7M.js} +2 -2
- package/dist/{chunk-Y7DK7HHJ.js → chunk-JPAKBNTM.js} +2 -2
- package/dist/{chunk-SPUJNJJC.js → chunk-KFIOPZ25.js} +2 -2
- package/dist/{chunk-JYYBA7TF.js → chunk-KOO37E4Y.js} +2 -2
- package/dist/{chunk-OTHZWLUD.js → chunk-KPB2QHJZ.js} +2 -2
- package/dist/{chunk-SBDCZ2AX.js → chunk-LBFFNDFM.js} +1 -1
- package/dist/chunk-LBFFNDFM.js.map +1 -0
- package/dist/{chunk-CT56C22C.js → chunk-LYBIHM4N.js} +4 -4
- package/dist/{chunk-3I7ASZN3.js → chunk-MFOSZUIT.js} +2 -2
- package/dist/{chunk-DZUJ46DO.js → chunk-NLEH4RTB.js} +2 -2
- package/dist/{chunk-ZO6AXLEH.js → chunk-OCCHUEZB.js} +2 -2
- package/dist/{chunk-EILZG5VC.js → chunk-OU34IQXV.js} +2 -2
- package/dist/{chunk-2XDWWPTN.js → chunk-OZDFB22S.js} +2 -2
- package/dist/{chunk-UIN2BWDD.js → chunk-PTZQYCJ4.js} +2 -2
- package/dist/{chunk-7BY7V4YX.js → chunk-Q4WONDMJ.js} +4 -3
- package/dist/{chunk-7BY7V4YX.js.map → chunk-Q4WONDMJ.js.map} +1 -1
- package/dist/{chunk-Z7PBQPJ4.js → chunk-QJW4MZSW.js} +2 -2
- package/dist/{chunk-R7JAM2XF.js → chunk-R2MZCYA6.js} +3 -3
- package/dist/{chunk-TF77C7SV.js → chunk-SR5LNI6Q.js} +7 -5
- package/dist/chunk-SR5LNI6Q.js.map +1 -0
- package/dist/{chunk-LBWQ65SX.js → chunk-T42L3S6A.js} +4 -4
- package/dist/{chunk-J275IYMG.js → chunk-THVI4Y7X.js} +34 -7
- package/dist/chunk-THVI4Y7X.js.map +1 -0
- package/dist/{chunk-QOS5LBZN.js → chunk-TJFI3K2O.js} +15 -3
- package/dist/chunk-TJFI3K2O.js.map +1 -0
- package/dist/{chunk-2YI72KM3.js → chunk-UCKG36HO.js} +2 -2
- package/dist/{chunk-SIHSCCUQ.js → chunk-UFR6HX7A.js} +1 -1
- package/dist/{chunk-CDUUDBWJ.js → chunk-VFYRYFLL.js} +2 -2
- package/dist/{chunk-XRYZRW54.js → chunk-WDXD6ITO.js} +2 -2
- package/dist/{chunk-4KYOLI6M.js → chunk-XGM3VQWG.js} +120 -14
- package/dist/chunk-XGM3VQWG.js.map +1 -0
- package/dist/{chunk-MN4KB2A4.js → chunk-YDKF4MSJ.js} +3 -3
- package/dist/{chunk-YLDXWCZP.js → chunk-YHGCT462.js} +14 -9
- package/dist/chunk-YHGCT462.js.map +1 -0
- package/dist/{chunk-7YQ4IYS2.js → chunk-YOXVZJFM.js} +2 -2
- package/dist/{chunk-ZWXJBFZU.js → chunk-YZJM6CLF.js} +8 -8
- package/dist/chunk-ZCUTSMR2.js +61 -0
- package/dist/chunk-ZCUTSMR2.js.map +1 -0
- package/dist/{chunk-LUNJ3WFO.js → chunk-ZK4BFABK.js} +4 -4
- package/dist/{chunk-V3MXUL3D.js → chunk-ZPOHEB5Z.js} +329 -653
- package/dist/chunk-ZPOHEB5Z.js.map +1 -0
- package/dist/{chunk-RDFF2NAU.js → chunk-ZXBTTMGZ.js} +184 -88
- package/dist/chunk-ZXBTTMGZ.js.map +1 -0
- package/dist/{cli-cShQ13XG.d.ts → cli-DO3i14pM.d.ts} +5 -5
- package/dist/cli.d.ts +25 -25
- package/dist/cli.js +51 -48
- package/dist/coding/pre-action-gate.d.ts +2 -60
- package/dist/compounding/engine.d.ts +4 -2
- package/dist/compounding/engine.js +4 -4
- 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 +10 -1
- package/dist/connectors/codex-materialize-runner.d.ts +3 -1
- package/dist/connectors/codex-materialize-runner.js +8 -5
- package/dist/connectors/codex-materialize.d.ts +16 -1
- package/dist/connectors/codex-materialize.js +10 -1
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.js +8 -5
- package/dist/consolidation-provenance-check.d.ts +4 -2
- package/dist/consolidation-undo.d.ts +4 -2
- package/dist/contradiction/index.d.ts +10 -270
- package/dist/contradiction/index.js +12 -7
- package/dist/{contradiction-review-QKJH5DKD.js → contradiction-review-WRVLRWHS.js} +6 -2
- package/dist/{contradiction-scan-VOTQRRSX.js → contradiction-scan-AKUWPX5N.js} +5 -3
- package/dist/converge-config.d.ts +3 -1
- package/dist/convergence-refresh.d.ts +4 -2
- package/dist/convergence-refresh.js +6 -6
- 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 +6 -6
- package/dist/cross-lingual-recall.d.ts +3 -1
- 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/{dependency-propagation-delivery-CsGg-VwS.d.ts → dependency-propagation-delivery-D23_x-s5.d.ts} +1 -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-origin-fields.d.ts +3 -1
- package/dist/entity-retrieval.d.ts +4 -2
- package/dist/entity-retrieval.js +4 -4
- package/dist/entity-schema.d.ts +3 -1
- package/dist/episodic-context.d.ts +3 -1
- package/dist/explicit-capture.d.ts +12 -12
- package/dist/explicit-capture.js +1 -1
- package/dist/external-wiki-access.d.ts +40 -40
- package/dist/external-wiki-access.js +22 -20
- 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 +40 -40
- 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-judge.js +2 -2
- 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 +9 -7
- package/dist/fallback-llm.d.ts +3 -1
- package/dist/graph-dashboard-diff.d.ts +3 -1
- package/dist/graph-dashboard-key.d.ts +3 -1
- package/dist/graph-dashboard-parser.d.ts +3 -1
- package/dist/graph-edge-reinforcement.d.ts +3 -1
- package/dist/graph-path-reconstruction.d.ts +3 -1
- package/dist/graph-path-scoring.d.ts +3 -1
- package/dist/graph-snapshot.d.ts +3 -1
- package/dist/graph.d.ts +3 -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--QhGIXF2.d.ts +284 -0
- package/dist/index.d.ts +314 -45
- package/dist/index.js +163 -88
- package/dist/intent.d.ts +3 -1
- package/dist/lcm/engine.d.ts +3 -1
- package/dist/lcm/index.d.ts +3 -1
- 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 +4 -4
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
- package/dist/maintenance/rebuild-memory-projection.d.ts +4 -2
- package/dist/maintenance/rebuild-memory-projection.js +5 -5
- package/dist/{maintenance-jhMpeGne.d.ts → maintenance-PFvY1Pw_.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +37 -37
- 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-subject-cli.d.ts +40 -40
- package/dist/memory-subject.d.ts +42 -42
- 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 +5 -5
- package/dist/namespaces/principal.d.ts +3 -1
- package/dist/namespaces/search.d.ts +3 -1
- package/dist/namespaces/storage.d.ts +5 -3
- package/dist/namespaces/storage.js +4 -4
- 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 +7 -7
- package/dist/operator-doctor-replica.d.ts +3 -1
- package/dist/operator-toolkit.d.ts +5 -3
- package/dist/operator-toolkit.js +19 -13
- package/dist/orchestration/compression-guideline-coordinator.d.ts +4 -2
- package/dist/orchestration/maintenance.d.ts +6 -4
- package/dist/orchestration/maintenance.js +10 -10
- package/dist/{orchestrator-DyGUC7re.d.ts → orchestrator-4wzJrPVm.d.ts} +23 -9
- package/dist/orchestrator.d.ts +12 -12
- package/dist/orchestrator.js +62 -60
- package/dist/patterns-cli.d.ts +3 -1
- package/dist/{pipeline-C25Oxtp1.d.ts → pipeline-CgXgdIrF.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/{public-http-CMe7NQzj.d.ts → public-http-DhIXYBYI.d.ts} +1 -1
- package/dist/{qmd-DkDVCbgF.d.ts → qmd-BppGGxsi.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/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-state.d.ts +3 -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 +3 -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/manifest.js +2 -2
- 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/{resolution-MFY72STR.js → resolution-4552BNRV.js} +14 -4
- package/dist/resolve-auth-token.d.ts +3 -1
- package/dist/resume-bundles.js +8 -2
- 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/salvage-envelope.js +1 -1
- package/dist/schemas.d.ts +44 -44
- package/dist/{scope-profiles-B9xMoFO-.d.ts → scope-profiles-ChZUtxDU.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +3 -1
- package/dist/search/factory.d.ts +3 -1
- package/dist/search/index.d.ts +3 -1
- 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-TddhF0y7.d.ts → semantic-BalR6EXU.d.ts} +1 -1
- package/dist/{semantic-consolidation-C4uykW84.d.ts → semantic-consolidation-mSPwQSmF.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +4 -2
- package/dist/semantic-consolidation.js +9 -6
- package/dist/semantic-rule-promotion.js +4 -4
- package/dist/semantic-rule-verifier.d.ts +3 -1
- package/dist/semantic-rule-verifier.js +4 -4
- package/dist/{service-DCZDZNcV.d.ts → service-BICWLwSP.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/skills-registry.js +4 -56
- package/dist/skills-registry.js.map +1 -1
- package/dist/source-agent-qualifier.d.ts +3 -1
- package/dist/source-agent-qualifier.js +8 -5
- package/dist/{storage-CcKmEjL8.d.ts → storage-B7urx1K3.d.ts} +1 -1
- package/dist/storage.d.ts +4 -2
- package/dist/storage.js +6 -6
- package/dist/subject-config.d.ts +3 -1
- package/dist/summarizer.d.ts +3 -1
- package/dist/summary-snapshot.d.ts +3 -1
- package/dist/support-passport/index.d.ts +43 -43
- package/dist/support-passport/index.js +24 -22
- 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/types.d.ts +20 -20
- package/dist/trust-score-stage.d.ts +3 -1
- package/dist/trust-score.d.ts +3 -1
- package/dist/{types-Pi0lfaEt.d.ts → types-ETU5N6nB.d.ts} +433 -7
- 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 +4 -4
- package/dist/who-knows-cli.d.ts +40 -40
- package/dist/who-knows-cli.js +5 -5
- package/dist/who-knows.d.ts +42 -42
- package/dist/who-knows.js +4 -4
- package/dist/write-envelope.d.ts +3 -1
- package/dist/write-envelope.js +1 -1
- package/package.json +2 -2
- package/src/access-boundary.ts +4 -0
- package/src/access-http.ts +6 -5
- package/src/access-mcp-admin-tools.ts +24 -0
- package/src/access-mcp-output-schemas.ts +14 -0
- package/src/access-mcp.ts +2 -2
- package/src/access-operations-batch.ts +5 -0
- package/src/access-service.ts +27 -0
- package/src/access-surface-catalog.test.ts +24 -0
- package/src/access-surface-catalog.ts +4 -0
- package/src/cli/skills-commands.ts +150 -0
- package/src/cli.ts +4 -2
- package/src/coding/action-gate.test.ts +341 -0
- package/src/coding/action-gate.ts +556 -0
- package/src/config.ts +9 -2
- package/src/connectors/codex-materialize-runner.ts +16 -0
- package/src/connectors/codex-materialize-skills.test.ts +141 -0
- package/src/connectors/codex-materialize.ts +58 -40
- package/src/connectors/materialize-paths.ts +50 -0
- package/src/connectors/materialize-skills.ts +127 -0
- package/src/contradiction/contradiction-review.ts +50 -4
- package/src/contradiction/contradiction-scan.ts +14 -3
- package/src/contradiction/resolution.ts +50 -2
- package/src/index.ts +9 -13
- package/src/orchestration/recall-rerank-coordinator.ts +123 -4
- package/src/orchestration/recall-result-formatter.ts +6 -2
- package/src/orchestration/recall-search-pipeline.ts +14 -1
- package/src/preferences/drift-config.ts +118 -0
- package/src/preferences/drift-recall.ts +133 -0
- package/src/preferences/drift-types.ts +87 -0
- package/src/preferences/index.ts +12 -0
- package/src/preferences/preference-drift.test.ts +690 -0
- package/src/preferences/preference-drift.ts +724 -0
- package/src/procedural/skill-io.test.ts +190 -0
- package/src/procedural/skill-io.ts +220 -0
- package/src/procedural/skill-projection.test.ts +214 -0
- package/src/procedural/skill-projection.ts +356 -0
- package/src/review/review-deck-access.test.ts +325 -0
- package/src/review/review-deck-http-base.ts +133 -0
- package/src/review/review-deck-mutation.test.ts +417 -0
- package/src/review/review-deck-mutation.ts +677 -0
- package/src/review/review-deck-snapshot.ts +196 -0
- package/src/review/review-deck-surface.ts +117 -0
- package/src/review/review-deck.test.ts +347 -0
- package/src/review/review-deck.ts +311 -0
- package/src/storage.ts +4 -6
- package/src/types.ts +9 -6
- package/dist/chunk-35NN3ZFA.js.map +0 -1
- package/dist/chunk-4KYOLI6M.js.map +0 -1
- package/dist/chunk-BWLRUMOG.js.map +0 -1
- package/dist/chunk-J275IYMG.js.map +0 -1
- package/dist/chunk-LGO6A7GJ.js.map +0 -1
- package/dist/chunk-QOS5LBZN.js.map +0 -1
- package/dist/chunk-RDFF2NAU.js.map +0 -1
- package/dist/chunk-SB7D4BT7.js.map +0 -1
- package/dist/chunk-SBDCZ2AX.js.map +0 -1
- package/dist/chunk-TF77C7SV.js.map +0 -1
- package/dist/chunk-TZNQUNKL.js.map +0 -1
- package/dist/chunk-V3MXUL3D.js.map +0 -1
- package/dist/chunk-XCTXS7VY.js +0 -402
- package/dist/chunk-XCTXS7VY.js.map +0 -1
- package/dist/chunk-YLDXWCZP.js.map +0 -1
- /package/dist/{auto-sync-H64ZCNIR.js.map → auto-sync-XVMLL2RH.js.map} +0 -0
- /package/dist/{chunk-YB42WZCY.js.map → chunk-2IXQSGCU.js.map} +0 -0
- /package/dist/{chunk-PE255F4T.js.map → chunk-2MVTAIL3.js.map} +0 -0
- /package/dist/{chunk-GDFVPUJ5.js.map → chunk-3NH3VP3U.js.map} +0 -0
- /package/dist/{chunk-GNCCUR6K.js.map → chunk-AXGFOFNY.js.map} +0 -0
- /package/dist/{chunk-5YQ63T4B.js.map → chunk-BK5G2MHO.js.map} +0 -0
- /package/dist/{chunk-LZH5FR2W.js.map → chunk-CQBIN77D.js.map} +0 -0
- /package/dist/{chunk-NKKD4ZAU.js.map → chunk-DORFF5N5.js.map} +0 -0
- /package/dist/{chunk-SQI57UCJ.js.map → chunk-DUEDOYZD.js.map} +0 -0
- /package/dist/{chunk-5NM4OH4P.js.map → chunk-DUZARALI.js.map} +0 -0
- /package/dist/{chunk-2E36UXVW.js.map → chunk-ECLJ4LA2.js.map} +0 -0
- /package/dist/{chunk-IID2CMUU.js.map → chunk-GHD2LLG4.js.map} +0 -0
- /package/dist/{chunk-ZQHI2BZB.js.map → chunk-HF5BUTI6.js.map} +0 -0
- /package/dist/{chunk-3DVBKTSO.js.map → chunk-HSZMX3ZJ.js.map} +0 -0
- /package/dist/{chunk-S2DPMJXH.js.map → chunk-I23ZHYSL.js.map} +0 -0
- /package/dist/{chunk-ODZG724P.js.map → chunk-I2HTKOOP.js.map} +0 -0
- /package/dist/{chunk-NTWN6HB2.js.map → chunk-IURMJBGP.js.map} +0 -0
- /package/dist/{chunk-OCZIYAE5.js.map → chunk-IWKGOCL6.js.map} +0 -0
- /package/dist/{chunk-UXO5IMBK.js.map → chunk-J3ATBB7M.js.map} +0 -0
- /package/dist/{chunk-Y7DK7HHJ.js.map → chunk-JPAKBNTM.js.map} +0 -0
- /package/dist/{chunk-SPUJNJJC.js.map → chunk-KFIOPZ25.js.map} +0 -0
- /package/dist/{chunk-JYYBA7TF.js.map → chunk-KOO37E4Y.js.map} +0 -0
- /package/dist/{chunk-OTHZWLUD.js.map → chunk-KPB2QHJZ.js.map} +0 -0
- /package/dist/{chunk-CT56C22C.js.map → chunk-LYBIHM4N.js.map} +0 -0
- /package/dist/{chunk-3I7ASZN3.js.map → chunk-MFOSZUIT.js.map} +0 -0
- /package/dist/{chunk-DZUJ46DO.js.map → chunk-NLEH4RTB.js.map} +0 -0
- /package/dist/{chunk-ZO6AXLEH.js.map → chunk-OCCHUEZB.js.map} +0 -0
- /package/dist/{chunk-EILZG5VC.js.map → chunk-OU34IQXV.js.map} +0 -0
- /package/dist/{chunk-2XDWWPTN.js.map → chunk-OZDFB22S.js.map} +0 -0
- /package/dist/{chunk-UIN2BWDD.js.map → chunk-PTZQYCJ4.js.map} +0 -0
- /package/dist/{chunk-Z7PBQPJ4.js.map → chunk-QJW4MZSW.js.map} +0 -0
- /package/dist/{chunk-R7JAM2XF.js.map → chunk-R2MZCYA6.js.map} +0 -0
- /package/dist/{chunk-LBWQ65SX.js.map → chunk-T42L3S6A.js.map} +0 -0
- /package/dist/{chunk-2YI72KM3.js.map → chunk-UCKG36HO.js.map} +0 -0
- /package/dist/{chunk-SIHSCCUQ.js.map → chunk-UFR6HX7A.js.map} +0 -0
- /package/dist/{chunk-CDUUDBWJ.js.map → chunk-VFYRYFLL.js.map} +0 -0
- /package/dist/{chunk-XRYZRW54.js.map → chunk-WDXD6ITO.js.map} +0 -0
- /package/dist/{chunk-MN4KB2A4.js.map → chunk-YDKF4MSJ.js.map} +0 -0
- /package/dist/{chunk-7YQ4IYS2.js.map → chunk-YOXVZJFM.js.map} +0 -0
- /package/dist/{chunk-ZWXJBFZU.js.map → chunk-YZJM6CLF.js.map} +0 -0
- /package/dist/{chunk-LUNJ3WFO.js.map → chunk-ZK4BFABK.js.map} +0 -0
- /package/dist/{contradiction-review-QKJH5DKD.js.map → contradiction-review-WRVLRWHS.js.map} +0 -0
- /package/dist/{contradiction-scan-VOTQRRSX.js.map → contradiction-scan-AKUWPX5N.js.map} +0 -0
- /package/dist/{resolution-MFY72STR.js.map → resolution-4552BNRV.js.map} +0 -0
package/src/access-service.ts
CHANGED
|
@@ -303,6 +303,7 @@ import {
|
|
|
303
303
|
readOfflineSyncFileContentChunk,
|
|
304
304
|
} from "./offline-sync.js";
|
|
305
305
|
import { selfDeps } from "./orchestration/self-deps.js";
|
|
306
|
+
import { ReviewDeckSurface } from "./review/review-deck-surface.js";
|
|
306
307
|
import { formatProfileTraceAscii } from "./profiling.js";
|
|
307
308
|
import { decideDisclosureEscalation } from "./recall-disclosure-escalation.js";
|
|
308
309
|
import { toRecallExplainJson } from "./recall-explain-renderer.js";
|
|
@@ -1243,6 +1244,7 @@ export class EngramAccessService extends SupportPassportAccessServiceBase {
|
|
|
1243
1244
|
private readonly corpusWatermarkCache = new CorpusWatermarkCache();
|
|
1244
1245
|
private readonly replicaDivergenceMonitor: ReplicaDivergenceMonitor;
|
|
1245
1246
|
private readonly injectedSupportPassportGatewayRoute: SupportPassportModelRoute | null;
|
|
1247
|
+
readonly reviewDeckEnabled: boolean;
|
|
1246
1248
|
|
|
1247
1249
|
/** AccessObserveWriteSurface (access-service decomposition). Lazy; selfDeps live wiring. */
|
|
1248
1250
|
private _accessObserveWriteSurface: AccessObserveWriteSurface | undefined;
|
|
@@ -1278,6 +1280,17 @@ export class EngramAccessService extends SupportPassportAccessServiceBase {
|
|
|
1278
1280
|
return this._accessAdminOpsSurface;
|
|
1279
1281
|
}
|
|
1280
1282
|
|
|
1283
|
+
private _reviewDeckSurface: ReviewDeckSurface | undefined;
|
|
1284
|
+
|
|
1285
|
+
private get reviewDeckSurface(): ReviewDeckSurface {
|
|
1286
|
+
if (!this._reviewDeckSurface) {
|
|
1287
|
+
this._reviewDeckSurface = new ReviewDeckSurface(
|
|
1288
|
+
selfDeps<ConstructorParameters<typeof ReviewDeckSurface>[0]>(this)
|
|
1289
|
+
);
|
|
1290
|
+
}
|
|
1291
|
+
return this._reviewDeckSurface;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1281
1294
|
/** AccessRecallSurface (access-service decomposition). Lazy; selfDeps live wiring. */
|
|
1282
1295
|
private _accessRecallSurface: AccessRecallSurface | undefined;
|
|
1283
1296
|
|
|
@@ -1308,6 +1321,7 @@ export class EngramAccessService extends SupportPassportAccessServiceBase {
|
|
|
1308
1321
|
options: {
|
|
1309
1322
|
resolveSecretRef?: ResolveSecretRefFn | null;
|
|
1310
1323
|
supportPassportGatewayRoute?: SupportPassportModelRoute | null;
|
|
1324
|
+
reviewDeckEnabled?: boolean;
|
|
1311
1325
|
} = {}
|
|
1312
1326
|
) {
|
|
1313
1327
|
super();
|
|
@@ -1318,6 +1332,7 @@ export class EngramAccessService extends SupportPassportAccessServiceBase {
|
|
|
1318
1332
|
// per-peer `unreachable` (never a throw).
|
|
1319
1333
|
this.replicaDivergenceMonitor = new ReplicaDivergenceMonitor({ resolveSecretRef: options.resolveSecretRef });
|
|
1320
1334
|
this.injectedSupportPassportGatewayRoute = options.supportPassportGatewayRoute ?? null;
|
|
1335
|
+
this.reviewDeckEnabled = options.reviewDeckEnabled === true;
|
|
1321
1336
|
const accessCaps = resolveAccessSetupCapabilities(orchestrator.config); // #1566 Cluster B
|
|
1322
1337
|
this.budget = new CrossNamespaceBudget({
|
|
1323
1338
|
enabled: accessCaps.recallCrossNamespaceBudget,
|
|
@@ -5687,4 +5702,16 @@ export class EngramAccessService extends SupportPassportAccessServiceBase {
|
|
|
5687
5702
|
}) {
|
|
5688
5703
|
return this.accessAdminOpsSurface.adminPromoteMemory(request);
|
|
5689
5704
|
}
|
|
5705
|
+
|
|
5706
|
+
async reviewDeckList(opts: Parameters<ReviewDeckSurface["list"]>[0]) {
|
|
5707
|
+
return this.reviewDeckSurface.list(opts);
|
|
5708
|
+
}
|
|
5709
|
+
|
|
5710
|
+
async reviewDeckAction(...args: Parameters<ReviewDeckSurface["action"]>) {
|
|
5711
|
+
return this.reviewDeckSurface.action(...args);
|
|
5712
|
+
}
|
|
5713
|
+
|
|
5714
|
+
async reviewDeckUndo(...args: Parameters<ReviewDeckSurface["undo"]>) {
|
|
5715
|
+
return this.reviewDeckSurface.undo(...args);
|
|
5716
|
+
}
|
|
5690
5717
|
}
|
|
@@ -170,6 +170,14 @@ function extractMcpDispatchMap(): Map<string, string> {
|
|
|
170
170
|
new URL("./support-passport/mcp-tools.ts", import.meta.url),
|
|
171
171
|
"SUPPORT_PASSPORT_MCP_MIGRATED_OPERATIONS",
|
|
172
172
|
),
|
|
173
|
+
// Third dispatch home (issue #2371): the admin/maintenance tool table
|
|
174
|
+
// contributes its own map fragment, spread into MCP_MIGRATED_OPERATIONS.
|
|
175
|
+
// Every module that can register a dispatch entry must be read here, or
|
|
176
|
+
// this validator reports a false "no dispatch wiring".
|
|
177
|
+
...extractMcpOperationMap(
|
|
178
|
+
new URL("./access-mcp-admin-tools.ts", import.meta.url),
|
|
179
|
+
"MCP_ADMIN_OPS_MIGRATED_OPERATIONS",
|
|
180
|
+
),
|
|
173
181
|
]);
|
|
174
182
|
}
|
|
175
183
|
|
|
@@ -317,6 +325,22 @@ function extractHttpRouteDispatchMap(): Map<string, Set<string>> {
|
|
|
317
325
|
}
|
|
318
326
|
}
|
|
319
327
|
}
|
|
328
|
+
if (/\bawait\s+this\.handleReviewDeckRequest\(/.test(source)) {
|
|
329
|
+
const deckSource = readFileSync(
|
|
330
|
+
new URL("./review/review-deck-http-base.ts", import.meta.url),
|
|
331
|
+
"utf-8",
|
|
332
|
+
);
|
|
333
|
+
const deckRoutes = [
|
|
334
|
+
["GET", "/engram/v1/review/deck", "review_deck_list"],
|
|
335
|
+
["POST", "/engram/v1/review/deck/action", "review_deck_action"],
|
|
336
|
+
["POST", "/engram/v1/review/deck/undo", "review_deck_undo"],
|
|
337
|
+
] as const;
|
|
338
|
+
for (const [method, pathname, operation] of deckRoutes) {
|
|
339
|
+
if (deckSource.includes(`"${pathname}"`) && deckSource.includes(`enforceTokenOp("${operation}")`)) {
|
|
340
|
+
routeOps.set(`${method} ${pathname}`, new Set([operation]));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
320
344
|
for (const [sourcePath, routes] of [
|
|
321
345
|
["./support-passport/access-http.ts", SUPPORT_PASSPORT_OWNER_HTTP_ROUTES],
|
|
322
346
|
["./support-passport/public-http.ts", SUPPORT_PASSPORT_PUBLIC_HTTP_ROUTES],
|
|
@@ -153,6 +153,7 @@ export const MCP_TOOLS: readonly McpToolEntry[] = [
|
|
|
153
153
|
{ tool: "review_list", operation: "review_list" },
|
|
154
154
|
{ tool: "review_resolve", operation: "review_resolve" },
|
|
155
155
|
{ tool: "contradiction_scan_run", operation: "contradiction_scan_run" },
|
|
156
|
+
{ tool: "preference_drift_scan", operation: "preference_drift_scan" },
|
|
156
157
|
{ tool: "memory_summarize_hourly", operation: "memory_summarize_hourly" },
|
|
157
158
|
{ tool: "conversation_index_update", operation: "conversation_index_update" },
|
|
158
159
|
{ tool: "profiling_report", operation: "profiling_report" },
|
|
@@ -253,6 +254,9 @@ export const HTTP_ROUTES: readonly HttpRouteEntry[] = [
|
|
|
253
254
|
{ method: "GET", pathname: "/engram/v1/procedural/stats", operation: "procedural_stats" },
|
|
254
255
|
{ method: "GET", pathname: "/engram/v1/trust-zones/records", operation: "trust_zones_records" },
|
|
255
256
|
{ method: "POST", pathname: "/engram/v1/review-disposition", operation: "review_disposition" },
|
|
257
|
+
{ method: "GET", pathname: "/engram/v1/review/deck", operation: "review_deck_list" },
|
|
258
|
+
{ method: "POST", pathname: "/engram/v1/review/deck/action", operation: "review_deck_action" },
|
|
259
|
+
{ method: "POST", pathname: "/engram/v1/review/deck/undo", operation: "review_deck_undo" },
|
|
256
260
|
{ method: "POST", pathname: "/engram/v1/trust-zones/promote", operation: "trust_zones_promote" },
|
|
257
261
|
{ method: "POST", pathname: "/engram/v1/trust-zones/demo-seed", operation: "trust_zones_demo_seed" },
|
|
258
262
|
{ method: "POST", pathname: "/v1/citations/observed", operation: "citations_observed" },
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill bundle export / import commands (issue #2369) — registered as
|
|
3
|
+
* `remnic export skills` and `remnic import skills <dir>`.
|
|
4
|
+
*
|
|
5
|
+
* Lives outside cli.ts (which is at its structural ceiling) and mirrors the
|
|
6
|
+
* registerMeetingsCommands seam: one registrar, no behavior of its own beyond
|
|
7
|
+
* option parsing and rendering. All projection, path safety, and persistence
|
|
8
|
+
* live in `procedural/skill-projection.ts` + `procedural/skill-io.ts`, so the
|
|
9
|
+
* CLI and the Codex materializer share one contract.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { CliCommand } from "../cli.js";
|
|
13
|
+
import type { Orchestrator } from "../orchestrator.js";
|
|
14
|
+
import {
|
|
15
|
+
exportSkillBundles,
|
|
16
|
+
persistImportedSkills,
|
|
17
|
+
readSkillBundlesFromDir,
|
|
18
|
+
} from "../procedural/skill-io.js";
|
|
19
|
+
import { projectProceduresToSkills } from "../procedural/skill-projection.js";
|
|
20
|
+
import { BUILTIN_SKILLS } from "../skills-registry.js";
|
|
21
|
+
import { expandTildePath } from "../utils/path.js";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Parse `--max-skills`. Rejects non-integers and negatives rather than
|
|
25
|
+
* silently defaulting (Review Prevention Checklist §1, §39); `0` is honored as
|
|
26
|
+
* the documented disable value (§33).
|
|
27
|
+
*/
|
|
28
|
+
function parseMaxSkills(raw: unknown, fallback: number): number {
|
|
29
|
+
if (raw === undefined || raw === null || raw === "") return fallback;
|
|
30
|
+
const value = Number(raw);
|
|
31
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
32
|
+
throw new Error(`Invalid --max-skills '${String(raw)}'. Expected a non-negative integer (0 exports nothing).`);
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function registerSkillsCommands(
|
|
38
|
+
exportCmd: CliCommand,
|
|
39
|
+
importCmd: CliCommand,
|
|
40
|
+
orchestrator: Orchestrator,
|
|
41
|
+
): void {
|
|
42
|
+
exportCmd
|
|
43
|
+
.command("skills")
|
|
44
|
+
.description(
|
|
45
|
+
"Export active procedure memories as portable skills/<slug>/SKILL.md bundles (issue #2369). Read-only with respect to memory.",
|
|
46
|
+
)
|
|
47
|
+
.option("--out <dir>", "Output directory (e.g. a host skills dir or a git repo)")
|
|
48
|
+
.option("--max-skills <n>", "Cap on exported bundles (0 exports none; default from config)")
|
|
49
|
+
.option("--namespace <ns>", "Namespace to export (default: config defaultNamespace)", "")
|
|
50
|
+
.action(async (...args: unknown[]) => {
|
|
51
|
+
const options = (args[0] ?? {}) as Record<string, unknown>;
|
|
52
|
+
const out = options.out ? String(options.out) : "";
|
|
53
|
+
if (!out) {
|
|
54
|
+
console.error("Missing --out. Example: remnic export skills --out ./exported-skills");
|
|
55
|
+
process.exitCode = 1;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (orchestrator.config.procedural.enabled !== true) {
|
|
59
|
+
console.error(
|
|
60
|
+
"procedural memory is disabled (procedural.enabled=false); there are no procedure memories to export.",
|
|
61
|
+
);
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
let maxSkills: number;
|
|
66
|
+
try {
|
|
67
|
+
maxSkills = parseMaxSkills(options.maxSkills, orchestrator.config.procedural.skillProjection.maxSkills);
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const namespace = options.namespace ? String(options.namespace) : "";
|
|
75
|
+
const storage = await orchestrator.getStorageForNamespace(namespace || undefined);
|
|
76
|
+
const bundles = projectProceduresToSkills(await storage.readAllMemories(), {
|
|
77
|
+
maxSkills,
|
|
78
|
+
reservedSlugs: BUILTIN_SKILLS.map((skill) => skill.slug),
|
|
79
|
+
});
|
|
80
|
+
const result = await exportSkillBundles({ bundles, outDir: expandTildePath(out) });
|
|
81
|
+
console.log(`Exported ${result.slugs.length} skill bundle(s) to ${result.outDir}`);
|
|
82
|
+
for (const slug of result.slugs) {
|
|
83
|
+
console.log(` ${slug}/SKILL.md`);
|
|
84
|
+
}
|
|
85
|
+
console.log("OK");
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
importCmd
|
|
89
|
+
.command("skills <dir>")
|
|
90
|
+
.description(
|
|
91
|
+
"Import skills/<slug>/SKILL.md bundles as pending_review procedure memories (issue #2369). Never executes bundle scripts.",
|
|
92
|
+
)
|
|
93
|
+
.option("--namespace <ns>", "Namespace to import into (default: config defaultNamespace)", "")
|
|
94
|
+
.action(async (...args: unknown[]) => {
|
|
95
|
+
const dir = args[0] ? String(args[0]) : "";
|
|
96
|
+
const options = (args[1] ?? {}) as Record<string, unknown>;
|
|
97
|
+
if (!dir) {
|
|
98
|
+
console.error("Usage: remnic import skills <dir>");
|
|
99
|
+
process.exitCode = 1;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (orchestrator.config.procedural.enabled !== true) {
|
|
103
|
+
console.error(
|
|
104
|
+
"procedural memory is disabled (procedural.enabled=false); enable it before importing procedures.",
|
|
105
|
+
);
|
|
106
|
+
process.exitCode = 1;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let read;
|
|
111
|
+
try {
|
|
112
|
+
read = await readSkillBundlesFromDir(expandTildePath(dir));
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
115
|
+
process.exitCode = 1;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
for (const skip of read.skipped) {
|
|
119
|
+
console.log(`Skipped ${skip.entry}: ${skip.reason}`);
|
|
120
|
+
}
|
|
121
|
+
if (read.bundles.length === 0) {
|
|
122
|
+
console.log("No SKILL.md bundles found.");
|
|
123
|
+
console.log("OK");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const namespace = options.namespace ? String(options.namespace) : "";
|
|
128
|
+
const storage = await orchestrator.getStorageForNamespace(namespace || undefined);
|
|
129
|
+
const { imported, rejected } = await persistImportedSkills({ storage, bundles: read.bundles });
|
|
130
|
+
|
|
131
|
+
// Direct writes bypass extraction, so the search index needs an explicit
|
|
132
|
+
// refresh or imported procedures stay undiscoverable (§31).
|
|
133
|
+
await orchestrator.qmd.probe();
|
|
134
|
+
if (orchestrator.qmd.isAvailable()) {
|
|
135
|
+
await orchestrator.qmd.update();
|
|
136
|
+
} else {
|
|
137
|
+
console.log(`QMD unavailable in this process; skipped reindex. Status: ${orchestrator.qmd.debugStatus()}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log(`Imported ${imported.length} procedure(s) as pending_review (promote after review).`);
|
|
141
|
+
for (const record of imported) {
|
|
142
|
+
const resources = record.hasUnimportedResources ? " [has unimported resources]" : "";
|
|
143
|
+
console.log(` ${record.slug}: ${record.steps} step(s)${resources}`);
|
|
144
|
+
}
|
|
145
|
+
for (const reject of rejected) {
|
|
146
|
+
console.log(` ${reject.slug}: ${reject.reason}`);
|
|
147
|
+
}
|
|
148
|
+
console.log("OK");
|
|
149
|
+
});
|
|
150
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { padEndDisplay, truncateGraphemeSafe } from "./whitespace.js";
|
|
|
16
16
|
import { runWearablesCliCommand } from "./wearables/cli.js";
|
|
17
17
|
import { registerMeetingsCommands } from "./cli/meetings-commands.js";
|
|
18
18
|
import { registerOkfCommands } from "./cli/okf-commands.js";
|
|
19
|
+
import { registerSkillsCommands } from "./cli/skills-commands.js";
|
|
19
20
|
import { registerResearchStatusCommands } from "./cli/research-status-commands.js";
|
|
20
21
|
import { registerCreationLedgerCommands } from "./cli/creation-ledger-commands.js";
|
|
21
22
|
import type {
|
|
@@ -4316,7 +4317,7 @@ export function registerCli(
|
|
|
4316
4317
|
}
|
|
4317
4318
|
});
|
|
4318
4319
|
|
|
4319
|
-
cmd
|
|
4320
|
+
const exportCmd = cmd
|
|
4320
4321
|
.command("export")
|
|
4321
4322
|
.description("Export Remnic memory to JSON, Markdown bundle, or SQLite")
|
|
4322
4323
|
.option("--format <format>", "Export format: json|md|sqlite", "json")
|
|
@@ -4368,7 +4369,7 @@ export function registerCli(
|
|
|
4368
4369
|
console.log("OK");
|
|
4369
4370
|
});
|
|
4370
4371
|
|
|
4371
|
-
cmd
|
|
4372
|
+
const importCmd = cmd
|
|
4372
4373
|
.command("import")
|
|
4373
4374
|
.description("Import Remnic memory from JSON bundle, Markdown bundle, or SQLite")
|
|
4374
4375
|
.option("--from <path>", "Import source path (dir or file)")
|
|
@@ -4424,6 +4425,7 @@ export function registerCli(
|
|
|
4424
4425
|
}
|
|
4425
4426
|
console.log("OK");
|
|
4426
4427
|
});
|
|
4428
|
+
registerSkillsCommands(exportCmd, importCmd, orchestrator);
|
|
4427
4429
|
|
|
4428
4430
|
cmd
|
|
4429
4431
|
.command("backup")
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import { recordCausalTrajectory } from "../causal-trajectory.js";
|
|
7
|
+
import type { CodingContext, MemoryFile } from "../types.js";
|
|
8
|
+
import {
|
|
9
|
+
ACTION_GATE_DEFAULTS,
|
|
10
|
+
type ActionGateAuditRecord,
|
|
11
|
+
type ActionGateCandidateSource,
|
|
12
|
+
type ActionGateRequest,
|
|
13
|
+
ActionGateService,
|
|
14
|
+
actionTermsFor,
|
|
15
|
+
createFailureMemoryCandidateSource,
|
|
16
|
+
createTrajectoryCandidateSource,
|
|
17
|
+
isFailureClassMemory,
|
|
18
|
+
parseActionGateConfig,
|
|
19
|
+
} from "./action-gate.js";
|
|
20
|
+
import { PreActionFailureGate, normalizeActionIntent } from "./pre-action-gate.js";
|
|
21
|
+
|
|
22
|
+
const codingContext: CodingContext = {
|
|
23
|
+
projectId: "proj-gate",
|
|
24
|
+
branch: "main",
|
|
25
|
+
rootPath: "/work/project",
|
|
26
|
+
defaultBranch: null,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function memory(id: string, content: string, overrides: Record<string, unknown> = {}): MemoryFile {
|
|
30
|
+
return {
|
|
31
|
+
path: `facts/2026-08-18/${id}.md`,
|
|
32
|
+
content,
|
|
33
|
+
frontmatter: {
|
|
34
|
+
id,
|
|
35
|
+
category: "correction",
|
|
36
|
+
created: "2026-08-18T00:00:00Z",
|
|
37
|
+
updated: "2026-08-18T00:00:00Z",
|
|
38
|
+
source: "test",
|
|
39
|
+
confidence: 0.9,
|
|
40
|
+
confidenceTier: "explicit",
|
|
41
|
+
tags: [],
|
|
42
|
+
status: "active",
|
|
43
|
+
...overrides,
|
|
44
|
+
} as MemoryFile["frontmatter"],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function request(overrides: Partial<ActionGateRequest> = {}): ActionGateRequest {
|
|
49
|
+
return {
|
|
50
|
+
sessionKey: "session-a",
|
|
51
|
+
turnId: "turn-1",
|
|
52
|
+
strategyId: "RUN_CHECK",
|
|
53
|
+
intent: { kind: "command", command: "pnpm", args: ["migrate", "--force"] },
|
|
54
|
+
codingContext,
|
|
55
|
+
memoryDir: "/tmp/does-not-matter",
|
|
56
|
+
...overrides,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function staticSource(id: string, memoryIds: string[]): ActionGateCandidateSource {
|
|
61
|
+
return {
|
|
62
|
+
id,
|
|
63
|
+
async find() {
|
|
64
|
+
return {
|
|
65
|
+
ok: true,
|
|
66
|
+
candidates: memoryIds.map((memoryId, index) => ({
|
|
67
|
+
memoryId,
|
|
68
|
+
score: memoryIds.length - index,
|
|
69
|
+
advisoryText: `advisory for ${memoryId}`,
|
|
70
|
+
})),
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
test("parses the actionGate block with safe defaults and zero-limit semantics", () => {
|
|
77
|
+
assert.deepEqual(parseActionGateConfig(undefined), ACTION_GATE_DEFAULTS);
|
|
78
|
+
assert.equal(parseActionGateConfig(undefined).enabled, false);
|
|
79
|
+
// CLI values arrive as strings.
|
|
80
|
+
assert.equal(parseActionGateConfig({ enabled: "false" }).enabled, false);
|
|
81
|
+
assert.equal(parseActionGateConfig({ enabled: "on" }).enabled, true);
|
|
82
|
+
assert.equal(parseActionGateConfig({ maxAdvisoriesPerTurn: "0" }).maxAdvisoriesPerTurn, 0);
|
|
83
|
+
assert.equal(parseActionGateConfig({ timeoutMs: "120" }).timeoutMs, 120);
|
|
84
|
+
assert.equal(parseActionGateConfig({ timeoutMs: 0 }).timeoutMs, 1);
|
|
85
|
+
assert.throws(() => parseActionGateConfig({ enabled: "maybe" }), /actionGate.enabled/);
|
|
86
|
+
assert.throws(() => parseActionGateConfig([]), /must be an object/);
|
|
87
|
+
assert.throws(() => parseActionGateConfig(null), /must be an object/);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("disabled gate performs no lookup on any path", async () => {
|
|
91
|
+
let calls = 0;
|
|
92
|
+
const source: ActionGateCandidateSource = {
|
|
93
|
+
id: "spy",
|
|
94
|
+
async find() {
|
|
95
|
+
calls += 1;
|
|
96
|
+
return { ok: true, candidates: [{ memoryId: "m1", advisoryText: "never" }] };
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
const audits: ActionGateAuditRecord[] = [];
|
|
100
|
+
const disabled = new ActionGateService(parseActionGateConfig({}), {
|
|
101
|
+
sources: [source],
|
|
102
|
+
audit: (record) => void audits.push(record),
|
|
103
|
+
});
|
|
104
|
+
const decision = await disabled.evaluate(request());
|
|
105
|
+
assert.equal(decision.status, "DISABLED");
|
|
106
|
+
assert.deepEqual(decision.advisories, []);
|
|
107
|
+
assert.equal(calls, 0);
|
|
108
|
+
assert.deepEqual(disabled.suppressedForTurnStart("session-a"), []);
|
|
109
|
+
disabled.noteTurnStartDelivery("session-a", ["m1"]);
|
|
110
|
+
assert.deepEqual(disabled.suppressedForTurnStart("session-a"), []);
|
|
111
|
+
|
|
112
|
+
const zeroBudget = new ActionGateService(parseActionGateConfig({ enabled: true, maxAdvisoriesPerTurn: 0 }), {
|
|
113
|
+
sources: [source],
|
|
114
|
+
});
|
|
115
|
+
const zeroDecision = await zeroBudget.evaluate(request());
|
|
116
|
+
assert.equal(zeroDecision.status, "DISABLED");
|
|
117
|
+
assert.match(zeroDecision.reason ?? "", /maxAdvisoriesPerTurn is 0/);
|
|
118
|
+
assert.equal(calls, 0);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("delivers one bounded advisory and suppresses it from turn-start recall", async () => {
|
|
122
|
+
const audits: ActionGateAuditRecord[] = [];
|
|
123
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true }), {
|
|
124
|
+
sources: [
|
|
125
|
+
createFailureMemoryCandidateSource({
|
|
126
|
+
async listMemories() {
|
|
127
|
+
return [
|
|
128
|
+
memory("mem-match", "Running pnpm migrate --force dropped the dev database."),
|
|
129
|
+
memory("mem-other", "Unrelated note about documentation."),
|
|
130
|
+
memory("mem-archived", "pnpm migrate --force failed again", { status: "archived" }),
|
|
131
|
+
];
|
|
132
|
+
},
|
|
133
|
+
}),
|
|
134
|
+
],
|
|
135
|
+
audit: (record) => void audits.push(record),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const decision = await service.evaluate(request());
|
|
139
|
+
assert.equal(decision.status, "MATCH_WARN");
|
|
140
|
+
assert.equal(decision.advisories.length, 1);
|
|
141
|
+
assert.equal(decision.advisories[0].memoryId, "mem-match");
|
|
142
|
+
assert.equal(decision.advisories[0].sourceId, "failure-memory");
|
|
143
|
+
assert.match(decision.advisories[0].text, /dropped the dev database/);
|
|
144
|
+
assert.ok(decision.advisories[0].text.length <= 400);
|
|
145
|
+
assert.deepEqual(decision.degradations, []);
|
|
146
|
+
|
|
147
|
+
// Double-delivery suppression: turn-start recall must skip what the gate sent.
|
|
148
|
+
assert.deepEqual(service.suppressedForTurnStart("session-a"), ["mem-match"]);
|
|
149
|
+
|
|
150
|
+
// Same turn, same action: deduplicated per fact per turn.
|
|
151
|
+
const repeat = await service.evaluate(request());
|
|
152
|
+
assert.deepEqual(repeat.advisories, []);
|
|
153
|
+
assert.deepEqual(repeat.suppressedIds, ["mem-match"]);
|
|
154
|
+
assert.equal(repeat.status, "NO_MATCH");
|
|
155
|
+
|
|
156
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
157
|
+
assert.equal(audits.length, 2);
|
|
158
|
+
assert.deepEqual(audits[0].deliveredIds, ["mem-match"]);
|
|
159
|
+
assert.deepEqual(audits[1].suppressedIds, ["mem-match"]);
|
|
160
|
+
assert.match(audits[0].fingerprint ?? "", /^v1:sha256:/);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test("skips candidates turn-start recall already delivered", async () => {
|
|
164
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true }), {
|
|
165
|
+
sources: [staticSource("static", ["mem-a"])],
|
|
166
|
+
});
|
|
167
|
+
service.noteTurnStartDelivery("session-a", ["mem-a"]);
|
|
168
|
+
const decision = await service.evaluate(request());
|
|
169
|
+
assert.equal(decision.status, "NO_MATCH");
|
|
170
|
+
assert.deepEqual(decision.suppressedIds, ["mem-a"]);
|
|
171
|
+
assert.deepEqual(decision.advisories, []);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("caps advisories per turn and resets the budget on the next turn", async () => {
|
|
175
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true, maxAdvisoriesPerTurn: 2 }), {
|
|
176
|
+
sources: [staticSource("static", ["mem-a", "mem-b", "mem-c"])],
|
|
177
|
+
});
|
|
178
|
+
const first = await service.evaluate(request());
|
|
179
|
+
assert.deepEqual(
|
|
180
|
+
first.advisories.map((advisory) => advisory.memoryId),
|
|
181
|
+
["mem-a", "mem-b"]
|
|
182
|
+
);
|
|
183
|
+
assert.deepEqual(first.suppressedIds, ["mem-c"]);
|
|
184
|
+
|
|
185
|
+
const nextTurn = await service.evaluate(request({ turnId: "turn-2" }));
|
|
186
|
+
// A new turn re-arms the budget: proposing the same action again warns again,
|
|
187
|
+
// which is the whole point of action-site delivery.
|
|
188
|
+
assert.deepEqual(
|
|
189
|
+
nextTurn.advisories.map((advisory) => advisory.memoryId),
|
|
190
|
+
["mem-a", "mem-b"]
|
|
191
|
+
);
|
|
192
|
+
assert.deepEqual(nextTurn.suppressedIds, ["mem-c"]);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("namespace scoping keeps advisories inside the requesting principal", async () => {
|
|
196
|
+
const byNamespace: Record<string, MemoryFile[]> = {
|
|
197
|
+
"tenant-a": [memory("mem-a", "pnpm migrate --force wiped tenant a data")],
|
|
198
|
+
"tenant-b": [memory("mem-b", "pnpm migrate --force wiped tenant b data")],
|
|
199
|
+
};
|
|
200
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true }), {
|
|
201
|
+
sources: [
|
|
202
|
+
createFailureMemoryCandidateSource({
|
|
203
|
+
async listMemories({ namespace }) {
|
|
204
|
+
return byNamespace[namespace ?? ""] ?? [];
|
|
205
|
+
},
|
|
206
|
+
}),
|
|
207
|
+
],
|
|
208
|
+
});
|
|
209
|
+
const a = await service.evaluate(request({ sessionKey: "s-a", namespace: "tenant-a" }));
|
|
210
|
+
const b = await service.evaluate(request({ sessionKey: "s-b", namespace: "tenant-b" }));
|
|
211
|
+
assert.deepEqual(
|
|
212
|
+
a.advisories.map((advisory) => advisory.memoryId),
|
|
213
|
+
["mem-a"]
|
|
214
|
+
);
|
|
215
|
+
assert.deepEqual(
|
|
216
|
+
b.advisories.map((advisory) => advisory.memoryId),
|
|
217
|
+
["mem-b"]
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test("source failure fails open with a distinct status and audit degradation", async () => {
|
|
222
|
+
const audits: ActionGateAuditRecord[] = [];
|
|
223
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true }), {
|
|
224
|
+
sources: [
|
|
225
|
+
{
|
|
226
|
+
id: "broken",
|
|
227
|
+
async find() {
|
|
228
|
+
throw new Error("store unreadable");
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
audit: (record) => void audits.push(record),
|
|
233
|
+
});
|
|
234
|
+
const decision = await service.evaluate(request());
|
|
235
|
+
assert.equal(decision.status, "ERROR_FAIL_OPEN");
|
|
236
|
+
assert.deepEqual(decision.advisories, []);
|
|
237
|
+
assert.match(decision.degradations[0], /broken: store unreadable/);
|
|
238
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
239
|
+
assert.equal(audits[0].status, "ERROR_FAIL_OPEN");
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
test("an over-deadline source fails open instead of delaying the action", async () => {
|
|
243
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true, timeoutMs: 5 }), {
|
|
244
|
+
sources: [
|
|
245
|
+
{
|
|
246
|
+
id: "slow",
|
|
247
|
+
find() {
|
|
248
|
+
return new Promise((resolve) =>
|
|
249
|
+
setTimeout(() => resolve({ ok: true, candidates: [{ memoryId: "late", advisoryText: "late" }] }), 200)
|
|
250
|
+
);
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
});
|
|
255
|
+
const startedAt = Date.now();
|
|
256
|
+
const decision = await service.evaluate(request());
|
|
257
|
+
assert.ok(Date.now() - startedAt < 150, "gate must not wait for the slow source");
|
|
258
|
+
assert.equal(decision.status, "ERROR_FAIL_OPEN");
|
|
259
|
+
assert.match(decision.degradations[0], /timed out after 5ms/);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test("an invalid action intent fails open rather than throwing", async () => {
|
|
263
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true }), {
|
|
264
|
+
sources: [staticSource("static", ["mem-a"])],
|
|
265
|
+
});
|
|
266
|
+
const decision = await service.evaluate(
|
|
267
|
+
request({ intent: { kind: "edit", filePath: "/elsewhere/secret.ts", editKind: "update" } })
|
|
268
|
+
);
|
|
269
|
+
assert.equal(decision.status, "ERROR_FAIL_OPEN");
|
|
270
|
+
assert.match(decision.reason ?? "", /contained/);
|
|
271
|
+
assert.deepEqual(decision.advisories, []);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test("trajectory source surfaces a recorded failure at the action site", async () => {
|
|
275
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-action-gate-"));
|
|
276
|
+
try {
|
|
277
|
+
const intent = { kind: "command" as const, command: "pnpm", args: ["migrate", "--force"] };
|
|
278
|
+
await recordCausalTrajectory({
|
|
279
|
+
memoryDir,
|
|
280
|
+
record: {
|
|
281
|
+
schemaVersion: 1,
|
|
282
|
+
trajectoryId: "traj-failure",
|
|
283
|
+
recordedAt: "2026-08-17T12:00:00Z",
|
|
284
|
+
sessionKey: "historical-session",
|
|
285
|
+
goal: "Migrate the database",
|
|
286
|
+
actionSummary: "Ran the forced migration",
|
|
287
|
+
observationSummary: "The migration destroyed local data",
|
|
288
|
+
outcomeKind: "failure",
|
|
289
|
+
outcomeSummary: "Dev database dropped",
|
|
290
|
+
followUpSummary: "Take a snapshot before migrating",
|
|
291
|
+
codingContext: { projectId: codingContext.projectId, branch: "main" },
|
|
292
|
+
actionIdentity: {
|
|
293
|
+
fingerprintVersion: 1,
|
|
294
|
+
fingerprint: normalizeActionIntent(intent, "RUN_CHECK", codingContext).fingerprint,
|
|
295
|
+
strategyId: "RUN_CHECK",
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
const service = new ActionGateService(parseActionGateConfig({ enabled: true, timeoutMs: 2000 }), {
|
|
300
|
+
sources: [createTrajectoryCandidateSource(new PreActionFailureGate({ timeoutMs: 1000 }))],
|
|
301
|
+
});
|
|
302
|
+
const decision = await service.evaluate(request({ intent, memoryDir }));
|
|
303
|
+
assert.equal(decision.status, "MATCH_WARN");
|
|
304
|
+
assert.equal(decision.advisories[0].memoryId, "traj-failure");
|
|
305
|
+
assert.equal(decision.advisories[0].sourceId, "causal-trajectory");
|
|
306
|
+
assert.match(decision.advisories[0].text, /Dev database dropped/);
|
|
307
|
+
|
|
308
|
+
const unrelated = await service.evaluate(
|
|
309
|
+
request({
|
|
310
|
+
turnId: "turn-2",
|
|
311
|
+
intent: { kind: "command", command: "pnpm", args: ["build"] },
|
|
312
|
+
memoryDir,
|
|
313
|
+
})
|
|
314
|
+
);
|
|
315
|
+
assert.equal(unrelated.status, "NO_MATCH");
|
|
316
|
+
} finally {
|
|
317
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test("failure-class detection and action terms stay deterministic", () => {
|
|
322
|
+
assert.equal(isFailureClassMemory(memory("m", "x")), true);
|
|
323
|
+
assert.equal(isFailureClassMemory(memory("m", "x", { category: "fact" })), false);
|
|
324
|
+
assert.equal(
|
|
325
|
+
isFailureClassMemory(memory("m", "x", { category: "procedure", structuredAttributes: { needsRepair: "true" } })),
|
|
326
|
+
true
|
|
327
|
+
);
|
|
328
|
+
assert.equal(isFailureClassMemory(memory("m", "x", { category: "fact", mw_fail: 3, mw_success: 1 })), true);
|
|
329
|
+
assert.equal(isFailureClassMemory(memory("m", "x", { category: "fact", mw_fail: 1, mw_success: 4 })), false);
|
|
330
|
+
assert.equal(isFailureClassMemory(memory("m", "x", { status: "pending_review" })), false);
|
|
331
|
+
|
|
332
|
+
assert.deepEqual(actionTermsFor({ kind: "command", command: "pnpm", args: ["migrate", "-f", "migrate"] }), [
|
|
333
|
+
"pnpm",
|
|
334
|
+
"migrate",
|
|
335
|
+
]);
|
|
336
|
+
assert.deepEqual(actionTermsFor({ kind: "edit", filePath: "src/config.ts", editKind: "update" }), [
|
|
337
|
+
"src",
|
|
338
|
+
"config.ts",
|
|
339
|
+
"update",
|
|
340
|
+
]);
|
|
341
|
+
});
|