@remnic/core 9.65.8 → 9.66.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +11 -12
- package/dist/access-admin-ops-surface.js +49 -46
- package/dist/access-authorization-probe.d.ts +11 -12
- package/dist/access-authorization-probe.js +50 -47
- package/dist/access-boundary.d.ts +11 -12
- package/dist/access-boundary.js +49 -46
- package/dist/access-citation-namespace.js +3 -3
- package/dist/access-cli.js +111 -106
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -2
- package/dist/access-coding-context-resolution.js +2 -2
- package/dist/access-extraction-force-flush.d.ts +11 -12
- package/dist/access-extraction-force-flush.js +49 -46
- package/dist/access-health-types.d.ts +1 -2
- package/dist/access-http-lcm-compaction.d.ts +11 -12
- package/dist/access-http-lifecycle-flush.d.ts +11 -12
- package/dist/access-http-offline-stream.d.ts +11 -12
- package/dist/access-http-query.d.ts +2 -3
- package/dist/access-http-query.js +51 -48
- package/dist/access-http.d.ts +12 -13
- package/dist/access-http.js +68 -65
- package/dist/access-identity-continuity-surface.d.ts +9 -10
- package/dist/access-identity-continuity-surface.js +49 -46
- package/dist/access-lcm-surface.d.ts +11 -12
- package/dist/access-lcm-surface.js +49 -46
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +11 -12
- package/dist/access-mcp.js +62 -59
- package/dist/access-memory-search-fanout.d.ts +2 -3
- package/dist/{access-namespace-preflight-CpAOrS-9.d.ts → access-namespace-preflight-CLWUoMyW.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -4
- package/dist/access-namespace-preflight.js +49 -46
- package/dist/access-observe-write-surface.d.ts +11 -12
- package/dist/access-observe-write-surface.js +49 -46
- package/dist/access-offline-manifest.d.ts +9 -10
- package/dist/access-offline-manifest.js +15 -15
- package/dist/access-operations-batch.js +54 -51
- package/dist/access-operations.d.ts +17 -18
- package/dist/access-operations.js +59 -56
- package/dist/access-recall-concurrency.d.ts +11 -12
- package/dist/access-recall-concurrency.js +49 -46
- package/dist/access-recall-response.d.ts +11 -12
- package/dist/access-recall-response.js +49 -46
- package/dist/access-recall-surface.d.ts +11 -12
- package/dist/access-recall-surface.js +49 -46
- package/dist/access-schema.d.ts +83 -83
- package/dist/access-schema.js +7 -7
- package/dist/{access-service-Diu61Cfv.d.ts → access-service-CEUE1Isj.d.ts} +66 -66
- package/dist/access-service-helpers.d.ts +11 -12
- package/dist/access-service.d.ts +11 -12
- package/dist/access-service.js +49 -46
- package/dist/access-surface-catalog.d.ts +11 -12
- package/dist/access-surface-catalog.js +53 -48
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -4
- package/dist/action-confidence.d.ts +1 -2
- package/dist/active-memory-bridge.d.ts +1 -2
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +1 -2
- package/dist/active-recall.js +11 -11
- package/dist/ambient-provenance.d.ts +1 -2
- package/dist/artifact-search.d.ts +1 -2
- package/dist/{auto-sync-2YPITIWN.js → auto-sync-Q6Q2FVSC.js} +9 -9
- package/dist/behavior-learner.d.ts +1 -2
- package/dist/behavior-signals.d.ts +1 -2
- package/dist/bootstrap.d.ts +9 -10
- package/dist/briefing-window.d.ts +2 -3
- package/dist/briefing.d.ts +2 -3
- package/dist/briefing.js +23 -23
- package/dist/buffer-surprise-report.d.ts +1 -2
- package/dist/buffer-turn-helpers.d.ts +1 -2
- package/dist/buffer.d.ts +2 -3
- package/dist/buffer.js +20 -4
- package/dist/bulk-import/index.d.ts +3 -4
- package/dist/calibration.d.ts +1 -2
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +1 -2
- package/dist/{capsule-merge-SGIVB3WA.js → capsule-merge-SEHERWWP.js} +4 -4
- package/dist/{catalog-9f-vEQLS.d.ts → catalog-D1HgugTA.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -2
- package/dist/causal-consolidation.d.ts +1 -2
- package/dist/causal-consolidation.js +24 -24
- package/dist/causal-trajectory-graph.d.ts +1 -2
- package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
- package/dist/{chunk-NPFUNWNX.js → chunk-23CVL7HS.js} +2 -2
- package/dist/{chunk-PO7NXBG2.js → chunk-2GF27PGH.js} +5 -5
- package/dist/{chunk-MY2BC6UE.js → chunk-2LBAFHOQ.js} +11 -11
- package/dist/{chunk-AZMLH5UT.js → chunk-33MFRY25.js} +2 -2
- package/dist/{chunk-UEBDCMOO.js → chunk-3TSU662L.js} +3 -3
- package/dist/{chunk-CAMNRAJF.js → chunk-4FHRZD5T.js} +2 -2
- package/dist/{chunk-FP7YTTVO.js → chunk-4OFKZAJG.js} +2 -1
- package/dist/chunk-4OFKZAJG.js.map +1 -0
- package/dist/{chunk-S5XOSTYM.js → chunk-4STAANV7.js} +3 -3
- package/dist/{chunk-LKYIOCWL.js → chunk-56IV4J5W.js} +546 -96
- package/dist/chunk-56IV4J5W.js.map +1 -0
- package/dist/{chunk-4F4AQFWL.js → chunk-6CEGSTBD.js} +10 -10
- package/dist/{chunk-JYSN42VN.js → chunk-6QDXA26G.js} +235 -181
- package/dist/chunk-6QDXA26G.js.map +1 -0
- package/dist/{chunk-MDD2RINF.js → chunk-6RUHELWR.js} +3 -3
- package/dist/{chunk-WNXYT4MK.js → chunk-72OIT7KS.js} +4 -4
- package/dist/{chunk-KQAFEZQX.js → chunk-7LCGFUMB.js} +4 -4
- package/dist/{chunk-SNOIKAHM.js → chunk-7UTDHQZ5.js} +3 -3
- package/dist/{chunk-5HK3CJAR.js → chunk-7XOG75AU.js} +3 -3
- package/dist/{chunk-7BDZTALN.js → chunk-AJTG3CP7.js} +12 -2
- package/dist/chunk-AJTG3CP7.js.map +1 -0
- package/dist/{chunk-2LWQSV6A.js → chunk-AL3UYZ5N.js} +3 -2
- package/dist/chunk-AL3UYZ5N.js.map +1 -0
- package/dist/{chunk-UPFNQJC7.js → chunk-CN4VKV3S.js} +2 -2
- package/dist/{chunk-PMVPCZJZ.js → chunk-CTCGHNWN.js} +6 -6
- package/dist/{chunk-EGBDFJ36.js → chunk-DD5JFCWM.js} +2 -2
- package/dist/{chunk-XBGHAAKR.js → chunk-DDX6KIXF.js} +2 -2
- package/dist/{chunk-JIYDRBVZ.js → chunk-DJORULH3.js} +2 -2
- package/dist/{chunk-UENKPWCS.js → chunk-DMEHOEC7.js} +6 -6
- package/dist/{chunk-7KQB4EBS.js → chunk-DUAJKRR2.js} +2 -2
- package/dist/{chunk-XDL5CYZN.js → chunk-EEOUMG3J.js} +2 -1
- package/dist/{chunk-XDL5CYZN.js.map → chunk-EEOUMG3J.js.map} +1 -1
- package/dist/{chunk-SEEJOGQX.js → chunk-EFQCDJZ2.js} +4 -4
- package/dist/{chunk-Q57GOHLF.js → chunk-EGALNSZ4.js} +3 -3
- package/dist/{chunk-KCT36JAW.js → chunk-ESNFSSO4.js} +2 -2
- package/dist/{chunk-XQ3HXAQH.js → chunk-ET2CNMLD.js} +4 -4
- package/dist/{chunk-PU56CXZA.js → chunk-EZSCW4EM.js} +2 -2
- package/dist/{chunk-HMZKGHMD.js → chunk-FESUGFIL.js} +3 -3
- package/dist/{chunk-3A2NJP2U.js → chunk-FKKGCGYL.js} +3 -3
- package/dist/{chunk-BWGCOLEL.js → chunk-FTTJRVB7.js} +2 -2
- package/dist/{chunk-ODU2CNNX.js → chunk-FYWLSFFS.js} +2 -2
- package/dist/{chunk-W2BAGGEW.js → chunk-GEJKYA7D.js} +33 -24
- package/dist/{chunk-W2BAGGEW.js.map → chunk-GEJKYA7D.js.map} +1 -1
- package/dist/chunk-GSKINLAK.js +267 -0
- package/dist/chunk-GSKINLAK.js.map +1 -0
- package/dist/{chunk-3PKAS6VL.js → chunk-GX6FTSYH.js} +2 -2
- package/dist/{chunk-76DIF5KT.js → chunk-H7VDIF2V.js} +2 -2
- package/dist/{chunk-F7XUD3PL.js → chunk-HJXA6ZM7.js} +2 -2
- package/dist/{chunk-4QEYREAV.js → chunk-HNPE66LB.js} +2 -2
- package/dist/{chunk-P36Z4JRA.js → chunk-I5VB44ZK.js} +2 -2
- package/dist/{chunk-EUYWQ7TS.js → chunk-IEZ6CGTW.js} +2 -2
- package/dist/{chunk-OXRRJXPR.js → chunk-IHGMRDEE.js} +275 -1678
- package/dist/chunk-IHGMRDEE.js.map +1 -0
- package/dist/{chunk-5DHKCO52.js → chunk-IVIAHQBR.js} +2 -2
- package/dist/{chunk-TFR3HG4K.js → chunk-J3OND5QT.js} +4 -4
- package/dist/{chunk-UW5NPZJ2.js → chunk-JALOAKSZ.js} +59 -7
- package/dist/chunk-JALOAKSZ.js.map +1 -0
- package/dist/{chunk-5ACCD4L7.js → chunk-JRRQ747T.js} +7 -7
- package/dist/{chunk-V4IDF3EZ.js → chunk-JTWZKNUH.js} +5 -5
- package/dist/chunk-K66OY4EI.js +202 -0
- package/dist/chunk-K66OY4EI.js.map +1 -0
- package/dist/{chunk-XAB6STPO.js → chunk-KODXCHXJ.js} +17 -3
- package/dist/chunk-KODXCHXJ.js.map +1 -0
- package/dist/{chunk-KZIF6XHX.js → chunk-KXIXO76C.js} +28 -15
- package/dist/chunk-KXIXO76C.js.map +1 -0
- package/dist/{chunk-5RWZH6PH.js → chunk-L4X4PJYK.js} +2 -2
- package/dist/{chunk-UTQUEHC7.js → chunk-LUDBXTBJ.js} +8 -8
- package/dist/{chunk-XNWXSGHS.js → chunk-MAH64N55.js} +28 -10
- package/dist/chunk-MAH64N55.js.map +1 -0
- package/dist/{chunk-LDKPDODJ.js → chunk-ME35HVDJ.js} +2 -2
- package/dist/{chunk-DPCXDG7G.js → chunk-MJRGVXPQ.js} +2 -2
- package/dist/{chunk-773TRRGT.js → chunk-MJUCDM3C.js} +2 -2
- package/dist/{chunk-T6ILXUAH.js → chunk-MN5NOOI7.js} +2 -2
- package/dist/{chunk-AHPIFKNG.js → chunk-N4F7ZSSG.js} +2 -2
- package/dist/{chunk-JOZUBF4A.js → chunk-NACLNNFQ.js} +2 -2
- package/dist/{chunk-LC2BDILZ.js → chunk-NBP4EX5N.js} +2 -2
- package/dist/{chunk-ZVPVTPGI.js → chunk-NNZFPYYX.js} +4 -4
- package/dist/{chunk-DA7ITC5Z.js → chunk-O57GM3FR.js} +2 -2
- package/dist/{chunk-7VZFRUQU.js → chunk-O7ERGZDA.js} +5 -5
- package/dist/{chunk-3SZD4CYO.js → chunk-OAJMQKQR.js} +3 -3
- package/dist/{chunk-HSZMX3ZJ.js → chunk-ODW5GDFE.js} +2 -2
- package/dist/{chunk-7WOWGRAU.js → chunk-PEBH5DCK.js} +10 -7
- package/dist/{chunk-7WOWGRAU.js.map → chunk-PEBH5DCK.js.map} +1 -1
- package/dist/{chunk-J2WC5LF4.js → chunk-QBC33MPY.js} +2 -1
- package/dist/{chunk-T7XP6IZE.js → chunk-QCRJMU5V.js} +2 -2
- package/dist/chunk-QJCWK2A7.js +1466 -0
- package/dist/chunk-QJCWK2A7.js.map +1 -0
- package/dist/{chunk-YEUXERJ6.js → chunk-RDGKVH6T.js} +7 -3
- package/dist/{chunk-YEUXERJ6.js.map → chunk-RDGKVH6T.js.map} +1 -1
- package/dist/{chunk-OA2O2GJ4.js → chunk-RZ3IZIJG.js} +3 -3
- package/dist/{chunk-UL4MKZHI.js → chunk-SN4JXNLL.js} +2 -2
- package/dist/chunk-TB2MJRI6.js +866 -0
- package/dist/chunk-TB2MJRI6.js.map +1 -0
- package/dist/{chunk-7PHI6GUI.js → chunk-TEZ2HTC7.js} +42 -2
- package/dist/chunk-TEZ2HTC7.js.map +1 -0
- package/dist/{chunk-CPA5NBHN.js → chunk-TNGH4ZYI.js} +2 -2
- package/dist/{chunk-F3NVYTTA.js → chunk-TNXNECAN.js} +6 -6
- package/dist/{chunk-BEC4YBNA.js → chunk-TVW4C7PV.js} +2 -2
- package/dist/{chunk-UFKPQBXH.js → chunk-U62OK7BB.js} +2 -2
- package/dist/{chunk-AX7UXCHJ.js → chunk-UYA36DQ7.js} +2 -1
- package/dist/chunk-UYA36DQ7.js.map +1 -0
- package/dist/{chunk-DEACDKE3.js → chunk-VCKWULAK.js} +112 -87
- package/dist/chunk-VCKWULAK.js.map +1 -0
- package/dist/chunk-VOSWUO3K.js +100 -0
- package/dist/chunk-VOSWUO3K.js.map +1 -0
- package/dist/{chunk-TUHBYJXL.js → chunk-VQ4AMTGZ.js} +1 -1
- package/dist/{chunk-3BCULS4U.js → chunk-VQNRICAQ.js} +145 -507
- package/dist/chunk-VQNRICAQ.js.map +1 -0
- package/dist/{chunk-H2YSH3DG.js → chunk-WKAXBXVA.js} +2 -2
- package/dist/{chunk-HRHO3ZNG.js → chunk-WKJFIMVN.js} +2 -2
- package/dist/{chunk-SXIMQLGV.js → chunk-WVGXCBOC.js} +2 -2
- package/dist/{chunk-CRML27CO.js → chunk-X5YYSAZX.js} +4 -4
- package/dist/{chunk-FZEEWOI2.js → chunk-XJJYSX6F.js} +2 -2
- package/dist/{chunk-U7EW2W4W.js → chunk-XKNHFDTT.js} +26 -6
- package/dist/chunk-XKNHFDTT.js.map +1 -0
- package/dist/{chunk-UG6VXIOK.js → chunk-XSTNGNJP.js} +2 -2
- package/dist/{chunk-YDPAE2RD.js → chunk-YFLLGRXO.js} +2 -2
- package/dist/{chunk-LPNCR4QK.js → chunk-YXFCALVT.js} +12 -12
- package/dist/{chunk-Q4WONDMJ.js → chunk-YYGZJPOK.js} +2 -2
- package/dist/{chunk-GTO56JY5.js → chunk-ZJPM7GZ3.js} +2 -2
- package/dist/{chunk-LOXHYCVS.js → chunk-ZW4VXELZ.js} +2 -2
- package/dist/{cli-O3F-ht3i.d.ts → cli-BEkm2MEf.d.ts} +5 -5
- package/dist/cli.d.ts +13 -14
- package/dist/cli.js +90 -85
- package/dist/coding/export-okf-codegraph.d.ts +56 -0
- package/dist/coding/export-okf-codegraph.js +526 -0
- package/dist/coding/export-okf-codegraph.js.map +1 -0
- package/dist/coding/pre-action-gate.d.ts +1 -2
- package/dist/compounding/engine.d.ts +2 -3
- package/dist/compounding/engine.js +24 -24
- package/dist/compounding/preference-consolidator.d.ts +1 -2
- package/dist/compression-optimizer.d.ts +1 -2
- package/dist/config.d.ts +1 -2
- package/dist/config.js +11 -11
- package/dist/connectors/codex-materialize-runner.d.ts +1 -2
- package/dist/connectors/codex-materialize-runner.js +23 -23
- package/dist/connectors/codex-materialize.d.ts +1 -2
- package/dist/connectors/index.d.ts +1 -2
- package/dist/connectors/index.js +23 -23
- package/dist/consolidation-provenance-check.d.ts +2 -3
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +2 -3
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +3 -4
- package/dist/contradiction/index.js +9 -9
- package/dist/{contradiction-scan-AKUWPX5N.js → contradiction-scan-NOYMFG66.js} +3 -3
- package/dist/converge-config.d.ts +1 -2
- package/dist/convergence-refresh.d.ts +2 -3
- package/dist/convergence-refresh.js +25 -25
- package/dist/conversation-index/backend.d.ts +1 -2
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +1 -2
- package/dist/conversation-index/faiss-adapter.d.ts +1 -2
- package/dist/conversation-index/indexer.d.ts +1 -2
- package/dist/conversation-index/search.d.ts +1 -2
- package/dist/corpus-watermark.d.ts +1 -2
- package/dist/corpus-watermark.js +25 -25
- package/dist/cross-lingual-recall.d.ts +1 -2
- package/dist/day-summary.d.ts +1 -2
- package/dist/delinearize.d.ts +1 -2
- package/dist/dependency-propagation-config.d.ts +1 -2
- package/dist/{dependency-propagation-delivery-CL6RWXTA.d.ts → dependency-propagation-delivery-BCpeo14F.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -2
- package/dist/direct-answer.d.ts +1 -2
- package/dist/embedding-fallback.d.ts +1 -2
- package/dist/enrichment/index.d.ts +1 -2
- package/dist/entity-origin-fields.d.ts +1 -2
- package/dist/entity-retrieval.d.ts +2 -3
- package/dist/entity-retrieval.js +23 -23
- package/dist/entity-schema.d.ts +1 -2
- package/dist/episodic-context.d.ts +1 -2
- package/dist/eval-trajectory-contracts.d.ts +1 -2
- package/dist/eval-trajectory-store.d.ts +1 -2
- package/dist/eval-trajectory.d.ts +1 -2
- package/dist/explicit-capture.d.ts +9 -10
- package/dist/explicit-capture.js +11 -11
- package/dist/external-wiki-access.d.ts +11 -12
- package/dist/external-wiki-access.js +50 -47
- package/dist/external-wiki-collection-registration.d.ts +1 -2
- package/dist/external-wiki-collection.d.ts +1 -2
- package/dist/external-wiki-mcp-tools.d.ts +11 -12
- package/dist/extraction-error-classification.d.ts +1 -2
- package/dist/extraction-faithfulness.d.ts +1 -2
- package/dist/extraction-faithfulness.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +1 -2
- package/dist/extraction-judge-training.d.ts +1 -2
- package/dist/extraction-judge.d.ts +1 -2
- package/dist/extraction-judge.js +2 -2
- package/dist/extraction-liveness.d.ts +1 -2
- package/dist/extraction-normalization.d.ts +1 -2
- package/dist/extraction-prompt.d.ts +1 -2
- package/dist/extraction-source-grounding-rules.d.ts +1 -2
- package/dist/extraction-source-grounding.d.ts +1 -2
- package/dist/extraction.d.ts +1 -2
- package/dist/extraction.js +32 -29
- package/dist/fallback-llm.d.ts +7 -2
- package/dist/fallback-llm.js +1 -1
- package/dist/{first-start-migration-4NETATFF.js → first-start-migration-KHIMCBIC.js} +3 -3
- package/dist/graph-dashboard-diff.d.ts +1 -2
- package/dist/graph-dashboard-key.d.ts +1 -2
- package/dist/graph-dashboard-parser.d.ts +1 -2
- package/dist/graph-edge-reinforcement.d.ts +1 -2
- package/dist/graph-path-reconstruction.d.ts +1 -2
- package/dist/graph-path-scoring.d.ts +1 -2
- package/dist/graph-snapshot.d.ts +1 -2
- package/dist/graph.d.ts +1 -2
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -2
- package/dist/importers/index.d.ts +1 -2
- package/dist/in-flight-reads.d.ts +1 -2
- package/dist/{index-C7Xep6S9.d.ts → index-D_pyMUaP.d.ts} +2 -2
- package/dist/index.d.ts +929 -700
- package/dist/index.js +167 -132
- package/dist/intent.d.ts +1 -2
- package/dist/lcm/engine.d.ts +1 -2
- package/dist/lcm/index.d.ts +1 -2
- package/dist/lcm/tools.d.ts +1 -2
- package/dist/lifecycle.d.ts +1 -2
- package/dist/live-connectors-runner.d.ts +1 -2
- package/dist/local-llm.d.ts +1 -2
- package/dist/local-model-endpoint.d.ts +1 -2
- package/dist/location/index.d.ts +315 -6
- package/dist/location/index.js +151 -19
- package/dist/maintenance/memory-governance.d.ts +1 -2
- package/dist/maintenance/memory-governance.js +23 -23
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +23 -23
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -3
- package/dist/maintenance/rebuild-memory-projection.js +24 -24
- package/dist/{maintenance-CJ-xqFp0.d.ts → maintenance-DDUX9d6D.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -12
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +1 -2
- package/dist/memory-cache.d.ts +1 -2
- package/dist/memory-controller.d.ts +1 -2
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -2
- package/dist/memory-projection-mutations.js +3 -3
- package/dist/memory-projection-store.d.ts +1 -2
- package/dist/memory-projection-store.js +1 -1
- package/dist/memory-provenance.d.ts +1 -2
- package/dist/memory-snapshot.d.ts +1 -2
- package/dist/memory-subject-cli.d.ts +11 -12
- package/dist/memory-subject.d.ts +11 -12
- package/dist/memory-subject.js +4 -4
- package/dist/memory-worth-outcomes.d.ts +2 -3
- package/dist/models-json.d.ts +1 -2
- package/dist/namespaces/migrate.d.ts +3 -4
- package/dist/namespaces/migrate.js +24 -24
- package/dist/namespaces/principal.d.ts +1 -2
- package/dist/namespaces/search.d.ts +1 -2
- package/dist/namespaces/search.js +5 -5
- package/dist/namespaces/storage.d.ts +3 -4
- package/dist/namespaces/storage.js +23 -23
- package/dist/native-knowledge.d.ts +1 -2
- package/dist/offline-sync-file-io.js +3 -3
- package/dist/offline-sync-impression-drain.d.ts +1 -2
- package/dist/offline-sync-impression-drain.js +9 -9
- package/dist/offline-sync.js +4 -4
- package/dist/operator-doctor-corpus.d.ts +1 -2
- package/dist/operator-doctor-corpus.js +26 -26
- package/dist/operator-doctor-replica.d.ts +1 -2
- package/dist/operator-toolkit.d.ts +3 -4
- package/dist/operator-toolkit.js +42 -42
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -3
- package/dist/orchestration/maintenance.d.ts +4 -5
- package/dist/orchestration/maintenance.js +37 -36
- package/dist/{orchestrator-BsntWxLy.d.ts → orchestrator-3F4jihCo.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -10
- package/dist/orchestrator.js +111 -106
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +1 -2
- package/dist/{pipeline-CVoysPm2.d.ts → pipeline-CB1dj6Uh.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -2
- package/dist/proactive-contention.d.ts +1 -2
- package/dist/provenance.d.ts +1 -2
- package/dist/{public-http-CuOxlTC2.d.ts → public-http-34-JIAGQ.d.ts} +1 -1
- package/dist/{purge-GB7PZHT2.js → purge-OP6BEDFY.js} +2 -2
- package/dist/{qmd-DWMAGA5l.d.ts → qmd-edLLZXc5.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -3
- package/dist/qmd-recall-cache.d.ts +1 -2
- package/dist/qmd.d.ts +2 -3
- package/dist/recall-concurrency-config.d.ts +1 -2
- package/dist/recall-disclosure-escalation.d.ts +1 -2
- package/dist/recall-explain-renderer.d.ts +1 -2
- package/dist/recall-memory-map.d.ts +1 -2
- package/dist/recall-planner-llm.d.ts +1 -2
- package/dist/recall-planner-llm.js +1 -1
- package/dist/recall-state.d.ts +1 -2
- package/dist/recall-tag-filter.d.ts +1 -2
- package/dist/recall-timings.d.ts +1 -2
- package/dist/recall-xray-cli.d.ts +1 -2
- package/dist/recall-xray-renderer.d.ts +1 -2
- package/dist/recall-xray.d.ts +1 -2
- package/dist/reconcile/cursor.d.ts +1 -2
- package/dist/reconcile/manifest.d.ts +1 -2
- package/dist/reconcile/manifest.js +4 -4
- package/dist/reconcile/plan.d.ts +1 -2
- package/dist/replay/normalizers/chatgpt.d.ts +1 -2
- package/dist/replay/normalizers/claude.d.ts +1 -2
- package/dist/replay/normalizers/openclaw.d.ts +1 -2
- package/dist/replay/normalizers/shared.d.ts +1 -2
- package/dist/replay/runner.d.ts +1 -2
- package/dist/replay/types.d.ts +1 -2
- package/dist/replica-divergence.d.ts +1 -2
- package/dist/replica-peers-config.d.ts +1 -2
- package/dist/{resolution-XWBPKYFB.js → resolution-4DLI3IOR.js} +10 -10
- package/dist/resolve-auth-token.d.ts +1 -2
- package/dist/resume-bundles.js +12 -12
- package/dist/retrieval-agents.d.ts +2 -3
- package/dist/retrieval-tiers.d.ts +1 -2
- package/dist/routing/engine.d.ts +1 -2
- package/dist/routing/store.d.ts +1 -2
- package/dist/salvage-envelope.d.ts +1 -2
- package/dist/salvage-envelope.js +6 -6
- package/dist/schemas.d.ts +639 -174
- package/dist/schemas.js +3 -1
- package/dist/{scope-profiles-CPWkW_dI.d.ts → scope-profiles-BF2lu81V.d.ts} +1 -1
- package/dist/search/document-scanner.js +1 -1
- package/dist/search/embed-helper.d.ts +1 -2
- package/dist/search/factory.d.ts +1 -2
- package/dist/search/factory.js +4 -4
- package/dist/search/index.d.ts +1 -2
- package/dist/search/index.js +4 -4
- package/dist/search/lancedb-backend.d.ts +1 -2
- package/dist/search/lancedb-backend.js +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -2
- package/dist/search/meilisearch-backend.js +1 -1
- package/dist/search/noop-backend.d.ts +1 -2
- package/dist/search/orama-backend.d.ts +1 -2
- package/dist/search/orama-backend.js +1 -1
- package/dist/search/port.d.ts +1 -2
- package/dist/search/remote-backend.d.ts +1 -2
- package/dist/secure-store/index.js +3 -3
- package/dist/{semantic-consolidation-CNFVBXFc.d.ts → semantic-consolidation-5OuWXBRt.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -3
- package/dist/semantic-consolidation.js +24 -24
- package/dist/semantic-rule-promotion.js +23 -23
- package/dist/semantic-rule-verifier.d.ts +1 -2
- package/dist/semantic-rule-verifier.js +23 -23
- package/dist/{service-Bb-JIdQ0.d.ts → service-CrqEhLXD.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -2
- package/dist/session-observer-state.d.ts +1 -2
- package/dist/shared-context/manager.d.ts +7 -8
- package/dist/signal.d.ts +1 -2
- package/dist/source-agent-qualifier.d.ts +1 -2
- package/dist/source-agent-qualifier.js +30 -27
- package/dist/standup/build.d.ts +16 -0
- package/dist/standup/build.js +17 -0
- package/dist/standup/build.js.map +1 -0
- package/dist/{storage-CukrlNKk.d.ts → storage-BQn-xnxm.d.ts} +1 -1
- package/dist/storage.d.ts +2 -3
- package/dist/storage.js +22 -22
- package/dist/subject-config.d.ts +1 -2
- package/dist/subject-config.js +5 -5
- package/dist/summarizer.d.ts +1 -2
- package/dist/summarizer.js +2 -2
- package/dist/summary-snapshot.d.ts +1 -2
- package/dist/support-passport/index.d.ts +16 -17
- package/dist/support-passport/index.js +52 -49
- package/dist/temporal-supersession.d.ts +2 -3
- package/dist/temporal-timeline-recall.d.ts +1 -2
- package/dist/temporal-validity.d.ts +1 -2
- package/dist/threading.d.ts +1 -2
- package/dist/tier-migration.d.ts +2 -3
- package/dist/tier-routing.d.ts +1 -2
- package/dist/tier-routing.js +2 -2
- package/dist/{tier-stats-4B5IJ3NE.js → tier-stats-2TOW3QNL.js} +3 -3
- package/dist/topics.d.ts +1 -2
- package/dist/transcript.d.ts +1 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +5 -5
- package/dist/transfer/export-okf.d.ts +39 -0
- package/dist/transfer/export-okf.js +112 -0
- package/dist/transfer/export-okf.js.map +1 -0
- package/dist/transfer/types.d.ts +78 -78
- package/dist/trust-score-stage.d.ts +1 -2
- package/dist/trust-score.d.ts +1 -2
- package/dist/{types-djxQlxJ7.d.ts → types-BRpcNjHZ.d.ts} +117 -2
- package/dist/types.d.ts +1 -2
- package/dist/utility-runtime.d.ts +1 -2
- package/dist/verified-recall.js +23 -23
- package/dist/who-knows-cli.d.ts +11 -12
- package/dist/who-knows-cli.js +24 -24
- package/dist/who-knows.d.ts +11 -12
- package/dist/who-knows.js +23 -23
- package/dist/write-envelope.d.ts +1 -2
- package/dist/write-envelope.js +5 -5
- package/package.json +34 -3
- package/src/access-admin-ops-surface.ts +6 -1
- package/src/access-boundary.ts +1 -0
- package/src/access-http.ts +3 -1
- package/src/access-mcp-output-schemas.ts +1 -0
- package/src/access-mcp.ts +3 -3
- package/src/access-operations.ts +1 -0
- package/src/access-service-offline-file-content.test.ts +63 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/activity/config.test.ts +1 -0
- package/src/activity/config.ts +21 -1
- package/src/activity/index.ts +1 -0
- package/src/activity/timeline/build.ts +279 -0
- package/src/activity/timeline/categories.ts +111 -0
- package/src/activity/timeline/classify.ts +110 -0
- package/src/activity/timeline/corrections.ts +145 -0
- package/src/activity/timeline/index.ts +6 -0
- package/src/activity/timeline/timeline.test.ts +277 -0
- package/src/activity/timeline/types.ts +106 -0
- package/src/activity/types.ts +6 -0
- package/src/cli/okf-commands.ts +45 -0
- package/src/cli.ts +2 -2
- package/src/coding/export-okf-codegraph.test.ts +381 -0
- package/src/coding/export-okf-codegraph.ts +565 -0
- package/src/config.test.ts +1 -0
- package/src/extraction-prompt-safety.test.ts +14 -2
- package/src/extraction.ts +21 -1
- package/src/fallback-llm.test.ts +134 -0
- package/src/fallback-llm.ts +77 -5
- package/src/location/access-operations.ts +17 -8
- package/src/location/backfill.ts +137 -0
- package/src/location/config.test.ts +3 -0
- package/src/location/config.ts +46 -2
- package/src/location/http-glue.ts +1 -1
- package/src/location/index.ts +3 -0
- package/src/location/intervals.ts +1 -0
- package/src/location/matching.test.ts +65 -0
- package/src/location/matching.ts +354 -0
- package/src/location/mcp-tools.ts +2 -1
- package/src/location/surfaces.test.ts +15 -2
- package/src/location/surfaces.ts +95 -18
- package/src/location/tagging.test.ts +119 -0
- package/src/location/tagging.ts +277 -0
- package/src/location/types.ts +23 -1
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/memory-projection-store.ts +3 -1
- package/src/okf/cli.ts +18 -5
- package/src/okf/config.ts +5 -0
- package/src/okf/index-files.test.ts +60 -0
- package/src/okf/index-files.ts +114 -0
- package/src/okf/render.ts +133 -0
- package/src/okf/type-mapping.test.ts +3 -0
- package/src/okf/type-mapping.ts +2 -0
- package/src/orchestration/extraction-run.ts +2 -1
- package/src/orchestration/generic-recall-paths.ts +4 -3
- package/src/schemas.ts +17 -1
- package/src/standup/access-operations.ts +14 -0
- package/src/standup/build.test.ts +34 -0
- package/src/standup/build.ts +115 -0
- package/src/standup/http-glue.ts +15 -0
- package/src/standup/mcp-tools.ts +16 -0
- package/src/support-passport/card-projection.ts +1 -0
- package/src/support-passport/card-service-commit-forwarding.test.ts +1 -0
- package/src/support-passport/card-service.test.ts +75 -1
- package/src/support-passport/card-service.ts +6 -3
- package/src/support-passport/card-state.ts +5 -1
- package/src/support-passport/offline-sync-guard.ts +14 -1
- package/src/transfer/export-okf.test.ts +164 -0
- package/src/transfer/export-okf.ts +286 -0
- package/dist/chunk-2LWQSV6A.js.map +0 -1
- package/dist/chunk-3BCULS4U.js.map +0 -1
- package/dist/chunk-7BDZTALN.js.map +0 -1
- package/dist/chunk-7PHI6GUI.js.map +0 -1
- package/dist/chunk-AX7UXCHJ.js.map +0 -1
- package/dist/chunk-DEACDKE3.js.map +0 -1
- package/dist/chunk-FP7YTTVO.js.map +0 -1
- package/dist/chunk-JYSN42VN.js.map +0 -1
- package/dist/chunk-KZIF6XHX.js.map +0 -1
- package/dist/chunk-LKYIOCWL.js.map +0 -1
- package/dist/chunk-OXRRJXPR.js.map +0 -1
- package/dist/chunk-U7EW2W4W.js.map +0 -1
- package/dist/chunk-UW5NPZJ2.js.map +0 -1
- package/dist/chunk-XAB6STPO.js.map +0 -1
- package/dist/chunk-XNWXSGHS.js.map +0 -1
- package/dist/types-CM86alG1.d.ts +0 -89
- /package/dist/{auto-sync-2YPITIWN.js.map → auto-sync-Q6Q2FVSC.js.map} +0 -0
- /package/dist/{capsule-merge-SGIVB3WA.js.map → capsule-merge-SEHERWWP.js.map} +0 -0
- /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-NPFUNWNX.js.map → chunk-23CVL7HS.js.map} +0 -0
- /package/dist/{chunk-PO7NXBG2.js.map → chunk-2GF27PGH.js.map} +0 -0
- /package/dist/{chunk-MY2BC6UE.js.map → chunk-2LBAFHOQ.js.map} +0 -0
- /package/dist/{chunk-AZMLH5UT.js.map → chunk-33MFRY25.js.map} +0 -0
- /package/dist/{chunk-UEBDCMOO.js.map → chunk-3TSU662L.js.map} +0 -0
- /package/dist/{chunk-CAMNRAJF.js.map → chunk-4FHRZD5T.js.map} +0 -0
- /package/dist/{chunk-S5XOSTYM.js.map → chunk-4STAANV7.js.map} +0 -0
- /package/dist/{chunk-4F4AQFWL.js.map → chunk-6CEGSTBD.js.map} +0 -0
- /package/dist/{chunk-MDD2RINF.js.map → chunk-6RUHELWR.js.map} +0 -0
- /package/dist/{chunk-WNXYT4MK.js.map → chunk-72OIT7KS.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-7LCGFUMB.js.map} +0 -0
- /package/dist/{chunk-SNOIKAHM.js.map → chunk-7UTDHQZ5.js.map} +0 -0
- /package/dist/{chunk-5HK3CJAR.js.map → chunk-7XOG75AU.js.map} +0 -0
- /package/dist/{chunk-UPFNQJC7.js.map → chunk-CN4VKV3S.js.map} +0 -0
- /package/dist/{chunk-PMVPCZJZ.js.map → chunk-CTCGHNWN.js.map} +0 -0
- /package/dist/{chunk-EGBDFJ36.js.map → chunk-DD5JFCWM.js.map} +0 -0
- /package/dist/{chunk-XBGHAAKR.js.map → chunk-DDX6KIXF.js.map} +0 -0
- /package/dist/{chunk-JIYDRBVZ.js.map → chunk-DJORULH3.js.map} +0 -0
- /package/dist/{chunk-UENKPWCS.js.map → chunk-DMEHOEC7.js.map} +0 -0
- /package/dist/{chunk-7KQB4EBS.js.map → chunk-DUAJKRR2.js.map} +0 -0
- /package/dist/{chunk-SEEJOGQX.js.map → chunk-EFQCDJZ2.js.map} +0 -0
- /package/dist/{chunk-Q57GOHLF.js.map → chunk-EGALNSZ4.js.map} +0 -0
- /package/dist/{chunk-KCT36JAW.js.map → chunk-ESNFSSO4.js.map} +0 -0
- /package/dist/{chunk-XQ3HXAQH.js.map → chunk-ET2CNMLD.js.map} +0 -0
- /package/dist/{chunk-PU56CXZA.js.map → chunk-EZSCW4EM.js.map} +0 -0
- /package/dist/{chunk-HMZKGHMD.js.map → chunk-FESUGFIL.js.map} +0 -0
- /package/dist/{chunk-3A2NJP2U.js.map → chunk-FKKGCGYL.js.map} +0 -0
- /package/dist/{chunk-BWGCOLEL.js.map → chunk-FTTJRVB7.js.map} +0 -0
- /package/dist/{chunk-ODU2CNNX.js.map → chunk-FYWLSFFS.js.map} +0 -0
- /package/dist/{chunk-3PKAS6VL.js.map → chunk-GX6FTSYH.js.map} +0 -0
- /package/dist/{chunk-76DIF5KT.js.map → chunk-H7VDIF2V.js.map} +0 -0
- /package/dist/{chunk-F7XUD3PL.js.map → chunk-HJXA6ZM7.js.map} +0 -0
- /package/dist/{chunk-4QEYREAV.js.map → chunk-HNPE66LB.js.map} +0 -0
- /package/dist/{chunk-P36Z4JRA.js.map → chunk-I5VB44ZK.js.map} +0 -0
- /package/dist/{chunk-EUYWQ7TS.js.map → chunk-IEZ6CGTW.js.map} +0 -0
- /package/dist/{chunk-5DHKCO52.js.map → chunk-IVIAHQBR.js.map} +0 -0
- /package/dist/{chunk-TFR3HG4K.js.map → chunk-J3OND5QT.js.map} +0 -0
- /package/dist/{chunk-5ACCD4L7.js.map → chunk-JRRQ747T.js.map} +0 -0
- /package/dist/{chunk-V4IDF3EZ.js.map → chunk-JTWZKNUH.js.map} +0 -0
- /package/dist/{chunk-5RWZH6PH.js.map → chunk-L4X4PJYK.js.map} +0 -0
- /package/dist/{chunk-UTQUEHC7.js.map → chunk-LUDBXTBJ.js.map} +0 -0
- /package/dist/{chunk-LDKPDODJ.js.map → chunk-ME35HVDJ.js.map} +0 -0
- /package/dist/{chunk-DPCXDG7G.js.map → chunk-MJRGVXPQ.js.map} +0 -0
- /package/dist/{chunk-773TRRGT.js.map → chunk-MJUCDM3C.js.map} +0 -0
- /package/dist/{chunk-T6ILXUAH.js.map → chunk-MN5NOOI7.js.map} +0 -0
- /package/dist/{chunk-AHPIFKNG.js.map → chunk-N4F7ZSSG.js.map} +0 -0
- /package/dist/{chunk-JOZUBF4A.js.map → chunk-NACLNNFQ.js.map} +0 -0
- /package/dist/{chunk-LC2BDILZ.js.map → chunk-NBP4EX5N.js.map} +0 -0
- /package/dist/{chunk-ZVPVTPGI.js.map → chunk-NNZFPYYX.js.map} +0 -0
- /package/dist/{chunk-DA7ITC5Z.js.map → chunk-O57GM3FR.js.map} +0 -0
- /package/dist/{chunk-7VZFRUQU.js.map → chunk-O7ERGZDA.js.map} +0 -0
- /package/dist/{chunk-3SZD4CYO.js.map → chunk-OAJMQKQR.js.map} +0 -0
- /package/dist/{chunk-HSZMX3ZJ.js.map → chunk-ODW5GDFE.js.map} +0 -0
- /package/dist/{chunk-J2WC5LF4.js.map → chunk-QBC33MPY.js.map} +0 -0
- /package/dist/{chunk-T7XP6IZE.js.map → chunk-QCRJMU5V.js.map} +0 -0
- /package/dist/{chunk-OA2O2GJ4.js.map → chunk-RZ3IZIJG.js.map} +0 -0
- /package/dist/{chunk-UL4MKZHI.js.map → chunk-SN4JXNLL.js.map} +0 -0
- /package/dist/{chunk-CPA5NBHN.js.map → chunk-TNGH4ZYI.js.map} +0 -0
- /package/dist/{chunk-F3NVYTTA.js.map → chunk-TNXNECAN.js.map} +0 -0
- /package/dist/{chunk-BEC4YBNA.js.map → chunk-TVW4C7PV.js.map} +0 -0
- /package/dist/{chunk-UFKPQBXH.js.map → chunk-U62OK7BB.js.map} +0 -0
- /package/dist/{chunk-TUHBYJXL.js.map → chunk-VQ4AMTGZ.js.map} +0 -0
- /package/dist/{chunk-H2YSH3DG.js.map → chunk-WKAXBXVA.js.map} +0 -0
- /package/dist/{chunk-HRHO3ZNG.js.map → chunk-WKJFIMVN.js.map} +0 -0
- /package/dist/{chunk-SXIMQLGV.js.map → chunk-WVGXCBOC.js.map} +0 -0
- /package/dist/{chunk-CRML27CO.js.map → chunk-X5YYSAZX.js.map} +0 -0
- /package/dist/{chunk-FZEEWOI2.js.map → chunk-XJJYSX6F.js.map} +0 -0
- /package/dist/{chunk-UG6VXIOK.js.map → chunk-XSTNGNJP.js.map} +0 -0
- /package/dist/{chunk-YDPAE2RD.js.map → chunk-YFLLGRXO.js.map} +0 -0
- /package/dist/{chunk-LPNCR4QK.js.map → chunk-YXFCALVT.js.map} +0 -0
- /package/dist/{chunk-Q4WONDMJ.js.map → chunk-YYGZJPOK.js.map} +0 -0
- /package/dist/{chunk-GTO56JY5.js.map → chunk-ZJPM7GZ3.js.map} +0 -0
- /package/dist/{chunk-LOXHYCVS.js.map → chunk-ZW4VXELZ.js.map} +0 -0
- /package/dist/{contradiction-scan-AKUWPX5N.js.map → contradiction-scan-NOYMFG66.js.map} +0 -0
- /package/dist/{first-start-migration-4NETATFF.js.map → first-start-migration-KHIMCBIC.js.map} +0 -0
- /package/dist/{purge-GB7PZHT2.js.map → purge-OP6BEDFY.js.map} +0 -0
- /package/dist/{resolution-XWBPKYFB.js.map → resolution-4DLI3IOR.js.map} +0 -0
- /package/dist/{tier-stats-4B5IJ3NE.js.map → tier-stats-2TOW3QNL.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/coding/architecture-card.ts","../src/coding/architecture-surfaces.ts","../src/coding/codegraph-runtime.ts","../src/coding/decision-records.ts"],"sourcesContent":["/**\n * Architecture card — pure deterministic builder (issue #1548 Track A PR 3).\n *\n * Produces a compact, sorted, byte-stable markdown card describing a\n * repository: manifests, top-level directories, language histogram by\n * extension, and entry points derived from manifests. The deterministic\n * card is useful on its own; an optional LLM summary pass (gated behind\n * `architectureCardLlmSummary`) can later prepend a human-readable\n * overview using the existing extraction engine.\n *\n * Design rules honoured:\n * - rule 38: every multi-value field is sorted before serialising so\n * two runs over the same fixture produce byte-identical output.\n * - rule 24/51: `repoRoot` must be an absolute, existing directory;\n * invalid input is rejected with a descriptive error.\n * - rule 34: scan failures produce a tagged outcome, never a crash.\n * - rule 48: the LLM pass is opt-in (default off).\n * - rule 13: on LLM failure the deterministic card ships unchanged.\n * - Privacy + speed: file *contents* are never read except for manifest\n * files (package.json, Cargo.toml, go.mod, pyproject.toml, pom.xml).\n *\n * This module is deliberately pure: no orchestrator references, no\n * config side-effects, no namespace wiring. Callers inject the repo\n * root and receive a string.\n */\nimport { readFile, readdir, lstat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { expandTildePath } from \"../utils/path.js\";\n\n// ──────────────────────────────────────────────────────────────────────────\n// Public types\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Maximum byte size of the serialised card. When the deterministic card\n * exceeds this, it is truncated with a visible marker so consumers know\n * information was elided (rule 34 — never silently incomplete).\n */\nexport const ARCHITECTURE_CARD_MAX_BYTES = 4096;\n\n/**\n * Visible marker appended when the card is truncated. Exported so callers\n * that read stored card content can detect truncation from the content\n * itself, without depending on a frontmatter tag that may go stale on\n * content-only updates (cursor review: \"stale truncated tag on update\").\n */\nexport const ARCHITECTURE_CARD_TRUNCATION_MARKER = \"… card truncated to fit size cap …\";\n\n/**\n * Maximum byte size of the LLM summary prefix. The summary is additive —\n * the deterministic card (manifests, languages, entry points) must ALWAYS\n * survive truncation. Clamping the summary before prepending prevents a\n * misbehaving or prompt-injected summariser from crowding out the\n * deterministic sections (codex review).\n */\nexport const ARCHITECTURE_CARD_MAX_SUMMARY_BYTES = 1024;\n\n/**\n * Manifest files the scanner knows how to parse for project metadata\n * (name, entry points). Single source of truth (rule 53 analog).\n */\nexport const KNOWN_MANIFEST_FILES = [\n \"package.json\",\n \"Cargo.toml\",\n \"go.mod\",\n \"pyproject.toml\",\n \"setup.py\",\n \"pom.xml\",\n \"build.gradle\",\n \"build.gradle.kts\",\n \"Gemfile\",\n \"composer.json\",\n \"mix.exs\",\n \"deno.json\",\n] as const;\n\n/**\n * Directories the scanner skips (would distort the histogram or are\n * universally non-source). Kept conservative — operators with unusual\n * layouts still get useful output.\n */\nexport const SCAN_IGNORE_DIRS: ReadonlySet<string> = new Set([\n \"node_modules\",\n \".git\",\n \".svn\",\n \".hg\",\n \"vendor\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \"env\",\n \"dist\",\n \"build\",\n \"target\",\n \"out\",\n \".next\",\n \".nuxt\",\n \"coverage\",\n \".cache\",\n \".turbo\",\n \".idea\",\n \".vscode\",\n]);\n\n/**\n * Result of a deterministic architecture-card build.\n */\nexport interface ArchitectureCard {\n /** The markdown card body (may be truncated to fit the byte cap). */\n readonly content: string;\n /** ISO timestamp of the build. */\n readonly generatedAt: string;\n /** Byte length of `content`. */\n readonly byteSize: number;\n /** Whether the card was truncated to fit `maxBytes`. */\n readonly truncated: boolean;\n}\n\n/**\n * Injectable LLM summariser. Receives the deterministic card and the\n * repo root; returns a summary string, or `null` to keep the\n * deterministic card unchanged. Implementations MUST NOT throw —\n * failures should return `null` (rule 13).\n */\nexport type ArchitectureCardSummariser = (\n deterministicCard: string,\n repoRoot: string,\n) => Promise<string | null>;\n\n/**\n * Minimal chat-completion surface for the architecture-card summariser.\n * Structural — satisfied by both `FallbackLlmClient` (gateway model\n * chain) and `LocalLlmClient` (Ollama / OpenAI-compatible local\n * endpoints) without this pure module importing either (rule 48 — the\n * builder stays free of orchestrator/client references). The shape\n * mirrors `Orchestrator.fastLlmForRerank` so callers resolve the client\n * gateway-first, matching LCM routing precedence.\n */\nexport interface ArchitectureCardLlmClient {\n chatCompletion(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options?: {\n temperature?: number;\n maxTokens?: number;\n timeoutMs?: number;\n operation?: string;\n priority?: \"background\" | \"recall-critical\";\n },\n ): Promise<{ content: string } | null>;\n}\n\nconst ARCHITECTURE_CARD_SUMMARY_SYSTEM_PROMPT = `You write a concise overview for a repository architecture card.\nGiven the deterministic card (languages, manifests, entry points), produce a 3-5 sentence plain-text overview naming the dominant language, the primary entry point, and the project's shape.\nRules:\n- Never invent facts absent from the input.\n- No headings, no markdown — just sentences.\n- Keep it under 600 characters.`;\n\n/**\n * Build an {@link ArchitectureCardSummariser} backed by an LLM client.\n * The client is a structural type so this module does NOT import\n * `LocalLlmClient` / `FallbackLlmClient` (rule 48 — pure builder). The\n * caller resolves which client to use (gateway-first, matching LCM) and\n * may pass `null` when none is configured — then the summariser is\n * `undefined` so the builder's LLM branch stays inert (no silent no-op).\n *\n * Failures return `null` (rule 13) so the deterministic card ships\n * unchanged; `buildArchitectureCard` additionally defends against\n * implementations that throw.\n */\nexport function createArchitectureCardSummariser(\n client: ArchitectureCardLlmClient | null,\n): ArchitectureCardSummariser | undefined {\n if (!client) return undefined;\n return async (deterministicCard, repoRoot) => {\n const response = await client.chatCompletion(\n [\n { role: \"system\", content: ARCHITECTURE_CARD_SUMMARY_SYSTEM_PROMPT },\n { role: \"user\", content: `Repository: ${path.basename(repoRoot) || repoRoot}\\n\\n${deterministicCard}` },\n ],\n {\n temperature: 0.2,\n maxTokens: 512,\n operation: \"architecture-card-summary\",\n priority: \"background\",\n },\n );\n return response?.content ?? null;\n };\n}\n\n/**\n * Optional dependencies for `buildArchitectureCard`.\n */\nexport interface BuildArchitectureCardOptions {\n /** Injected clock — makes tests deterministic. */\n now?: Date;\n /** Override the byte cap (defaults to {@link ARCHITECTURE_CARD_MAX_BYTES}). */\n maxBytes?: number;\n /**\n * When `true`, invoke `summariser` to prepend an LLM overview.\n * Callers gate this on `codingKnowledge.architectureCardLlmSummary`\n * (rule 48 — opt-in).\n */\n llmSummary?: boolean;\n /** The summariser implementation (required when `llmSummary` is true). */\n summariser?: ArchitectureCardSummariser;\n}\n\n/**\n * Tagged failure from the build (rule 34).\n */\nexport type ArchitectureCardBuildFailure =\n | { ok: false; code: \"invalid_root\" | \"scan_failed\"; detail: string };\n\n/**\n * Tagged result: success carries the card; failure carries a code.\n */\nexport type ArchitectureCardBuildResult =\n | { ok: true; card: ArchitectureCard }\n | ArchitectureCardBuildFailure;\n\n// ──────────────────────────────────────────────────────────────────────────\n// Public entry — buildArchitectureCard\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Deterministically build an architecture card for a repository.\n *\n * The scan:\n * 1. Reads top-level directory entries (sorted, rule 38).\n * 2. Parses any present manifest files for project name + entry points.\n * 3. Walks up to two levels deep to compute a language histogram by\n * extension (capped to keep the scan fast on large repos).\n * 4. Renders a compact markdown card, sorted throughout.\n *\n * File *contents* are never read except for manifest files. The walker\n * only reads directory entries and file extensions (privacy + speed).\n */\nexport async function buildArchitectureCard(\n repoRoot: string,\n options: BuildArchitectureCardOptions = {},\n): Promise<ArchitectureCardBuildResult> {\n if (typeof repoRoot !== \"string\" || repoRoot.length === 0) {\n return { ok: false, code: \"invalid_root\", detail: \"repoRoot must be a non-empty string\" };\n }\n // Expand `~` per rule 17 — codingContext.rootPath often carries a tilde\n // that Node's path.resolve does NOT expand (cursor review: tilde not expanded).\n const absoluteRoot = path.resolve(expandTildePath(repoRoot));\n try {\n // Use lstat, not stat, so symlinked manifests/dirs are NOT followed\n // (codex review: symlinks could read outside the repo root).\n const rootStat = await lstat(absoluteRoot);\n if (!rootStat.isDirectory()) {\n return { ok: false, code: \"invalid_root\", detail: `not a directory: ${absoluteRoot}` };\n }\n } catch (err) {\n return {\n ok: false,\n code: \"invalid_root\",\n detail: `repoRoot not accessible: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // Probe root readability BEFORE scanning. An unreadable root (EACCES,\n // transient I/O) must surface as scan_failed, not a silent empty card —\n // otherwise refresh could overwrite a valid card with a sparse scan (codex\n // review). lstat can succeed while readdir is denied.\n try {\n await readdir(absoluteRoot);\n } catch (err) {\n return {\n ok: false,\n code: \"scan_failed\",\n detail: `repoRoot not readable: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n try {\n const scan = await scanRepository(absoluteRoot);\n const deterministic = renderCard(scan, options.now ?? new Date());\n const maxBytes = options.maxBytes ?? ARCHITECTURE_CARD_MAX_BYTES;\n\n let content = deterministic;\n if (options.llmSummary === true && options.summariser) {\n try {\n const summary = await options.summariser(deterministic, absoluteRoot);\n if (typeof summary === \"string\" && summary.trim().length > 0) {\n // Reserve the deterministic card's budget FIRST — it must ALWAYS\n // survive (rule 34 + codex/kilo review). The final `capToBytes`\n // truncates from the END, so the summary is prepended only into the\n // space left after the deterministic card + separator, additionally\n // clamped to the summary cap. A summary can never crowd out or\n // truncate the deterministic sections when the card fits the cap.\n const separator = \"\\n\\n---\\n\\n\";\n const detBytes = Buffer.byteLength(deterministic, \"utf-8\");\n const sepBytes = Buffer.byteLength(separator, \"utf-8\");\n const summaryBudget = Math.min(\n ARCHITECTURE_CARD_MAX_SUMMARY_BYTES,\n maxBytes - detBytes - sepBytes,\n );\n if (summaryBudget > 0) {\n const clampedSummary = clampSummaryToBytes(summary.trim(), summaryBudget);\n if (clampedSummary.length > 0) {\n content = `${clampedSummary}${separator}${deterministic}`;\n }\n }\n // else: the deterministic card already fills the cap — ship it\n // alone rather than prepend a summary that would truncate it.\n }\n } catch (err) {\n // rule 13: LLM failure → deterministic card ships unchanged.\n // Intentionally swallowed — the summariser contract says \"don't\n // throw\", but we defend against implementations that do.\n void err;\n }\n }\n\n const { text: truncatedContent, truncated } = capToBytes(content, maxBytes);\n return {\n ok: true,\n card: {\n content: truncatedContent,\n generatedAt: (options.now ?? new Date()).toISOString(),\n byteSize: Buffer.byteLength(truncatedContent, \"utf-8\"),\n truncated,\n },\n };\n } catch (err) {\n return {\n ok: false,\n code: \"scan_failed\",\n detail: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Scan — directory walk + manifest parse (deterministic)\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface RepoScan {\n root: string;\n topDirs: string[];\n manifests: ParsedManifest[];\n languageHistogram: LanguageEntry[];\n}\n\ninterface LanguageEntry {\n ext: string;\n count: number;\n}\n\ninterface ParsedManifest {\n filename: string;\n name: string | null;\n entryPoints: string[];\n}\n\nasync function scanRepository(root: string): Promise<RepoScan> {\n const topEntries = await readSortedDirEntries(root);\n const topDirs = topEntries.filter((e) => e.isDirectory && !SCAN_IGNORE_DIRS.has(e.name)).map((e) => e.name);\n const manifestFiles = topEntries\n .filter((e) => e.isFile && KNOWN_MANIFEST_FILES.includes(e.name as (typeof KNOWN_MANIFEST_FILES)[number]))\n .map((e) => e.name);\n\n const manifests: ParsedManifest[] = [];\n for (const mf of sortStrings(manifestFiles)) {\n const parsed = await parseManifest(path.join(root, mf));\n manifests.push({ filename: mf, name: parsed.name, entryPoints: sortStrings(parsed.entryPoints) });\n }\n\n const languageHistogram = await computeLanguageHistogram(root, topEntries);\n\n return {\n root: path.basename(root) || root,\n topDirs: sortStrings(topDirs),\n manifests,\n languageHistogram: sortLanguageHistogram(languageHistogram),\n };\n}\n\ninterface DirEntry {\n name: string;\n isDirectory: boolean;\n isFile: boolean;\n}\n\nasync function readSortedDirEntries(dir: string): Promise<DirEntry[]> {\n let names: string[];\n try {\n names = await readdir(dir);\n } catch {\n return [];\n }\n const entries: DirEntry[] = [];\n for (const name of sortStrings(names)) {\n try {\n const s = await lstat(path.join(dir, name));\n // Skip symlinks — they could point outside the repo root (codex review).\n if (s.isSymbolicLink()) continue;\n entries.push({ name, isDirectory: s.isDirectory(), isFile: s.isFile() });\n } catch {\n // vanished between readdir+stat — skip.\n }\n }\n return entries;\n}\n\nasync function computeLanguageHistogram(\n root: string,\n topEntries: DirEntry[],\n): Promise<LanguageEntry[]> {\n const counts = new Map<string, number>();\n const dirsToScan = topEntries\n .filter((e) => e.isDirectory && !SCAN_IGNORE_DIRS.has(e.name))\n .map((e) => path.join(root, e.name));\n // Also count files in the root itself.\n const rootFiles = topEntries.filter((e) => e.isFile);\n\n const visitDir = async (dir: string, depth: number): Promise<void> => {\n if (depth > 2) return; // cap walk depth for speed\n let entries: DirEntry[];\n try {\n entries = await readSortedDirEntries(dir);\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.isDirectory) {\n if (!SCAN_IGNORE_DIRS.has(entry.name)) {\n await visitDir(path.join(dir, entry.name), depth + 1);\n }\n } else if (entry.isFile) {\n const ext = path.extname(entry.name).toLowerCase();\n if (ext.length > 0) {\n counts.set(ext, (counts.get(ext) ?? 0) + 1);\n }\n }\n }\n };\n\n // Count root-level files first.\n for (const f of rootFiles) {\n const ext = path.extname(f.name).toLowerCase();\n if (ext.length > 0) counts.set(ext, (counts.get(ext) ?? 0) + 1);\n }\n // Walk subdirectories (breadth-first-ish via sequential await).\n for (const dir of dirsToScan) {\n await visitDir(dir, 0);\n }\n\n return Array.from(counts.entries()).map(([ext, count]) => ({ ext, count }));\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Manifest parse — narrow, known formats only\n// ──────────────────────────────────────────────────────────────────────────\n\nasync function parseManifest(filePath: string): Promise<{ name: string | null; entryPoints: string[] }> {\n const filename = path.basename(filePath);\n try {\n const raw = await readFile(filePath, \"utf-8\");\n switch (filename) {\n case \"package.json\":\n return parsePackageJson(raw);\n case \"pyproject.toml\":\n case \"setup.py\":\n return parsePythonProject(raw, filename);\n case \"go.mod\":\n return parseGoMod(raw);\n case \"Cargo.toml\":\n return parseCargoToml(raw);\n default:\n // Other manifests: extract nothing; presence alone is useful.\n return { name: null, entryPoints: [] };\n }\n } catch {\n return { name: null, entryPoints: [] };\n }\n}\n\nfunction parsePackageJson(raw: string): { name: string | null; entryPoints: string[] } {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { name: null, entryPoints: [] };\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return { name: null, entryPoints: [] };\n }\n const obj = parsed as Record<string, unknown>;\n const name = typeof obj[\"name\"] === \"string\" ? obj[\"name\"] : null;\n const entryPoints: string[] = [];\n const bin = obj[\"bin\"];\n if (typeof bin === \"string\") {\n entryPoints.push(bin);\n } else if (typeof bin === \"object\" && bin !== null && !Array.isArray(bin)) {\n for (const [key, value] of Object.entries(bin)) {\n // Record the target path when it is a string (e.g. {remnic:'dist/cli.js'}\n // → 'dist/cli.js'); fall back to the bin-key form for non-string\n // values. `bin` is already narrowed to a record by the typeof/!null/\n // !isArray guard above, so no cast is needed (codex review P2).\n entryPoints.push(typeof value === \"string\" ? value : `bin/${key}`);\n }\n }\n const main = typeof obj[\"main\"] === \"string\" ? obj[\"main\"] : null;\n if (main) entryPoints.push(main);\n const module = typeof obj[\"module\"] === \"string\" ? obj[\"module\"] : null;\n if (module) entryPoints.push(module);\n const scripts = obj[\"scripts\"];\n if (typeof scripts === \"object\" && scripts !== null && !Array.isArray(scripts)) {\n const scriptKeys = Object.keys(scripts as Record<string, unknown>);\n // Only surface the most useful entry-point scripts.\n for (const key of [\"start\", \"dev\", \"serve\"]) {\n if (scriptKeys.includes(key)) entryPoints.push(`scripts.${key}`);\n }\n }\n return { name, entryPoints };\n}\n\nfunction parsePythonProject(raw: string, _filename: string): { name: string | null; entryPoints: string[] } {\n // pyproject.toml: extract [project] name; setup.py: extract name=.\n const entryPoints: string[] = [];\n let name: string | null = null;\n const nameMatch = raw.match(/^name\\s*=\\s*[\"']([^\"']+)[\"']/m);\n if (nameMatch) name = nameMatch[1] ?? null;\n // Anchor on the next `[section]` header OR end-of-string (`$`). Do NOT use\n // `\\Z` — JavaScript regex treats it as a literal `Z`, so a `[project.scripts]`\n // table at EOF (the common layout) never matched and every console-script\n // entry point was dropped from the card (codex P2 review).\n const scriptsMatch = raw.match(/\\[project\\.scripts\\]([\\s\\S]*?)(?:\\n\\[|$)/);\n if (scriptsMatch && scriptsMatch[1]) {\n for (const line of scriptsMatch[1].split(\"\\n\")) {\n const m = line.match(/^([a-zA-Z0-9_-]+)\\s*=/);\n if (m && m[1]) entryPoints.push(`scripts.${m[1]}`);\n }\n }\n return { name, entryPoints };\n}\n\nfunction parseGoMod(raw: string): { name: string | null; entryPoints: string[] } {\n const moduleMatch = raw.match(/^module\\s+(\\S+)/m);\n const name = moduleMatch && moduleMatch[1] ? moduleMatch[1] : null;\n return { name, entryPoints: name ? [\"main.go\"] : [] };\n}\n\nfunction parseCargoToml(raw: string): { name: string | null; entryPoints: string[] } {\n const nameMatch = raw.match(/^name\\s*=\\s*\"([^\"]+)\"/m);\n const name = nameMatch && nameMatch[1] ? nameMatch[1] : null;\n const entryPoints: string[] = [];\n if (/\\[\\[bin\\]\\]/.test(raw)) entryPoints.push(\"src/bin/\");\n if (name) entryPoints.push(\"src/main.rs\");\n return { name, entryPoints };\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Render — deterministic markdown\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction renderCard(scan: RepoScan, now: Date): string {\n const lines: string[] = [];\n lines.push(`# Architecture Card — ${scan.root}`);\n lines.push(\"\");\n lines.push(`_Generated ${now.toISOString()}_`);\n lines.push(\"\");\n\n // Project name from the first manifest that provides one.\n const namedManifest = scan.manifests.find((m) => m.name !== null);\n if (namedManifest && namedManifest.name) {\n lines.push(`**Project:** ${namedManifest.name}`);\n lines.push(\"\");\n }\n\n // Manifests\n if (scan.manifests.length > 0) {\n lines.push(\"## Manifests\");\n for (const m of scan.manifests) {\n const label = m.name ? `${m.filename} (${m.name})` : m.filename;\n lines.push(`- ${label}`);\n }\n lines.push(\"\");\n }\n\n // Top-level directories\n if (scan.topDirs.length > 0) {\n lines.push(\"## Top-level directories\");\n // Wrap into columns of 4 for compactness.\n const cols = 4;\n for (let i = 0; i < scan.topDirs.length; i += cols) {\n const row = scan.topDirs.slice(i, i + cols).join(\" · \");\n lines.push(`- ${row}`);\n }\n lines.push(\"\");\n }\n\n // Language histogram (top 10 by count, ties broken alphabetically)\n if (scan.languageHistogram.length > 0) {\n lines.push(\"## Languages (by file count)\");\n const top = scan.languageHistogram.slice(0, 10);\n for (const entry of top) {\n lines.push(`- ${entry.ext}: ${entry.count}`);\n }\n lines.push(\"\");\n }\n\n // Entry points\n const allEntryPoints = sortStrings(scan.manifests.flatMap((m) => m.entryPoints));\n if (allEntryPoints.length > 0) {\n lines.push(\"## Entry points\");\n for (const ep of allEntryPoints) {\n lines.push(`- ${ep}`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd() + \"\\n\";\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Helpers — sort + cap\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction sortStrings(values: string[]): string[] {\n return [...values].sort((a, b) => a.localeCompare(b));\n}\n\nfunction sortLanguageHistogram(entries: LanguageEntry[]): LanguageEntry[] {\n return [...entries].sort((a, b) => {\n if (b.count !== a.count) return b.count - a.count;\n return a.ext.localeCompare(b.ext);\n });\n}\n\n/**\n * Cap a string to `maxBytes` of UTF-8. If truncation occurs, append a\n * visible marker on its own line (rule 34 — never silently incomplete).\n */\nfunction capToBytes(text: string, maxBytes: number): { text: string; truncated: boolean } {\n const byteLen = Buffer.byteLength(text, \"utf-8\");\n if (byteLen <= maxBytes) {\n return { text, truncated: false };\n }\n const marker = `\\n\\n_${ARCHITECTURE_CARD_TRUNCATION_MARKER}_`;\n const markerBytes = Buffer.byteLength(marker, \"utf-8\");\n const budget = maxBytes - markerBytes;\n if (budget <= 0) {\n // Extremely tight cap — return just the marker.\n return { text: marker.trimStart(), truncated: true };\n }\n // Walk the string to find a UTF-8-safe cut point.\n let cut = 0;\n let running = 0;\n const chars = [...text];\n for (let i = 0; i < chars.length; i++) {\n const charBytes = Buffer.byteLength(chars[i], \"utf-8\");\n if (running + charBytes > budget) break;\n running += charBytes;\n cut = i + 1;\n }\n return { text: chars.slice(0, cut).join(\"\") + marker, truncated: true };\n}\n\n/**\n * Clamp an LLM SUMMARY to `maxBytes` of UTF-8. Unlike {@link capToBytes}, this\n * uses a neutral trailing ellipsis (never the card-truncation marker) and keeps\n * the result — ellipsis included — within `maxBytes`. A clamped summary must\n * never imply the deterministic CARD was truncated, nor spill past its reserved\n * budget into the deterministic sections (cursor/codex review).\n */\nfunction clampSummaryToBytes(text: string, maxBytes: number): string {\n if (maxBytes <= 0) return \"\";\n if (Buffer.byteLength(text, \"utf-8\") <= maxBytes) return text;\n const ellipsis = \" …\";\n const budget = maxBytes - Buffer.byteLength(ellipsis, \"utf-8\");\n if (budget <= 0) return \"\";\n let cut = 0;\n let running = 0;\n const chars = [...text];\n for (let i = 0; i < chars.length; i++) {\n const charBytes = Buffer.byteLength(chars[i], \"utf-8\");\n if (running + charBytes > budget) break;\n running += charBytes;\n cut = i + 1;\n }\n return chars.slice(0, cut).join(\"\") + ellipsis;\n}\n","/**\n * Architecture-card surface contract + handler (issue #1548 Track A PR 3).\n *\n * Mirrors the decision-surfaces pattern (PR 2): one shared implementation\n * behind the MCP, HTTP, and CLI surfaces. All three transports dispatch\n * through the `coding_architecture` boundary operation, which calls\n * {@link handleCodingArchitecture} via the service delegate.\n *\n * Gate (rule 39): `codingKnowledge.enabled + architectureCard + coding\n * context` — one predicate, identical on every surface. The tools/list\n * visibility gate checks conditions 1–2 only (config-level).\n *\n * Persistence (rule 43): the card is written through the storage\n * manager's normal persist pipeline (writeMemory for the initial card,\n * updateMemory for refreshes) so catalog recording + reindex fire. No\n * direct `fs` writes of memory content. Each refresh snapshots the\n * prior content via page-versioning before overwriting (rule 25 —\n * preserve the old before the new is ready).\n *\n * Subcommands:\n * - `get`: return the current architecture card (or not-found).\n * - `refresh`: build a fresh card from the repo, persist it, and\n * snapshot the prior version.\n */\nimport type {\n CodingKnowledgeConfig,\n CodingContext,\n MemoryFile,\n MemoryFrontmatter,\n MemoryStatus,\n} from \"../types.js\";\nimport type { VersionTrigger, VersioningConfig } from \"../page-versioning.js\";\nimport type { MemoryWriteResult } from \"../storage.js\";\nimport { stripAttributesSuffix } from \"../structured-attributes.js\";\nimport { ARCHITECTURE_CARD_TRUNCATION_MARKER, type ArchitectureCardBuildResult } from \"./architecture-card.js\";\nimport { log } from \"../logger.js\";\nimport { composeMemoryEnvelope, type SealedMemoryEnvelope } from \"../write-envelope.js\";\nimport { isCodingKnowledgeFeatureEnabled } from \"./coding-knowledge-config.js\";\n\n// ──────────────────────────────────────────────────────────────────────────\n// Subcommands\n// ──────────────────────────────────────────────────────────────────────────\n\nexport const ARCHITECTURE_SUBCOMMANDS = [\"get\", \"refresh\"] as const;\n\nexport type ArchitectureSubcommand = (typeof ARCHITECTURE_SUBCOMMANDS)[number];\n\nconst SUBCOMMAND_VALUES = ARCHITECTURE_SUBCOMMANDS as readonly string[];\n\n/** Type guard — narrows an unknown subcommand string. */\nexport function isArchitectureSubcommand(value: unknown): value is ArchitectureSubcommand {\n return typeof value === \"string\" && SUBCOMMAND_VALUES.includes(value);\n}\n\n/** Human-readable subcommand list for error messages (rule 51). */\nexport function formatArchitectureSubcommands(): string {\n return ARCHITECTURE_SUBCOMMANDS.join(\", \");\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Surface request / response shapes\n// ──────────────────────────────────────────────────────────────────────────\n\n/** Canonical surface request — one shape for all three transports. */\nexport interface ArchitectureSurfaceRequest {\n subcommand: ArchitectureSubcommand;\n sessionKey?: string;\n namespace?: string;\n}\n\n/** Surface response — discriminated union on `subcommand`. */\nexport type ArchitectureSurfaceResponse =\n | {\n subcommand: \"get\";\n found: boolean;\n card?: {\n content: string;\n generatedAt: string;\n byteSize: number;\n truncated: boolean;\n };\n }\n | {\n subcommand: \"refresh\";\n refreshed: boolean;\n memoryId: string;\n byteSize: number;\n truncated: boolean;\n buildCode?: string;\n /**\n * Present when the refresh was tombstone-blocked (#1579): the new card\n * content landed pending_review (no active overwrite). Callers/UI surface\n * this so operators see why the active card didn't update (#1645).\n */\n blockedReason?: string;\n /** The tombstone id that blocked the write, when `blockedReason` is set. */\n blockedBy?: string;\n };\n\n// ──────────────────────────────────────────────────────────────────────────\n// Storage contract — narrow subset of StorageManager\n// ──────────────────────────────────────────────────────────────────────────\n\n/** Tag identifying the architecture card memory (single card per namespace). */\nexport const ARCHITECTURE_CARD_TAG = \"architecture-card\";\n\n/** Structured attribute marking a memory as the architecture card. */\nexport const ARCHITECTURE_CARD_KIND = \"architecture\";\n\n/**\n * Structural subset of StorageManager the architecture handler reads or\n * writes. Kept narrow so the module stays decoupled from storage.ts and\n * is unit-testable with a stub.\n */\nexport interface ArchitectureSurfaceStorage {\n readonly dir: string;\n /** The resolved namespace — used for logging/observability. */\n readonly namespace: string;\n readAllMemories(): Promise<readonly MemoryFile[]>;\n /** Sealed-envelope write entry point (issue #1989 PR4). */\n writeSealedMemory(\n envelope: SealedMemoryEnvelope,\n extras: { status?: MemoryStatus },\n ): Promise<MemoryWriteResult>;\n updateMemory(\n id: string,\n newContent: string,\n options?: { supersedes?: string; lineage?: string[]; actor?: string; sourceConnector?: string },\n ): Promise<boolean>;\n}\n\n/**\n * Card-builder dependency. The handler delegates repo scanning to this\n * function so tests can inject a fixed card without touching the\n * filesystem.\n */\nexport type ArchitectureCardBuilder = (\n repoRoot: string,\n) => Promise<ArchitectureCardBuildResult>;\n\n/**\n * Page-versioning snapshot dependency. The handler calls this BEFORE\n * overwriting the card content so the prior version is preserved\n * (rule 25).\n */\nexport interface ArchitectureVersioningHook {\n /**\n * Snapshot the current content of the card memory before refresh.\n * Failures are logged but do not block the refresh (best-effort).\n */\n snapshotIfExists(memory: MemoryFile): Promise<void>;\n}\n\n/**\n * Dependencies the handler borrows from the service. The service\n * constructs this context per call; the handler never touches the\n * orchestrator directly.\n */\nexport interface ArchitectureSurfaceContext {\n readonly codingKnowledge: CodingKnowledgeConfig;\n getCodingContext(sessionKey: string): CodingContext | null;\n /** Resolve storage through the SAME namespace path as memory_store. */\n resolveStorage(request: ArchitectureSurfaceRequest): Promise<ArchitectureSurfaceStorage>;\n /** Build the architecture card from a repo root. */\n buildCard: ArchitectureCardBuilder;\n /** Snapshot the prior card version before refresh (rule 25). */\n versioning: ArchitectureVersioningHook;\n /** Throw the surface-appropriate input-validation error. */\n throwInputError(message: string): never;\n /** Server-resolved connector identity for provenance. */\n readonly sourceConnector?: string;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Handler — the single shared implementation behind all three surfaces\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * The single shared implementation behind the MCP, HTTP, and CLI\n * architecture-card surfaces.\n *\n * Gate (rule 39): `codingKnowledge.enabled + architectureCard + coding\n * context`. Persistence (rule 43): cards are written through the storage\n * manager's normal persist pipeline. Refresh (rule 25): the prior card\n * is snapshotted via page-versioning BEFORE the content is overwritten.\n */\nexport async function handleCodingArchitecture(\n request: ArchitectureSurfaceRequest,\n ctx: ArchitectureSurfaceContext,\n): Promise<ArchitectureSurfaceResponse> {\n const codingContext = request.sessionKey\n ? ctx.getCodingContext(request.sessionKey)\n : null;\n // Rule 39 + type-guard narrowing: check `codingContext` inline so TS\n // narrows it to CodingContext here, with no non-null assertion cast.\n if (\n codingContext === null ||\n !isCodingKnowledgeFeatureEnabled(ctx.codingKnowledge, \"architectureCard\", codingContext)\n ) {\n ctx.throwInputError(\n \"coding_architecture requires codingKnowledge.enabled, codingKnowledge.architectureCard, and an attached coding context\",\n );\n }\n switch (request.subcommand) {\n case \"get\":\n return architectureGet(request, ctx);\n case \"refresh\":\n return architectureRefresh(request, ctx, codingContext);\n }\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Subcommand handlers\n// ──────────────────────────────────────────────────────────────────────────\n\n\nasync function architectureGet(\n request: ArchitectureSurfaceRequest,\n ctx: ArchitectureSurfaceContext,\n): Promise<ArchitectureSurfaceResponse> {\n const storage = await ctx.resolveStorage(request);\n const existing = await findArchitectureCardMemory(storage);\n if (!existing) {\n return { subcommand: \"get\", found: false };\n }\n const content = stripAttributesSuffix(existing.content);\n return {\n subcommand: \"get\",\n found: true,\n card: {\n content,\n generatedAt: existing.frontmatter.updated ?? existing.frontmatter.created,\n byteSize: Buffer.byteLength(content, \"utf-8\"),\n // Derive truncation from the CONTENT marker, not a frontmatter tag —\n // the refresh update path changes content without rewriting tags, so\n // a tag-based check goes stale (cursor review: stale truncated tag).\n truncated: content.includes(ARCHITECTURE_CARD_TRUNCATION_MARKER),\n },\n };\n}\n\nasync function architectureRefresh(\n request: ArchitectureSurfaceRequest,\n ctx: ArchitectureSurfaceContext,\n codingContext: CodingContext,\n): Promise<ArchitectureSurfaceResponse> {\n const repoRoot = codingContext.rootPath ?? codingContext.projectId;\n // Authorize the write + resolve storage BEFORE scanning the repo or\n // invoking the summariser, so an unauthorized refresh fails fast instead\n // of doing work (and an LLM call) it cannot persist (codex review: buildCard\n // ran before the write ACL was enforced).\n const storage = await ctx.resolveStorage(request);\n const buildResult = await ctx.buildCard(repoRoot);\n if (!buildResult.ok) {\n // A failed build is a tagged outcome, not a crash. Log the full detail\n // for operators; it may include absolute paths / raw I/O messages that\n // must NOT reach clients (cursor review: raw build errors reach clients).\n log.warn(\n `coding_architecture/refresh: card build failed (code=${buildResult.code}): ${buildResult.detail}`,\n );\n // Persist nothing on build failure — no stale card left behind (rule 44).\n // Client-facing error carries only the code.\n ctx.throwInputError(\n `coding_architecture refresh failed: card build returned ${buildResult.code}`,\n );\n }\n\n const cardContent = buildResult.card.content;\n const tags = [ARCHITECTURE_CARD_TAG];\n if (buildResult.card.truncated) tags.push(\"truncated\");\n\n const existing = await findArchitectureCardMemory(storage);\n if (existing) {\n // rule 25: snapshot the prior content BEFORE overwriting.\n await ctx.versioning.snapshotIfExists(existing);\n const updated = await storage.updateMemory(existing.frontmatter.id, cardContent, {\n actor: \"coding-architecture-refresh\",\n ...(ctx.sourceConnector ? { sourceConnector: ctx.sourceConnector } : {}),\n });\n if (!updated) {\n log.warn(\n `coding_architecture/refresh: updateMemory returned false for id=${existing.frontmatter.id} — falling back to writeMemory`,\n );\n // Sealed-envelope write (issue #1989 PR4): system-built card content —\n // strict compose; an invalid card is a code bug that must surface.\n const fallbackWrite = await storage.writeSealedMemory(\n composeMemoryEnvelope(\n {\n content: cardContent,\n category: \"fact\",\n confidence: 1.0,\n tags,\n structuredAttributes: { cardKind: ARCHITECTURE_CARD_KIND },\n ...(ctx.sourceConnector ? { sourceConnector: ctx.sourceConnector } : {}),\n },\n { source: \"coding-architecture\" },\n ),\n {},\n );\n log.info(\n `access-write op=coding_architecture/refresh memoryId=${fallbackWrite.id} (fallback write) byteSize=${buildResult.card.byteSize}`,\n );\n return refreshResponse(fallbackWrite, buildResult.card);\n }\n log.info(\n `access-write op=coding_architecture/refresh memoryId=${existing.frontmatter.id} (updated) byteSize=${buildResult.card.byteSize}`,\n );\n return {\n subcommand: \"refresh\",\n refreshed: true,\n memoryId: existing.frontmatter.id,\n byteSize: buildResult.card.byteSize,\n truncated: buildResult.card.truncated,\n };\n }\n\n // First card for this namespace — write a new memory.\n // Sealed-envelope write (issue #1989 PR4): strict — see the fallback site.\n const newWrite = await storage.writeSealedMemory(\n composeMemoryEnvelope(\n {\n content: cardContent,\n category: \"fact\",\n confidence: 1.0,\n tags,\n structuredAttributes: { cardKind: ARCHITECTURE_CARD_KIND },\n ...(ctx.sourceConnector ? { sourceConnector: ctx.sourceConnector } : {}),\n },\n { source: \"coding-architecture\" },\n ),\n {},\n );\n log.info(\n `access-write op=coding_architecture/refresh memoryId=${newWrite.id} (new) byteSize=${buildResult.card.byteSize}`,\n );\n return refreshResponse(newWrite, buildResult.card);\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Local helpers\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Build the refresh response from a write outcome, surfacing a\n * tombstone block (#1579) as `refreshed:false` + a blocked reason so\n * callers/UI see why the active card didn't update (#1645). Mirrors the\n * guard pattern in wearables/memory-gen.ts: a blocked write lands\n * pending_review (no active copy) and must NOT report `refreshed:true`.\n */\nfunction refreshResponse(\n writeResult: MemoryWriteResult,\n card: { byteSize: number; truncated: boolean },\n): ArchitectureSurfaceResponse {\n if (writeResult.tombstoneBlocked) {\n return {\n subcommand: \"refresh\",\n refreshed: false,\n memoryId: writeResult.id,\n byteSize: card.byteSize,\n truncated: card.truncated,\n blockedReason: \"tombstone-blocked\",\n ...(writeResult.blockedBy !== undefined ? { blockedBy: writeResult.blockedBy } : {}),\n };\n }\n return {\n subcommand: \"refresh\",\n refreshed: true,\n memoryId: writeResult.id,\n byteSize: card.byteSize,\n truncated: card.truncated,\n };\n}\n\n/**\n * Find the existing architecture-card memory in the namespace, if any.\n * Identified by the `architecture-card` tag + `cardKind=architecture`\n * structured attribute. A single card per namespace is the invariant;\n * if multiple exist (race), the most recently updated wins.\n */\nexport async function findArchitectureCardMemory(\n storage: ArchitectureSurfaceStorage,\n): Promise<MemoryFile | null> {\n const memories = await storage.readAllMemories();\n const cards = memories.filter((m) => {\n if (m.frontmatter.category !== \"fact\") return false;\n const tags = m.frontmatter.tags ?? [];\n if (!tags.includes(ARCHITECTURE_CARD_TAG)) return false;\n // Require the cardKind structured attribute so a user-created fact that\n // merely happens to be tagged \"architecture-card\" is NOT mistaken for\n // the managed card and overwritten on refresh (codex review).\n if (m.frontmatter.structuredAttributes?.cardKind !== ARCHITECTURE_CARD_KIND) return false;\n // Any outer status other than undefined/\"active\" means retired.\n const outer = m.frontmatter.status;\n if (outer !== undefined && outer !== \"active\") return false;\n // Also skip cards archived via archivedAt without an explicit status\n // (cursor review: archived cards can still match the tag filter).\n if (m.frontmatter.archivedAt !== undefined && m.frontmatter.archivedAt !== null) return false;\n return true;\n });\n if (cards.length === 0) return null;\n // Most recently updated wins (deterministic tie-break by id).\n cards.sort((a, b) => {\n const aUpdated = a.frontmatter.updated ?? a.frontmatter.created;\n const bUpdated = b.frontmatter.updated ?? b.frontmatter.created;\n if (aUpdated !== bUpdated) return bUpdated.localeCompare(aUpdated);\n return b.frontmatter.id.localeCompare(a.frontmatter.id);\n });\n return cards[0] ?? null;\n}\n\n/**\n * Build a {@link MemoryFrontmatter}-shaped patch that marks a memory as\n * the architecture card. Exported for test fixtures.\n */\nexport function architectureCardFrontmatterMarker(): Partial<MemoryFrontmatter> {\n return {\n tags: [ARCHITECTURE_CARD_TAG],\n };\n}\n\n/** Page-version snapshot writer (decoupled type — matches page-versioning.createVersion's call). */\ntype CreatePageVersion = (\n pagePath: string,\n content: string,\n trigger: VersionTrigger,\n config: VersioningConfig,\n logger: undefined,\n note: string,\n memoryDir: string,\n) => Promise<unknown>;\n\n/**\n * Build the page-versioning snapshot hook from operator config.\n *\n * - Skips entirely when versioning is disabled — no sidecars written for a\n * feature the operator turned off (codex review: hardcoded config ignored\n * operator settings).\n * - Reads the FULL file (frontmatter + body) from disk so a revert restores\n * the complete memory, not just the body (codex review: snapshot was\n * body-only).\n */\nexport function createArchitectureVersioningHook(\n enabled: boolean,\n maxVersionsPerPage: number,\n sidecarDir: string,\n memoryDir: string,\n readFile: (path: string) => Promise<string>,\n writeVersion: CreatePageVersion,\n): ArchitectureVersioningHook {\n return {\n async snapshotIfExists(memory) {\n if (!enabled) return;\n try {\n const fullContent = await readFile(memory.path);\n await writeVersion(\n memory.path,\n fullContent,\n \"manual\",\n { enabled: true, maxVersionsPerPage, sidecarDir },\n undefined,\n \"architecture-card-refresh\",\n memoryDir,\n );\n } catch {\n // Best-effort — a snapshot failure does not block the refresh.\n }\n },\n };\n}\n","/**\n * Runtime bridge between the access surfaces (MCP/HTTP/CLI) and the optional\n * @remnic/coding-graph package (issue #1554).\n *\n * WHY THIS MODULE EXISTS\n *\n * The 14 codegraph parity tools (`codegraph_index`, `search_graph`, ...) must\n * not bundle @remnic/coding-graph into @remnic/core -- it is an optional peer\n * dependency that hosts opt into. Every code path that needs a GraphStore\n * calls {@link getCodegraphStore} here; this module owns:\n *\n * - the store-module boundary — @remnic/coding-graph is imported by the\n * ONE shared loader (optional-coding-graph.ts; single cache and\n * contract check per process). This module narrows that shared module\n * to the runtime's GraphStore view; it never imports the package\n * itself;\n * - per-project GraphStore caching (one open SQLite handle per\n * `(principal, projectId)` pair, lifecycle-tracked so a host process can\n * close them on shutdown);\n * - DB path resolution -- the on-disk location of each project's graph DB,\n * derived from `codingKnowledge.codegraphDbDir` or memoryDir.\n *\n * No orchestrator imports (rule 11 -- no shared mutable state). No access to\n * the access-service facade: this module is the borrowed dependency, called\n * by the surface handler via a context seam.\n */\nimport path from \"node:path\";\nimport { readFile, realpath } from \"node:fs/promises\";\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport { pathToFileURL } from \"node:url\";\nimport { createHash } from \"node:crypto\";\nimport { expandTildePath } from \"../utils/path.js\";\n\nimport type { PluginConfig, CodingKnowledgeConfig, CodingContext } from \"../types.js\";\nimport { buildCodingGraphInstallHint, isCodingGraphInstalled, tryLoadCodingGraphModule } from \"./optional-coding-graph.js\";\nimport { displayErrorDetail } from \"../runtime/better-sqlite.js\";\n// Type-only reference to the surface context shape (ts-import-type rule).\n// Erased at compile time, so the runtime → surfaces → runtime import cycle is\n// type-only and has no runtime effect.\nimport type { CodegraphSurfaceContext } from \"./codegraph-surfaces.js\";\n\n\n\n/**\n * Minimal structural shape of the @remnic/coding-graph public surface this\n * runtime needs. Kept hand-written (not imported) so core compiles on the\n * base install where the optional peer is absent.\n */\ninterface CodegraphModule {\n GraphStore: {\n open(options: { dbPath: string; repoRoot?: string }): Promise<CodegraphStore>;\n };\n // PR3 (issue #1553) functions — present when @remnic/coding-graph ships\n // them. Each is optional in the structural type so a partial install that\n // predates PR3 still loads; the delegate functions check typeof and degrade.\n executeReindex?(options: {\n store: CodegraphStore;\n git: unknown;\n repoRoot: string;\n parseFile: (input: unknown) => Promise<unknown>;\n candidatePaths?: readonly string[];\n }): Promise<unknown>;\n getIndexStatus?(store: CodegraphStore, git: unknown, repoRoot: string): unknown;\n computeBlastRadius?(\n store: CodegraphStore,\n directlyAffected: ReadonlySet<string>,\n maxDepth?: number,\n ): unknown;\n defaultCodingGitInvoker?: unknown;\n createCodingGraphEngine?(options?: unknown): { parseFile(input: unknown): Promise<unknown> };\n // LSP resolution (issue #1917): present when @remnic/coding-graph ships\n executeLspResolution?(requests: readonly unknown[], options: unknown): Promise<unknown>;\n planLspUpgrades?(sites: readonly unknown[], budget: { maxRequests: number }): { requests: readonly unknown[]; budgetExhausted: number };\n LspClient?: {\n connect(options: {\n launchSpec: { command: string; args: readonly string[] };\n rootUri: string | null;\n timeoutMs: number;\n }): Promise<{ ok: true; client: unknown } | { ok: false; degradation: unknown }>;\n };\n}\n\n/**\n * The narrow GraphStore surface the codegraph tools call into. Methods here\n * mirror the public class exported by @remnic/coding-graph; the runtime\n * never invents new ones.\n */\nexport interface CodegraphStore {\n schemaVersion(): number;\n schemaStats(): CodegraphSchemaStatsResult;\n searchGraph(query: unknown): CodegraphSearchResult;\n traverse(query: unknown): CodegraphTraverseResult;\n snippetFor(query: unknown): Promise<CodegraphSnippetResult>;\n deadCode(): CodegraphDeadCodeResult;\n close(): Promise<void>;\n // PR3 meta + write methods (issue #1553/#1554). Optional in the structural\n // type so the narrow stub used by early tests still satisfies the shape.\n readMeta?(key: string): { ok: true; value: string | null } | { ok: false; code: string };\n readFileHashes?(): { ok: true; value: ReadonlyMap<string, string> } | { ok: false; code: string };\n writeMeta?(key: string, value: string): void;\n upsertFileBatch?(\n files: readonly unknown[],\n deletePaths?: readonly string[],\n ): Promise<{ ok: true; results: unknown[] } | { ok: false; code: string }>;\n upsertEdges?(\n edges: readonly CodegraphEdgeInput[],\n ): Promise<{ ok: true; persisted: number; skipped: number } | { ok: false; code: string }>;\n /** Find the node whose span contains the byte offset (issue #1917). */\n findNodeBySpan?(filePath: string, byteOffset: number): string | null;\n /** Retire stale lsp-provenance edges for a file (issue #1895). */\n reconcileLspEdges?(\n filePath: string,\n assertedEdges: ReadonlyArray<{ srcQualifiedName: string; dstQualifiedName: string; type: string }>,\n ): number;\n /** Callee names already CALLS-linked from a caller with a given provenance (issue #1917). */\n resolvedCalleeNames?(srcQualifiedName: string, provenance: string, filePath?: string): string[];\n /** Current CALLS edges of a provenance owned by a caller symbol in a file (issue #1917). */\n callEdgesForCaller?(\n srcQualifiedName: string,\n filePath: string,\n provenance: string,\n ): Array<{ srcQualifiedName: string; dstQualifiedName: string; dstName: string; type: string }>;\n}\n\n/**\n * Minimal edge shape for standalone trace ingestion (mirrors the subset of\n * @remnic/coding-graph's EdgeIR the trace path populates).\n */\nexport interface CodegraphEdgeInput {\n srcQualifiedName: string;\n dstQualifiedName: string;\n type: string;\n confidence: number;\n provenance: string;\n}\n\nexport type CodegraphSchemaStatsResult =\n | { ok: true; fileCount: number; nodeCount: number; edgeCount: number; symbolKinds: Record<string, number> }\n | { ok: false; code: string };\n\nexport type CodegraphSearchResult =\n | { ok: true; hits: unknown[] }\n | { ok: false; code: string };\n\nexport type CodegraphTraverseResult =\n | { ok: true; hits: unknown[] }\n | { ok: false; code: string };\n\nexport type CodegraphSnippetResult =\n | { ok: true; snippet: string; startLine: number; endLine: number }\n | { ok: false; code: string };\n\nexport type CodegraphDeadCodeResult =\n | { ok: true; hits: unknown[] }\n | { ok: false; code: string };\n\n// ──────────────────────────────────────────────────────────────────────────\n// Gate predicate — rule 39: ONE predicate, identical on every surface\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Config-only visibility gate. Returns true iff the master\n * `codingKnowledge.enabled` switch AND the `codegraphTools` feature switch\n * are both on. The tools/list visibility check, the HTTP route guard, and\n * the CLI command guard all read this predicate (or its runtime-tightened\n * sibling {@link codegraphRuntimeAvailable}) -- never the raw config flags.\n *\n * When this returns false the MCP `tools/list` is byte-identical to\n * pre-feature (rule 39).\n */\nexport function codegraphSurfaceVisible(config: PluginConfig): boolean {\n const ck = config.codingKnowledge;\n // Guard: some code paths (test stubs, partially-constructed configs) may\n // not have codingKnowledge populated. Fail closed — tools hidden.\n if (ck === undefined || ck === null) return false;\n return ck.enabled === true && ck.codegraphTools === true;\n}\n\n/**\n * Runtime-availability predicate -- tightens the config gate with the\n * loader probe. Call sites that are about to OPEN a GraphStore must use\n * this (config alone is insufficient; the package may be missing).\n *\n * Cached: the loader probe's outcome is memoized by optional-coding-graph.ts\n * (see its file header -- success and absent outcomes are sticky). This\n * function never throws.\n */\nexport async function codegraphRuntimeAvailable(config: PluginConfig): Promise<boolean> {\n return codegraphSurfaceVisible(config) && (await isCodingGraphInstalled());\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// DB path resolution -- rule 11 (no path assembly at call sites)\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Resolve a per-project graph DB path. The layout is:\n *\n * <codegraphDbDir>/<principalSafe>/<projectIdSafe>.sqlite (explicit root)\n * <memoryDir>/codegraph/<principalSafe>/<projectIdSafe>.sqlite (default)\n *\n * Both `principalSafe` and `projectIdSafe` are sanitized to a stable,\n * filesystem-safe token so a hostile project id (e.g. `../../etc/passwd`)\n * cannot escape the codegraph root. The function never touches the\n * filesystem -- callers create the parent directory before opening the DB.\n */\n/**\n * Resolve the codegraph root directory (issue #1554 review thread: reject\n * relative roots). An explicit `codegraphDbDir` may be a `~\\`-prefixed path;\n * the default is memoryDir/codegraph. The result MUST be absolute —\n * GraphStore.open rejects relative dbPath with \"dbPath must be absolute\",\n * and list_projects would otherwise silently read a CWD-relative directory.\n * Failing early here gives callers a tagged, actionable error.\n */\nfunction resolveCodegraphRoot(config: PluginConfig, memoryDir: string): string {\n const rawDir = config.codingKnowledge.codegraphDbDir.trim();\n const root = rawDir.length > 0 ? expandTildePath(rawDir) : path.join(memoryDir, \"codegraph\");\n if (!path.isAbsolute(root)) {\n throw new CodegraphRuntimeError(\n \"store_error\",\n \"codegraph DB root must be an absolute path; set codingKnowledge.codegraphDbDir (or memoryDir) to an absolute path\",\n );\n }\n return root;\n}\n\nexport function resolveCodegraphDbPath(params: {\n readonly config: PluginConfig;\n readonly memoryDir: string;\n readonly principal: string;\n readonly projectId: string;\n}): string {\n const { config, memoryDir, principal, projectId } = params;\n const root = resolveCodegraphRoot(config, memoryDir);\n const principalSafe = sanitizePathSegment(principal);\n const projectSafe = sanitizePathSegment(projectId);\n return path.join(root, principalSafe, `${projectSafe}.sqlite`);\n}\n\n/**\n * Reject anything that is not a flat, filesystem-safe token. `_` is the\n * canonical fallback so an empty/whitespace principal still lands in a\n * stable per-process directory rather than the root.\n */\nfunction sanitizePathSegment(input: string): string {\n const trimmed = (input ?? \"\").trim();\n if (trimmed.length === 0) return \"_\";\n // Permit letters, digits, dash, underscore, dot, colon -- the stable\n // characters that appear in projectId (`origin:<hex>`, `root:<hex>`)\n // and principal (`alice`, `team-foo`). Everything else collapses to `_`.\n const sanitized = trimmed.replace(/[^A-Za-z0-9._:-]+/g, \"_\");\n // Strip leading dots so the segment cannot be `.` / `..` and refuse any\n // path separator that survived (defense-in-depth).\n return sanitized.replace(/^\\.+/, \"\").replace(/[/\\\\]+/g, \"_\") || \"_\";\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Per-project store cache\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface CachedStore {\n readonly store: CodegraphStore;\n readonly repoRoot: string | undefined;\n /** Monotonic so closeAll() drains in FIFO order. */\n readonly openedAt: number;\n}\n\nconst storeCache = new Map<string, CachedStore>();\n\nfunction storeCacheKey(principalSafe: string, projectSafe: string, dbPath: string): string {\n // Thread 8 (issue #1554): include the resolved DB path so two configs\n // sharing a principal/project but differing in codegraphDbDir (or memoryDir)\n // get distinct cache entries — otherwise the second config reuses the first\n // config's open SQLite handle and reads/writes the wrong graph DB.\n return `${principalSafe}::${projectSafe}::${dbPath}`;\n}\n\n/**\n * Narrow the module served by the shared loader (optional-coding-graph.ts)\n * to this runtime's structural view. The shared loader owns the single\n * dynamic import, cache, and miss/incompatible diagnostics; this predicate\n * only checks the GraphStore capability the runtime needs. A missing,\n * broken, or engine-incompatible install collapses to `null` (graceful\n * degradation -- surfaces translate to the install hint).\n */\nfunction isCodegraphModule(value: object): value is CodegraphModule {\n if (!value || typeof value !== \"object\") return false;\n const candidate = value as Record<string, unknown>;\n const graphStore = candidate.GraphStore as { open?: unknown } | undefined;\n return graphStore !== undefined && typeof graphStore.open === \"function\";\n}\n\nasync function resolveCodegraphModule(): Promise<CodegraphModule | null> {\n const mod = await tryLoadCodingGraphModule();\n if (mod === null || !isCodegraphModule(mod)) return null;\n return mod;\n}\n\n/**\n * Resolve a per-project store. The cache returns the SAME handle for the\n * same `(principal, projectId)` pair; the repoRoot that wins is the FIRST\n * opener's -- subsequent openers with a different repoRoot are rejected\n * (rule 42 -- a session cannot rebind another session's graph to a\n * different repo mid-flight).\n *\n * The `codingKnowledge` gate is RE-CHECKED here (defense-in-depth) even\n * though the surface handler already gated; a direct caller that bypasses\n * the handler still cannot open a store on a disabled config.\n */\nexport async function getCodegraphStore(params: {\n readonly config: PluginConfig;\n readonly memoryDir: string;\n readonly principal: string;\n readonly projectId: string;\n readonly repoRoot?: string;\n}): Promise<CodegraphStore> {\n const { config, memoryDir, principal, projectId, repoRoot } = params;\n if (!codegraphSurfaceVisible(config)) {\n throw new CodegraphRuntimeError(\n \"disabled\",\n \"codegraph tools are disabled (codingKnowledge.enabled or codingKnowledge.codegraphTools is false)\",\n );\n }\n const mod = await resolveCodegraphModule();\n if (mod === null) {\n throw new CodegraphRuntimeError(\"package_missing\", buildCodingGraphInstallHint());\n }\n // Key the cache on SANITIZED values AND the resolved DB path (thread 8):\n // two different raw identifiers that sanitize to the same path segment\n // share one store handle (prevents two open handles on the same SQLite\n // file), and two configs with different roots get distinct entries.\n const principalSafe = sanitizePathSegment(principal);\n const projectSafe = sanitizePathSegment(projectId);\n const dbPath = resolveCodegraphDbPath({ config, memoryDir, principal, projectId });\n const key = storeCacheKey(principalSafe, projectSafe, dbPath);\n const cached = storeCache.get(key);\n if (cached !== undefined) {\n if (repoRoot !== undefined && cached.repoRoot === undefined) {\n // Thread 11 (issue #1554): the cached store was opened rootless (e.g. a\n // get_schema call with no repoRoot). A later call that DOES supply a\n // repoRoot needs repo-root-bound operations (snippet reads file content)\n // to work, so close the rootless handle and reopen bound to repoRoot.\n storeCache.delete(key);\n try {\n await cached.store.close();\n } catch {\n // Best-effort close; the reopen below still proceeds.\n }\n const store = await mod.GraphStore.open({ dbPath, repoRoot });\n storeCache.set(key, { store, repoRoot, openedAt: Date.now() });\n return store;\n }\n if (repoRoot !== undefined && cached.repoRoot !== undefined && cached.repoRoot !== repoRoot) {\n throw new CodegraphRuntimeError(\n \"repo_root_conflict\",\n `codegraph store for project ${projectId} is already bound to repo root ${cached.repoRoot}; refusing to rebind to ${repoRoot}`,\n );\n }\n return cached.store;\n }\n const store = await mod.GraphStore.open({ dbPath, repoRoot });\n storeCache.set(key, { store, repoRoot, openedAt: Date.now() });\n return store;\n}\n\n/**\n * List projects known to this principal by walking the codegraph root for\n * `.sqlite` files. Pure-filesystem; no store opens. Returns project ids in\n * the same sanitized form they were stored under.\n */\nexport function listCodegraphProjects(params: {\n readonly config: PluginConfig;\n readonly memoryDir: string;\n readonly principal: string;\n readonly listDir: (dir: string) => readonly string[];\n}): readonly string[] {\n const { config, memoryDir, principal, listDir } = params;\n if (!codegraphSurfaceVisible(config)) return [];\n let root: string;\n try {\n root = resolveCodegraphRoot(config, memoryDir);\n } catch {\n // A relative/misconfigured root means no projects are listable; the\n // open path reports the tagged error, list degrades to empty.\n return [];\n }\n const principalSafe = sanitizePathSegment(principal);\n const principalDir = path.join(root, principalSafe);\n let entries: readonly string[];\n try {\n entries = listDir(principalDir);\n } catch {\n return [];\n }\n const projects: string[] = [];\n for (const entry of entries) {\n if (entry.endsWith(\".sqlite\")) {\n projects.push(entry.slice(0, -\".sqlite\".length));\n }\n }\n return projects;\n}\n\n/**\n * Drop a project's store from the cache (closing its handle) AND delete the\n * on-disk DB file. Idempotent: a missing project is a no-op. The caller\n * MUST pass `confirm: true` -- this is the rule-48 explicit-confirm\n * invariant for destructive operations; never defaulted to proceed.\n */\nexport async function deleteCodegraphProject(params: {\n readonly config: PluginConfig;\n readonly memoryDir: string;\n readonly principal: string;\n readonly projectId: string;\n readonly confirm: boolean;\n readonly removeFile: (filePath: string) => void;\n}): Promise<{ deleted: boolean; projectId: string }> {\n const { config, memoryDir, principal, projectId, confirm, removeFile } = params;\n if (!confirm) {\n throw new CodegraphRuntimeError(\n \"confirm_required\",\n \"codegraph_delete_project requires confirm: true; destructive operations are never defaulted to proceed (rule 48)\",\n );\n }\n if (!codegraphSurfaceVisible(config)) {\n throw new CodegraphRuntimeError(\"disabled\", \"codegraph tools are disabled\");\n }\n // Thread 10 (issue #1554): build the cache key from SANITIZED values + the\n // resolved DB path so deletion finds the live entry regardless of which raw\n // projectId form (e.g. github.com/test/repo) was used to open it. Without\n // this, deleteCodegraphProject unlinks the SQLite file while the cached\n // handle stays open and subsequent reads still see the \"deleted\" graph.\n const principalSafe = sanitizePathSegment(principal);\n const projectSafe = sanitizePathSegment(projectId);\n const dbPath = resolveCodegraphDbPath({ config, memoryDir, principal, projectId });\n const key = storeCacheKey(principalSafe, projectSafe, dbPath);\n const cached = storeCache.get(key);\n if (cached !== undefined) {\n storeCache.delete(key);\n try {\n await cached.store.close();\n } catch {\n // Best-effort close; the file delete below still proceeds.\n }\n }\n // dbPath resolved above for the cache key; reuse it for the file delete.\n let deleted = false;\n try {\n removeFile(dbPath);\n deleted = true;\n } catch (err) {\n // ENOENT means the file was already absent — treat as deleted (idempotent).\n // All other errors (EACCES, EISDIR, ...) surface as deleted=false.\n const code = (err as NodeJS.ErrnoException)?.code;\n if (code === \"ENOENT\") {\n deleted = true;\n } else {\n deleted = false;\n }\n }\n return { deleted, projectId };\n}\n\n/** Drain and close every cached store. Used by the daemon shutdown path. */\nexport async function closeAllCodegraphStores(): Promise<void> {\n const entries = [...storeCache.values()];\n storeCache.clear();\n await Promise.all(\n entries.map(async (entry) => {\n try {\n await entry.store.close();\n } catch {\n // Best-effort.\n }\n }),\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Context delegate factory — returns the 4 runtime delegates bound to the\n// access-service's store resolution, so the service can spread them into the\n// CodegraphSurfaceContext in a single line (keeps access-service.ts thin —\n// ratchet rule 4: god files gain registration/delegation only).\n// ──────────────────────────────────────────────────────────────────────────\n\nexport function makeCodegraphRuntimeDelegates(): Pick<\n CodegraphSurfaceContext,\n \"runReindex\" | \"runLspResolution\" | \"reportIndexStatus\" | \"detectChanges\" | \"ingestTraces\"\n> {\n return {\n runReindex: (store, repoRoot, mode) => runCodegraphReindex({ store, repoRoot, mode }),\n reportIndexStatus: (store, repoRoot) => reportCodegraphIndexStatus({ store, repoRoot }),\n detectChanges: (store, repoRoot, head) => detectCodegraphChanges({ store, repoRoot, head }),\n ingestTraces: (store, traces) => ingestCodegraphTraces({ store, traces }),\n runLspResolution: (store, repoRoot, lspConfig) => runCodegraphLspResolution({ store, repoRoot, lspConfig }),\n };\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Runtime delegates — the surface handlers call these to invoke the real\n// @remnic/coding-graph functions (executeReindex / getIndexStatus / detect /\n// upsertEdges). Each degrades to a clean tagged outcome when the runtime or\n// the engine is unavailable, so the surface never reports stub success\n// (issue #1554 P1 fix).\n// ──────────────────────────────────────────────────────────────────────────\n\nexport type CodegraphDelegateOutcome<T> =\n | ({ ok: true } & T)\n | { ok: false; code: string; message: string };\n\n/**\n * Run a reindex via @remnic/coding-graph's executeReindex. The engine\n * (parseFile) is injected from createCodingGraphEngine; when the engine is\n * the PR1 placeholder (throws not_implemented), the outcome degrades to\n * `engine_unavailable` rather than the handler reporting stub success.\n */\nexport async function runCodegraphReindex(params: {\n readonly store: CodegraphStore;\n readonly repoRoot: string;\n readonly mode: string;\n}): Promise<CodegraphDelegateOutcome<{ mode: string; filesIngested: number; head: string | null }>> {\n const mod = await resolveCodegraphModule();\n if (mod === null) {\n return { ok: false, code: \"package_missing\", message: \"The @remnic/coding-graph package is not installed.\" };\n }\n // Thread 13 (issue #1554): defaultCodingGitInvoker is a FACTORY FUNCTION\n // (returns the CodingGitInvoker), not an object instance. The previous\n // `typeof ... !== \"object\"` check always failed, so codegraph_index /\n // codegraph_index_status degraded to runtime_unavailable even with the\n // optional package present.\n if (typeof mod.executeReindex !== \"function\" || typeof mod.defaultCodingGitInvoker !== \"function\") {\n return { ok: false, code: \"runtime_unavailable\", message: \"executeReindex is not available in the installed @remnic/coding-graph.\" };\n }\n const git = (mod.defaultCodingGitInvoker as () => unknown)() as {\n listTrackedFiles(cwd: string): { ok: true; paths: readonly string[] } | { ok: false; code: string };\n };\n let engine: { parseFile(input: unknown): Promise<unknown> };\n try {\n if (typeof mod.createCodingGraphEngine !== \"function\") {\n return { ok: false, code: \"engine_unavailable\", message: \"createCodingGraphEngine is not exported by @remnic/coding-graph.\" };\n }\n engine = mod.createCodingGraphEngine();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"engine_unavailable\", message: `The coding-graph engine is not ready: ${msg}` };\n }\n // Thread 14 (issue #1554): executeReindex's full-reindex branch treats an\n // omitted candidatePaths as non-authoritative and returns a noop with\n // filesIngested:0. Discover the repo's tracked files via the git invoker\n // and pass them so a first index of a real repo actually ingests files.\n let candidatePaths: readonly string[] = [];\n try {\n const tracked = git.listTrackedFiles(params.repoRoot);\n if (tracked.ok) {\n candidatePaths = tracked.paths;\n }\n // A git failure here is non-fatal: executeReindex will noop cleanly and\n // the caller sees filesIngested:0 rather than a false error. The status\n // tool reports the underlying git mode separately.\n } catch {\n // Best-effort discovery; leave candidatePaths empty on throw.\n }\n try {\n const result = (await mod.executeReindex({\n store: params.store,\n git,\n repoRoot: params.repoRoot,\n parseFile: (input: unknown) => engine.parseFile(input),\n candidatePaths,\n })) as { ok: boolean; mode?: string; filesIngested?: number; head?: string | null; code?: string; message?: string };\n if (result && result.ok === true) {\n return { ok: true, mode: result.mode ?? \"auto\", filesIngested: result.filesIngested ?? 0, head: result.head ?? null };\n }\n return {\n ok: false,\n code: (result?.code as string) ?? \"store_error\",\n message: (result?.message as string) ?? \"executeReindex reported a failure.\",\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"store_error\", message: msg };\n }\n}\n\n\n/**\n * True when a tracked path resolves — via a symlinked file or any symlinked\n * parent — outside repoRoot. Mirrors the reindex path's guard (reindex.ts\n * `symlinkEscapesRoot`, rule 3): without it, a tracked `*.ts` symlink to a\n * private file outside the checkout would be parsed and sent to a language\n * server. A realpath error returns false so the normal read path surfaces\n * the natural failure.\n */\nasync function lspPathEscapesRoot(repoRoot: string, absPath: string): Promise<boolean> {\n try {\n const [realRoot, realAbs] = await Promise.all([realpath(repoRoot), realpath(absPath)]);\n const rel = path.relative(realRoot, realAbs);\n return rel === \"..\" || rel.startsWith(\"..\" + path.sep) || path.isAbsolute(rel);\n } catch {\n return false;\n }\n}\n\n/** Sync variant for the executor's resolveContent seam. */\nfunction lspPathEscapesRootSync(repoRoot: string, absPath: string): boolean {\n try {\n const realRoot = realpathSync(repoRoot);\n const realAbs = realpathSync(absPath);\n const rel = path.relative(realRoot, realAbs);\n return rel === \"..\" || rel.startsWith(\"..\" + path.sep) || path.isAbsolute(rel);\n } catch {\n return false;\n }\n}\n\n/**\n * Default LSP server launch specs per language. The config's\n * `codingKnowledge.lsp.servers` overrides these; a language with neither\n * an override nor a default is skipped (degradation, not an error).\n */\nconst DEFAULT_LSP_SERVERS: Record<string, { command: string; args: string[] }> = {\n typescript: { command: \"typescript-language-server\", args: [\"--stdio\"] },\n tsx: { command: \"typescript-language-server\", args: [\"--stdio\"] },\n javascript: { command: \"typescript-language-server\", args: [\"--stdio\"] },\n python: { command: \"pyright-langserver\", args: [\"--stdio\"] },\n go: { command: \"gopls\", args: [] },\n rust: { command: \"rust-analyzer\", args: [] },\n};\n\n/** One gathered candidate call site (pre-planner shape). */\ninterface GatheredLspSite {\n filePath: string;\n language: string;\n content: string;\n calleeByteOffset: number;\n calleeName: string;\n srcQualifiedName: string;\n}\n\n/**\n * Run LSP type resolution after a heuristic reindex (issue #1917).\n * Re-parses tracked files, gathers call sites Phase A left unresolved\n * (member accesses plus bare calls with no existing CALLS edge), groups\n * them by language, and per language connects a real language server via\n * `LspClient.connect` and invokes `executeLspResolution`.\n *\n * Degrades cleanly at every seam: missing package/functions, no language\n * server for a language, or a failed handshake all leave the heuristic\n * edges standing (soft-fail, mirrors #1894's documented posture).\n */\nexport async function runCodegraphLspResolution(params: {\n readonly store: CodegraphStore;\n readonly repoRoot: string;\n readonly lspConfig: NonNullable<CodingKnowledgeConfig[\"lsp\"]>;\n}): Promise<\n | {\n ok: true;\n upgraded: number;\n unresolved: number;\n budgetExhausted: number;\n degradations?: Array<{ language: string; code: string; message: string }>;\n }\n | { ok: false; code: string; message: string }\n> {\n const mod = await resolveCodegraphModule();\n if (mod === null) {\n return { ok: false, code: \"package_missing\", message: \"@remnic/coding-graph is not installed.\" };\n }\n if (\n typeof mod.executeLspResolution !== \"function\" ||\n typeof mod.planLspUpgrades !== \"function\" ||\n typeof mod.LspClient?.connect !== \"function\"\n ) {\n return { ok: false, code: \"runtime_unavailable\", message: \"LSP resolution is not available in the installed @remnic/coding-graph.\" };\n }\n const engine = mod.createCodingGraphEngine?.() ?? null;\n if (engine === null) {\n return { ok: false, code: \"engine_unavailable\", message: \"createCodingGraphEngine is not available.\" };\n }\n // Resolve to an absolute root up front: the executor builds file://\n // URIs by joining workspaceRoot, and a relative root (\".\") would yield\n // malformed URIs like file://src/foo.ts (review thread). The reindex\n // path resolves relative cwd values the same way.\n const repoRoot = path.resolve(params.repoRoot);\n const gitFactory = mod.defaultCodingGitInvoker as\n | (() => { listTrackedFiles(cwd: string): { ok: true; paths: readonly string[] } | { ok: false; code: string } })\n | undefined;\n if (typeof gitFactory !== \"function\") {\n return { ok: true, upgraded: 0, unresolved: 0, budgetExhausted: 0 };\n }\n const tracked = gitFactory().listTrackedFiles(repoRoot);\n if (!(\"paths\" in tracked)) {\n return { ok: true, upgraded: 0, unresolved: 0, budgetExhausted: 0 };\n }\n\n // Memoized per-caller lookup of already-resolved callee names: a bare\n // call whose (src)-[CALLS]->(dst.name == callee) edge already exists was\n // resolved by Phase A and must not consume LSP budget (review thread:\n // budget starvation). Member accesses are Phase A's deliberate skips —\n // always candidates.\n // Provenance matters: only HEURISTIC edges mark a site as Phase-A\n // resolved. A site whose only edge is a prior \"lsp\" edge MUST be\n // re-planned — excluding it from the plan while reconciling the file\n // would retire that still-valid lsp edge (review thread). When the\n // installed store predates resolvedCalleeNames, nothing is treated as\n // resolved (conservative: spends budget, never mis-retires).\n // Memo key includes the caller FILE: duplicate top-level qualified\n // names across files must not leak each other's resolutions.\n const resolvedCalleesBySrc = new Map<string, Set<string>>();\n const alreadyResolved = (filePath: string, srcQualifiedName: string, calleeName: string): boolean => {\n const key = `${filePath}\\u0000${srcQualifiedName}`;\n let names = resolvedCalleesBySrc.get(key);\n if (names === undefined) {\n names = new Set<string>();\n if (typeof params.store.resolvedCalleeNames === \"function\") {\n for (const name of params.store.resolvedCalleeNames(srcQualifiedName, \"heuristic\", filePath)) {\n names.add(name);\n }\n }\n resolvedCalleesBySrc.set(key, names);\n }\n return names.has(calleeName);\n };\n\n // Gather unresolved call sites from the freshly indexed source.\n const sites: GatheredLspSite[] = [];\n const gatheredCountByFile = new Map<string, number>();\n // Sites excluded because Phase A already resolved them (heuristic edge).\n // A file with ANY filtered site must not reconcile: those sites are not\n // in the asserted set, so reconciliation would retire their prior lsp\n // edges even though the sites were never re-queried (review thread).\n const filteredCountByFile = new Map<string, number>();\n // Caller symbols of filtered sites per file — their CURRENT lsp edges\n // are appended to the asserted set at reconcile time so stale cleanup\n // still runs for the rest of the file without dropping them.\n const filteredSrcByFile = new Map<string, Map<string, Set<string>>>();\n // Files that parsed cleanly this run — the safe candidates for the\n // empty-set reconcile below.\n const parsedFiles = new Set<string>();\n for (const rel of tracked.paths) {\n const absPath = path.join(repoRoot, rel);\n // Same symlink containment the reindex path enforces (rule 3).\n if (await lspPathEscapesRoot(repoRoot, absPath)) continue;\n let content: string;\n try {\n content = await readFile(absPath, \"utf-8\");\n } catch {\n continue;\n }\n let parsed: unknown;\n try {\n parsed = await engine.parseFile({ path: rel, content });\n } catch {\n continue;\n }\n if (!parsed || typeof parsed !== \"object\" || !(\"ok\" in parsed) || parsed.ok !== true || !(\"ir\" in parsed)) continue;\n const ir = parsed.ir;\n if (!ir || typeof ir !== \"object\" || !(\"callSites\" in ir) || !Array.isArray(ir.callSites)) continue;\n parsedFiles.add(rel);\n const language = \"language\" in ir && typeof ir.language === \"string\" ? ir.language : \"\";\n const symbols = \"symbols\" in ir && Array.isArray(ir.symbols) ? ir.symbols : [];\n // UTF-8 view of the source for byte-exact callee-name searches.\n const contentBytes = Buffer.from(content, \"utf-8\");\n for (const site of ir.callSites) {\n if (!site || typeof site !== \"object\" || !(\"span\" in site)) continue;\n const span = site.span;\n if (!span || typeof span !== \"object\" || !(\"startByte\" in span) || typeof span.startByte !== \"number\") continue;\n const calleeName =\n \"calleeNameCandidates\" in site && Array.isArray(site.calleeNameCandidates) && typeof site.calleeNameCandidates[0] === \"string\"\n ? site.calleeNameCandidates[0]\n : \"\";\n if (calleeName.length === 0) continue;\n // Innermost enclosing symbol = SMALLEST containing span (review\n // thread: first-match picks the outermost container for nested\n // symbols, attaching edges to the wrong caller).\n let srcQualifiedName = \"\";\n let bestSpanSize = Number.POSITIVE_INFINITY;\n for (const sym of symbols) {\n if (!sym || typeof sym !== \"object\" || !(\"span\" in sym) || !(\"qualifiedName\" in sym)) continue;\n const ss = sym.span;\n if (!ss || typeof ss !== \"object\" || !(\"startByte\" in ss) || !(\"endByte\" in ss)) continue;\n if (typeof ss.startByte !== \"number\" || typeof ss.endByte !== \"number\") continue;\n if (ss.startByte <= span.startByte && span.startByte < ss.endByte) {\n const size = ss.endByte - ss.startByte;\n if (size < bestSpanSize) {\n bestSpanSize = size;\n srcQualifiedName = typeof sym.qualifiedName === \"string\" ? sym.qualifiedName : \"\";\n }\n }\n }\n if (srcQualifiedName.length === 0) continue;\n const memberAccess = \"memberAccess\" in site && site.memberAccess === true;\n if (!memberAccess && alreadyResolved(rel, srcQualifiedName, calleeName)) {\n filteredCountByFile.set(rel, (filteredCountByFile.get(rel) ?? 0) + 1);\n let srcs = filteredSrcByFile.get(rel);\n if (srcs === undefined) {\n srcs = new Map<string, Set<string>>();\n filteredSrcByFile.set(rel, srcs);\n }\n const callees = srcs.get(srcQualifiedName);\n if (callees === undefined) srcs.set(srcQualifiedName, new Set([calleeName]));\n else callees.add(calleeName);\n continue;\n }\n // Position the definition query on the callee NAME, not the call\n // expression start (member calls: `obj.save()` must query at `save`).\n // The search runs in Buffer space because span offsets are UTF-8\n // BYTES while string indexOf returns UTF-16 code units — non-ASCII\n // source before the callee would skew a string-index search (review\n // thread). Bounded to this call site's span (parser rule 20).\n const nameIdx = contentBytes.indexOf(Buffer.from(calleeName, \"utf-8\"), span.startByte);\n const endByte = \"endByte\" in span && typeof span.endByte === \"number\" ? span.endByte : span.startByte + calleeName.length;\n const calleeByteOffset = nameIdx >= 0 && nameIdx < endByte ? nameIdx : span.startByte;\n sites.push({ filePath: rel, language, content, calleeByteOffset, calleeName, srcQualifiedName });\n gatheredCountByFile.set(rel, (gatheredCountByFile.get(rel) ?? 0) + 1);\n }\n }\n // Retire stale lsp edges for files that parsed cleanly and have NO LSP\n // candidates at all this run (e.g. a previously upgraded member call was\n // deleted while its containing function remains). The heuristic reindex\n // deliberately keeps lsp-provenance rows out of its stale-delete scope,\n // so this pass is the only owner of that cleanup (review thread). Files\n // with filtered (heuristic-resolved) sites are left alone — their prior\n // lsp edges were not re-queried.\n // Filtered (Phase-A-resolved) sites keep their CURRENT lsp edges by\n // asserting them explicitly — reconciliation can then retire genuinely\n // stale edges in the same file without dropping preserved ones. When\n // the store predates callEdgesForCaller, preservation is impossible,\n // so callers below fall back to skipping reconcile for such files.\n const canPreserve = typeof params.store.callEdgesForCaller === \"function\";\n const preservedEdgesForFile = (\n rel: string,\n ): Array<{ srcQualifiedName: string; dstQualifiedName: string; type: string }> => {\n const srcs = filteredSrcByFile.get(rel);\n if (srcs === undefined || !canPreserve) return [];\n const preserved: Array<{ srcQualifiedName: string; dstQualifiedName: string; type: string }> = [];\n for (const [src] of srcs) {\n // Preserve ONLY lsp edges that DUPLICATE a current heuristic\n // resolution (same src, same dst) — the covering edge a filtered\n // bare call still asserts today. A dstName-only match would also\n // re-assert a REMOVED member call's edge when a same-named bare\n // call stays filtered (review thread); requiring the exact\n // heuristic dst retires those while keeping the live coverage.\n // Cost: an lsp edge MORE precise than its heuristic twin (rare\n // re-export chains) is retired too — conservative, the heuristic\n // edge still represents the call.\n const heuristicDsts = new Set(\n params.store.callEdgesForCaller!(src, rel, \"heuristic\").map((e) => e.dstQualifiedName),\n );\n for (const edge of params.store.callEdgesForCaller!(src, rel, \"lsp\")) {\n if (!heuristicDsts.has(edge.dstQualifiedName)) continue;\n preserved.push({\n srcQualifiedName: edge.srcQualifiedName,\n dstQualifiedName: edge.dstQualifiedName,\n type: edge.type,\n });\n }\n }\n return preserved;\n };\n if (typeof params.store.reconcileLspEdges === \"function\") {\n for (const rel of parsedFiles) {\n if ((gatheredCountByFile.get(rel) ?? 0) !== 0) continue;\n const filteredCount = filteredCountByFile.get(rel) ?? 0;\n if (filteredCount > 0 && !canPreserve) continue;\n params.store.reconcileLspEdges(rel, preservedEdgesForFile(rel));\n }\n }\n if (sites.length === 0) {\n return { ok: true, upgraded: 0, unresolved: 0, budgetExhausted: 0 };\n }\n\n // Group by language; each group gets its own server connection. The\n // budget is shared across groups (maxRequestsPerRun is per RUN).\n const byLanguage = new Map<string, GatheredLspSite[]>();\n // Caller symbol -> FILES, for attributing apply-time skips to the file\n // batches they may belong to (the apply callback sees upgrades, not\n // files). A SET because duplicate caller qualified names can exist in\n // multiple tracked files — a skip conservatively suppresses reconcile\n // in every file that could own the skipped edge (review thread: a\n // single-file map was overwritten by the later file).\n const srcToFiles = new Map<string, Set<string>>();\n for (const site of sites) {\n const group = byLanguage.get(site.language);\n if (group === undefined) byLanguage.set(site.language, [site]);\n else group.push(site);\n const files = srcToFiles.get(site.srcQualifiedName);\n if (files === undefined) srcToFiles.set(site.srcQualifiedName, new Set([site.filePath]));\n else files.add(site.filePath);\n }\n\n const configServers = params.lspConfig.servers ?? {};\n const timeoutMs = params.lspConfig.timeoutMs ?? 3000;\n let remainingBudget = Math.max(1, Math.floor(params.lspConfig.maxRequestsPerRun ?? 500));\n const rootUri = pathToFileURL(repoRoot).href;\n // Cross-file definition targets need their bytes for position→offset\n // conversion (review thread: without resolveContent, cross-file\n // upgrades — the point of Phase B — stay unresolved).\n const resolveContent = (filePath: string): string | null => {\n const absPath = path.join(repoRoot, filePath);\n if (lspPathEscapesRootSync(repoRoot, absPath)) return null;\n try {\n return readFileSync(absPath, \"utf-8\");\n } catch {\n return null;\n }\n };\n\n let upgraded = 0;\n let unresolved = 0;\n let budgetExhausted = 0;\n const degradations: Array<{ language: string; code: string; message: string }> = [];\n for (const [language, group] of byLanguage) {\n if (remainingBudget <= 0) {\n budgetExhausted += group.length;\n continue;\n }\n const rawSpec = configServers[language] ?? DEFAULT_LSP_SERVERS[language];\n if (rawSpec === undefined) {\n // A language with candidates but no launch spec is a DIAGNOSABLE\n // gap, not ordinary unresolved calls (review thread): surface it so\n // the operator knows to configure codingKnowledge.lsp.servers.\n degradations.push({\n language,\n code: \"no_launch_spec\",\n message: `No LSP server configured for ${language} (${group.length} candidate call site(s)); set codingKnowledge.lsp.servers.${language}.`,\n });\n unresolved += group.length;\n continue;\n }\n const launchSpec = { command: rawSpec.command, args: rawSpec.args ?? [] };\n const plan = mod.planLspUpgrades(group, { maxRequests: remainingBudget });\n budgetExhausted += plan.budgetExhausted;\n remainingBudget -= plan.requests.length;\n if (plan.requests.length === 0) continue;\n // Reconciliation is only safe for files whose gathered sites ALL made\n // it into the plan — a budget-truncated file would otherwise retire\n // valid lsp edges its omitted call sites still assert (review thread).\n const plannedCountByFile = new Map<string, number>();\n for (const req of plan.requests) {\n if (req && typeof req === \"object\" && \"filePath\" in req && typeof req.filePath === \"string\") {\n plannedCountByFile.set(req.filePath, (plannedCountByFile.get(req.filePath) ?? 0) + 1);\n }\n }\n const connected = await mod.LspClient.connect({ launchSpec, rootUri, timeoutMs });\n if (!connected.ok) {\n // A missing/misconfigured server is a DIAGNOSABLE condition, not a\n // silent count (review thread): record the degradation so\n // codegraph_index can distinguish \"server absent\" from \"LSP found\n // no definitions\".\n const deg = connected.degradation;\n const code =\n deg && typeof deg === \"object\" && \"code\" in deg && typeof deg.code === \"string\" ? deg.code : \"connect_failed\";\n const message =\n deg && typeof deg === \"object\" && \"detail\" in deg && typeof deg.detail === \"string\"\n ? deg.detail\n : `LSP server for ${language} failed to connect.`;\n degradations.push({ language, code, message });\n unresolved += plan.requests.length;\n // The planned requests never reached a server — hand their budget\n // back so a missing server for one language cannot starve the\n // remaining language groups (review thread).\n remainingBudget += plan.requests.length;\n continue;\n }\n const client = connected.client;\n // Skip tracking keyed by FILE (via the upgrades' caller symbols):\n // a skip must (a) not count as an upgrade and (b) suppress\n // reconciliation for exactly the file batch that observed it — a\n // boolean flag went stale whenever the executor skipped a batch's\n // reconcile (non-exhaustive) or never called apply (zero upgrades)\n // (review threads).\n let skippedEdgesTotal = 0;\n const skippedFiles = new Set<string>();\n try {\n const result = await mod.executeLspResolution(plan.requests, {\n client,\n workspaceRoot: repoRoot,\n resolveContent,\n nodeLocator: (filePath: string, byteOffset: number) =>\n typeof params.store.findNodeBySpan === \"function\" ? params.store.findNodeBySpan(filePath, byteOffset) : null,\n applyUpgrades: async (upgrades: readonly CodegraphEdgeInput[]) => {\n if (typeof params.store.upsertEdges !== \"function\") {\n throw new Error(\"store.upsertEdges is not available\");\n }\n const result = await params.store.upsertEdges(upgrades);\n // Throw ONLY when nothing persisted (ok:false) — the executor's\n // transactional contract holds because no state changed. A\n // skipped>0 result has ALREADY committed the resolvable edges in\n // one transaction, so throwing after the fact would desync the\n // executor's view from the DB (skipped reconciliation +\n // undercounted upgrades while edges persist — review thread).\n // Skips are surfaced as a degradation instead of a silent drop.\n if (!result.ok) {\n // The executor catches this throw and counts the batch as\n // unresolved — record the failure as a degradation FIRST so\n // a failed write (store_closed, SQLite error) is diagnosable\n // from the index summary, not indistinguishable from\n // \"no definitions found\" (review thread).\n degradations.push({\n language,\n code: \"edge_write_failed\",\n message: `upsertEdges failed for ${language}: ${result.code}.`,\n });\n throw new Error(`upsertEdges failed: ${result.code}`);\n }\n if (result.skipped > 0) {\n skippedEdgesTotal += result.skipped;\n for (const upgrade of upgrades) {\n for (const file of srcToFiles.get(upgrade.srcQualifiedName) ?? []) {\n skippedFiles.add(file);\n }\n }\n degradations.push({\n language,\n code: \"edges_skipped\",\n message: `upsertEdges persisted ${result.persisted} and skipped ${result.skipped} edge(s) for ${language} (unresolvable endpoints).`,\n });\n }\n },\n reconcileLspEdges: (\n filePath: string,\n assertedEdges: ReadonlyArray<{ srcQualifiedName: string; dstQualifiedName: string; type: string }>,\n ) => {\n if (typeof params.store.reconcileLspEdges !== \"function\") return;\n if (plannedCountByFile.get(filePath) !== gatheredCountByFile.get(filePath)) return;\n // This file's batch had skipped writes — its asserted set is\n // incomplete, so reconciling would retire edges that were never\n // re-asserted (see skip tracking above).\n if (skippedFiles.has(filePath)) return;\n // Heuristic-filtered sites were NOT re-queried: their current\n // lsp edges are appended to the asserted set so they survive\n // while stale edges for RE-QUERIED sites still get retired.\n // Without the preservation seam, skip (conservative).\n if ((filteredCountByFile.get(filePath) ?? 0) > 0 && !canPreserve) return;\n params.store.reconcileLspEdges(filePath, [...assertedEdges, ...preservedEdgesForFile(filePath)]);\n },\n });\n if (result && typeof result === \"object\" && \"upgraded\" in result && typeof result.upgraded === \"number\") {\n // The executor counts every upgrade it HANDED to applyUpgrades;\n // subtract the writes the store skipped so the reported number\n // reflects edges that actually persisted (review thread).\n upgraded += Math.max(0, result.upgraded - skippedEdgesTotal);\n unresolved += \"unresolved\" in result && typeof result.unresolved === \"number\" ? result.unresolved : 0;\n budgetExhausted += \"budgetExhausted\" in result && typeof result.budgetExhausted === \"number\" ? result.budgetExhausted : 0;\n // A mid-run server crash / protocol error returns counts PLUS a\n // degradation tag — dropping it would make the failure look like\n // ordinary unresolved calls (review thread).\n if (\"degradation\" in result && result.degradation && typeof result.degradation === \"object\") {\n const rd = result.degradation;\n degradations.push({\n language,\n code: \"code\" in rd && typeof rd.code === \"string\" ? rd.code : \"lsp_degraded\",\n message: \"detail\" in rd && typeof rd.detail === \"string\" ? rd.detail : `LSP pass for ${language} degraded mid-run.`,\n });\n }\n } else {\n unresolved += plan.requests.length;\n }\n } catch (err) {\n // Sanitized detail only (class name + Node error code) — this\n // message reaches client surfaces via result.lsp and must not leak\n // absolute paths or stack fragments (review thread; mirrors\n // displayErrorDetail's contract). The full error is recoverable\n // from server logs, not from the tool response.\n const detail = displayErrorDetail(err);\n return {\n ok: false,\n code: \"lsp_resolution_error\",\n message: detail.length > 0 ? `LSP resolution failed: ${detail}.` : \"LSP resolution failed.\",\n };\n } finally {\n const disposable = client as { dispose?: () => Promise<void> };\n if (typeof disposable.dispose === \"function\") {\n try {\n await disposable.dispose();\n } catch {\n // Disposal failure is not actionable — the child process is\n // reaped by the OS when the parent exits.\n }\n }\n }\n }\n return {\n ok: true,\n upgraded,\n unresolved,\n budgetExhausted,\n ...(degradations.length > 0 ? { degradations } : {}),\n };\n}\n\n/**\n * Report index status via @remnic/coding-graph's getIndexStatus. Never throws\n * — a git failure degrades to `mode: \"git_unavailable\"` in the status body.\n */\nexport async function reportCodegraphIndexStatus(params: {\n readonly store: CodegraphStore;\n readonly repoRoot: string;\n}): Promise<CodegraphDelegateOutcome<{ status: Record<string, unknown> }>> {\n const mod = await resolveCodegraphModule();\n if (mod === null) {\n return { ok: false, code: \"package_missing\", message: \"The @remnic/coding-graph package is not installed.\" };\n }\n // Thread 13 (issue #1554): defaultCodingGitInvoker is a factory function.\n if (typeof mod.getIndexStatus !== \"function\" || typeof mod.defaultCodingGitInvoker !== \"function\") {\n return { ok: false, code: \"runtime_unavailable\", message: \"getIndexStatus is not available in the installed @remnic/coding-graph.\" };\n }\n const git = (mod.defaultCodingGitInvoker as () => unknown)();\n try {\n const status = mod.getIndexStatus(params.store, git, params.repoRoot) as Record<string, unknown>;\n return { ok: true, status };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"store_error\", message: msg };\n }\n}\n\n/**\n * Detect changes + blast radius. Gathers the diff, fresh-parses changed\n * files, finds directly-affected symbols, and computes blast radius. When\n * the engine is the PR1 placeholder, degrades to `engine_unavailable`.\n */\nexport async function detectCodegraphChanges(params: {\n readonly store: CodegraphStore;\n readonly repoRoot: string;\n readonly head: string;\n}): Promise<CodegraphDelegateOutcome<{ affected: readonly unknown[] }>> {\n const mod = await resolveCodegraphModule();\n if (mod === null) {\n return { ok: false, code: \"package_missing\", message: \"The @remnic/coding-graph package is not installed.\" };\n }\n if (typeof mod.computeBlastRadius !== \"function\") {\n return { ok: false, code: \"runtime_unavailable\", message: \"computeBlastRadius is not available in the installed @remnic/coding-graph.\" };\n }\n // The full detect-changes pipeline (gather hunks → fresh parse → find\n // affected → blast radius) needs a real engine. When the engine is the\n // PR1 placeholder the surface degrades honestly. The wiring here is real:\n // once the engine lands (#1551 PR2), this path returns live results.\n let engine: { parseFile(input: unknown): Promise<unknown> };\n try {\n if (typeof mod.createCodingGraphEngine !== \"function\") {\n return { ok: false, code: \"engine_unavailable\", message: \"createCodingGraphEngine is not exported by @remnic/coding-graph.\" };\n }\n engine = mod.createCodingGraphEngine();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"engine_unavailable\", message: `The coding-graph engine is not ready: ${msg}` };\n }\n void engine;\n void params;\n // Without a full hunk-gathering + fresh-parse pipeline wired through the\n // runtime yet, compute blast radius over an empty affected set so the\n // store read path is exercised. The pipeline's missing middle (hunk\n // gathering) lands with the engine in #1551 PR2; until then this is an\n // honest empty result, NOT a stub success claiming affected symbols.\n try {\n const result = mod.computeBlastRadius(params.store, new Set<string>()) as { ok: boolean; affected?: unknown[]; code?: string };\n if (result && result.ok === true) {\n return { ok: true, affected: result.affected ?? [] };\n }\n return { ok: false, code: (result?.code as string) ?? \"store_error\", message: \"computeBlastRadius reported a failure.\" };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"store_error\", message: msg };\n }\n}\n\n/**\n * Persist runtime call traces as HTTP_CALLS edges via the store's\n * standalone upsertEdges write path. Each trace is mapped to an edge with\n * provenance \"trace\"; edges whose endpoints do not resolve to an indexed\n * node are counted in `skipped` (returned to the caller) rather than\n * silently dropped.\n */\nexport async function ingestCodegraphTraces(params: {\n readonly store: CodegraphStore;\n readonly traces: readonly unknown[];\n}): Promise<CodegraphDelegateOutcome<{ accepted: number; persisted: number; skipped: number }>> {\n if (typeof params.store.upsertEdges !== \"function\") {\n return {\n ok: false,\n code: \"runtime_unavailable\",\n message: \"The installed @remnic/coding-graph does not expose upsertEdges; traces cannot be persisted.\",\n };\n }\n const edges: CodegraphEdgeInput[] = [];\n let accepted = 0;\n for (const trace of params.traces) {\n const t = trace as { caller?: string; callee?: string; confidence?: number };\n if (typeof t?.caller !== \"string\" || typeof t?.callee !== \"string\") {\n // Malformed trace — skip (the surface validates traces is an array;\n // individual trace shape is validated here so a bad row does not\n // abort the whole batch).\n continue;\n }\n accepted += 1;\n edges.push({\n srcQualifiedName: t.caller,\n dstQualifiedName: t.callee,\n type: \"HTTP_CALLS\",\n confidence: typeof t.confidence === \"number\" && t.confidence >= 0 && t.confidence <= 1 ? t.confidence : 0.5,\n provenance: \"trace\",\n });\n }\n try {\n const result = await params.store.upsertEdges(edges);\n if (result.ok === true) {\n return { ok: true, accepted, persisted: result.persisted, skipped: result.skipped };\n }\n return { ok: false, code: result.code, message: \"store.upsertEdges reported a failure.\" };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { ok: false, code: \"store_error\", message: msg };\n }\n}\n\n\n/**\n * Derive a stable per-repo project id from an absolute repoRoot (issue #1554\n * review threads 7/9/11). Used by the shared store resolver when a caller\n * invokes a codegraph tool with repoRoot but no explicit project and no\n * session coding context (e.g. a standalone stdio-MCP call). The `root:<hex>`\n * form matches the coding-context id convention so a derived id is\n * distinguishable from an `origin:<hex>` remote id. Centralized here so every\n * store-backed tool derives the SAME id and can reopen the DB index created.\n */\nexport function deriveCodegraphProjectId(repoRoot: string): string {\n return `root:${createHash(\"sha256\").update(repoRoot).digest(\"hex\").slice(0, 16)}`;\n}\n\n/**\n * Resolve the project id for a store-backed codegraph tool from a surface\n * request (issue #1554 review threads 7/9/11). This is the SHARED chokepoint\n * every store-backed tool funnels through, so index / search_graph /\n * get_schema / index_status all reopen the SAME DB:\n * 1. an explicit `project` wins;\n * 2. else a session coding context's projectId;\n * 3. else a stable `root:<hex>` derived from `repoRoot` (standalone callers);\n * 4. else a TAGGED `project_required` error (never a plain Error, so the\n * surface maps it into a structured response rather than an unstructured\n * tool error).\n *\n * The request shape is structural (not the surfaces' CodegraphSurfaceRequest\n * type) to keep this module free of a runtime import cycle with the surfaces.\n */\nexport function resolveCodegraphProjectId(params: {\n readonly request: { readonly project?: unknown; readonly sessionKey?: unknown; readonly repoRoot?: unknown };\n readonly getCodingContext: (sessionKey: string) => { readonly projectId: string } | null;\n}): string {\n const { request, getCodingContext } = params;\n const explicit = typeof request.project === \"string\" ? request.project.trim() : \"\";\n if (explicit.length > 0) return explicit;\n const sessionKey = typeof request.sessionKey === \"string\" ? request.sessionKey.trim() : \"\";\n if (sessionKey.length > 0) {\n const cc = getCodingContext(sessionKey);\n if (cc !== null) return cc.projectId;\n }\n const repoRoot = typeof request.repoRoot === \"string\" ? request.repoRoot.trim() : \"\";\n if (repoRoot.length > 0) return deriveCodegraphProjectId(repoRoot);\n throw new CodegraphRuntimeError(\n \"project_required\",\n \"codegraph: project must be supplied explicitly, via a session coding context, or alongside a repoRoot\",\n );\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Tagged runtime error -- `code` is the load-bearing signal (rule 34)\n// ──────────────────────────────────────────────────────────────────────────\n\nexport type CodegraphRuntimeErrorCode =\n | \"disabled\"\n | \"package_missing\"\n | \"repo_root_conflict\"\n | \"confirm_required\"\n | \"project_required\"\n | \"project_not_found\"\n | \"store_error\";\n\nexport class CodegraphRuntimeError extends Error {\n readonly code: CodegraphRuntimeErrorCode;\n constructor(code: CodegraphRuntimeErrorCode, message: string) {\n super(message);\n this.name = \"CodegraphRuntimeError\";\n this.code = code;\n }\n}\n\n// Re-export the gate predicate's input type for callers that only need the\n// config slice (e.g. surface modules that receive CodingKnowledgeConfig).\nexport type { CodingKnowledgeConfig, CodingContext };\n","/**\n * Decision records — pure storage contract (issue #1548 Track A PR 1).\n *\n * The four-memory-shape memory layer stores architectural decisions as\n * markdown files with YAML frontmatter under the coding namespace. This\n * module is the **pure contract**: data shape, parse, serialise, validate,\n * and the supersede mutation. No filesystem, no orchestrator — callers\n * (PR 2's MCP/HTTP/CLI surfaces and the orchestrator's normal persist\n * pipeline) hang these helpers onto real storage.\n *\n * Why markdown + frontmatter?\n * - QMD searches the body for free (rule 43 — storage chokepoint means the\n * orchestrator persist pipeline fires for catalog + reindex + dedup).\n * - Human-reviewable diff via the same tooling as any other memory page.\n * - The body carries prose; the frontmatter carries the searchable,\n * structured fields.\n *\n * Why this parser/serialiser and not a YAML dep?\n * - The surface used here is intentionally narrow: scalar strings and\n * flow-style arrays of strings. A full YAML dependency is heavier than\n * the parser we need and would unlock a footgun (block-scalar\n * representations, anchors, multiple-document streams) we deliberately\n * want to be impossible.\n *\n * Supersede ordering (rule 25): the replacement record MUST land on disk\n * BEFORE the superseded record's `status` flips, so a process crash between\n * the two writes leaves the new decision discoverable rather than nothing.\n *\n * Pure module — type-only import of the plugin config interface keeps this\n * dependency-free (the entry types live in `../types.ts`).\n */\nimport type { CodingKnowledgeConfig } from \"../types.js\";\n\n// ──────────────────────────────────────────────────────────────────────────\n// Public types\n// ──────────────────────────────────────────────────────────────────────────\n\nexport type DecisionStatus = \"proposed\" | \"accepted\" | \"superseded\" | \"rejected\";\n\nexport const DECISION_STATUSES = [\n \"proposed\",\n \"accepted\",\n \"superseded\",\n \"rejected\",\n] as const satisfies readonly DecisionStatus[];\n\n/**\n * The \"active\" statuses callers surface in standing-decisions lists, briefing\n * text, and the search-by-default index. Exported as a frozen set so the\n * decision-records tests, the briefing helper, and the future list surface\n * share one declaration (rule 53 — single source of truth for classification).\n *\n * Stand-up note: superseded + rejected are intentionally excluded. A supersede\n * edge (`b.supersedes = \"a\"`) tells callers what to fall back to.\n */\nexport const ACTIVE_DECISION_STATUSES: ReadonlySet<DecisionStatus> = new Set<DecisionStatus>([\n \"proposed\",\n \"accepted\",\n]);\n\n/**\n * Least-privileged default for a parsed record whose frontmatter omits\n * `status` (rule 48). \"Proposed\" — never \"accepted\" — because accepting a\n * decision is a deliberate operator action.\n */\nexport const DEFAULT_DECISION_STATUS: DecisionStatus = \"proposed\";\n\nexport interface DecisionRecord {\n /** Stable identifier — typically `ADR-XXXX` or `MADR-XXXX`. Must be unique. */\n id: string;\n /** One-line summary surfaced in briefings and `list` output. */\n title: string;\n /** Status lifecycle (rule 51: only the four declared values). */\n status: DecisionStatus;\n /** The problem / context the decision addresses. */\n context: string;\n /** The decision itself. */\n decision: string;\n /** Trade-offs, follow-ups, consequences. Optional — free-form. */\n consequences: string | undefined;\n /** Entity references (entity IDs, doc anchors, code paths). May be empty. */\n entityRefs: string[];\n /** The record this one supersedes — set by `applySupersede`, never by hand. */\n supersedes?: string;\n}\n\n/**\n * Input shape for `serializeDecisionRecord`. Mirrors `DecisionRecord` but\n * keeps `supersedes` reachable so callers writing the replacement before\n * applying supersede can serialise the new record alone.\n */\nexport type DecisionRecordInput = Omit<DecisionRecord, \"supersedes\"> & {\n supersedes?: string;\n};\n\n// ──────────────────────────────────────────────────────────────────────────\n// Gate / type guard\n// ──────────────────────────────────────────────────────────────────────────\n\nconst DECISION_STATUS_BY_VALUE: Record<string, DecisionStatus> = Object.freeze({\n proposed: \"proposed\",\n accepted: \"accepted\",\n superseded: \"superseded\",\n rejected: \"rejected\",\n}) as Record<string, DecisionStatus>;\n\nexport function isDecisionStatus(value: unknown): value is DecisionStatus {\n return (\n typeof value === \"string\"\n && Object.prototype.hasOwnProperty.call(DECISION_STATUS_BY_VALUE, value)\n );\n}\n\nconst FRONTMATTER_KEYS = Object.freeze([\n \"id\",\n \"title\",\n \"status\",\n \"context\",\n \"decision\",\n \"consequences\",\n \"entityRefs\",\n \"supersedes\",\n] as const satisfies readonly (keyof DecisionRecord | \"id\")[]);\n\n// ──────────────────────────────────────────────────────────────────────────\n// Serialise\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Render a decision record as markdown with a YAML frontmatter block.\n *\n * Frontmatter keys are sorted ascending (rule 38). Strings are double-quoted\n * so reserved YAML characters (`#`, `:`, leading-digits, list-like prefixes)\n * survive a round-trip without the caller caring.\n */\nexport function serializeDecisionRecord(record: DecisionRecordInput): string {\n const lines: string[] = [\"---\"];\n for (const key of FRONTMATTER_KEYS) {\n const present =\n key === \"supersedes\"\n ? record.supersedes !== undefined\n : key === \"consequences\"\n ? record.consequences !== undefined\n : true;\n if (!present) continue;\n lines.push(`${key}: ${encodeFrontmatterValue(key, record)}`);\n }\n lines.push(\"---\", \"\");\n if (record.context) lines.push(record.context);\n lines.push(\"\");\n lines.push(\"# Decision\");\n lines.push(\"\");\n if (record.decision) lines.push(record.decision);\n if (record.consequences !== undefined && record.consequences.length > 0) {\n lines.push(\"\");\n lines.push(\"# Consequences\");\n lines.push(\"\");\n lines.push(record.consequences);\n }\n if (record.entityRefs.length > 0) {\n lines.push(\"\");\n lines.push(\"# Entity references\");\n for (const ref of record.entityRefs) lines.push(`- ${ref}`);\n }\n // Trailing newline keeps the file POSIX-well-formed for `cat`/editors.\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nfunction encodeFrontmatterValue(\n key: (typeof FRONTMATTER_KEYS)[number],\n record: DecisionRecordInput,\n): string {\n if (key === \"entityRefs\") {\n const refs = record.entityRefs;\n if (refs.length === 0) return \"[]\";\n const inner = refs.map((ref) => `\"${escapeYamlString(ref)}\"`).join(\", \");\n return `[${inner}]`;\n }\n if (key === \"status\") return `\"${record.status}\"`;\n if (key === \"supersedes\") return `\"${record.supersedes ?? \"\"}\"`;\n if (key === \"consequences\") return `\"${escapeYamlString(record.consequences ?? \"\")}\"`;\n const value = record[key];\n return `\"${escapeYamlString(typeof value === \"string\" ? value : String(value))}\"`;\n}\n\nfunction escapeYamlString(value: string): string {\n // Inside a double-quoted YAML scalar, escape backslashes and double-quotes\n // AND emit real newlines as a `\\n` escape (the parser below mirrors this).\n // Keeping all scalars single-line makes the line-based frontmatter parser\n // safe and the file diff-friendly.\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\");\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Parse\n// ──────────────────────────────────────────────────────────────────────────\n\ninterface ParsedFrontmatter {\n readonly fields: Readonly<Record<string, unknown>>;\n readonly body: string;\n}\n\n/**\n * Parse a decision record from a markdown string with a YAML frontmatter\n * block. Throws (with a message listing the valid statuses, rule 51) when\n * the document does not match the contract.\n *\n * Missing / undefined `status` defaults to `\"proposed\"` (rule 48 — least\n * privileged).\n */\nexport function parseDecisionRecord(raw: string): DecisionRecord {\n const { fields, body } = extractFrontmatter(raw);\n\n // Surface unexpected keys early — silent drift is rule 51's worst case.\n for (const fieldKey of Object.keys(fields)) {\n if (!FRONTMATTER_KEYS.includes(fieldKey as (typeof FRONTMATTER_KEYS)[number])) {\n throw new Error(\n `decision record frontmatter contains unknown key '${fieldKey}'; valid keys are ${FRONTMATTER_KEYS.join(\", \")}.`,\n );\n }\n }\n\n const id = requireString(fields.id, \"id\");\n const title = requireString(fields.title, \"title\");\n const context = requireString(fields.context, \"context\");\n const decision = requireString(fields.decision, \"decision\");\n const consequences =\n fields.consequences === undefined ? undefined : requireString(fields.consequences, \"consequences\");\n\n let status: DecisionStatus = DEFAULT_DECISION_STATUS;\n if (fields.status !== undefined && fields.status !== null) {\n if (!isDecisionStatus(fields.status)) {\n throw new Error(\n `decision '${id}' has invalid status '${JSON.stringify(fields.status)}'; valid statuses are ${DECISION_STATUSES.join(\", \")}.`,\n );\n }\n status = fields.status;\n }\n\n const entityRefs = parseEntityRefs(fields.entityRefs);\n const supersedes =\n fields.supersedes === undefined ? undefined : requireString(fields.supersedes, \"supersedes\");\n\n // The parser is intentionally permissive about the on-disk shape. A\n // record with `status: \"superseded\"` and no `supersedes` field is the\n // shape `applySupersede` writes for the replaced record — the\n // `supersedes` edge lives on the *replacement*, not the superseded one,\n // so this branch must accept the canonical serialised form and stay\n // round-trippable. Excluding superseded records from \"active\" listings is\n // `listActive`'s job (rule 53, single classification source), not the\n // parser's.\n\n const record: DecisionRecord = {\n id,\n title,\n status,\n context,\n decision,\n consequences,\n entityRefs,\n ...(supersedes !== undefined ? { supersedes } : {}),\n };\n // Body is preserved byte-for-byte on serialise; we don't introspect it\n // here so format-neutral round-trips stay open (rule 38).\n void body;\n return record;\n}\n\nfunction requireString(field: unknown, key: string): string {\n if (field === undefined || field === null) {\n throw new Error(`decision record frontmatter is missing required field '${key}'.`);\n }\n if (typeof field !== \"string\") {\n throw new Error(\n `decision record frontmatter field '${key}' must be a string; got ${JSON.stringify(field)}.`,\n );\n }\n return field;\n}\n\nfunction parseEntityRefs(field: unknown): string[] {\n if (field === undefined) return [];\n if (!Array.isArray(field)) {\n throw new Error(\n `decision record frontmatter field 'entityRefs' must be an array of strings; got ${JSON.stringify(field)}.`,\n );\n }\n for (const entry of field) {\n if (typeof entry !== \"string\") {\n throw new Error(\n `decision record frontmatter 'entityRefs' entries must be strings; got ${JSON.stringify(entry)}.`,\n );\n }\n }\n return [...field];\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// YAML frontmatter subset (intentionally narrow)\n// ──────────────────────────────────────────────────────────────────────────\n\nfunction extractFrontmatter(raw: string): ParsedFrontmatter {\n const text = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;\n if (!text.startsWith(\"---\\n\")) {\n throw new Error(\n \"decision record must start with a YAML frontmatter fence (`---\\\\n`); got a document with no leading fence.\",\n );\n }\n const closeAt = text.indexOf(\"\\n---\", 4);\n if (closeAt === -1) {\n throw new Error(\n \"decision record frontmatter is missing its closing fence (`\\\\n---`); the document is truncated.\",\n );\n }\n const yamlBody = text.slice(4, closeAt);\n const after = text.slice(closeAt + 4);\n const body = after.startsWith(\"\\n\") ? after.slice(1) : after;\n return { fields: parseYamlMapping(yamlBody), body };\n}\n\nfunction parseYamlMapping(input: string): Record<string, unknown> {\n const fields: Record<string, unknown> = {};\n for (const rawLine of input.split(\"\\n\")) {\n const line = rawLine.trimEnd();\n if (line.length === 0 || line.startsWith(\"#\")) continue;\n const colonAt = line.indexOf(\":\");\n if (colonAt === -1) {\n throw new Error(`decision record frontmatter line is not a key:value pair: \"${line}\".`);\n }\n const key = line.slice(0, colonAt).trim();\n const valueText = line.slice(colonAt + 1).trim();\n if (key.length === 0) {\n throw new Error(`decision record frontmatter has an empty key in line: \"${line}\".`);\n }\n fields[key] = decodeScalar(valueText);\n }\n return fields;\n}\n\nfunction decodeScalar(valueText: string): unknown {\n if (valueText.length === 0) return \"\";\n const lower = valueText.toLowerCase();\n if (lower === \"true\") return true;\n if (lower === \"false\") return false;\n if (lower === \"null\" || lower === \"~\") return null;\n if (/^-?\\d+$/.test(valueText)) return Number(valueText);\n if (/^\".*\"$/.test(valueText)) {\n // Restore escapes — order matters: handle the backslash-pair first so\n // the literal `\\\\n` we emit from `escapeYamlString` decodes to a real\n // newline (NOT a backslash-n).\n return valueText\n .slice(1, -1)\n .replace(/\\\\\\\\/g, \"\\u0000\")\n .replace(/\\\\n/g, \"\\n\")\n .replace(/\\\\\"/g, '\"')\n .replace(/\\u0000/g, \"\\\\\");\n }\n if (/^\\[.*\\]$/.test(valueText)) return parseFlowList(valueText);\n return valueText;\n}\n\nfunction parseFlowList(valueText: string): unknown[] {\n const inner = valueText.slice(1, -1).trim();\n if (inner.length === 0) return [];\n const out: string[] = [];\n let buf = \"\";\n let inQuotes = false;\n // Track whether we are sitting on a backslash so that `\\\"` inside a\n // quoted element is recognised as an escaped quote rather than a\n // closing quote. Without this flag, a ref containing a literal `\"`\n // (e.g. an entity id like `org/dept/\\\"lead\\\"`) would close its own\n // element early and the next comma would split a string in half\n // (cursor bug d16b2a18, review round on PR #1590).\n let escaped = false;\n for (let i = 0; i < inner.length; i += 1) {\n const c = inner[i]!;\n if (escaped) {\n buf += c;\n escaped = false;\n continue;\n }\n if (c === \"\\\\\") {\n buf += c;\n escaped = true;\n continue;\n }\n if (c === '\"') {\n inQuotes = !inQuotes;\n buf += c;\n continue;\n }\n if (c === \",\" && !inQuotes) {\n out.push(stripFlowStringQuotes(buf.trim()));\n buf = \"\";\n continue;\n }\n buf += c;\n }\n if (buf.length > 0) out.push(stripFlowStringQuotes(buf.trim()));\n return out;\n}\n\nfunction stripFlowStringQuotes(value: string): string {\n if (value.length >= 2 && value.startsWith('\"') && value.endsWith('\"')) {\n return value\n .slice(1, -1)\n .replace(/\\\\\\\\/g, \"\\u0000\")\n .replace(/\\\\n/g, \"\\n\")\n .replace(/\\\\\"/g, '\"')\n .replace(/\\u0000/g, \"\\\\\");\n }\n return value;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Supersede\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Pure supersede mutation: given the current record set, the id of a record\n * to supersede, and the replacement record (already accepted), returns a new\n * list with the replacement appended and the old record flipped to\n * `superseded`.\n *\n * The hook fires `event: \"write:<replacementId>\"` BEFORE\n * `event: \"mutate:<oldId>:superseded\"` so storage callers can guarantee\n * disk-order matches the rule-25 requirement (the replacement lands before\n * the old record's status flips).\n */\nexport function applySupersede(\n records: readonly DecisionRecord[],\n targetId: string,\n replacement: DecisionRecord,\n hook?: (event: string) => void,\n): DecisionRecord[] {\n const target = records.find((r) => r.id === targetId);\n if (!target) {\n throw new Error(\n `applySupersede cannot find target record '${targetId}' in the current record set.`,\n );\n }\n // Reject a collision where `replacement.id` already exists in the record\n // set. Without this guard, an operator typo or MCP rename can silently\n // overwrite an unrelated decision with a record that `supersedes` itself,\n // corrupting the decision history (chatgpt-codex-connector review on\n // PR #1590). The replacement must either be a NEW id (append) or the\n // same id as the target (in-place replacement — supported as a separate\n // edge case below).\n const existing = records.find((r) => r.id === replacement.id);\n if (existing && replacement.id !== targetId) {\n throw new Error(\n `applySupersede replacement id '${replacement.id}' already exists in the record set; ` +\n `pick a new id to avoid silently overwriting an unrelated decision.`,\n );\n }\n const next: DecisionRecord[] = records.map((r) =>\n r.id === targetId\n ? { ...r, status: \"superseded\" as DecisionStatus, supersedes: undefined }\n : r,\n );\n const replacementWithEdge: DecisionRecord = { ...replacement, supersedes: targetId };\n // Same-id replacement path: a single record swaps its body in place. The\n // entry keeps its place in the array (so the listing order is preserved)\n // and the new record still carries the supersede edge for traceability.\n if (replacement.id === targetId) {\n const idx = next.findIndex((r) => r.id === targetId);\n next[idx] = replacementWithEdge;\n } else {\n next.push(replacementWithEdge);\n }\n\n hook?.(`write:${replacement.id}`);\n hook?.(`mutate:${targetId}:superseded`);\n\n return next;\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Listing\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Filter a record set down to \"standing\" decisions (proposed + accepted).\n * Uses the explicitly-exported `ACTIVE_DECISION_STATUSES` set (rule 53 — one\n * classification source) so callers cannot drift.\n */\nexport function listActive(records: readonly DecisionRecord[]): DecisionRecord[] {\n return records.filter((r) => ACTIVE_DECISION_STATUSES.has(r.status));\n}\n\n// ──────────────────────────────────────────────────────────────────────────\n// Coding-knowledge feature gate (Track A PR 1 wiring boundary)\n// ──────────────────────────────────────────────────────────────────────────\n\n/**\n * Single source of truth for \"are decision records active for this operator?\"\n * (rule 39 — every behaviour dependent on Track A consults this, not raw\n * config reads). The master gate is `codingKnowledge.enabled`; the\n * decision-record subsystem has its own on-switch.\n */\nexport function isDecisionRecordsEnabled(config: CodingKnowledgeConfig): boolean {\n return config.enabled === true && config.decisionRecords === true;\n}\n"],"mappings":"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","names":["readFile","path","readFile","path","store","path","readFile","result"]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
tagPersistedMemories
|
|
3
|
+
} from "./chunk-TB2MJRI6.js";
|
|
1
4
|
import {
|
|
2
5
|
hasBroadGraphIntent,
|
|
3
6
|
planRecallMode
|
|
@@ -16,7 +19,7 @@ import {
|
|
|
16
19
|
} from "./chunk-6Q3ZTEF6.js";
|
|
17
20
|
import {
|
|
18
21
|
resolveScopeProfilePlan
|
|
19
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ESNFSSO4.js";
|
|
20
23
|
import {
|
|
21
24
|
parseFlexibleIsoTimestamp
|
|
22
25
|
} from "./chunk-P7FMDTKL.js";
|
|
@@ -30,7 +33,7 @@ import {
|
|
|
30
33
|
} from "./chunk-JUOZ62Y7.js";
|
|
31
34
|
import {
|
|
32
35
|
resolveCodingNamespaceOverlay
|
|
33
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-QBC33MPY.js";
|
|
34
37
|
import {
|
|
35
38
|
abortError,
|
|
36
39
|
throwIfAborted
|
|
@@ -1572,6 +1575,7 @@ ${normalized}`).digest("hex");
|
|
|
1572
1575
|
log.warn("runExtraction: durable-commit callback failed", error);
|
|
1573
1576
|
}
|
|
1574
1577
|
const runPostPersistBestEffort = runExtractionPostPersistBestEffort.bind(null, runDeadlineAware);
|
|
1578
|
+
await tagPersistedMemories(storage, persistedIds, this.config);
|
|
1575
1579
|
const postPersist = await runExtractionPostPersist({
|
|
1576
1580
|
result,
|
|
1577
1581
|
storage,
|
|
@@ -1708,4 +1712,4 @@ export {
|
|
|
1708
1712
|
ExtractionDeadlineError,
|
|
1709
1713
|
ExtractionRunCoordinator
|
|
1710
1714
|
};
|
|
1711
|
-
//# sourceMappingURL=chunk-
|
|
1715
|
+
//# sourceMappingURL=chunk-RDGKVH6T.js.map
|