@remnic/core 9.65.1 → 9.65.2
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 +11 -11
- package/dist/access-admin-ops-surface.js +35 -34
- package/dist/access-authorization-probe.d.ts +12 -13
- package/dist/access-authorization-probe.js +36 -35
- package/dist/access-boundary.d.ts +12 -156
- package/dist/access-boundary.js +35 -34
- package/dist/access-cli.js +107 -104
- 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 +11 -11
- package/dist/access-extraction-force-flush.js +35 -34
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http-lifecycle-flush.d.ts +12 -13
- package/dist/access-http-offline-stream.d.ts +11 -11
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +37 -36
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +54 -53
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +35 -34
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +35 -34
- package/dist/access-mcp-admin-tools.js +1 -1
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +47 -44
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-BKUnKsBv.d.ts → access-namespace-preflight-Dhvcl-T0.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +35 -34
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +35 -34
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-offline-manifest.js +5 -5
- package/dist/access-operations-batch.js +38 -37
- package/dist/access-operations.d.ts +18 -19
- package/dist/access-operations.js +41 -40
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +35 -34
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +35 -34
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +35 -34
- package/dist/access-schema.d.ts +118 -118
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-B1Lbb-nQ.d.ts → access-service-Bke1alZO.d.ts} +478 -74
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +35 -34
- package/dist/access-surface-catalog.d.ts +12 -13
- package/dist/access-surface-catalog.js +39 -36
- 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 +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +6 -1
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-5L7EUZ27.js → auto-sync-H64ZCNIR.js} +13 -5
- package/dist/{auto-sync-5L7EUZ27.js.map → auto-sync-H64ZCNIR.js.map} +1 -1
- 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-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +16 -15
- 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 +4 -4
- 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/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/{catalog-DjVhJoRM.d.ts → catalog-DV6qnbr7.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 +17 -16
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-LYIZXQYY.js → chunk-2E36UXVW.js} +2 -2
- package/dist/{chunk-7QFBLYFP.js → chunk-2XDWWPTN.js} +3 -3
- package/dist/{chunk-CFRBTATE.js → chunk-2YI72KM3.js} +3 -3
- package/dist/{chunk-3YTTAGPB.js → chunk-3DVBKTSO.js} +2 -2
- package/dist/{chunk-VPGRXEAB.js → chunk-3I7ASZN3.js} +2 -2
- package/dist/{chunk-EIR5VLIH.js → chunk-4K7IW3F7.js} +2 -2
- package/dist/chunk-4K7IW3F7.js.map +1 -0
- package/dist/{chunk-WTOE7CW4.js → chunk-4KYOLI6M.js} +13 -13
- package/dist/chunk-573TEZCD.js +88 -0
- package/dist/chunk-573TEZCD.js.map +1 -0
- package/dist/{chunk-ESCQ6LY7.js → chunk-5NM4OH4P.js} +3 -3
- package/dist/{chunk-Y23B2QXP.js → chunk-5YQ63T4B.js} +2 -2
- package/dist/{chunk-PMVPCZJZ.js → chunk-6433HV72.js} +2 -2
- package/dist/{chunk-4NZHHGVL.js → chunk-7BDZTALN.js} +4 -1
- package/dist/chunk-7BDZTALN.js.map +1 -0
- package/dist/{chunk-NS5ETDYD.js → chunk-7BEPVIH3.js} +3 -3
- package/dist/{chunk-JG22O53B.js → chunk-7CBKAQIG.js} +2 -1
- package/dist/chunk-7CBKAQIG.js.map +1 -0
- package/dist/{chunk-W6TSGWYS.js → chunk-7YQ4IYS2.js} +2 -2
- package/dist/chunk-AAXJNINV.js +55 -0
- package/dist/chunk-AAXJNINV.js.map +1 -0
- package/dist/{chunk-YQ3CBLL4.js → chunk-BWLRUMOG.js} +78 -8
- package/dist/chunk-BWLRUMOG.js.map +1 -0
- package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-CEH2AFXG.js → chunk-C24UZSFW.js} +6 -6
- package/dist/{chunk-ZPN7W3OP.js → chunk-CDUUDBWJ.js} +3 -3
- package/dist/{chunk-5UYSCYR7.js → chunk-CT56C22C.js} +4 -4
- package/dist/{chunk-HJQZQUPC.js → chunk-DJZWNKFO.js} +5 -5
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/{chunk-CCTVAVTT.js → chunk-DZUJ46DO.js} +2 -2
- package/dist/{chunk-N6TRHP72.js → chunk-EILZG5VC.js} +2 -2
- package/dist/{chunk-GXWDWOWP.js → chunk-GDFVPUJ5.js} +2 -2
- package/dist/{chunk-7PWWGYGO.js → chunk-GNCCUR6K.js} +2 -2
- package/dist/{chunk-KPBLJCCV.js → chunk-IID2CMUU.js} +2 -2
- package/dist/{chunk-DEFI2QBT.js → chunk-J275IYMG.js} +25 -22
- package/dist/chunk-J275IYMG.js.map +1 -0
- package/dist/{chunk-UYCIS6V5.js → chunk-JCWY73FK.js} +2 -2
- package/dist/{chunk-SYJ6EKKE.js → chunk-JYYBA7TF.js} +2 -2
- package/dist/{chunk-T42L3S6A.js → chunk-LBWQ65SX.js} +4 -4
- package/dist/{chunk-MSTNSVXI.js → chunk-LDBFXD4F.js} +2 -1
- package/dist/chunk-LDBFXD4F.js.map +1 -0
- package/dist/{chunk-LWVO2QZV.js → chunk-LGO6A7GJ.js} +50 -50
- package/dist/{chunk-CEQF6L5K.js → chunk-LUNJ3WFO.js} +9 -7
- package/dist/chunk-LUNJ3WFO.js.map +1 -0
- package/dist/{chunk-2572MRP2.js → chunk-LZH5FR2W.js} +2 -2
- package/dist/{chunk-256FBCVX.js → chunk-M4AHBM72.js} +7 -7
- package/dist/{chunk-YEQEGSJA.js → chunk-MN4KB2A4.js} +3 -3
- package/dist/{chunk-AGKIG3YA.js → chunk-NKKD4ZAU.js} +2 -2
- package/dist/{chunk-3TMYV3LP.js → chunk-NTWN6HB2.js} +5 -5
- package/dist/{chunk-63FHSH7E.js → chunk-OCZIYAE5.js} +4 -4
- package/dist/{chunk-I2HTKOOP.js → chunk-ODZG724P.js} +2 -2
- package/dist/{chunk-HQSBYI5X.js → chunk-OTHZWLUD.js} +2 -2
- package/dist/{chunk-4W6INNXO.js → chunk-PE255F4T.js} +2 -2
- package/dist/{chunk-6L27N6YI.js → chunk-QOS5LBZN.js} +2 -2
- package/dist/{chunk-G72IPMR7.js → chunk-R4OCGPSH.js} +2 -2
- package/dist/{chunk-MIBKEW7A.js → chunk-R7JAM2XF.js} +3 -3
- package/dist/{chunk-LCU5R6TQ.js → chunk-RAIUTAZZ.js} +22 -3
- package/dist/chunk-RAIUTAZZ.js.map +1 -0
- package/dist/chunk-RIAM7DND.js +167 -0
- package/dist/chunk-RIAM7DND.js.map +1 -0
- package/dist/{chunk-JBPKEARU.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-HUNSEO5U.js → chunk-S2DPMJXH.js} +2 -2
- package/dist/{chunk-3PXVYJMC.js → chunk-SB7D4BT7.js} +536 -114
- package/dist/chunk-SB7D4BT7.js.map +1 -0
- package/dist/{chunk-JFJ3MHGV.js → chunk-SBDCZ2AX.js} +1 -1
- package/dist/chunk-SBDCZ2AX.js.map +1 -0
- package/dist/{chunk-HQSPXTQO.js → chunk-SIHSCCUQ.js} +1 -1
- package/dist/{chunk-R3AAOKR2.js → chunk-SPUJNJJC.js} +2 -2
- package/dist/{chunk-IAY7YBXS.js → chunk-SQI57UCJ.js} +2 -2
- package/dist/{chunk-CTQRPANJ.js → chunk-SVSRPG6M.js} +2 -2
- package/dist/{chunk-56BSXSHC.js → chunk-TBOJ76ER.js} +14 -1
- package/dist/{chunk-56BSXSHC.js.map → chunk-TBOJ76ER.js.map} +1 -1
- package/dist/{chunk-Z54TXZ2F.js → chunk-TF77C7SV.js} +14 -7
- package/dist/chunk-TF77C7SV.js.map +1 -0
- package/dist/{chunk-S2VBSTTA.js → chunk-THG4GYIE.js} +2 -2
- package/dist/{chunk-IXRC7EQG.js → chunk-TR7DGXGI.js} +2 -2
- package/dist/{chunk-GEULB2VI.js → chunk-TZNQUNKL.js} +7 -1
- package/dist/chunk-TZNQUNKL.js.map +1 -0
- package/dist/{chunk-BC4QD3FM.js → chunk-UIN2BWDD.js} +2 -2
- package/dist/{chunk-JTSVMJHV.js → chunk-UXO5IMBK.js} +3 -3
- package/dist/{chunk-DBXZZIDU.js → chunk-V3MXUL3D.js} +138 -73
- package/dist/chunk-V3MXUL3D.js.map +1 -0
- package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-MUJ4QFUQ.js → chunk-W4BMEGQA.js} +4 -4
- package/dist/{chunk-5HK3CJAR.js → chunk-W675UJCZ.js} +2 -2
- package/dist/{chunk-MDVBCPOS.js → chunk-XCTXS7VY.js} +2 -2
- package/dist/{chunk-53ENM6F6.js → chunk-XRYZRW54.js} +2 -2
- package/dist/{chunk-VJ6ECBIP.js → chunk-Y7DK7HHJ.js} +2 -2
- package/dist/{chunk-3MADV4YC.js → chunk-YB42WZCY.js} +2 -2
- package/dist/{chunk-X5SDZMO7.js → chunk-YHCBJULX.js} +2 -2
- package/dist/{chunk-3RHFGGI5.js → chunk-YLDXWCZP.js} +20 -5
- package/dist/chunk-YLDXWCZP.js.map +1 -0
- package/dist/{chunk-6JJT5AKI.js → chunk-Z7PBQPJ4.js} +2 -2
- package/dist/{chunk-ALCJRQ72.js → chunk-ZO6AXLEH.js} +2 -2
- package/dist/{chunk-VZVP2W4O.js → chunk-ZQHI2BZB.js} +2 -2
- package/dist/{chunk-CUS6S7PN.js → chunk-ZWXJBFZU.js} +9 -9
- package/dist/chunk-ZWXJBFZU.js.map +1 -0
- package/dist/{cli-Pulnz-qm.d.ts → cli-cShQ13XG.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +77 -75
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +17 -16
- 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 +6 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +16 -15
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +16 -15
- 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 +10 -2
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +18 -17
- package/dist/conversation-index/backend.d.ts +1 -1
- 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 +18 -17
- package/dist/cross-lingual-recall.d.ts +1 -1
- 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-Co17gxYb.d.ts → dependency-propagation-delivery-CsGg-VwS.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-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +16 -15
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/explicit-capture.js +7 -6
- package/dist/external-wiki-access.d.ts +12 -13
- package/dist/external-wiki-access.js +36 -35
- 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 +11 -11
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- 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-normalization.js +2 -2
- package/dist/extraction-prompt.d.ts +2 -2
- package/dist/extraction-prompt.js +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 +22 -21
- package/dist/fallback-llm.d.ts +1 -1
- 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 +716 -699
- package/dist/index.js +173 -125
- 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 +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +16 -15
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +16 -15
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +17 -16
- package/dist/{maintenance-DiSLtVN7.d.ts → maintenance-jhMpeGne.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- 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-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-subject-cli.d.ts +177 -0
- package/dist/memory-subject-cli.js +16 -0
- package/dist/memory-subject.d.ts +128 -0
- package/dist/memory-subject.js +44 -0
- package/dist/memory-subject.js.map +1 -0
- package/dist/memory-worth-outcomes.d.ts +5 -4
- package/dist/memory-worth-outcomes.js +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +17 -16
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +6 -6
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +16 -15
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +19 -18
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +26 -24
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +22 -21
- package/dist/{orchestrator-DzCaxNS4.d.ts → orchestrator-DyGUC7re.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +108 -105
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-HJ8DKbFl.d.ts → pipeline-C25Oxtp1.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-DwXauTX3.d.ts → public-http-CMe7NQzj.d.ts} +1 -1
- package/dist/{qmd-BzxluoLt.d.ts → qmd-DkDVCbgF.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/qmd.js +4 -4
- 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-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 +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/manifest.js +3 -3
- package/dist/reconcile/plan.d.ts +1 -1
- 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/{resolution-DKMBPXHI.js → resolution-MFY72STR.js} +11 -3
- package/dist/resolution-MFY72STR.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +7 -2
- 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/salvage-envelope.js +10 -2
- package/dist/schemas.d.ts +104 -90
- package/dist/schemas.js +1 -1
- package/dist/{scope-profiles-CEMZz0t5.d.ts → scope-profiles-B9xMoFO-.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 +5 -5
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +9 -9
- 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-D9dYj6vu.d.ts → semantic-consolidation-C4uykW84.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +17 -16
- package/dist/semantic-rule-promotion.js +16 -15
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +16 -15
- package/dist/{service-_qgST_0y.d.ts → service-DCZDZNcV.d.ts} +2 -2
- 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 +11 -11
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +18 -17
- package/dist/{storage-B9lbNTYE.d.ts → storage-CcKmEjL8.d.ts} +3 -2
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +18 -17
- package/dist/subject-config.d.ts +38 -0
- package/dist/subject-config.js +20 -0
- package/dist/subject-config.js.map +1 -0
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +14 -14
- package/dist/support-passport/index.js +38 -37
- 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 +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/types.d.ts +66 -66
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-BrEzuxPA.d.ts → types-Pi0lfaEt.d.ts} +38 -29
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +16 -15
- package/dist/who-knows-cli.d.ts +11 -11
- package/dist/who-knows-cli.js +17 -16
- package/dist/who-knows.d.ts +11 -11
- package/dist/who-knows.js +16 -15
- package/dist/write-envelope.d.ts +5 -2
- package/dist/write-envelope.js +10 -1
- package/package.json +2 -2
- package/scripts/build-with-heap.mjs +1 -1
- package/src/access-boundary.ts +2 -0
- package/src/access-mcp-admin-tools.ts +14 -0
- package/src/access-mcp-output-schemas.ts +6 -0
- package/src/access-mcp.ts +6 -6
- package/src/access-operations-batch.ts +8 -0
- package/src/access-service.ts +85 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/config.ts +10 -17
- package/src/extraction-prompt.ts +1 -0
- package/src/extraction.ts +4 -1
- package/src/index.ts +5 -6
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/memory-subject-cli.ts +135 -0
- package/src/memory-subject.test.ts +48 -0
- package/src/memory-subject.ts +314 -0
- package/src/memory-worth-outcomes.test.ts +6 -2
- package/src/memory-worth-outcomes.ts +11 -7
- package/src/operator-toolkit.ts +1 -1
- package/src/orchestration/extraction-persist.ts +48 -48
- package/src/orchestration/recall-internal.ts +6 -5
- package/src/procedural/library-maintenance.test.ts +582 -0
- package/src/procedural/library-maintenance.ts +546 -0
- package/src/procedural/maintenance-config.ts +78 -0
- package/src/procedural/procedure-recall.ts +29 -1
- package/src/procedural/procedure-stats.ts +20 -0
- package/src/schemas.ts +7 -0
- package/src/spaces/index.ts +38 -2
- package/src/storage.ts +6 -2
- package/src/subject-config.ts +80 -0
- package/src/types.ts +26 -29
- package/src/write-envelope.test.ts +14 -0
- package/src/write-envelope.ts +24 -3
- package/dist/chunk-3PXVYJMC.js.map +0 -1
- package/dist/chunk-3RHFGGI5.js.map +0 -1
- package/dist/chunk-4NZHHGVL.js.map +0 -1
- package/dist/chunk-CEQF6L5K.js.map +0 -1
- package/dist/chunk-CUS6S7PN.js.map +0 -1
- package/dist/chunk-DBXZZIDU.js.map +0 -1
- package/dist/chunk-DEFI2QBT.js.map +0 -1
- package/dist/chunk-EIR5VLIH.js.map +0 -1
- package/dist/chunk-GEULB2VI.js.map +0 -1
- package/dist/chunk-JFJ3MHGV.js.map +0 -1
- package/dist/chunk-JG22O53B.js.map +0 -1
- package/dist/chunk-LCU5R6TQ.js.map +0 -1
- package/dist/chunk-MSTNSVXI.js.map +0 -1
- package/dist/chunk-YQ3CBLL4.js.map +0 -1
- package/dist/chunk-Z54TXZ2F.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
- /package/dist/{chunk-LYIZXQYY.js.map → chunk-2E36UXVW.js.map} +0 -0
- /package/dist/{chunk-7QFBLYFP.js.map → chunk-2XDWWPTN.js.map} +0 -0
- /package/dist/{chunk-CFRBTATE.js.map → chunk-2YI72KM3.js.map} +0 -0
- /package/dist/{chunk-3YTTAGPB.js.map → chunk-3DVBKTSO.js.map} +0 -0
- /package/dist/{chunk-VPGRXEAB.js.map → chunk-3I7ASZN3.js.map} +0 -0
- /package/dist/{chunk-WTOE7CW4.js.map → chunk-4KYOLI6M.js.map} +0 -0
- /package/dist/{chunk-ESCQ6LY7.js.map → chunk-5NM4OH4P.js.map} +0 -0
- /package/dist/{chunk-Y23B2QXP.js.map → chunk-5YQ63T4B.js.map} +0 -0
- /package/dist/{chunk-PMVPCZJZ.js.map → chunk-6433HV72.js.map} +0 -0
- /package/dist/{chunk-NS5ETDYD.js.map → chunk-7BEPVIH3.js.map} +0 -0
- /package/dist/{chunk-W6TSGWYS.js.map → chunk-7YQ4IYS2.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-CEH2AFXG.js.map → chunk-C24UZSFW.js.map} +0 -0
- /package/dist/{chunk-ZPN7W3OP.js.map → chunk-CDUUDBWJ.js.map} +0 -0
- /package/dist/{chunk-5UYSCYR7.js.map → chunk-CT56C22C.js.map} +0 -0
- /package/dist/{chunk-HJQZQUPC.js.map → chunk-DJZWNKFO.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-CCTVAVTT.js.map → chunk-DZUJ46DO.js.map} +0 -0
- /package/dist/{chunk-N6TRHP72.js.map → chunk-EILZG5VC.js.map} +0 -0
- /package/dist/{chunk-GXWDWOWP.js.map → chunk-GDFVPUJ5.js.map} +0 -0
- /package/dist/{chunk-7PWWGYGO.js.map → chunk-GNCCUR6K.js.map} +0 -0
- /package/dist/{chunk-KPBLJCCV.js.map → chunk-IID2CMUU.js.map} +0 -0
- /package/dist/{chunk-UYCIS6V5.js.map → chunk-JCWY73FK.js.map} +0 -0
- /package/dist/{chunk-SYJ6EKKE.js.map → chunk-JYYBA7TF.js.map} +0 -0
- /package/dist/{chunk-T42L3S6A.js.map → chunk-LBWQ65SX.js.map} +0 -0
- /package/dist/{chunk-LWVO2QZV.js.map → chunk-LGO6A7GJ.js.map} +0 -0
- /package/dist/{chunk-2572MRP2.js.map → chunk-LZH5FR2W.js.map} +0 -0
- /package/dist/{chunk-256FBCVX.js.map → chunk-M4AHBM72.js.map} +0 -0
- /package/dist/{chunk-YEQEGSJA.js.map → chunk-MN4KB2A4.js.map} +0 -0
- /package/dist/{chunk-AGKIG3YA.js.map → chunk-NKKD4ZAU.js.map} +0 -0
- /package/dist/{chunk-3TMYV3LP.js.map → chunk-NTWN6HB2.js.map} +0 -0
- /package/dist/{chunk-63FHSH7E.js.map → chunk-OCZIYAE5.js.map} +0 -0
- /package/dist/{chunk-I2HTKOOP.js.map → chunk-ODZG724P.js.map} +0 -0
- /package/dist/{chunk-HQSBYI5X.js.map → chunk-OTHZWLUD.js.map} +0 -0
- /package/dist/{chunk-4W6INNXO.js.map → chunk-PE255F4T.js.map} +0 -0
- /package/dist/{chunk-6L27N6YI.js.map → chunk-QOS5LBZN.js.map} +0 -0
- /package/dist/{chunk-G72IPMR7.js.map → chunk-R4OCGPSH.js.map} +0 -0
- /package/dist/{chunk-MIBKEW7A.js.map → chunk-R7JAM2XF.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-HUNSEO5U.js.map → chunk-S2DPMJXH.js.map} +0 -0
- /package/dist/{chunk-HQSPXTQO.js.map → chunk-SIHSCCUQ.js.map} +0 -0
- /package/dist/{chunk-R3AAOKR2.js.map → chunk-SPUJNJJC.js.map} +0 -0
- /package/dist/{chunk-IAY7YBXS.js.map → chunk-SQI57UCJ.js.map} +0 -0
- /package/dist/{chunk-CTQRPANJ.js.map → chunk-SVSRPG6M.js.map} +0 -0
- /package/dist/{chunk-S2VBSTTA.js.map → chunk-THG4GYIE.js.map} +0 -0
- /package/dist/{chunk-IXRC7EQG.js.map → chunk-TR7DGXGI.js.map} +0 -0
- /package/dist/{chunk-BC4QD3FM.js.map → chunk-UIN2BWDD.js.map} +0 -0
- /package/dist/{chunk-JTSVMJHV.js.map → chunk-UXO5IMBK.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-MUJ4QFUQ.js.map → chunk-W4BMEGQA.js.map} +0 -0
- /package/dist/{chunk-5HK3CJAR.js.map → chunk-W675UJCZ.js.map} +0 -0
- /package/dist/{chunk-MDVBCPOS.js.map → chunk-XCTXS7VY.js.map} +0 -0
- /package/dist/{chunk-53ENM6F6.js.map → chunk-XRYZRW54.js.map} +0 -0
- /package/dist/{chunk-VJ6ECBIP.js.map → chunk-Y7DK7HHJ.js.map} +0 -0
- /package/dist/{chunk-3MADV4YC.js.map → chunk-YB42WZCY.js.map} +0 -0
- /package/dist/{chunk-X5SDZMO7.js.map → chunk-YHCBJULX.js.map} +0 -0
- /package/dist/{chunk-6JJT5AKI.js.map → chunk-Z7PBQPJ4.js.map} +0 -0
- /package/dist/{chunk-ALCJRQ72.js.map → chunk-ZO6AXLEH.js.map} +0 -0
- /package/dist/{chunk-VZVP2W4O.js.map → chunk-ZQHI2BZB.js.map} +0 -0
- /package/dist/{resolution-DKMBPXHI.js.map → memory-subject-cli.js.map} +0 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure library health maintenance (issue #2370).
|
|
3
|
+
*
|
|
4
|
+
* Covers the acceptance matrix:
|
|
5
|
+
* - shadow report on the canonical fixture (merge / retire-failing /
|
|
6
|
+
* retire-idle / user-edited flag-only, zero actions on non-active
|
|
7
|
+
* statuses) and that shadow writes NOTHING;
|
|
8
|
+
* - apply executes transitions on a real StorageManager, is idempotent,
|
|
9
|
+
* bumps the run marker, and post-apply recall no longer injects
|
|
10
|
+
* archived procedures;
|
|
11
|
+
* - repair flag from real causal-trajectory records;
|
|
12
|
+
* - config parsing (string coercion, zero semantics, loud rejection);
|
|
13
|
+
* - the service gate returns { enabled: false } with maintenance off;
|
|
14
|
+
* - end-to-end: injected procedures reach LastRecallSnapshot.memoryIds
|
|
15
|
+
* and accrue mw_* via recordMemoryOutcome through the real recall path.
|
|
16
|
+
*/
|
|
17
|
+
import test from "node:test";
|
|
18
|
+
import assert from "node:assert/strict";
|
|
19
|
+
import os from "node:os";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
|
22
|
+
|
|
23
|
+
import { StorageManager } from "../storage.js";
|
|
24
|
+
import { parseConfig } from "../config.js";
|
|
25
|
+
import type { PluginConfig } from "../types.js";
|
|
26
|
+
import { Orchestrator } from "../orchestrator.js";
|
|
27
|
+
import { EngramAccessService } from "../access-service.js";
|
|
28
|
+
import { recordMemoryOutcome } from "../memory-worth-outcomes.js";
|
|
29
|
+
import { recordCausalTrajectory, type CausalTrajectoryRecord } from "../causal-trajectory.js";
|
|
30
|
+
import {
|
|
31
|
+
runProcedureLibraryMaintenance,
|
|
32
|
+
readProcedureMaintenanceMarker,
|
|
33
|
+
} from "./library-maintenance.js";
|
|
34
|
+
import { computeProcedureStats } from "./procedure-stats.js";
|
|
35
|
+
import {
|
|
36
|
+
buildProcedurePersistBody,
|
|
37
|
+
type ProcedureStep,
|
|
38
|
+
} from "./procedure-types.js";
|
|
39
|
+
import { buildProcedureRecallSection } from "./procedure-recall.js";
|
|
40
|
+
|
|
41
|
+
const NOW = new Date("2026-08-18T12:00:00.000Z");
|
|
42
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
43
|
+
|
|
44
|
+
function maintenanceConfig(memoryDir?: string, overrides: Record<string, unknown> = {}): PluginConfig {
|
|
45
|
+
return parseConfig({
|
|
46
|
+
openaiApiKey: "sk-test",
|
|
47
|
+
...(memoryDir !== undefined ? { memoryDir } : {}),
|
|
48
|
+
procedural: {
|
|
49
|
+
enabled: true,
|
|
50
|
+
lookbackDays: 14,
|
|
51
|
+
maintenance: { enabled: true, ...overrides },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Raw procedure file with full frontmatter control (memory-worth test pattern). */
|
|
57
|
+
async function writeProcedure(
|
|
58
|
+
storage: StorageManager,
|
|
59
|
+
id: string,
|
|
60
|
+
body: string,
|
|
61
|
+
extraFrontmatter: string[] = [],
|
|
62
|
+
): Promise<string> {
|
|
63
|
+
const baseDir = (storage as unknown as { baseDir: string }).baseDir;
|
|
64
|
+
const dir = path.join(baseDir, "procedures");
|
|
65
|
+
await mkdir(dir, { recursive: true });
|
|
66
|
+
const lines = [
|
|
67
|
+
"---",
|
|
68
|
+
`id: ${id}`,
|
|
69
|
+
"category: procedure",
|
|
70
|
+
`created: ${new Date(NOW.getTime() - 30 * DAY_MS).toISOString()}`,
|
|
71
|
+
`updated: ${new Date(NOW.getTime() - 30 * DAY_MS).toISOString()}`,
|
|
72
|
+
"source: procedure-miner",
|
|
73
|
+
"confidence: 0.8",
|
|
74
|
+
"tags: []",
|
|
75
|
+
...extraFrontmatter,
|
|
76
|
+
"---",
|
|
77
|
+
];
|
|
78
|
+
const filePath = path.join(dir, `${id}.md`);
|
|
79
|
+
await writeFile(filePath, `${lines.join("\n")}\n\n${body}\n`, "utf-8");
|
|
80
|
+
return filePath;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function steps(): ProcedureStep[] {
|
|
84
|
+
return [
|
|
85
|
+
{ order: 1, intent: "Check the deployment checklist", toolCall: { kind: "deploy_cli", signature: "deploy --check" } },
|
|
86
|
+
{ order: 2, intent: "Run the migration", toolCall: { kind: "migrate_cli", signature: "migrate --up" } },
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function duplicateBody(updatedOffsetDays: number): string {
|
|
91
|
+
const title = "When you work on goals like: ship the payment service safely";
|
|
92
|
+
const body = buildProcedurePersistBody(title, steps());
|
|
93
|
+
// buildProcedurePersistBody output is deterministic; embed the offset in
|
|
94
|
+
// frontmatter instead of the body so the two dups stay signature-identical.
|
|
95
|
+
void updatedOffsetDays;
|
|
96
|
+
return body;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const NON_ACTIVE_STATUSES = [
|
|
100
|
+
"pending_review",
|
|
101
|
+
"rejected",
|
|
102
|
+
"quarantined",
|
|
103
|
+
"superseded",
|
|
104
|
+
"archived",
|
|
105
|
+
] as const;
|
|
106
|
+
|
|
107
|
+
/** The canonical acceptance fixture: 2 dups + failing + idle + user-edited + every non-active status. */
|
|
108
|
+
async function seedFixture(storage: StorageManager): Promise<void> {
|
|
109
|
+
await writeProcedure(storage, "proc-dup-a", duplicateBody(5), [
|
|
110
|
+
`updated: ${new Date(NOW.getTime() - 5 * DAY_MS).toISOString()}`,
|
|
111
|
+
]);
|
|
112
|
+
await writeProcedure(storage, "proc-dup-b", duplicateBody(1), [
|
|
113
|
+
`updated: ${new Date(NOW.getTime() - 1 * DAY_MS).toISOString()}`,
|
|
114
|
+
]);
|
|
115
|
+
await writeProcedure(
|
|
116
|
+
storage,
|
|
117
|
+
"proc-failing",
|
|
118
|
+
buildProcedurePersistBody("When you work on goals like: rotate the database credentials", [
|
|
119
|
+
{ order: 1, intent: "Rotate credentials", toolCall: { kind: "rotate_cli", signature: "rotate --now" } },
|
|
120
|
+
{ order: 2, intent: "Verify the new credentials", toolCall: { kind: "verify_cli", signature: "verify --creds" } },
|
|
121
|
+
]),
|
|
122
|
+
["mw_success: 1", "mw_fail: 6"],
|
|
123
|
+
);
|
|
124
|
+
await writeProcedure(
|
|
125
|
+
storage,
|
|
126
|
+
"proc-idle",
|
|
127
|
+
buildProcedurePersistBody("When you work on goals like: clean up the staging environment", [
|
|
128
|
+
{ order: 1, intent: "List staging resources", toolCall: { kind: "list_cli", signature: "list --env staging" } },
|
|
129
|
+
{ order: 2, intent: "Delete unused resources", toolCall: { kind: "delete_cli", signature: "delete --unused" } },
|
|
130
|
+
]),
|
|
131
|
+
[
|
|
132
|
+
`updated: ${new Date(NOW.getTime() - 100 * DAY_MS).toISOString()}`,
|
|
133
|
+
`lastAccessed: ${new Date(NOW.getTime() - 100 * DAY_MS).toISOString()}`,
|
|
134
|
+
],
|
|
135
|
+
);
|
|
136
|
+
// User-edited: same mined shape but with hand-written guidance appended, and
|
|
137
|
+
// failure-dominant counters that MUST be waived by the user-edited exemption.
|
|
138
|
+
const editedBody =
|
|
139
|
+
buildProcedurePersistBody("When you work on goals like: tune the cache thresholds", [
|
|
140
|
+
{ order: 1, intent: "Measure current hit rate", toolCall: { kind: "cache_cli", signature: "cache --stats" } },
|
|
141
|
+
{ order: 2, intent: "Raise the TTL", toolCall: { kind: "cache_cli", signature: "cache --ttl 600" } },
|
|
142
|
+
]) + "\nHand-written note: always page the on-call engineer first.\n";
|
|
143
|
+
await writeProcedure(storage, "proc-user-edited", editedBody, ["mw_success: 1", "mw_fail: 6"]);
|
|
144
|
+
// Non-active statuses share the dup cluster signature AND failure-dominant
|
|
145
|
+
// counters — they must never become merge or retire candidates (§41).
|
|
146
|
+
for (const [index, status] of NON_ACTIVE_STATUSES.entries()) {
|
|
147
|
+
await writeProcedure(storage, `proc-${status}`, duplicateBody(0), [
|
|
148
|
+
`status: ${status}`,
|
|
149
|
+
`mw_success: 0`,
|
|
150
|
+
`mw_fail: 9`,
|
|
151
|
+
`updated: ${new Date(NOW.getTime() - index - 1).toISOString()}`,
|
|
152
|
+
]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
test("shadow report proposes exactly one merge, two retires, one user-edited flag; non-active statuses never act", async () => {
|
|
157
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-shadow-"));
|
|
158
|
+
try {
|
|
159
|
+
const storage = new StorageManager(dir);
|
|
160
|
+
await storage.ensureDirectories();
|
|
161
|
+
await seedFixture(storage);
|
|
162
|
+
|
|
163
|
+
const report = await runProcedureLibraryMaintenance({
|
|
164
|
+
storage,
|
|
165
|
+
memoryDir: dir,
|
|
166
|
+
config: maintenanceConfig(),
|
|
167
|
+
apply: false,
|
|
168
|
+
now: NOW,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
assert.equal(report.mode, "shadow");
|
|
172
|
+
assert.equal(report.appliedCount, 0);
|
|
173
|
+
const merges = report.proposed.filter((a) => a.action === "merge");
|
|
174
|
+
const retires = report.proposed.filter((a) => a.action === "retire");
|
|
175
|
+
const userEditedFlags = report.proposed.filter((a) => a.action === "flag_user_edited");
|
|
176
|
+
assert.equal(merges.length, 1, `expected exactly one merge, got ${JSON.stringify(merges)}`);
|
|
177
|
+
assert.deepEqual(merges[0]!.memoryIds, ["proc-dup-b", "proc-dup-a"], "most-recently-updated member is canonical");
|
|
178
|
+
assert.equal(merges[0]!.canonicalId, "proc-dup-b");
|
|
179
|
+
assert.deepEqual(
|
|
180
|
+
retires.map((a) => a.reasonCode).sort(),
|
|
181
|
+
["retire_failure_dominant", "retire_idle"],
|
|
182
|
+
);
|
|
183
|
+
assert.deepEqual(retires.map((a) => a.memoryIds), [["proc-failing"], ["proc-idle"]]);
|
|
184
|
+
assert.equal(userEditedFlags.length, 1);
|
|
185
|
+
assert.equal(userEditedFlags[0]!.memoryIds[0], "proc-user-edited");
|
|
186
|
+
for (const status of NON_ACTIVE_STATUSES) {
|
|
187
|
+
const touching = report.proposed.filter((a) => a.memoryIds.includes(`proc-${status}`));
|
|
188
|
+
assert.equal(touching.length, 0, `${status} procedure must never be a candidate`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Shadow writes NOTHING: statuses unchanged, no marker.
|
|
192
|
+
const after = await storage.readAllMemories();
|
|
193
|
+
assert.equal(after.filter((m) => m.frontmatter.status === "active").length, 5);
|
|
194
|
+
assert.equal(await readProcedureMaintenanceMarker(dir), null);
|
|
195
|
+
} finally {
|
|
196
|
+
await rm(dir, { recursive: true, force: true });
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
test("apply executes transitions, stamps the #687 contract on the canonical, archives retires, is idempotent", async () => {
|
|
201
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-apply-"));
|
|
202
|
+
try {
|
|
203
|
+
const storage = new StorageManager(dir);
|
|
204
|
+
await storage.ensureDirectories();
|
|
205
|
+
await seedFixture(storage);
|
|
206
|
+
|
|
207
|
+
const report = await runProcedureLibraryMaintenance({
|
|
208
|
+
storage,
|
|
209
|
+
memoryDir: dir,
|
|
210
|
+
config: maintenanceConfig(),
|
|
211
|
+
apply: true,
|
|
212
|
+
now: NOW,
|
|
213
|
+
});
|
|
214
|
+
assert.equal(report.mode, "apply");
|
|
215
|
+
assert.ok(report.appliedCount > 0);
|
|
216
|
+
|
|
217
|
+
const after = await storage.readAllMemories();
|
|
218
|
+
const byId = new Map(after.map((m) => [m.frontmatter.id, m]));
|
|
219
|
+
|
|
220
|
+
const dupA = byId.get("proc-dup-a")!;
|
|
221
|
+
assert.equal(dupA.frontmatter.status, "superseded");
|
|
222
|
+
assert.equal(dupA.frontmatter.supersededBy, "proc-dup-b");
|
|
223
|
+
const canonical = byId.get("proc-dup-b")!;
|
|
224
|
+
assert.equal(canonical.frontmatter.status, "active");
|
|
225
|
+
assert.equal(canonical.frontmatter.reinforcement_count, 2);
|
|
226
|
+
assert.equal(canonical.frontmatter.derived_via, "pattern-reinforcement");
|
|
227
|
+
assert.deepEqual([...canonical.frontmatter.derived_from ?? []].sort(), ["proc-dup-a", "proc-dup-b"]);
|
|
228
|
+
assert.ok(canonical.frontmatter.last_reinforced_at);
|
|
229
|
+
|
|
230
|
+
// Retires demoted to archived (§: demotion, never deletion) — archived
|
|
231
|
+
// files leave the live tree, so the ids no longer resolve via readAllMemories.
|
|
232
|
+
assert.equal(byId.has("proc-failing"), false, "failure-dominant procedure archived");
|
|
233
|
+
assert.equal(byId.has("proc-idle"), false, "idle procedure archived");
|
|
234
|
+
const archived = await storage.readArchivedMemories();
|
|
235
|
+
const archivedIds = new Set(archived.map((m) => m.frontmatter.id));
|
|
236
|
+
assert.ok(archivedIds.has("proc-failing"));
|
|
237
|
+
assert.ok(archivedIds.has("proc-idle"));
|
|
238
|
+
|
|
239
|
+
// User-edited untouched by apply.
|
|
240
|
+
const edited = byId.get("proc-user-edited")!;
|
|
241
|
+
assert.equal(edited.frontmatter.status, "active");
|
|
242
|
+
assert.equal(edited.frontmatter.structuredAttributes?.needsRepair, undefined);
|
|
243
|
+
|
|
244
|
+
// Marker persisted; stats surface exposes it.
|
|
245
|
+
const marker = await readProcedureMaintenanceMarker(dir);
|
|
246
|
+
assert.ok(marker);
|
|
247
|
+
assert.equal(marker!.lastApplyAt, NOW.toISOString());
|
|
248
|
+
|
|
249
|
+
// Follow-up recall no longer injects the retired procedures.
|
|
250
|
+
const section = await buildProcedureRecallSection(
|
|
251
|
+
storage,
|
|
252
|
+
"ship the payment service safely deployment checklist",
|
|
253
|
+
maintenanceConfig(),
|
|
254
|
+
);
|
|
255
|
+
assert.ok(section);
|
|
256
|
+
assert.match(section!, /proc-dup-b/);
|
|
257
|
+
assert.doesNotMatch(section!, /proc-failing/);
|
|
258
|
+
assert.doesNotMatch(section!, /proc-idle/);
|
|
259
|
+
|
|
260
|
+
// Idempotent re-run: nothing left to propose.
|
|
261
|
+
const second = await runProcedureLibraryMaintenance({
|
|
262
|
+
storage,
|
|
263
|
+
memoryDir: dir,
|
|
264
|
+
config: maintenanceConfig(),
|
|
265
|
+
apply: true,
|
|
266
|
+
now: NOW,
|
|
267
|
+
});
|
|
268
|
+
// The user-edited advisory flag is report-only (nothing written, nothing
|
|
269
|
+
// to converge), so it MAY reappear; no write-capable action may.
|
|
270
|
+
const writeActions = second.proposed.filter((a) => a.action !== "flag_user_edited");
|
|
271
|
+
assert.equal(writeActions.length, 0, `expected a converged no-op, got ${JSON.stringify(writeActions)}`);
|
|
272
|
+
} finally {
|
|
273
|
+
await rm(dir, { recursive: true, force: true });
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
function trajectory(trajectoryId: string, actionSummary: string): CausalTrajectoryRecord {
|
|
278
|
+
return {
|
|
279
|
+
schemaVersion: 1,
|
|
280
|
+
trajectoryId,
|
|
281
|
+
recordedAt: new Date(NOW.getTime() - DAY_MS).toISOString(),
|
|
282
|
+
sessionKey: "session-proc-maintenance",
|
|
283
|
+
goal: "Keep procedures healthy",
|
|
284
|
+
actionSummary,
|
|
285
|
+
observationSummary: "The run produced reusable signal.",
|
|
286
|
+
outcomeKind: "success",
|
|
287
|
+
outcomeSummary: "Done.",
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
test("repair flag: tools absent from recent trajectories get needsRepair; present tools do not", async () => {
|
|
292
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-repair-"));
|
|
293
|
+
try {
|
|
294
|
+
await recordCausalTrajectory({ memoryDir: dir, record: trajectory("traj-1", "Ran deploy_cli then tailed logs_cli output.") });
|
|
295
|
+
|
|
296
|
+
const storage = new StorageManager(dir);
|
|
297
|
+
await storage.ensureDirectories();
|
|
298
|
+
await writeProcedure(storage, "proc-stale", buildProcedurePersistBody("When you work on goals like: migrate the ledger", [
|
|
299
|
+
{ order: 1, intent: "Run the migration", toolCall: { kind: "ghost_tool", signature: "ghost --run" } },
|
|
300
|
+
{ order: 2, intent: "Verify row counts", toolCall: { kind: "verify_cli", signature: "verify --rows" } },
|
|
301
|
+
]));
|
|
302
|
+
await writeProcedure(storage, "proc-fresh", buildProcedurePersistBody("When you work on goals like: deploy the service", [
|
|
303
|
+
{ order: 1, intent: "Run the deploy", toolCall: { kind: "deploy_cli", signature: "deploy --prod" } },
|
|
304
|
+
{ order: 2, intent: "Watch the logs", toolCall: { kind: "logs_cli", signature: "logs --follow" } },
|
|
305
|
+
]));
|
|
306
|
+
|
|
307
|
+
const report = await runProcedureLibraryMaintenance({
|
|
308
|
+
storage,
|
|
309
|
+
memoryDir: dir,
|
|
310
|
+
config: maintenanceConfig(dir),
|
|
311
|
+
apply: true,
|
|
312
|
+
now: NOW,
|
|
313
|
+
});
|
|
314
|
+
const flags = report.proposed.filter((a) => a.action === "flag_repair");
|
|
315
|
+
assert.equal(flags.length, 1, `expected exactly the stale-tool procedure, got ${JSON.stringify(flags)}`);
|
|
316
|
+
assert.equal(flags[0]!.memoryIds[0], "proc-stale");
|
|
317
|
+
assert.match(flags[0]!.reason, /ghost_tool/);
|
|
318
|
+
|
|
319
|
+
const after = await storage.readAllMemories();
|
|
320
|
+
const stale = after.find((m) => m.frontmatter.id === "proc-stale")!;
|
|
321
|
+
const stamp = stale.frontmatter.structuredAttributes?.needsRepair;
|
|
322
|
+
assert.ok(stamp, "needsRepair must be stamped in apply mode");
|
|
323
|
+
const parsed = JSON.parse(stamp!) as { reason: string; detectedAt: string };
|
|
324
|
+
assert.equal(parsed.detectedAt, NOW.toISOString());
|
|
325
|
+
// Repair is flag-only: the body is never rewritten.
|
|
326
|
+
assert.match(stale.content, /ghost_tool/);
|
|
327
|
+
const fresh = after.find((m) => m.frontmatter.id === "proc-fresh")!;
|
|
328
|
+
assert.equal(fresh.frontmatter.structuredAttributes?.needsRepair, undefined);
|
|
329
|
+
} finally {
|
|
330
|
+
await rm(dir, { recursive: true, force: true });
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
test("idle window uses [start, end): exactly-at-boundary is fresh, one ms older retires", async () => {
|
|
335
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-boundary-"));
|
|
336
|
+
try {
|
|
337
|
+
const storage = new StorageManager(dir);
|
|
338
|
+
await storage.ensureDirectories();
|
|
339
|
+
const body = (n: string) =>
|
|
340
|
+
buildProcedurePersistBody(`When you work on goals like: benchmark the ${n} pipeline`, [
|
|
341
|
+
{ order: 1, intent: `Measure ${n}` },
|
|
342
|
+
{ order: 2, intent: "Record the numbers" },
|
|
343
|
+
]);
|
|
344
|
+
await writeProcedure(storage, "proc-at-boundary", body("alpha"), [
|
|
345
|
+
`lastAccessed: ${new Date(NOW.getTime() - 90 * DAY_MS).toISOString()}`,
|
|
346
|
+
]);
|
|
347
|
+
await writeProcedure(storage, "proc-just-older", body("beta"), [
|
|
348
|
+
`lastAccessed: ${new Date(NOW.getTime() - 90 * DAY_MS - 1).toISOString()}`,
|
|
349
|
+
]);
|
|
350
|
+
|
|
351
|
+
const report = await runProcedureLibraryMaintenance({
|
|
352
|
+
storage,
|
|
353
|
+
memoryDir: dir,
|
|
354
|
+
config: maintenanceConfig(),
|
|
355
|
+
apply: false,
|
|
356
|
+
now: NOW,
|
|
357
|
+
});
|
|
358
|
+
const idles = report.proposed.filter((a) => a.reasonCode === "retire_idle");
|
|
359
|
+
assert.deepEqual(idles.map((a) => a.memoryIds), [["proc-just-older"]]);
|
|
360
|
+
} finally {
|
|
361
|
+
await rm(dir, { recursive: true, force: true });
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test("canonical comparator: equal updated timestamps fall back to stable id order (returns 0 only on full ties)", async () => {
|
|
366
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-tie-"));
|
|
367
|
+
try {
|
|
368
|
+
const storage = new StorageManager(dir);
|
|
369
|
+
await storage.ensureDirectories();
|
|
370
|
+
const sameTs = new Date(NOW.getTime() - 3 * DAY_MS).toISOString();
|
|
371
|
+
await writeProcedure(storage, "proc-tie-b", duplicateBody(3), [`updated: ${sameTs}`]);
|
|
372
|
+
await writeProcedure(storage, "proc-tie-a", duplicateBody(3), [`updated: ${sameTs}`]);
|
|
373
|
+
|
|
374
|
+
const report = await runProcedureLibraryMaintenance({
|
|
375
|
+
storage,
|
|
376
|
+
memoryDir: dir,
|
|
377
|
+
config: maintenanceConfig(),
|
|
378
|
+
apply: false,
|
|
379
|
+
now: NOW,
|
|
380
|
+
});
|
|
381
|
+
const merge = report.proposed.find((a) => a.action === "merge")!;
|
|
382
|
+
assert.ok(merge);
|
|
383
|
+
assert.equal(merge.canonicalId, "proc-tie-a", "lexicographically smaller id wins the tie");
|
|
384
|
+
} finally {
|
|
385
|
+
await rm(dir, { recursive: true, force: true });
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
test("config: defaults, string coercion, zero semantics, loud rejection of invalid values", () => {
|
|
390
|
+
const defaults = parseConfig({ procedural: { maintenance: { enabled: true } } }).procedural.maintenance;
|
|
391
|
+
assert.equal(defaults.enabled, true);
|
|
392
|
+
assert.equal(defaults.retireIdleDays, 90);
|
|
393
|
+
assert.equal(defaults.retireMinOutcomes, 5);
|
|
394
|
+
assert.equal(defaults.retireFailRatio, 2);
|
|
395
|
+
assert.equal(defaults.mergeEnabled, true);
|
|
396
|
+
|
|
397
|
+
const off = parseConfig({}).procedural.maintenance;
|
|
398
|
+
assert.equal(off.enabled, false, "maintenance defaults off");
|
|
399
|
+
|
|
400
|
+
// CLI string forms (§17/§24).
|
|
401
|
+
const strings = parseConfig({
|
|
402
|
+
procedural: {
|
|
403
|
+
maintenance: {
|
|
404
|
+
enabled: "true",
|
|
405
|
+
retireIdleDays: "30",
|
|
406
|
+
retireMinOutcomes: "8",
|
|
407
|
+
retireFailRatio: "3",
|
|
408
|
+
mergeEnabled: "false",
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
}).procedural.maintenance;
|
|
412
|
+
assert.equal(strings.enabled, true);
|
|
413
|
+
assert.equal(strings.retireIdleDays, 30);
|
|
414
|
+
assert.equal(strings.retireMinOutcomes, 8);
|
|
415
|
+
assert.equal(strings.retireFailRatio, 3);
|
|
416
|
+
assert.equal(strings.mergeEnabled, false);
|
|
417
|
+
|
|
418
|
+
// `0` disables idle-based retirement (§33 documented zero semantics).
|
|
419
|
+
assert.equal(
|
|
420
|
+
parseConfig({ procedural: { maintenance: { enabled: true, retireIdleDays: 0 } } }).procedural.maintenance.retireIdleDays,
|
|
421
|
+
0,
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
assert.throws(() => parseConfig({ procedural: { maintenance: { retireIdleDays: "abc" } } }), /retireIdleDays/);
|
|
425
|
+
assert.throws(() => parseConfig({ procedural: { maintenance: { retireMinOutcomes: 4.5 } } }), /integer/);
|
|
426
|
+
assert.throws(() => parseConfig({ procedural: { maintenance: { retireFailRatio: 0 } } }), /positive/);
|
|
427
|
+
assert.throws(() => parseConfig({ procedural: { maintenance: { enabled: "fales" } } }), /maintenance.enabled/);
|
|
428
|
+
assert.throws(() => parseConfig({ procedural: { maintenance: "nope" } }), /must be an object/);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
test("module gate: procedural.maintenance disabled returns skippedReason and proposes nothing", async () => {
|
|
432
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-gate-"));
|
|
433
|
+
try {
|
|
434
|
+
const storage = new StorageManager(dir);
|
|
435
|
+
await storage.ensureDirectories();
|
|
436
|
+
await writeProcedure(storage, "proc-gate", duplicateBody(1));
|
|
437
|
+
|
|
438
|
+
const disabled = await runProcedureLibraryMaintenance({
|
|
439
|
+
storage,
|
|
440
|
+
memoryDir: dir,
|
|
441
|
+
config: maintenanceConfig(undefined, { enabled: false }),
|
|
442
|
+
apply: true,
|
|
443
|
+
now: NOW,
|
|
444
|
+
});
|
|
445
|
+
assert.equal(disabled.skippedReason, "maintenance_disabled");
|
|
446
|
+
assert.equal(disabled.proposed.length, 0);
|
|
447
|
+
assert.equal(await readProcedureMaintenanceMarker(dir), null, "disabled gate writes no marker");
|
|
448
|
+
|
|
449
|
+
const proceduralOff = await runProcedureLibraryMaintenance({
|
|
450
|
+
storage,
|
|
451
|
+
memoryDir: dir,
|
|
452
|
+
config: parseConfig({ procedural: { enabled: false, maintenance: { enabled: true } } }),
|
|
453
|
+
apply: true,
|
|
454
|
+
now: NOW,
|
|
455
|
+
});
|
|
456
|
+
assert.equal(proceduralOff.skippedReason, "procedural_disabled");
|
|
457
|
+
} finally {
|
|
458
|
+
await rm(dir, { recursive: true, force: true });
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
test("service gate: maintenance off (including string \"false\"/\"0\") returns { enabled: false } before any storage read", async () => {
|
|
463
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-service-"));
|
|
464
|
+
try {
|
|
465
|
+
for (const enabledValue of [false, "false", "0", "no", "off"]) {
|
|
466
|
+
const config = parseConfig({
|
|
467
|
+
openaiApiKey: "sk-test",
|
|
468
|
+
memoryDir: dir,
|
|
469
|
+
qmdEnabled: false,
|
|
470
|
+
procedural: { enabled: true, maintenance: { enabled: enabledValue as boolean } },
|
|
471
|
+
});
|
|
472
|
+
const service = new EngramAccessService(new Orchestrator(config));
|
|
473
|
+
const result = await service.procedureLibraryMaintenance({ apply: true });
|
|
474
|
+
assert.deepEqual(result, { enabled: false }, `enabled=${JSON.stringify(enabledValue)} must gate off`);
|
|
475
|
+
|
|
476
|
+
}
|
|
477
|
+
} finally {
|
|
478
|
+
await rm(dir, { recursive: true, force: true });
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
test("end-to-end: injected procedure reaches LastRecallSnapshot.memoryIds and accrues mw_fail via memory_outcome", async () => {
|
|
483
|
+
const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-e2e-"));
|
|
484
|
+
try {
|
|
485
|
+
const config = parseConfig({
|
|
486
|
+
openaiApiKey: "sk-test",
|
|
487
|
+
memoryDir,
|
|
488
|
+
workspaceDir: path.join(memoryDir, "workspace"),
|
|
489
|
+
qmdEnabled: false,
|
|
490
|
+
embeddingFallbackEnabled: false,
|
|
491
|
+
multiGraphMemoryEnabled: false,
|
|
492
|
+
entityGraphEnabled: false,
|
|
493
|
+
timeGraphEnabled: false,
|
|
494
|
+
causalGraphEnabled: false,
|
|
495
|
+
extractionJudgeEnabled: false,
|
|
496
|
+
temporalSupersessionEnabled: false,
|
|
497
|
+
contradictionDetectionEnabled: false,
|
|
498
|
+
chunkingEnabled: false,
|
|
499
|
+
extractionMinChars: 0,
|
|
500
|
+
extractionMinImportanceLevel: "trivial",
|
|
501
|
+
inlineSourceAttributionEnabled: false,
|
|
502
|
+
initGateTimeoutMs: 200,
|
|
503
|
+
procedural: { enabled: true, maintenance: { enabled: true } },
|
|
504
|
+
});
|
|
505
|
+
const orchestrator = new Orchestrator(config);
|
|
506
|
+
const storage = await orchestrator.getStorage("default");
|
|
507
|
+
await storage.ensureDirectories();
|
|
508
|
+
|
|
509
|
+
const body = buildProcedurePersistBody(
|
|
510
|
+
"When you work on goals like: deploy the payment service and run the database migration",
|
|
511
|
+
steps(),
|
|
512
|
+
);
|
|
513
|
+
const baseDir = (storage as unknown as { baseDir: string }).baseDir;
|
|
514
|
+
const proceduresDir = path.join(baseDir, "procedures");
|
|
515
|
+
await mkdir(proceduresDir, { recursive: true });
|
|
516
|
+
const id = "proc-e2e";
|
|
517
|
+
const filePath = path.join(proceduresDir, `${id}.md`);
|
|
518
|
+
const frontmatter = [
|
|
519
|
+
"---",
|
|
520
|
+
`id: ${id}`,
|
|
521
|
+
"category: procedure",
|
|
522
|
+
"status: active",
|
|
523
|
+
`created: ${NOW.toISOString()}`,
|
|
524
|
+
`updated: ${NOW.toISOString()}`,
|
|
525
|
+
"source: procedure-miner",
|
|
526
|
+
"confidence: 0.8",
|
|
527
|
+
"tags: []",
|
|
528
|
+
"---",
|
|
529
|
+
].join("\n");
|
|
530
|
+
await writeFile(filePath, `${frontmatter}\n\n${body}\n`, "utf-8");
|
|
531
|
+
|
|
532
|
+
const context = await orchestrator.recall(
|
|
533
|
+
"I need to deploy the payment service and run the database migration",
|
|
534
|
+
"sess-proc-maint-e2e",
|
|
535
|
+
);
|
|
536
|
+
assert.ok(typeof context === "string" && context.length > 0, "recall must return context");
|
|
537
|
+
|
|
538
|
+
const snapshot = await orchestrator.getLastRecall("sess-proc-maint-e2e");
|
|
539
|
+
assert.ok(snapshot, "snapshot must exist after recall");
|
|
540
|
+
assert.ok(
|
|
541
|
+
(snapshot!.memoryIds ?? []).includes(id),
|
|
542
|
+
`procedure id must reach LastRecallSnapshot.memoryIds (got ${JSON.stringify(snapshot!.memoryIds)})`,
|
|
543
|
+
);
|
|
544
|
+
assert.ok(context!.includes(id), "procedure preview must be injected into the context");
|
|
545
|
+
|
|
546
|
+
// The real outcome path (same function the memory_outcome op dispatches to).
|
|
547
|
+
const outcome = await recordMemoryOutcome(storage, { memoryPath: filePath, outcome: "failure" });
|
|
548
|
+
assert.ok(outcome.ok, `outcome must succeed on an eligible procedure (got ${JSON.stringify(outcome)})`);
|
|
549
|
+
assert.equal(outcome.ok && outcome.mw_fail, 1);
|
|
550
|
+
const after = await storage.getMemoryById(id);
|
|
551
|
+
assert.ok(after);
|
|
552
|
+
assert.equal(after!.frontmatter.mw_fail, 1);
|
|
553
|
+
assert.equal(after!.frontmatter.mw_success, 0);
|
|
554
|
+
await orchestrator.destroy();
|
|
555
|
+
} finally {
|
|
556
|
+
await rm(memoryDir, { recursive: true, force: true });
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
test("stats surface exposes lastMaintenanceAt and needsRepairFlags", async () => {
|
|
561
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-proc-maint-stats-"));
|
|
562
|
+
try {
|
|
563
|
+
const storage = new StorageManager(dir);
|
|
564
|
+
await storage.ensureDirectories();
|
|
565
|
+
await writeProcedure(storage, "proc-stats", duplicateBody(1));
|
|
566
|
+
const before = await computeProcedureStats({ storage, config: maintenanceConfig(), nowMs: NOW.getTime() });
|
|
567
|
+
assert.equal(before.lastMaintenanceAt, null);
|
|
568
|
+
assert.equal(before.needsRepairFlags, 0);
|
|
569
|
+
|
|
570
|
+
await runProcedureLibraryMaintenance({
|
|
571
|
+
storage,
|
|
572
|
+
memoryDir: dir,
|
|
573
|
+
config: maintenanceConfig(),
|
|
574
|
+
apply: true,
|
|
575
|
+
now: NOW,
|
|
576
|
+
});
|
|
577
|
+
const after = await computeProcedureStats({ storage, config: maintenanceConfig(), nowMs: NOW.getTime() });
|
|
578
|
+
assert.equal(after.lastMaintenanceAt, NOW.toISOString());
|
|
579
|
+
} finally {
|
|
580
|
+
await rm(dir, { recursive: true, force: true });
|
|
581
|
+
}
|
|
582
|
+
});
|