@hawkeyexl/manni 4.5.0 → 4.6.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/README.md +1 -1
- package/dist/batch-OZOACN4G.js +41 -0
- package/dist/build-Z5VOVADH.js +32 -0
- package/dist/calibrate-TZYT42DR.js +36 -0
- package/dist/capture-SL4MNDDP.js +34 -0
- package/dist/check-5OMA42Y6.js +26 -0
- package/dist/{check-ESNS7ZBC.js → check-OAJWC3WD.js} +7 -5
- package/dist/{check-RQIIIURI.js → check-PKY7KTQE.js} +13 -14
- package/dist/check-WB2QDHJQ.js +880 -0
- package/dist/check-WB2QDHJQ.js.map +1 -0
- package/dist/{chunk-F2OVHJNC.js → chunk-2JFPBZJK.js} +11 -11
- package/dist/{chunk-CP4ZM43V.js → chunk-2KRB3EG7.js} +2 -2
- package/dist/{chunk-QLUMKWQQ.js → chunk-2M6DVNI5.js} +10 -6
- package/dist/{chunk-QLUMKWQQ.js.map → chunk-2M6DVNI5.js.map} +1 -1
- package/dist/{chunk-HQFVJDEN.js → chunk-3NWX34ZI.js} +19 -19
- package/dist/{chunk-TCC737IS.js → chunk-5G53XATW.js} +4 -4
- package/dist/{chunk-B7XUEQF3.js → chunk-6KKZXB2O.js} +7 -5
- package/dist/{chunk-B7XUEQF3.js.map → chunk-6KKZXB2O.js.map} +1 -1
- package/dist/{chunk-SNEHX4VE.js → chunk-733Y2STG.js} +2 -2
- package/dist/{chunk-ELZ2IIOF.js → chunk-73TC4DYH.js} +2 -2
- package/dist/{chunk-QY3DOZMS.js → chunk-7WRP5FFP.js} +4 -4
- package/dist/{chunk-3R5Y3XOL.js → chunk-APKH2T6E.js} +29 -591
- package/dist/chunk-APKH2T6E.js.map +1 -0
- package/dist/{chunk-FLF6AECQ.js → chunk-B3TS4WRM.js} +17 -15
- package/dist/{chunk-FLF6AECQ.js.map → chunk-B3TS4WRM.js.map} +1 -1
- package/dist/chunk-BWCWTHYS.js +146 -0
- package/dist/chunk-BWCWTHYS.js.map +1 -0
- package/dist/{chunk-C6HZ6C5T.js → chunk-C3B2VJNC.js} +2 -2
- package/dist/{chunk-NN4ASVTY.js → chunk-C73RSUIC.js} +4 -4
- package/dist/chunk-CU57HT2E.js +116 -0
- package/dist/chunk-CU57HT2E.js.map +1 -0
- package/dist/chunk-CWXZ2MRT.js +222 -0
- package/dist/chunk-CWXZ2MRT.js.map +1 -0
- package/dist/{chunk-GAZFKZHM.js → chunk-DC5DDJVE.js} +6 -6
- package/dist/{chunk-52PDIZKV.js → chunk-ECVQNGTH.js} +3 -3
- package/dist/chunk-FLAO4ZS3.js +502 -0
- package/dist/chunk-FLAO4ZS3.js.map +1 -0
- package/dist/chunk-FQGLRJGX.js +174 -0
- package/dist/chunk-FQGLRJGX.js.map +1 -0
- package/dist/{chunk-XWFNO5PO.js → chunk-GAJIJKET.js} +3 -3
- package/dist/{chunk-QCBICNKC.js → chunk-GREQKO6M.js} +202 -54
- package/dist/chunk-GREQKO6M.js.map +1 -0
- package/dist/chunk-HX44GB4Z.js +30 -0
- package/dist/chunk-HX44GB4Z.js.map +1 -0
- package/dist/{chunk-7ZUCEMCY.js → chunk-IY7NYNPZ.js} +9 -11
- package/dist/{chunk-7ZUCEMCY.js.map → chunk-IY7NYNPZ.js.map} +1 -1
- package/dist/{chunk-527HHQPS.js → chunk-KCOFEWV5.js} +6 -4
- package/dist/{chunk-527HHQPS.js.map → chunk-KCOFEWV5.js.map} +1 -1
- package/dist/chunk-M2RLHZ4J.js +849 -0
- package/dist/chunk-M2RLHZ4J.js.map +1 -0
- package/dist/{chunk-K3U5F2QT.js → chunk-M6GSS72T.js} +12 -12
- package/dist/{chunk-UK2I3ACY.js → chunk-MHM4QEBV.js} +4 -4
- package/dist/{chunk-EL2BZTDL.js → chunk-MOWMCEOJ.js} +13 -11
- package/dist/{chunk-EL2BZTDL.js.map → chunk-MOWMCEOJ.js.map} +1 -1
- package/dist/{chunk-OIZ3XMKB.js → chunk-MWBJ3KTF.js} +4 -4
- package/dist/chunk-N7JSEDSC.js +233 -0
- package/dist/chunk-N7JSEDSC.js.map +1 -0
- package/dist/{chunk-MZC62HPZ.js → chunk-NBMPHD4I.js} +2 -2
- package/dist/{chunk-YA63PVWI.js → chunk-NHHOPZRA.js} +12 -10
- package/dist/{chunk-YA63PVWI.js.map → chunk-NHHOPZRA.js.map} +1 -1
- package/dist/{chunk-DX32P2DT.js → chunk-NTWW7J76.js} +2 -2
- package/dist/{chunk-6XTQDFGP.js → chunk-PCFG7E6B.js} +3 -3
- package/dist/{chunk-6XTQDFGP.js.map → chunk-PCFG7E6B.js.map} +1 -1
- package/dist/{chunk-SJO2FTPG.js → chunk-PL4UAF4S.js} +73 -1304
- package/dist/chunk-PL4UAF4S.js.map +1 -0
- package/dist/chunk-QCHVR4ZM.js +286 -0
- package/dist/chunk-QCHVR4ZM.js.map +1 -0
- package/dist/{chunk-JQU7FHYH.js → chunk-QW77LCOU.js} +10 -10
- package/dist/{chunk-IA7BMIPE.js → chunk-SM6NOMJS.js} +2 -2
- package/dist/{chunk-DE7JSWXV.js → chunk-SWSTHZBI.js} +8 -6
- package/dist/{chunk-DE7JSWXV.js.map → chunk-SWSTHZBI.js.map} +1 -1
- package/dist/{chunk-NGK3N6F2.js → chunk-T6SYGLWR.js} +3 -3
- package/dist/chunk-TH4JVQPF.js +133 -0
- package/dist/chunk-TH4JVQPF.js.map +1 -0
- package/dist/{chunk-TVIX653Q.js → chunk-TLXE7LYK.js} +4 -4
- package/dist/{chunk-HVFR66GQ.js → chunk-TUAAR3MM.js} +3280 -283
- package/dist/chunk-TUAAR3MM.js.map +1 -0
- package/dist/{chunk-TA42STP7.js → chunk-UAKNZVCD.js} +4 -4
- package/dist/{chunk-C3KI45RF.js → chunk-UJSGS2Y5.js} +4 -4
- package/dist/{chunk-ZX43SRZR.js → chunk-UWQ2UVHE.js} +8 -6
- package/dist/{chunk-ZX43SRZR.js.map → chunk-UWQ2UVHE.js.map} +1 -1
- package/dist/chunk-WQWKYAAK.js +86 -0
- package/dist/chunk-WQWKYAAK.js.map +1 -0
- package/dist/{chunk-LJ2RDH3F.js → chunk-XG6PVB5S.js} +1 -23
- package/dist/chunk-XG6PVB5S.js.map +1 -0
- package/dist/{chunk-Q35YIDBV.js → chunk-XKBEHKWO.js} +29 -264
- package/dist/chunk-XKBEHKWO.js.map +1 -0
- package/dist/chunk-XPEWUK7J.js +532 -0
- package/dist/chunk-XPEWUK7J.js.map +1 -0
- package/dist/{chunk-BOIF2XGG.js → chunk-XXDXIIQ4.js} +2 -2
- package/dist/chunk-YLK2J5YK.js +610 -0
- package/dist/chunk-YLK2J5YK.js.map +1 -0
- package/dist/{chunk-7OQAU4EA.js → chunk-Z4IZGEM3.js} +16 -12
- package/dist/{chunk-7OQAU4EA.js.map → chunk-Z4IZGEM3.js.map} +1 -1
- package/dist/{cli-E3H6ZP4I.js → cli-6EWVMEN6.js} +5 -3
- package/dist/{cli-E3H6ZP4I.js.map → cli-6EWVMEN6.js.map} +1 -1
- package/dist/{cli-MHTYPVOD.js → cli-6H7HVDMQ.js} +113 -20
- package/dist/{cli-MHTYPVOD.js.map → cli-6H7HVDMQ.js.map} +1 -1
- package/dist/{cli-HUIMNJT6.js → cli-EPVZHAZS.js} +19 -20
- package/dist/{cli-HUIMNJT6.js.map → cli-EPVZHAZS.js.map} +1 -1
- package/dist/{cli-6PGVHP7Y.js → cli-LUCSGTVI.js} +17 -19
- package/dist/{cli-6PGVHP7Y.js.map → cli-LUCSGTVI.js.map} +1 -1
- package/dist/{cli-PRZHQ3QB.js → cli-NIG4N3XM.js} +14 -15
- package/dist/{cli-PRZHQ3QB.js.map → cli-NIG4N3XM.js.map} +1 -1
- package/dist/{cli-TYGOHJOJ.js → cli-PSKNB66T.js} +225 -58
- package/dist/cli-PSKNB66T.js.map +1 -0
- package/dist/{cli-QKIJOXGW.js → cli-UO4NHIB3.js} +17 -17
- package/dist/{cli-AAG3N4NB.js → cli-UQ7A3YA2.js} +17 -18
- package/dist/{cli-AAG3N4NB.js.map → cli-UQ7A3YA2.js.map} +1 -1
- package/dist/{cli-YW6VWBHX.js → cli-YHYDLQAF.js} +10 -10
- package/dist/cli.js +11 -11
- package/dist/config-P4HDNTYD.js +26 -0
- package/dist/conformance-ZFCMKM6M.js +18 -0
- package/dist/docmeta.js +9 -9
- package/dist/github-7ZCH5PSO.js +26 -0
- package/dist/github-POT6724K.js +31 -0
- package/dist/host-6GURH5HE.js +23 -0
- package/dist/index.d.ts +72 -4
- package/dist/index.js +176 -166
- package/dist/index.js.map +1 -1
- package/dist/{json-4DCKDGUV.js → json-KT2K62L5.js} +12 -13
- package/dist/lint-5AQ5C2BV.js +29 -0
- package/dist/list-5JZKX2NK.js +28 -0
- package/dist/list-SWPFXQMU.js +30 -0
- package/dist/{page-QEDB7EVU.js → page-UPSXRP75.js} +11 -12
- package/dist/prepare-6GNEWCNH.js +155 -0
- package/dist/prepare-6GNEWCNH.js.map +1 -0
- package/dist/{pretty-SQX33UM2.js → pretty-Q6FQAOK4.js} +13 -14
- package/dist/{pretty-5DGEBZSV.js → pretty-SQRPFPSQ.js} +12 -13
- package/dist/provider-AMGRDY6V.js +34 -0
- package/dist/release-IECYCLTD.js +36 -0
- package/dist/release-IECYCLTD.js.map +1 -0
- package/dist/{reporters-OHSI3RMV.js → reporters-45MMC2ID.js} +11 -12
- package/dist/{reporters-YELDDYJD.js → reporters-XUV4MM64.js} +7 -5
- package/dist/reporters-XUV4MM64.js.map +1 -0
- package/dist/run-KMWY2IAN.js +32 -0
- package/dist/run-KMWY2IAN.js.map +1 -0
- package/dist/{term-2WMDZ4PY.js → term-PCJUCWNF.js} +16 -17
- package/dist/{term-2WMDZ4PY.js.map → term-PCJUCWNF.js.map} +1 -1
- package/dist/validate-IMNCZNWG.js +17 -0
- package/dist/validate-IMNCZNWG.js.map +1 -0
- package/package.json +2 -2
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/plugin/manni/hooks/hooks.json +47 -0
- package/dist/batch-GOE3UXOD.js +0 -36
- package/dist/build-M7BMEHL2.js +0 -33
- package/dist/calibrate-6RRAILUY.js +0 -31
- package/dist/capture-RJPQ6B4N.js +0 -32
- package/dist/check-BQD64X3N.js +0 -27
- package/dist/chunk-3R5Y3XOL.js.map +0 -1
- package/dist/chunk-3YHAYXBC.js +0 -164
- package/dist/chunk-3YHAYXBC.js.map +0 -1
- package/dist/chunk-HVFR66GQ.js.map +0 -1
- package/dist/chunk-LJ2RDH3F.js.map +0 -1
- package/dist/chunk-NAZRLJAK.js +0 -3090
- package/dist/chunk-NAZRLJAK.js.map +0 -1
- package/dist/chunk-Q35YIDBV.js.map +0 -1
- package/dist/chunk-QCBICNKC.js.map +0 -1
- package/dist/chunk-SJO2FTPG.js.map +0 -1
- package/dist/chunk-TU2WUBVZ.js +0 -2
- package/dist/cli-TYGOHJOJ.js.map +0 -1
- package/dist/github-3WMSTNTK.js +0 -32
- package/dist/github-OXSJQ4PS.js +0 -27
- package/dist/lint-YDHVVZHT.js +0 -30
- package/dist/list-3ZO2NIYO.js +0 -31
- package/dist/list-EJH6VAOW.js +0 -29
- package/dist/run-IP6NZHAG.js +0 -33
- package/dist/validate-G6HH3YXL.js +0 -16
- /package/dist/{batch-GOE3UXOD.js.map → batch-OZOACN4G.js.map} +0 -0
- /package/dist/{build-M7BMEHL2.js.map → build-Z5VOVADH.js.map} +0 -0
- /package/dist/{calibrate-6RRAILUY.js.map → calibrate-TZYT42DR.js.map} +0 -0
- /package/dist/{capture-RJPQ6B4N.js.map → capture-SL4MNDDP.js.map} +0 -0
- /package/dist/{check-BQD64X3N.js.map → check-5OMA42Y6.js.map} +0 -0
- /package/dist/{check-ESNS7ZBC.js.map → check-OAJWC3WD.js.map} +0 -0
- /package/dist/{check-RQIIIURI.js.map → check-PKY7KTQE.js.map} +0 -0
- /package/dist/{chunk-F2OVHJNC.js.map → chunk-2JFPBZJK.js.map} +0 -0
- /package/dist/{chunk-CP4ZM43V.js.map → chunk-2KRB3EG7.js.map} +0 -0
- /package/dist/{chunk-HQFVJDEN.js.map → chunk-3NWX34ZI.js.map} +0 -0
- /package/dist/{chunk-TCC737IS.js.map → chunk-5G53XATW.js.map} +0 -0
- /package/dist/{chunk-SNEHX4VE.js.map → chunk-733Y2STG.js.map} +0 -0
- /package/dist/{chunk-ELZ2IIOF.js.map → chunk-73TC4DYH.js.map} +0 -0
- /package/dist/{chunk-QY3DOZMS.js.map → chunk-7WRP5FFP.js.map} +0 -0
- /package/dist/{chunk-C6HZ6C5T.js.map → chunk-C3B2VJNC.js.map} +0 -0
- /package/dist/{chunk-NN4ASVTY.js.map → chunk-C73RSUIC.js.map} +0 -0
- /package/dist/{chunk-GAZFKZHM.js.map → chunk-DC5DDJVE.js.map} +0 -0
- /package/dist/{chunk-52PDIZKV.js.map → chunk-ECVQNGTH.js.map} +0 -0
- /package/dist/{chunk-XWFNO5PO.js.map → chunk-GAJIJKET.js.map} +0 -0
- /package/dist/{chunk-K3U5F2QT.js.map → chunk-M6GSS72T.js.map} +0 -0
- /package/dist/{chunk-UK2I3ACY.js.map → chunk-MHM4QEBV.js.map} +0 -0
- /package/dist/{chunk-OIZ3XMKB.js.map → chunk-MWBJ3KTF.js.map} +0 -0
- /package/dist/{chunk-MZC62HPZ.js.map → chunk-NBMPHD4I.js.map} +0 -0
- /package/dist/{chunk-DX32P2DT.js.map → chunk-NTWW7J76.js.map} +0 -0
- /package/dist/{chunk-JQU7FHYH.js.map → chunk-QW77LCOU.js.map} +0 -0
- /package/dist/{chunk-IA7BMIPE.js.map → chunk-SM6NOMJS.js.map} +0 -0
- /package/dist/{chunk-NGK3N6F2.js.map → chunk-T6SYGLWR.js.map} +0 -0
- /package/dist/{chunk-TVIX653Q.js.map → chunk-TLXE7LYK.js.map} +0 -0
- /package/dist/{chunk-TA42STP7.js.map → chunk-UAKNZVCD.js.map} +0 -0
- /package/dist/{chunk-C3KI45RF.js.map → chunk-UJSGS2Y5.js.map} +0 -0
- /package/dist/{chunk-BOIF2XGG.js.map → chunk-XXDXIIQ4.js.map} +0 -0
- /package/dist/{cli-QKIJOXGW.js.map → cli-UO4NHIB3.js.map} +0 -0
- /package/dist/{chunk-TU2WUBVZ.js.map → cli-YHYDLQAF.js.map} +0 -0
- /package/dist/{cli-YW6VWBHX.js.map → config-P4HDNTYD.js.map} +0 -0
- /package/dist/{github-3WMSTNTK.js.map → conformance-ZFCMKM6M.js.map} +0 -0
- /package/dist/{github-OXSJQ4PS.js.map → github-7ZCH5PSO.js.map} +0 -0
- /package/dist/{json-4DCKDGUV.js.map → github-POT6724K.js.map} +0 -0
- /package/dist/{lint-YDHVVZHT.js.map → host-6GURH5HE.js.map} +0 -0
- /package/dist/{list-3ZO2NIYO.js.map → json-KT2K62L5.js.map} +0 -0
- /package/dist/{list-EJH6VAOW.js.map → lint-5AQ5C2BV.js.map} +0 -0
- /package/dist/{page-QEDB7EVU.js.map → list-5JZKX2NK.js.map} +0 -0
- /package/dist/{pretty-5DGEBZSV.js.map → list-SWPFXQMU.js.map} +0 -0
- /package/dist/{pretty-SQX33UM2.js.map → page-UPSXRP75.js.map} +0 -0
- /package/dist/{reporters-OHSI3RMV.js.map → pretty-Q6FQAOK4.js.map} +0 -0
- /package/dist/{reporters-YELDDYJD.js.map → pretty-SQRPFPSQ.js.map} +0 -0
- /package/dist/{run-IP6NZHAG.js.map → provider-AMGRDY6V.js.map} +0 -0
- /package/dist/{validate-G6HH3YXL.js.map → reporters-45MMC2ID.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tracevals/commands/check.ts","../src/tracevals/rules/judge.ts","../src/tracevals/rules/judge-prompt.ts","../src/tracevals/rules/timeline.ts"],"sourcesContent":["/**\n * `manni tracevals check <trace>`: judge the last turn of one session against\n * the rules that governed it (proposal 0079). `checkTurn` is the same\n * judgement inside a Stop or SubagentStop hook, with the hook's model and\n * every gate of \"When tracevals stays out of the way\".\n *\n * Both are read-only over the trace and the sources. What they write is the\n * rules cache and the verdict cache, under `judge.cacheDir`. The hook also\n * writes the session ledger, for every turn it parses, which `check` by hand\n * only reads and sums up.\n */\nimport { writeFile } from \"node:fs/promises\";\nimport { basename, resolve } from \"node:path\";\nimport type { InferenceProvider, ProviderName } from \"@hawkeyexl/inference\";\nimport { discoverConfig, type TracevalsConfig } from \"../core/config.js\";\nimport {\n constructProvider,\n resolveSelectionIdentity,\n selectHookProvider,\n selectProvider,\n type ProviderSelection,\n} from \"../judge/provider.js\";\nimport { renderCheck } from \"../reporters/conformance.js\";\nimport type { SummaryFormat } from \"../reporters/index.js\";\nimport { hostHolds, hostSetting, queued, QUEUE_WAIT_MS, type HostApi } from \"../rules/host.js\";\nimport {\n allVerdictsCached,\n applicableRules,\n judgeTurn,\n StateLimits,\n TurnCache,\n type TurnFinding,\n type TurnJudgement,\n type TurnRule,\n} from \"../rules/judge.js\";\nimport { ruleKey } from \"../rules/judge-prompt.js\";\nimport {\n ledgerPath,\n readLedger,\n recordFacts,\n recordTurn,\n rollup,\n turnFacts,\n writeLedger,\n type Ledger,\n type LedgerOutcome,\n type SessionRollup,\n} from \"../rules/ledger.js\";\nimport { warn } from \"../../shared/warn.js\";\nimport { libraryLocalModels, type LocalModels } from \"../rules/local.js\";\nimport { mockTurnJudge } from \"../rules/mock.js\";\nimport { resolveTurnSources, type RuleSource } from \"../rules/sources.js\";\nimport { lastTurn, subagentTurn, type TurnSlice } from \"../rules/turn.js\";\nimport { parseTraceFile } from \"../trace/claude.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport { TracevalsError } from \"../types.js\";\nimport {\n assertDownloaded,\n conformanceOf,\n extraction,\n firstLine,\n isNetworkProvider,\n JUDGE_ENV,\n localGate,\n markJudgeProcess,\n offlineRefusal,\n rulesCacheFor,\n type GateSkip,\n type Identity,\n type LocalGate,\n} from \"./conformance.js\";\n\n/** Why a judgement stopped short, as the report's `skipped` names it. */\nexport type CheckSkip = \"empty-turn\" | \"no-sources\" | \"not-applicable\";\n\n/** Every gate a hook can stop at, in the proposal's order. */\nexport type HookGate =\n | \"not-in-play\"\n | \"judge-session\"\n | CheckSkip\n | LocalGate\n | \"busy\";\n\nexport interface CheckSourceEntry {\n path: string;\n format: RuleSource[\"format\"];\n skill?: string;\n trigger: string;\n rules: number;\n origin: \"declared\" | \"extracted\";\n}\n\nexport interface CheckReport {\n trace: string;\n sessionId: string;\n /** The subagent a SubagentStop judged, or null for the main session. */\n agentId: string | null;\n turn: { from: number; to: number };\n /** Null when the run stopped before a judge was asked. */\n judge: { provider: string; model: string; mode: TurnJudgement[\"mode\"]; runs: number } | null;\n /** Null when no source needed the extraction model. */\n extraction: { provider: string; model: string } | null;\n sources: CheckSourceEntry[];\n /** Only `fail` and `needs-review`. */\n findings: TurnFinding[];\n summary: { sources: number; rules: number; notApplicable: number; fail: number; needsReview: number };\n /** By hand, the session ledger summed up per rule. Null when it holds nothing, and under a hook. */\n session: SessionRollup | null;\n skipped: CheckSkip | null;\n warnings: string[];\n exitCode: number;\n}\n\n/** Test seams; production builds every one of these from config. */\ninterface Seams {\n /** The judge, in place of the selected provider. */\n judge?: InferenceProvider;\n /** The extraction model, in place of the out-of-loop provider. */\n extractor?: InferenceProvider;\n localModels?: LocalModels;\n /** The model host's calls, in place of the library's. */\n hostApi?: HostApi;\n}\n\ninterface Params extends Seams {\n config: TracevalsConfig;\n configDir: string;\n trace: Trace;\n turn: TurnSlice;\n sessionId: string;\n agentId: string | null;\n agentType?: string;\n projectDir: string;\n projectRoot?: string;\n env?: Record<string, string | undefined>;\n judgeSelection: ProviderSelection;\n runs: number;\n inLoop: boolean;\n noCache: boolean;\n offline: boolean;\n lastAssistantMessage?: string;\n}\n\ntype Outcome =\n | { kind: \"report\"; report: CheckReport; judgement?: TurnJudgement }\n | { kind: \"gate\"; skip: GateSkip<HookGate> };\n\nconst idOf = (p: InferenceProvider): Identity => ({\n provider: p.provider() as ProviderName,\n model: p.modelName(),\n});\n\nconst LEDGER_OUTCOME: Record<TurnJudgement[\"verdicts\"][number][\"outcome\"], LedgerOutcome> = {\n fail: \"broken\",\n followed: \"followed\",\n \"needs-review\": \"needs-review\",\n \"not-applicable\": \"not-applicable\",\n};\n\n/** How far a run got, for the ledger. */\ninterface Seen {\n sources: RuleSource[];\n judgement?: TurnJudgement;\n}\n\n/**\n * The pipeline both modes run, with the session ledger around it. The hook\n * records every turn it parses, judged or not. By hand the ledger is only\n * read, and summed up for the report.\n */\nasync function conform(p: Params): Promise<Outcome> {\n const ledgerFile = ledgerPath(p.projectDir, p.sessionId, p.agentId);\n const ledger = await readLedger(ledgerFile);\n const seen: Seen = { sources: [] };\n const outcome = await judgeTurnOf(p, ledger, seen);\n if (p.inLoop) await record(p, ledgerFile, ledger, seen);\n else if (outcome.kind === \"report\") outcome.report.session = rollup(ledger);\n return outcome;\n}\n\n/** This turn's facts, and its verdicts when it was judged. A failed write warns. */\nasync function record(p: Params, file: string, ledger: Ledger, seen: Seen): Promise<void> {\n const facts = turnFacts(p.trace, p.turn, seen.sources, {\n cwd: p.projectDir,\n root: p.projectRoot ?? p.projectDir,\n redact: p.config.judge.redact,\n });\n let next = recordFacts(ledger, facts);\n if (seen.judgement !== undefined) {\n next = recordTurn(\n next,\n p.turn.from,\n seen.judgement.verdicts.map((v) => ({\n key: ruleKey(v.source, v.rule),\n text: v.text,\n outcome: LEDGER_OUTCOME[v.outcome],\n note: v.reasoning ?? \"\",\n })),\n );\n }\n try {\n await writeLedger(file, next);\n } catch (err) {\n warn(`could not write the session ledger ${file}: ${firstLine(err)}`);\n }\n}\n\n/** Sources, extraction, the judge. */\nasync function judgeTurnOf(p: Params, ledger: Ledger, seen: Seen): Promise<Outcome> {\n const { config, turn } = p;\n const conformance = conformanceOf(config);\n const local = p.localModels ?? libraryLocalModels(config.providers);\n const report: CheckReport = {\n trace: p.trace.file,\n sessionId: p.sessionId,\n agentId: p.agentId,\n turn: { from: turn.from, to: turn.to },\n judge: null,\n extraction: null,\n sources: [],\n findings: [],\n summary: { sources: 0, rules: 0, notApplicable: 0, fail: 0, needsReview: 0 },\n session: null,\n skipped: null,\n warnings: [...p.trace.warnings],\n exitCode: 0,\n };\n const stop = (skipped: CheckSkip): Outcome => {\n report.skipped = skipped;\n return { kind: \"report\", report };\n };\n\n // Gate 3.\n if (turn.window.empty) return stop(\"empty-turn\");\n\n // Gate 4.\n const resolved = await resolveTurnSources(p.trace, turn, {\n projectDir: p.projectDir,\n ...(p.projectRoot !== undefined ? { projectRoot: p.projectRoot } : {}),\n ...(p.env !== undefined ? { env: p.env } : {}),\n include: conformance.include,\n exclude: conformance.exclude,\n plans: conformance.plans,\n ...(p.agentType !== undefined ? { agentType: p.agentType } : {}),\n });\n report.warnings.push(...resolved.warnings);\n const { sources } = resolved;\n seen.sources = sources;\n report.summary.sources = sources.length;\n if (sources.length === 0) return stop(\"no-sources\");\n\n const judgeId = p.judge !== undefined ? idOf(p.judge) : await resolveSelectionIdentity(config, p.judgeSelection);\n const judgeIsLocal = judgeId.provider === \"llama-cpp\";\n\n // Gate 5, for the judge. Extraction's own model is asked below, only when a\n // source needs it.\n if (p.inLoop && judgeIsLocal) {\n const skip = await localGate(local, judgeId.model, [\"downloading\"]);\n if (skip !== undefined) return { kind: \"gate\", skip };\n }\n\n // Extraction, between gates 4 and 6, with the out-of-loop model always.\n const host = hostSetting(p.inLoop, p.sessionId, config.providers[\"llama-cpp\"]?.keepAlive);\n const ex = await extraction(config, rulesCacheFor(config, p.configDir, p.noCache), p.extractor, host);\n if (sources.some((s) => ex.needs(s))) {\n report.extraction = { provider: ex.identity.provider, model: ex.identity.model };\n if (p.offline && isNetworkProvider(ex.identity.provider)) {\n throw offlineRefusal(\"extraction\", ex.identity);\n }\n if (ex.identity.provider === \"llama-cpp\") {\n if (p.inLoop) {\n const skip = await localGate(\n local,\n ex.identity.model,\n [\"downloading\", \"not-downloaded\", \"memory\"],\n () => hostHolds(ex.identity.model, p.hostApi),\n );\n if (skip !== undefined) return { kind: \"gate\", skip };\n } else {\n await assertDownloaded(local, ex.identity.model);\n }\n }\n }\n const rules: TurnRule[] = [];\n for (const source of sources) {\n const { rules: found, origin } = await ex.rulesOf(source);\n report.sources.push({\n path: source.displayPath,\n format: source.format,\n ...(source.skill !== undefined ? { skill: source.skill } : {}),\n trigger: source.trigger,\n rules: found.length,\n origin,\n });\n for (const rule of found) rules.push({ source, rule });\n }\n report.summary.rules = rules.length;\n\n // Gate 6.\n const { applicable } = applicableRules(rules, turn.window);\n if (applicable.length === 0) {\n report.summary.notApplicable = rules.length;\n return stop(\"not-applicable\");\n }\n\n if (p.offline && isNetworkProvider(judgeId.provider)) {\n throw offlineRefusal(\"the judge\", judgeId);\n }\n const cacheRoot = resolve(p.configDir, config.judge.cacheDir);\n const limits = new StateLimits(resolve(cacheRoot, \"limits\"), !p.noCache);\n const plan = {\n trace: p.trace,\n turn,\n rules,\n runs: p.runs,\n temperature: config.judge.temperature,\n zones: config.judge.zones,\n render: {\n maxBlockChars: config.render.maxBlockChars,\n maxTotalChars: config.render.maxTotalChars,\n redact: config.judge.redact,\n },\n ...(p.lastAssistantMessage !== undefined ? { lastAssistantMessage: p.lastAssistantMessage } : {}),\n ledger,\n project: { cwd: p.projectDir, root: p.projectRoot ?? p.projectDir },\n cache: new TurnCache(resolve(cacheRoot, \"turns\"), !p.noCache),\n };\n\n // Gates 7 and 8, model on disk and memory. The memory probe is skipped when\n // the model will not be loaded or is loaded already: every applicable\n // rule's verdict is cached (gate 9, read from the remembered state limit\n // without a provider), or the host holds the model. The verdict cache is\n // otherwise read inside judgeTurn, once the provider reports its limit.\n if (judgeIsLocal) {\n if (p.inLoop) {\n const skip = await localGate(\n local,\n judgeId.model,\n [\"not-downloaded\", \"memory\"],\n async () =>\n allVerdictsCached({ ...plan, limits }, judgeId) || (await hostHolds(judgeId.model, p.hostApi)),\n );\n if (skip !== undefined) return { kind: \"gate\", skip };\n } else {\n await assertDownloaded(local, judgeId.model);\n }\n }\n\n markJudgeProcess();\n const provider =\n p.judge ??\n (judgeId.provider === \"mock\"\n ? mockTurnJudge(judgeId.model)\n : constructProvider(config, judgeId, { host }));\n let ran: Awaited<ReturnType<typeof queued<TurnJudgement>>>;\n try {\n ran = await queued(judgeId.model, () =>\n judgeTurn({ ...plan, provider, limits }),\n );\n } catch (err) {\n if (err instanceof TracevalsError) throw err;\n throw new TracevalsError(`could not judge the last turn: ${firstLine(err)}`);\n }\n if (ran.busy) {\n return {\n kind: \"gate\",\n skip: {\n gate: \"busy\",\n message: `tracevals skipped this turn: ${judgeId.model} was busy with other judgements for ${String(QUEUE_WAIT_MS / 60_000)} minutes.`,\n },\n };\n }\n const judgement = ran.value;\n seen.judgement = judgement;\n report.judge = {\n provider: judgeId.provider,\n model: judgeId.model,\n mode: judgement.mode,\n runs: judgement.runs,\n };\n report.findings = judgement.findings;\n report.summary.notApplicable = judgement.notApplicable;\n report.summary.fail = judgement.findings.filter((f) => f.outcome === \"fail\").length;\n report.summary.needsReview = judgement.findings.length - report.summary.fail;\n report.warnings.push(...judgement.warnings);\n report.exitCode = report.summary.fail > 0 ? 1 : 0;\n return { kind: \"report\", report, judgement };\n}\n\nasync function readTrace(path: string): Promise<Trace> {\n try {\n return await parseTraceFile(path);\n } catch (err) {\n throw new TracevalsError(`cannot read trace ${path}: ${firstLine(err)}`);\n }\n}\n\n// ── By hand ──────────────────────────────────────────────────────\n\nexport interface CheckOptions extends Seams {\n tracePath: string;\n /** Project root for resolving sources; default the trace's recorded cwd. */\n project?: string;\n provider?: string;\n model?: string;\n local?: boolean;\n /** Overrides `judge.ensembleRuns`. */\n runs?: number;\n noCache?: boolean;\n offline?: boolean;\n format?: SummaryFormat;\n output?: string;\n color?: boolean;\n /** Directory holding manni.config.yaml; defaults to cwd. */\n configDir?: string;\n config?: string;\n noConfig?: boolean;\n env?: Record<string, string | undefined>;\n}\n\nexport interface CheckResult {\n report: CheckReport;\n rendered: string;\n}\n\nexport async function runCheck(options: CheckOptions): Promise<CheckResult> {\n const { config, dir: configDir } = await discoverConfig(options.configDir ?? process.cwd(), {\n ...(options.config === undefined ? {} : { configPath: options.config }),\n ...(options.noConfig === undefined ? {} : { noConfig: options.noConfig }),\n });\n const judgeSelection = selectProvider(config, {\n ...(options.provider !== undefined ? { provider: options.provider } : {}),\n ...(options.model !== undefined ? { model: options.model } : {}),\n ...(options.local !== undefined ? { local: options.local } : {}),\n });\n const trace = await readTrace(options.tracePath);\n const outcome = await conform({\n config,\n configDir,\n trace,\n turn: lastTurn(trace),\n sessionId: trace.sessionId ?? basename(trace.file).replace(/\\.jsonl$/, \"\"),\n agentId: null,\n projectDir: options.project ?? trace.cwd,\n ...(options.project !== undefined ? { projectRoot: options.project } : {}),\n ...(options.env !== undefined ? { env: options.env } : {}),\n judgeSelection,\n runs: options.runs ?? config.judge.ensembleRuns,\n inLoop: false,\n noCache: options.noCache === true,\n offline: options.offline === true,\n ...seamsOf(options),\n });\n // By hand only the report's own skips exist; the other gates act under a hook.\n if (outcome.kind === \"gate\") throw new TracevalsError(outcome.skip.message);\n const { report } = outcome;\n const rendered =\n options.format === \"json\"\n ? JSON.stringify(report, null, 2)\n : renderCheck(report, { color: options.color === true });\n if (options.output !== undefined) await writeFile(options.output, rendered, \"utf-8\");\n return { report, rendered };\n}\n\nfunction seamsOf(s: Seams): Seams {\n return {\n ...(s.judge !== undefined ? { judge: s.judge } : {}),\n ...(s.extractor !== undefined ? { extractor: s.extractor } : {}),\n ...(s.localModels !== undefined ? { localModels: s.localModels } : {}),\n ...(s.hostApi !== undefined ? { hostApi: s.hostApi } : {}),\n };\n}\n\n// ── Inside a hook ────────────────────────────────────────────────\n\n/** What a Stop or SubagentStop envelope carries, as the family hook passes it. */\nexport interface TurnCheckInput extends Seams {\n transcriptPath: string;\n /** SubagentStop: the subagent's own transcript, judged alone. */\n agentTranscriptPath?: string;\n agentId?: string;\n /** SubagentStop: the subagent type, whose definition governs the run. */\n agentType?: string;\n /** Appended when the transcript lags the Stop. */\n lastAssistantMessage?: string;\n sessionId: string;\n cwd: string;\n inLoop: true;\n /** Defaults to `process.env`; gate 2 and the source walk read it. */\n env?: Record<string, string | undefined>;\n}\n\nexport interface TurnCheckResult {\n /** The gate that ended the run. A message is set where the proposal says one. */\n skipped?: { gate: HookGate; message?: string };\n judgement?: TurnJudgement;\n /** Only `fail` and `needs-review`; empty when skipped. */\n findings: TurnFinding[];\n /** Absent for gates 1, 2, 5, 8, 9 and a busy host. */\n report?: CheckReport;\n /** 1 when a rule was broken with a confident verdict. */\n exitCode: 0 | 1;\n}\n\n/**\n * Gates 1 to 9 for one turn, then the judgement. The skip messages are said\n * once per session by the caller, which knows the session. An operational\n * failure throws a `TracevalsError`.\n */\nexport async function checkTurn(input: TurnCheckInput): Promise<TurnCheckResult> {\n const { config, dir: configDir } = await discoverConfig(input.cwd);\n // Gate 1. The transcript is not parsed.\n if (config.conformance === null) {\n return { skipped: { gate: \"not-in-play\" }, findings: [], exitCode: 0 };\n }\n // Gate 2: a judge's own session.\n const env = input.env ?? process.env;\n if ((env[JUDGE_ENV] ?? \"\") !== \"\") {\n return { skipped: { gate: \"judge-session\" }, findings: [], exitCode: 0 };\n }\n const subagent = input.agentTranscriptPath !== undefined;\n const trace = await readTrace(input.agentTranscriptPath ?? input.transcriptPath);\n const outcome = await conform({\n config,\n configDir,\n trace,\n turn: subagent ? subagentTurn(trace) : lastTurn(trace),\n sessionId: input.sessionId,\n agentId: input.agentId ?? null,\n ...(input.agentType !== undefined ? { agentType: input.agentType } : {}),\n projectDir: input.cwd,\n ...(input.env !== undefined ? { env: input.env } : {}),\n judgeSelection: selectHookProvider(config),\n runs: config.conformance.hook.runs,\n inLoop: true,\n noCache: false,\n offline: false,\n ...(input.lastAssistantMessage !== undefined\n ? { lastAssistantMessage: input.lastAssistantMessage }\n : {}),\n ...seamsOf(input),\n });\n if (outcome.kind === \"gate\") {\n return { skipped: outcome.skip, findings: [], exitCode: 0 };\n }\n const { report, judgement } = outcome;\n if (report.skipped !== null) {\n return { skipped: { gate: report.skipped }, findings: [], report, exitCode: 0 };\n }\n return {\n ...(judgement !== undefined ? { judgement } : {}),\n findings: report.findings,\n report,\n exitCode: report.exitCode === 1 ? 1 : 0,\n };\n}\n","/**\n * The turn judge (proposal 0079, \"The judge, decisions first\" and \"The block\n * bar\"). It checks one turn against the rules that governed it.\n *\n * Each rule is judged on its own, against the rendered turn. Which path runs\n * is detected from the provider, never configured. A decision-only provider\n * gets one `decide` call, one question per rule, branching from the turn.\n * Every provider that generates gets `runs` calls of `completeJSONShared`, one\n * item per rule, each answered with a sentence of reasoning and then three\n * independent scores. Both share what earlier turns of the transcript did,\n * and a scored rule's item carries what the session ledger holds for it.\n *\n * Only a confident violation blocks. Everything short of that is\n * `needs-review`, and an errored rule can only go there, never to a silent\n * pass and never to a fail.\n */\nimport {\n JsonCache,\n buildCacheKey,\n canDecide,\n completeJSONShared,\n sha256,\n type DecideAnswer,\n type DecisionProvider,\n type InferenceProvider,\n type ZoneThresholds,\n} from \"@hawkeyexl/inference\";\nimport { DECISION_ONLY_PROVIDERS } from \"../../shared/providers.js\";\nimport type { TraceWindow } from \"../graders/util.js\";\nimport { evaluateWhen } from \"../graders/when.js\";\nimport { makeRedactor } from \"../judge/redact.js\";\nimport { renderTrace } from \"../judge/render.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport type { Rule } from \"./extract.js\";\nimport {\n TURN_JUDGE_PROMPT_VERSION,\n TURN_JUDGE_SYSTEM_PROMPT,\n TURN_SCORES,\n buildDecisionState,\n buildRuleItem,\n buildTurnShared,\n questionFor,\n ruleKey,\n TURN_SCHEMA,\n type TurnScore,\n} from \"./judge-prompt.js\";\nimport { historyBlock, type Ledger } from \"./ledger.js\";\nimport type { RuleSource } from \"./sources.js\";\nimport { timelineBlock } from \"./timeline.js\";\nimport type { TurnSlice } from \"./turn.js\";\n\n/** Default location, under the tool's per-project cache directory. */\nexport const DEFAULT_TURN_CACHE_DIR = \".manni/tracevals/cache/turns\";\n\n/**\n * Characters per token when fitting a provider's state limit. Prose and code\n * run near 4 characters a token in common tokenizers, and dense text such as\n * JSON, paths and hashes runs lower. 3 errs toward a smaller render, which\n * costs evidence; erring the other way costs the request.\n */\nexport const CHARS_PER_TOKEN = 3;\n\nexport interface TurnRule {\n /** `path` lets the earlier turns say the session read the source. */\n source: Pick<RuleSource, \"displayPath\"> & Partial<Pick<RuleSource, \"path\">>;\n rule: Rule;\n}\n\nexport interface TurnJudgeInput {\n trace: Trace;\n turn: TurnSlice;\n /** Every in-scope rule, sources ordered farthest to nearest. */\n rules: TurnRule[];\n provider: InferenceProvider;\n /** Scored runs. A decision-only provider makes one call and reports 1. */\n runs: number;\n temperature: number;\n zones: ZoneThresholds;\n render: { maxBlockChars: number; maxTotalChars: number; redact: string[] };\n /** The Stop payload's `last_assistant_message`, appended when the transcript lags. */\n lastAssistantMessage?: string;\n /**\n * The session's earlier verdicts, and which earlier turns had no rule in\n * scope. Only a scored rule's item carries its own history.\n */\n ledger?: Ledger;\n /** Where paths in earlier turns are made relative; the trace's cwd by default. */\n project?: { cwd: string; root: string };\n cache?: TurnCache;\n}\n\nexport interface TurnFinding {\n source: string;\n rule: string;\n text: string;\n outcome: \"fail\" | \"needs-review\";\n observed: string;\n confidence: number;\n /** The judge's reasoning. A decision-only provider gives none. */\n reasoning?: string;\n}\n\n/** Every rule sent to the judge, with where its verdict landed. */\nexport interface TurnVerdict {\n source: string;\n rule: string;\n text: string;\n outcome: Outcome;\n reasoning?: string;\n}\n\nexport interface TurnJudgement {\n mode: \"decision\" | \"generative\";\n runs: number;\n /** Only `fail` and `needs-review`; a rule left out passed or did not apply. */\n findings: TurnFinding[];\n /** One per rule sent to the judge, whatever its outcome. */\n verdicts: TurnVerdict[];\n /** Rules sent to the judge. */\n judged: number;\n /** Rules whose `when` failed over the turn, plus those scored not applicable. */\n notApplicable: number;\n /** Every rule's verdict came from the cache. */\n cached: boolean;\n warnings: string[];\n}\n\ntype Scores = Record<TurnScore, number> & { reasoning?: string };\n\n/** One rule's answers: a score set per run that answered. */\ninterface Verdict {\n runs: Scores[];\n error?: string;\n}\n\nexport type Outcome = \"fail\" | \"not-applicable\" | \"followed\" | \"needs-review\";\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n\nfunction isScores(v: unknown): v is Scores {\n return isRecord(v) && TURN_SCORES.every((s) => typeof v[s] === \"number\");\n}\n\n/**\n * Raw scores per rule and turn, before the block bar is applied, so a change\n * of `zones` reuses them. A rule with an errored run is never written.\n */\nexport class TurnCache {\n private readonly store: JsonCache<unknown>;\n\n constructor(dir: string = DEFAULT_TURN_CACHE_DIR, enabled = true) {\n this.store = new JsonCache<unknown>(dir, enabled, \"manni-tracevals\");\n }\n\n /** An entry of any other shape, from an older version, is a miss. */\n get(key: string): Scores[] | undefined {\n const v = this.store.get(key);\n if (!isRecord(v) || !Array.isArray(v.runs) || v.runs.length === 0) return undefined;\n const runs: unknown[] = v.runs;\n return runs.every(isScores) ? runs : undefined;\n }\n\n set(key: string, runs: Scores[]): void {\n this.store.set(key, { runs });\n }\n}\n\nexport interface ModelId {\n provider: string;\n model: string;\n}\n\n/**\n * What a provider's `stateLimit()` last said, per provider and model, with\n * `null` for one that has no limit. A local model loads to report it, and the\n * limit sets how much of the turn is rendered, which the verdict key hashes. So\n * \"is every verdict cached?\" could not be answered without loading the model\n * until this remembered the answer. A stale limit costs a miss, never a wrong\n * verdict, because a hit is keyed by the text it was scored on.\n */\nexport class StateLimits {\n private readonly store: JsonCache<unknown>;\n\n constructor(dir: string, enabled = true) {\n this.store = new JsonCache<unknown>(dir, enabled, \"manni-tracevals\");\n }\n\n get(id: ModelId): number | null | undefined {\n const v = this.store.get(buildCacheKey([id.provider, id.model]));\n return isRecord(v) && (v.limit === null || typeof v.limit === \"number\") ? v.limit : undefined;\n }\n\n set(id: ModelId, limit: number | null): void {\n this.store.set(buildCacheKey([id.provider, id.model]), { limit });\n }\n}\n\n/** Gate 6: a rule whose `when` fails over the turn is skipped, never passed. */\nexport function applicableRules(\n rules: TurnRule[],\n window: TraceWindow,\n): { applicable: TurnRule[]; notApplicable: number } {\n const applicable = rules.filter(\n (r) => evaluateWhen({ when: r.rule.when }, window).armed,\n );\n return { applicable, notApplicable: rules.length - applicable.length };\n}\n\ninterface Planned {\n /** Decision question id: source index among every input source, then rule id. */\n qid: string;\n source: string;\n id: string;\n text: string;\n /** The ledger's block for this rule, \"\" for none and on the decision path. */\n history: string;\n /** The scored path's item for this rule. */\n item: string;\n}\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n/** Decision-only providers decide; every provider that generates is scored. */\nfunction decisionOnly(provider: InferenceProvider): DecisionProvider | undefined {\n return DECISION_ONLY_PROVIDERS.has(provider.provider()) && canDecide(provider)\n ? provider\n : undefined;\n}\n\n/** The input without the provider, which a gate can use before one is built. */\nexport type TurnPlanInput = Omit<TurnJudgeInput, \"provider\">;\n\ninterface Plan {\n planned: Planned[];\n turnText: string;\n /** The transcript's account of earlier turns, \"\" for none. */\n earlier: string;\n warnings: string[];\n hits: Map<Planned, Verdict>;\n todo: Planned[];\n keyOf: (p: Planned) => string;\n}\n\n/**\n * Everything short of the model call: each rule's item, the turn rendered to\n * `limit` (undefined for no limit), and the verdict cache read. `decisionOnly`\n * and `limit` are all that come from the provider, so a caller that knows both\n * can plan without one.\n */\nfunction planTurn(\n input: TurnPlanInput,\n id: ModelId,\n decisionOnly: boolean,\n limit: number | undefined,\n): Plan {\n const runs = decisionOnly ? 1 : input.runs;\n const { applicable } = applicableRules(input.rules, input.turn.window);\n const warnings: string[] = [];\n const hits = new Map<Planned, Verdict>();\n\n // Indexed over every input source, so a question id does not move when a\n // farther source's rules happen not to apply.\n const sourceIndex = new Map<string, number>();\n for (const r of input.rules) {\n const path = r.source.displayPath;\n if (!sourceIndex.has(path)) sourceIndex.set(path, sourceIndex.size);\n }\n const planned: Planned[] = applicable.map(({ source, rule }) => {\n const history =\n !decisionOnly && input.ledger !== undefined\n ? historyBlock(input.ledger, ruleKey(source.displayPath, rule.id), rule.text, input.turn.from)\n : \"\";\n return {\n qid: `${String(sourceIndex.get(source.displayPath))}:${rule.id}`,\n source: source.displayPath,\n id: rule.id,\n text: rule.text,\n history,\n item: buildRuleItem(source.displayPath, rule, history),\n };\n });\n if (planned.length === 0) {\n return { planned, turnText: \"\", earlier: \"\", warnings, hits, todo: [], keyOf: () => \"\" };\n }\n\n // Render the turn, to the state limit when there is one. Every rule counts\n // toward the longest, cached or not, so the render and its key stay put.\n const tail = lastMessageLine(input);\n let budget = input.render.maxTotalChars;\n let byLimit = false;\n if (limit !== undefined) {\n const longest = Math.max(\n ...planned.map((p) =>\n decisionOnly ? JSON.stringify(questionFor(p.source, p)).length : p.item.length,\n ),\n );\n const fixed = decisionOnly\n ? buildDecisionState(\"\").length\n : TURN_JUDGE_SYSTEM_PROMPT.length + buildTurnShared(\"\").length;\n const fit = limit * CHARS_PER_TOKEN - longest - fixed;\n if (fit < budget) {\n budget = fit;\n byLimit = true;\n }\n }\n // Earlier turns share the budget with the turn, and take at most a quarter\n // of it, so the turn itself is never crowded out.\n const sources = [\n ...new Map(\n input.rules.flatMap(({ source: { path, displayPath } }) =>\n // A source with no file (the typed prompts, an inline plan) is never read.\n path !== undefined && path !== \"\" ? [[displayPath, { path, displayPath }] as const] : [],\n ),\n ).values(),\n ];\n const earlier = timelineBlock(input.trace, input.turn.from, {\n cwd: input.project?.cwd ?? input.trace.cwd,\n root: input.project?.root ?? input.trace.cwd,\n redact: input.render.redact,\n sources,\n ...(input.ledger !== undefined ? { ledger: input.ledger } : {}),\n maxChars: Math.floor(budget / 4),\n });\n budget -= buildTurnShared(\"\", earlier).length - buildTurnShared(\"\").length;\n const cut = { happened: false };\n const turnText =\n renderTrace(input.trace, {\n maxBlockChars: input.render.maxBlockChars,\n maxTotalChars: budget - tail.length,\n redact: input.render.redact,\n window: input.turn.window,\n onTruncated: () => {\n cut.happened = true;\n },\n }) + tail;\n if (cut.happened) {\n warnings.push(\n byLimit\n ? `the turn was cut to fit the state limit of ${String(limit)} tokens of ${id.provider}/${id.model}; the judge saw its head and tail`\n : `the turn was cut to the render cap of ${String(input.render.maxTotalChars)} characters; the judge saw its head and tail`,\n );\n }\n\n // Gate 9: the same turn, rule and model reuse the verdict.\n const base = [\n id.provider,\n id.model,\n decisionOnly ? \"decision\" : \"generative\",\n `r${String(runs)}`,\n `t${String(input.temperature)}`,\n `turn-v${String(TURN_JUDGE_PROMPT_VERSION)}`,\n sha256(turnText),\n sha256(earlier),\n ];\n const keyOf = (p: Planned): string =>\n buildCacheKey([...base, sha256(JSON.stringify([p.source, p.id, p.text, p.history]))]);\n const todo: Planned[] = [];\n for (const p of planned) {\n const hit = input.cache?.get(keyOf(p));\n if (hit !== undefined) hits.set(p, { runs: hit });\n else todo.push(p);\n }\n return { planned, turnText, earlier, warnings, hits, todo, keyOf };\n}\n\n/**\n * Whether every applicable rule already has its verdict, answered without a\n * provider and so without loading a local model. The render depends on the\n * provider's state limit, which `StateLimits` remembers from the last\n * judgement, so a model never judged with is unknown and the answer is no.\n * A decision-only provider is never asked here: it is not a local model.\n */\nexport function allVerdictsCached(\n input: TurnPlanInput & { limits: StateLimits },\n id: ModelId,\n): boolean {\n const limit = input.limits.get(id);\n if (limit === undefined || DECISION_ONLY_PROVIDERS.has(id.provider)) return false;\n const plan = planTurn(input, id, false, limit ?? undefined);\n return plan.planned.length > 0 && plan.todo.length === 0;\n}\n\nexport async function judgeTurn(\n input: TurnJudgeInput & { limits?: StateLimits },\n): Promise<TurnJudgement> {\n const { provider, zones } = input;\n const decider = decisionOnly(provider);\n const mode = decider !== undefined ? \"decision\" : \"generative\";\n const runs = decider !== undefined ? 1 : input.runs;\n const id: ModelId = { provider: provider.provider(), model: provider.modelName() };\n const { applicable, notApplicable } = applicableRules(input.rules, input.turn.window);\n const result: TurnJudgement = {\n mode,\n runs,\n findings: [],\n verdicts: [],\n judged: applicable.length,\n notApplicable,\n cached: false,\n warnings: [],\n };\n if (applicable.length === 0) return result;\n\n // The provider's limit, remembered. A remembered one lets a fully cached\n // turn finish without asking the provider at all; any miss asks for the real\n // one, which refreshes the memory, and plans again if it moved.\n const fresh = async (): Promise<number | null> => {\n const real = canDecide(provider) ? await provider.stateLimit() : null;\n input.limits?.set(id, real);\n return real;\n };\n const remembered = input.limits?.get(id);\n let limit = remembered ?? (await fresh());\n let plan = planTurn(input, id, decider !== undefined, limit ?? undefined);\n if (remembered !== undefined && plan.todo.length > 0) {\n const real = await fresh();\n if (real !== limit) {\n limit = real;\n plan = planTurn(input, id, decider !== undefined, limit ?? undefined);\n }\n }\n const { planned, hits: verdicts, todo, keyOf, turnText, earlier } = plan;\n const warnings = plan.warnings;\n result.warnings = warnings;\n result.cached = todo.length === 0;\n if (todo.length > 0) {\n const scored =\n decider !== undefined\n ? await decide(decider, todo, buildDecisionState(turnText, earlier))\n : await score(provider, todo, buildTurnShared(turnText, earlier), runs, input.temperature);\n if (scored.every((v) => v.runs.length === 0)) {\n throw new Error(scored.find((v) => v.error !== undefined)?.error ?? \"every judge call errored\");\n }\n const errored = scored.filter((v) => v.error !== undefined);\n if (errored.length > 0) {\n warnings.push(\n `the judge errored on ${String(errored.length)} of ${String(todo.length)} rules, so they need review: ${errored[0]?.error ?? \"\"}`,\n );\n }\n todo.forEach((p, i) => {\n const v = scored[i] ?? { runs: [], error: \"the judge returned nothing\" };\n verdicts.set(p, v);\n if (v.error === undefined) input.cache?.set(keyOf(p), v.runs);\n });\n }\n\n for (const p of planned) {\n const v = verdicts.get(p) ?? { runs: [], error: \"the judge returned nothing\" };\n const outcome = outcomeOf(v, runs, zones);\n const reasoning = v.runs.find((r) => typeof r.reasoning === \"string\")?.reasoning;\n result.verdicts.push({\n source: p.source,\n rule: p.id,\n text: p.text,\n outcome,\n ...(reasoning !== undefined ? { reasoning } : {}),\n });\n if (outcome === \"not-applicable\") result.notApplicable += 1;\n else if (outcome !== \"followed\") result.findings.push(findingOf(p, outcome, v, runs));\n }\n return result;\n}\n\n/** One `decide` call; each option's probability becomes its score. */\nasync function decide(\n decider: DecisionProvider,\n todo: Planned[],\n state: string,\n): Promise<Verdict[]> {\n const response = await decider.decide({\n state,\n questions: Object.fromEntries(todo.map((p) => [p.qid, questionFor(p.source, p)])),\n });\n const answers: Record<string, DecideAnswer | undefined> = response.answers;\n return todo.map((p) => {\n const answer = answers[p.qid];\n if (answer === undefined) return { runs: [], error: \"the judge returned no answer for this rule\" };\n const pct = (s: TurnScore): number => Math.round((answer.probabilities[s] ?? 0) * 100);\n return {\n runs: [\n {\n followed: pct(\"followed\"),\n \"not-followed\": pct(\"not-followed\"),\n \"not-applicable\": pct(\"not-applicable\"),\n },\n ],\n };\n });\n}\n\n/** `runs` shared-prefix calls, one item per rule. */\nasync function score(\n provider: InferenceProvider,\n todo: Planned[],\n shared: string,\n runs: number,\n temperature: number,\n): Promise<Verdict[]> {\n const verdicts: Verdict[] = todo.map(() => ({ runs: [] }));\n const errors = todo.map(() => 0);\n for (let run = 0; run < runs; run++) {\n const response = await completeJSONShared(provider, {\n system: TURN_JUDGE_SYSTEM_PROMPT,\n shared,\n items: todo.map((p) => p.item),\n schema: TURN_SCHEMA,\n temperature,\n });\n verdicts.forEach((v, i) => {\n const answer = response.answers[i];\n if (answer !== undefined && \"json\" in answer && isScores(answer.json)) {\n v.runs.push(answer.json);\n return;\n }\n errors[i] = (errors[i] ?? 0) + 1;\n v.error ??= answer !== undefined && \"error\" in answer ? answer.error : \"the judge returned nothing\";\n });\n }\n return verdicts.map((v, i) =>\n v.error === undefined || v.runs.length === 0\n ? v\n : { ...v, error: `${String(errors[i] ?? 0)} of ${String(runs)} runs errored: ${v.error}` },\n );\n}\n\nfunction classify(s: Scores, zones: ZoneThresholds): Outcome {\n // An integer over 100 lands on the same double as the zone's literal, where\n // the zone times 100 can miss it (0.7 * 100 is 70.00000000000001).\n if (s[\"not-followed\"] / 100 >= zones.autoFail) return \"fail\";\n if (s[\"not-applicable\"] / 100 >= zones.autoPass) return \"not-applicable\";\n if (s.followed / 100 >= zones.autoPass) return \"followed\";\n return \"needs-review\";\n}\n\n/** Every run has to agree: a split ensemble, or any error, is review. */\nfunction outcomeOf(v: Verdict, runs: number, zones: ZoneThresholds): Outcome {\n if (v.error !== undefined || v.runs.length < runs) return \"needs-review\";\n const each = v.runs.map((s) => classify(s, zones));\n if (each.every((c) => c === \"fail\")) return \"fail\";\n if (each.every((c) => c === \"not-applicable\")) return \"not-applicable\";\n if (each.every((c) => c === \"not-applicable\" || c === \"followed\")) return \"followed\";\n return \"needs-review\";\n}\n\nfunction findingOf(\n p: Planned,\n outcome: TurnFinding[\"outcome\"],\n v: Verdict,\n runs: number,\n): TurnFinding {\n const base = { source: p.source, rule: p.id, text: p.text, outcome };\n if (v.runs.length === 0) {\n return {\n ...base,\n observed: `the judge returned no answer for this rule: ${v.error ?? \"\"}`,\n confidence: 0,\n };\n }\n const mean = (s: TurnScore): number =>\n Math.round(v.runs.reduce((sum, r) => sum + r[s], 0) / v.runs.length);\n const scores = `not-followed ${String(mean(\"not-followed\"))}, followed ${String(mean(\"followed\"))}, not-applicable ${String(mean(\"not-applicable\"))}`;\n const errored = v.error !== undefined && runs > 1 ? `; ${v.error}` : \"\";\n const reasoning = v.runs.find((r) => typeof r.reasoning === \"string\")?.reasoning;\n return {\n ...base,\n observed: `${scores}${errored}${reasoning !== undefined ? `. ${reasoning}` : \"\"}`,\n confidence: round(mean(\"not-followed\") / 100),\n ...(reasoning !== undefined ? { reasoning } : {}),\n };\n}\n\n/**\n * The transcript is written asynchronously, so its last message can lag the\n * Stop. The payload's copy is appended when the window does not end with it,\n * scrubbed and clipped as every rendered block is.\n */\nfunction lastMessageLine(input: TurnPlanInput): string {\n const message = input.lastAssistantMessage?.trim();\n if (message === undefined || message === \"\") return \"\";\n if (input.turn.window.assistantTexts.at(-1)?.trim() === message) return \"\";\n const safe = makeRedactor(input.render.redact)(message);\n const max = input.render.maxBlockChars;\n const clipped =\n safe.length <= max\n ? safe\n : `${safe.slice(0, max)} [... truncated ${String(safe.length - max)} chars ...]`;\n return `\\n[assistant] ${clipped}`;\n}\n","/**\n * The turn judge's prompt surface (proposal 0079, \"The judge, decisions\n * first\", reworded by proposal 0080 to judge the last turn against the\n * session). Each rule is judged on its own: the shared part is what earlier\n * turns did and the rendered turn, and each rule is one item appended to it. A decision-only provider\n * gets the same text as its state and one question per rule.\n */\nimport type { DecideQuestion } from \"@hawkeyexl/inference\";\n\n/**\n * Part of the turn verdict cache key: bump whenever anything in this file that\n * reaches a provider changes. `test/tracevals/unit/rules-judge.test.ts` pins it\n * to a digest of the surface, so the pair has to move together.\n */\nexport const TURN_JUDGE_PROMPT_VERSION = 7;\n\nexport const TURN_JUDGE_SYSTEM_PROMPT = [\n \"You check the last turn of an AI coding agent's session against one rule.\",\n \"The last turn starts at the last prompt the user typed and runs to the end of the transcript.\",\n \"The transcript shows the user's prompts, the agent's tool calls with their inputs, and its replies.\",\n '\"Earlier in this session\" lists what the session did before the last turn.',\n \"\",\n \"A prompt the user typed overrides any rule. Doing what the user explicitly asked is never a violation.\",\n \"\",\n \"Judge only from what the transcript and the earlier turns show. Do not guess.\",\n \"A rule applies only once the session does the kind of work it covers.\",\n \"Score it broken only for what the last turn did, or for the last turn saying the work is done without it.\",\n].join(\"\\n\");\n\n/** The three scores, each independent of the others, 0 to 100. */\nexport const TURN_SCORES = [\"not-applicable\", \"followed\", \"not-followed\"] as const;\nexport type TurnScore = (typeof TURN_SCORES)[number];\n\nconst SCORE = { type: \"integer\", minimum: 0, maximum: 100 } as const;\n\n/**\n * `reasoning` is declared first and always required, so a model writing the\n * object in order says what it saw before it commits to a score. It is not\n * length-capped: a 240-character cap was measured, and a model cut off\n * mid-reasoning committed to wrong scores on the fixtures.\n */\nexport const TURN_SCHEMA = {\n type: \"object\",\n required: [\"reasoning\", ...TURN_SCORES],\n additionalProperties: false,\n properties: {\n reasoning: { type: \"string\" },\n \"not-applicable\": SCORE,\n followed: SCORE,\n \"not-followed\": SCORE,\n },\n};\n\n/** Decision-only providers: the three options, one per score. */\nexport const TURN_CRITERIA: Record<TurnScore, string> = {\n followed: \"The session does what the rule asks.\",\n \"not-followed\":\n \"The last turn did what the rule forbids, skipped what it requires, or said the work is done without it.\",\n \"not-applicable\": \"The rule does not apply yet, or the last turn did nothing it covers.\",\n};\n\n/** How a rule is named to a model. */\nexport function ruleKey(displayPath: string, id: string): string {\n return `${displayPath}#${id}`;\n}\n\n/**\n * The part every rule's call shares: what earlier turns of the transcript\n * did, when any did something, then the turn.\n */\nexport function buildTurnShared(turn: string, earlier = \"\"): string {\n return `${earlier !== \"\" ? `${earlier}\\n\\n` : \"\"}# The turn\\n\\n${turn}\\n\\n`;\n}\n\n/**\n * One rule's item, appended to the shared part as it is. `history` is the\n * ledger's block for the rule, or \"\" when earlier turns have nothing to say.\n */\nexport function buildRuleItem(\n displayPath: string,\n rule: { id: string; text: string },\n history = \"\",\n): string {\n return [\n \"# The rule\",\n \"\",\n `${ruleKey(displayPath, rule.id)}: ${rule.text}`,\n \"\",\n ...(history !== \"\" ? [history, \"\"] : []),\n \"First say in one or two sentences what the session shows about this rule. Then score each as a whole number from 0 to 100: \" +\n \"the rule does not apply yet, or the last turn did nothing it covers; the session follows it; the last turn broke it, or the last turn says the work is done without it.\",\n ].join(\"\\n\");\n}\n\n/** A decision-only provider's state: the system prompt, then the shared part. */\nexport function buildDecisionState(turn: string, earlier = \"\"): string {\n return `${TURN_JUDGE_SYSTEM_PROMPT}\\n\\n${buildTurnShared(turn, earlier)}`;\n}\n\nexport function questionFor(\n displayPath: string,\n rule: { id: string; text: string },\n): DecideQuestion {\n return {\n type: \"choice\",\n instructions: `Did this turn follow ${ruleKey(displayPath, rule.id)}? The rule: ${rule.text}`,\n criteria: { ...TURN_CRITERIA },\n };\n}\n","/**\n * \"# Earlier in this session\", read from the transcript (proposal 0080,\n * \"Earlier in this session, from the transcript\"). Every turn before the\n * judged one that did something gets a line, newest last, so a rule about a\n * procedure that spans turns is judged with the whole session behind it. The\n * ledger only says which of those turns had no rule in scope.\n */\nimport { makeRedactor } from \"../judge/redact.js\";\nimport { materialize } from \"../graders/util.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport { clipTo, projectPath, turnFacts, type Ledger } from \"./ledger.js\";\nimport type { RuleSource } from \"./sources.js\";\nimport { isTypedPrompt } from \"./turn.js\";\n\nconst HEAD = \"# Earlier in this session\\n\\n\";\nconst RESULT_CHARS = 120;\nconst TICK_CHARS = 60;\nconst SPAWNS = 10;\n/** A task line in Spec Kit, Kiro and OpenSpec task lists. */\nconst TASK = /^\\s*-\\s+\\[([ xX])\\]\\s+(.+?)\\s*$/;\n/** A task's leading id: `T014`, `FR-001`, `1.2`. */\nconst TASK_ID = /^(?:[A-Z]+(?:-[A-Z]+)*-?\\d+(?:\\.\\d+)*|\\d+(?:\\.\\d+)*)(?=[\\s:.)\\]]|$)/;\n\nexport interface TimelineOptions {\n cwd: string;\n root: string;\n redact: readonly string[];\n /** The rule sources a `read` fact names; others' reads are left out. */\n sources: Pick<RuleSource, \"path\" | \"displayPath\">[];\n /** Marks a turn it recorded with no rules in scope. */\n ledger?: Ledger;\n maxChars?: number;\n}\n\ninterface ToolResult {\n text: string;\n isError: boolean;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n/** Every tool_result block in the trace, by the id of the call it answers. */\nfunction toolResults(trace: Trace): Map<string, ToolResult> {\n const out = new Map<string, ToolResult>();\n for (const e of trace.events) {\n if (e.kind !== \"tool_result\") continue;\n const message = e.raw.message;\n const content: unknown = isRecord(message) ? message.content : undefined;\n if (!Array.isArray(content)) continue;\n for (const block of content as unknown[]) {\n if (!isRecord(block) || block.type !== \"tool_result\" || typeof block.tool_use_id !== \"string\") continue;\n const body: unknown = block.content;\n const text =\n typeof body === \"string\"\n ? body\n : Array.isArray(body)\n ? (body as unknown[])\n .flatMap((b) => (isRecord(b) && typeof b.text === \"string\" ? [b.text] : []))\n .join(\"\\n\")\n : \"\";\n out.set(block.tool_use_id, { text, isError: block.is_error === true });\n }\n }\n return out;\n}\n\n/** The `tool_use` id of the call at `index`, read from its event. */\nfunction callId(trace: Trace, index: number): string | undefined {\n // Find by ordinal: the event array need not hold one event per ordinal.\n const id = trace.events.find((e) => e.index === index)?.raw.id;\n return typeof id === \"string\" ? id : undefined;\n}\n\n/** Texts of the task lines in `text` whose box is ticked (`x`) or not (` `). */\nfunction tasks(text: string, ticked: boolean): string[] {\n return text.split(/\\r?\\n/).flatMap((line) => {\n const m = TASK.exec(line);\n const box = m?.[1];\n const body = m?.[2];\n if (box === undefined || body === undefined) return [];\n return (box !== \" \") === ticked ? [body] : [];\n });\n}\n\n/** The tasks an edit ticks: unticked in its old string, ticked with the same text in its new. */\nfunction ticks(oldText: unknown, newText: unknown): string[] {\n if (typeof oldText !== \"string\" || typeof newText !== \"string\") return [];\n const now = new Set(tasks(newText, true));\n return tasks(oldText, false).filter((t) => now.has(t));\n}\n\nconst list = (verb: string, items: string[]): string[] =>\n items.length > 0 ? [`${verb} ${items.join(\", \")}`] : [];\n\n/**\n * The block for the turns before `before`, or \"\" when none did anything.\n * Over `maxChars`, the oldest lines go first, and a marker line says which.\n */\nexport function timelineBlock(trace: Trace, before: number, opts: TimelineOptions): string {\n const scrub = makeRedactor(opts.redact);\n const results = toolResults(trace);\n const starts = trace.events\n .filter((e) => e.index < before && e.sidechain !== true && isTypedPrompt(e))\n .map((e) => e.index);\n\n const lines = starts.flatMap((from, i) => {\n const end = starts[i + 1] ?? before;\n const window = materialize(trace, \"turn\", \"earlier turn\", [{ start: from, end }], undefined, new Set([undefined]));\n // turnFacts reads only the window and bounds; 0 just satisfies TurnSlice.\n const facts = turnFacts(trace, { window, from, to: end - 1, sessionTurnCount: 0 }, opts.sources, opts);\n const spawns = trace.agentSpawns\n .filter((a) => a.index >= from && a.index < end)\n .slice(0, SPAWNS)\n .map((a) => {\n const result = results.get(a.toolUseId ?? callId(trace, a.index) ?? \"\");\n // Redact, then clip, so a cap never lands mid-secret.\n const first = scrub(result?.text ?? \"\").trim().split(/\\r?\\n/)[0]?.trim() ?? \"\";\n return first === \"\"\n ? `spawned ${a.subagentType}`\n : `spawned ${a.subagentType}, which returned ${clipTo(first, RESULT_CHARS)}`;\n });\n const calls = window.toolCalls;\n const asked = calls.some((c) => c.name === \"AskUserQuestion\") ? [\"asked the user\"] : [];\n const ticked = calls.flatMap((c) => {\n if (typeof c.input.file_path !== \"string\") return [];\n const edits: unknown[] =\n c.name === \"Edit\" ? [c.input] : c.name === \"MultiEdit\" && Array.isArray(c.input.edits) ? c.input.edits : [];\n const path = scrub(projectPath(c.input.file_path, opts.cwd, opts.root));\n return edits.flatMap((e) =>\n isRecord(e)\n ? ticks(e.old_string, e.new_string).map((t) => {\n const safe = scrub(t);\n return `ticked ${TASK_ID.exec(safe)?.[0] ?? clipTo(safe, TICK_CHARS)} in ${path}`;\n })\n : [],\n );\n });\n const approved = calls.some((c) => {\n if (c.name !== \"ExitPlanMode\") return false;\n const result = results.get(callId(trace, c.index) ?? \"\");\n return result !== undefined && !result.isError;\n })\n ? [\"had a plan approved\"]\n : [];\n const parts = [\n ...list(\"ran\", facts.commands),\n ...list(\"wrote\", facts.wrote),\n ...list(\"read\", facts.read),\n ...facts.skills.map((s) => `ran skill ${s}`),\n ...spawns,\n ...asked,\n ...[...new Set(ticked)],\n ...approved,\n ];\n if (parts.length === 0) return [];\n const out = opts.ledger?.turns.find((t) => t.turn === from)?.inScope === false;\n return [{ turn: from, line: `- turn ${String(from)}: ${parts.join(\"; \")}${out ? \" (no rules in scope)\" : \"\"}` }];\n });\n\n // Drop the oldest until the block fits, the marker's length included.\n const max = opts.maxChars ?? Number.POSITIVE_INFINITY;\n const marker = (n: number): string => {\n const a = String(lines[0]?.turn);\n const b = String(lines[n - 1]?.turn);\n return n === 1 ? `- (turn ${a}: 1 line left out)` : `- (turns ${a}–${b}: ${String(n)} lines left out)`;\n };\n let kept = lines.reduce((sum, l) => sum + l.line.length + 1, HEAD.length - 1);\n let dropped = 0;\n const size = (): number => kept + (dropped > 0 ? marker(dropped).length + 1 : 0);\n while (dropped < lines.length && size() > max) {\n kept -= (lines[dropped]?.line.length ?? 0) + 1;\n dropped += 1;\n }\n if (dropped === lines.length) return \"\";\n const shown = lines.slice(dropped).map((l) => l.line);\n return `${HEAD}${[...(dropped > 0 ? [marker(dropped)] : []), ...shown].join(\"\\n\")}`;\n}\n"],"mappings":"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","names":["isRecord","decisionOnly"]}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
spliceEntryField,
|
|
17
17
|
unifiedDiff,
|
|
18
18
|
withClaimLines
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-IY7NYNPZ.js";
|
|
20
20
|
import {
|
|
21
21
|
CITATIONS_KEY,
|
|
22
22
|
CITE_SECTION,
|
|
@@ -54,10 +54,10 @@ import {
|
|
|
54
54
|
stripMarkers,
|
|
55
55
|
twoManifestsRefusal,
|
|
56
56
|
urlManifestRefusal
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-QW77LCOU.js";
|
|
58
58
|
import {
|
|
59
59
|
renderCheckGithub
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-GAJIJKET.js";
|
|
61
61
|
import {
|
|
62
62
|
refusalLine,
|
|
63
63
|
removalLine,
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
renderRemovePretty,
|
|
66
66
|
renderUpdatePretty,
|
|
67
67
|
rewriteLine
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-T6SYGLWR.js";
|
|
69
69
|
import {
|
|
70
70
|
blockMatches,
|
|
71
71
|
claimEnd,
|
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
toValidationResult,
|
|
95
95
|
unitAt,
|
|
96
96
|
unitText
|
|
97
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-UAKNZVCD.js";
|
|
98
98
|
import {
|
|
99
99
|
renderCheckJson,
|
|
100
100
|
renderRemoveJson,
|
|
@@ -140,11 +140,11 @@ import {
|
|
|
140
140
|
spellSource,
|
|
141
141
|
statementForms,
|
|
142
142
|
validateEntry
|
|
143
|
-
} from "./chunk-
|
|
143
|
+
} from "./chunk-MHM4QEBV.js";
|
|
144
144
|
import {
|
|
145
145
|
reencryptData,
|
|
146
146
|
reencryptMetadata
|
|
147
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-TLXE7LYK.js";
|
|
148
148
|
import {
|
|
149
149
|
ENCRYPTION_KEY_ENV,
|
|
150
150
|
MAX_RANGE_LINES,
|
|
@@ -170,7 +170,7 @@ import {
|
|
|
170
170
|
toBodyLines,
|
|
171
171
|
toFileLines,
|
|
172
172
|
writeEncryptionKey
|
|
173
|
-
} from "./chunk-
|
|
173
|
+
} from "./chunk-TUAAR3MM.js";
|
|
174
174
|
import {
|
|
175
175
|
LEGACY_CONFIG_NAMES,
|
|
176
176
|
STDIN_TOKEN,
|
|
@@ -181,7 +181,7 @@ import {
|
|
|
181
181
|
resolveTargetSet,
|
|
182
182
|
supportedExtensions,
|
|
183
183
|
writeFileAtomic
|
|
184
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-KCOFEWV5.js";
|
|
185
185
|
import {
|
|
186
186
|
findConfigFile,
|
|
187
187
|
findFamilyConfigFile,
|
|
@@ -195,7 +195,7 @@ import {
|
|
|
195
195
|
readConfigFile,
|
|
196
196
|
readFamilyConfigFile,
|
|
197
197
|
selectCollections
|
|
198
|
-
} from "./chunk-
|
|
198
|
+
} from "./chunk-XKBEHKWO.js";
|
|
199
199
|
import {
|
|
200
200
|
ToolError
|
|
201
201
|
} from "./chunk-G3T47CFV.js";
|
|
@@ -931,4 +931,4 @@ export {
|
|
|
931
931
|
runKeyRotate,
|
|
932
932
|
runKeySet
|
|
933
933
|
};
|
|
934
|
-
//# sourceMappingURL=chunk-
|
|
934
|
+
//# sourceMappingURL=chunk-2JFPBZJK.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
listInTree,
|
|
6
6
|
safeRead,
|
|
7
7
|
segments
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-APKH2T6E.js";
|
|
9
9
|
import {
|
|
10
10
|
TracevalsError
|
|
11
11
|
} from "./chunk-UKZNLVJW.js";
|
|
@@ -171,4 +171,4 @@ async function discoverArtifacts(options) {
|
|
|
171
171
|
export {
|
|
172
172
|
discoverArtifacts
|
|
173
173
|
};
|
|
174
|
-
//# sourceMappingURL=chunk-
|
|
174
|
+
//# sourceMappingURL=chunk-2KRB3EG7.js.map
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
discoverArtifacts
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2KRB3EG7.js";
|
|
5
5
|
import {
|
|
6
6
|
parseHookPayload,
|
|
7
7
|
readStdin
|
|
8
8
|
} from "./chunk-TZOYZK2E.js";
|
|
9
9
|
import {
|
|
10
|
-
MANIFEST_VERSION,
|
|
11
10
|
hashFile,
|
|
12
|
-
loadConfig,
|
|
13
|
-
makeRedactor,
|
|
14
11
|
manifestPathFor,
|
|
15
12
|
relPosix,
|
|
16
13
|
sha256Hex,
|
|
17
14
|
writeManifest
|
|
18
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-APKH2T6E.js";
|
|
16
|
+
import {
|
|
17
|
+
loadConfig
|
|
18
|
+
} from "./chunk-XPEWUK7J.js";
|
|
19
|
+
import {
|
|
20
|
+
MANIFEST_VERSION,
|
|
21
|
+
makeRedactor
|
|
22
|
+
} from "./chunk-CU57HT2E.js";
|
|
19
23
|
import {
|
|
20
24
|
TracevalsError
|
|
21
25
|
} from "./chunk-UKZNLVJW.js";
|
|
@@ -208,4 +212,4 @@ export {
|
|
|
208
212
|
runCapture,
|
|
209
213
|
renderCapture
|
|
210
214
|
};
|
|
211
|
-
//# sourceMappingURL=chunk-
|
|
215
|
+
//# sourceMappingURL=chunk-2M6DVNI5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracevals/commands/capture.ts","../src/tracevals/capture/build.ts"],"sourcesContent":["/**\n * `manni tracevals capture` — record what the project's instruction artifacts\n * said, and at which commit, at the moment a session started (ADR 01024).\n *\n * **This is the one write path `run` never takes.** CLAUDE.md states that\n * evaluation is read-only, so the manifest is written by a separate,\n * explicitly-invoked command — the same shape as `fill`. `run` only ever reads\n * a manifest, and degrades cleanly when there is none.\n *\n * Designed to be wired to a `SessionStart` hook, which constrains it in two\n * ways that are not obvious:\n *\n * - **Nothing goes to stdout in hook mode.** Claude Code adds a\n * SessionStart hook's stdout to the model's context, so a report printed\n * there would be a side effect on the very session being observed. In hook\n * mode the report goes to stderr, where an exit-0 hook's output is a debug\n * line and nothing more.\n * - **The transcript is never read.** `transcript_path` is recorded as a\n * correlation key only. At SessionStart the file barely exists, and the\n * reference warns that it lags the conversation in any case.\n */\nimport { resolve } from \"node:path\";\nimport { loadConfig } from \"../core/config.js\";\nimport { buildManifest } from \"../capture/build.js\";\nimport { manifestPathFor, writeManifest } from \"../capture/manifest.js\";\nimport type { SessionManifest } from \"../capture/types.js\";\nimport { parseHookPayload, readStdin } from \"../capture/hook.js\";\nimport type { SummaryFormat } from \"../reporters/index.js\";\nimport { TracevalsError } from \"../types.js\";\n\nexport interface CaptureCommandOptions {\n /**\n * The hook payload. Undefined means \"read stdin\"; an empty string means\n * \"there was none\", which is the hand-run path.\n */\n stdin?: string;\n /** Overrides the payload's `cwd` as the project root to scan. */\n project?: string;\n /** Overrides the payload's `session_id`. */\n sessionId?: string;\n /** Write here instead of `<project>/<capture.dir>/<session-id>.json`. */\n out?: string;\n /** Directory holding manni.config.yaml; defaults to the project root. */\n configDir?: string;\n /** `-c/--config`: read this file instead of discovering one. */\n config?: string;\n /** `--no-config`: skip discovery and run on the built-in defaults. */\n noConfig?: boolean;\n format?: SummaryFormat;\n /**\n * Version recorded in the manifest. Passed in rather than read from\n * package.json here: this module is bundled into an unpredictable chunk\n * path, so any relative require of it resolves differently in dist than in\n * src. The CLI, which is not bundled away, supplies it.\n */\n version?: string;\n}\n\nexport interface CaptureCommandResult {\n manifest: SessionManifest;\n /** Where the manifest was written. */\n path: string;\n /** The report, wherever it is destined for. */\n rendered: string;\n /** What the caller should print to stdout — empty in hook mode. */\n stdout: string;\n /** What the caller should print to stderr — the report, in hook mode. */\n stderr: string;\n exitCode: number;\n}\n\nexport async function runCapture(\n options: CaptureCommandOptions = {},\n): Promise<CaptureCommandResult> {\n const raw = options.stdin ?? (await readStdin());\n const hookMode = raw.trim().length > 0;\n const payload = hookMode ? parseHookPayload(raw) : {};\n\n const sessionId = options.sessionId ?? payload.sessionId;\n if (sessionId === undefined) {\n // Without an id the manifest has no name and no join key, and writing one\n // under a guessed name would produce evidence nothing could ever find.\n throw new TracevalsError(\n \"no session id: pipe a Claude Code hook payload on stdin, or pass --session-id\",\n );\n }\n\n const root = resolve(options.project ?? payload.cwd ?? process.cwd());\n const config = await loadConfig(options.configDir ?? root, {\n ...(options.config === undefined ? {} : { configPath: options.config }),\n ...(options.noConfig === undefined ? {} : { noConfig: options.noConfig }),\n });\n\n const manifest = await buildManifest({\n sessionId,\n root,\n hookEvent: payload.hookEvent ?? \"manual\",\n ...(payload.reason !== undefined ? { reason: payload.reason } : {}),\n ...(payload.transcriptPath !== undefined\n ? { transcriptPath: payload.transcriptPath }\n : {}),\n config,\n redact: config.judge.redact,\n ...(options.version !== undefined ? { version: options.version } : {}),\n });\n\n const path =\n options.out ??\n manifestPathFor(resolve(root, config.capture.dir), sessionId);\n try {\n await writeManifest(path, manifest);\n } catch (err) {\n throw new TracevalsError(\n `could not write ${path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n const rendered =\n options.format === \"json\"\n ? JSON.stringify({ path, manifest }, null, 2)\n : renderCapture(path, manifest);\n\n return {\n manifest,\n path,\n rendered,\n // The whole point of the split: a SessionStart hook's stdout becomes model\n // context, so hook mode writes none.\n stdout: hookMode ? \"\" : rendered,\n stderr: hookMode ? rendered : \"\",\n exitCode: 0,\n };\n}\n\nexport function renderCapture(\n path: string,\n manifest: SessionManifest,\n): string {\n const lines = [\n `Captured session ${manifest.sessionId}`,\n ` manifest ${path}`,\n ` artifacts ${manifest.artifacts.length} hashed`,\n ];\n if (manifest.git !== undefined) {\n lines.push(\n ` commit ${manifest.git.sha}${manifest.git.branch ? ` (${manifest.git.branch})` : \"\"}${\n manifest.git.dirty ? \" — working tree dirty\" : \"\"\n }`,\n );\n } else {\n lines.push(\" commit not a git repository, or git is unavailable\");\n }\n lines.push(` device ${manifest.device.id} (${manifest.device.platform})`);\n return lines.join(\"\\n\");\n}\n","/**\n * Building a session manifest (ADR 01024) — the producing half.\n *\n * Separate from `capture/manifest.ts` because this side reaches for\n * `discoverArtifacts`, which imports `artifacts/resolve.ts`, which consumes a\n * manifest. Producing and consuming therefore cannot share a module.\n */\nimport { spawn } from \"node:child_process\";\nimport { hostname, platform, userInfo } from \"node:os\";\nimport { resolve } from \"node:path\";\nimport { discoverArtifacts } from \"../artifacts/discover.js\";\nimport { makeRedactor, type Redactor } from \"../judge/redact.js\";\nimport { hashFile, relPosix, sha256Hex } from \"./manifest.js\";\nimport {\n MANIFEST_VERSION,\n type ManifestArtifact,\n type ManifestGit,\n type SessionManifest,\n} from \"./types.js\";\n\nexport interface BuildManifestOptions {\n sessionId: string;\n /** Project root to scan, and the base every artifact path is relative to. */\n root: string;\n hookEvent?: string;\n reason?: string;\n transcriptPath?: string;\n /** The resolved config section, recorded as provenance. */\n config?: unknown;\n /** `judge.redact` sources, applied to the manifest's free text (ADR 01020). */\n redact?: readonly string[];\n version?: string;\n /** Test seam: `false` skips shelling out to git. */\n git?: ManifestGit | false;\n}\n\n/**\n * Hash every instruction artifact the project holds, at the commit it holds\n * them at.\n *\n * The population is `discoverArtifacts`' — the same one `fill` authors against\n * — so capture and authoring never disagree about what an instruction artifact\n * is. That scope is **project-only** by its own design note, so a user-level or\n * plugin artifact is simply absent from the manifest, and its hash check at run\n * time degrades to the mtime heuristic rather than to a wrong answer.\n *\n * **Redaction covers the free text and never a join key.** `root`,\n * `transcriptPath`, `git.branch`, `reason` and the recorded `config` go through\n * the `judge.redact` redactor; `sessionId`, an artifact's `name` and `path`,\n * and every `sha256` do not. A redactor applied to a join key would turn an\n * exact check into a silent `skipped` — the one failure mode this whole feature\n * exists to remove — and those keys are the project's own vocabulary and its\n * repository-relative paths, not somewhere a credential lives. A secret in an\n * artifact path is a problem to fix in the path, the same call ADR 01020 makes\n * about a secret in a `SKILL.md`.\n */\nexport async function buildManifest(\n options: BuildManifestOptions,\n): Promise<SessionManifest> {\n const root = resolve(options.root);\n const redact = makeRedactor(options.redact ?? []);\n\n const discovered = await discoverArtifacts({ root });\n const artifacts: ManifestArtifact[] = [];\n for (const found of discovered.artifacts) {\n const rel = relPosix(root, found.artifact.path);\n if (rel === null) continue;\n const digest = await hashFile(found.artifact.path);\n // An artifact that cannot be read is one the manifest says nothing about,\n // which degrades to the mtime heuristic at run time. Never a crash.\n if (digest === null) continue;\n artifacts.push({\n name: found.artifact.name,\n type: found.artifact.type,\n path: rel,\n sha256: digest,\n bytes: Buffer.byteLength(found.artifact.content, \"utf-8\"),\n });\n }\n // Stable order, so two captures of an unchanged tree produce the same bytes.\n artifacts.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n\n const git =\n options.git === false ? undefined : (options.git ?? (await readGit(root)));\n\n return {\n version: MANIFEST_VERSION,\n sessionId: options.sessionId,\n capturedAt: new Date().toISOString(),\n hookEvent: options.hookEvent ?? \"manual\",\n ...(options.reason !== undefined ? { reason: redact(options.reason) } : {}),\n ...(options.transcriptPath !== undefined\n ? { transcriptPath: redact(options.transcriptPath) }\n : {}),\n root: redact(root),\n ...(git !== undefined\n ? {\n git: {\n sha: git.sha,\n ...(git.branch !== undefined ? { branch: redact(git.branch) } : {}),\n dirty: git.dirty,\n },\n }\n : {}),\n device: { id: deviceId(), platform: platform() },\n tool: { name: \"manni-tracevals\", version: options.version ?? \"unknown\" },\n artifacts,\n config: redactDeep(options.config ?? {}, redact),\n };\n}\n\n/**\n * A stable, opaque per-machine id. Not the hostname: \"was this captured here?\"\n * is the whole question, and answering it does not require shipping the name of\n * the machine into a file that travels with the repository.\n */\nexport function deviceId(): string {\n let user = \"\";\n try {\n user = userInfo().username;\n } catch {\n // A container with no passwd entry throws; the digest is still stable.\n }\n return sha256Hex(`${hostname()} ${user} ${platform()}`).slice(0, 16);\n}\n\n/**\n * Redact every string in a JSON-shaped value. Used for the recorded config\n * only — never for a join key.\n */\nexport function redactDeep(value: unknown, redact: Redactor): unknown {\n if (typeof value === \"string\") return redact(value);\n if (Array.isArray(value)) return value.map((v) => redactDeep(v, redact));\n if (value !== null && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, member] of Object.entries(value)) {\n out[key] = redactDeep(member, redact);\n }\n return out;\n }\n return value;\n}\n\n/**\n * What `git` says about `root`, or nothing. Every failure mode — git absent,\n * not a repository, a timeout — degrades to an absent block, because a manifest\n * without a SHA is still a manifest with hashes in it.\n */\nexport async function readGit(root: string): Promise<ManifestGit | undefined> {\n const sha = await git([\"rev-parse\", \"HEAD\"], root);\n if (sha === null || !/^[0-9a-f]{40}$/.test(sha)) return undefined;\n const branch = await git([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], root);\n const status = await git(\n [\"status\", \"--porcelain\", \"--untracked-files=no\"],\n root,\n );\n return {\n sha,\n // Detached HEAD reports the literal \"HEAD\", which is not a branch name.\n ...(branch !== null && branch !== \"HEAD\" ? { branch } : {}),\n dirty: status !== null && status.length > 0,\n };\n}\n\n/** One `git` invocation, argv-only and bounded — the shape ADR 01011 uses. */\nfunction git(\n args: string[],\n cwd: string,\n timeoutMs = 5000,\n): Promise<string | null> {\n return new Promise((settle) => {\n let done = false;\n let child;\n try {\n // shell:false — nothing here is ever parsed as shell syntax.\n child = spawn(\"git\", args, { cwd, shell: false, windowsHide: true });\n } catch {\n settle(null);\n return;\n }\n // `finish` is declared below the timer because it clears it; the timer\n // callback only runs after both exist.\n const timer = setTimeout(() => {\n child.kill();\n finish(null);\n }, timeoutMs);\n const finish = (value: string | null): void => {\n if (done) return;\n done = true;\n clearTimeout(timer);\n settle(value);\n };\n let out = \"\";\n child.stdout.on(\"data\", (d: Buffer) => {\n out += d.toString(\"utf-8\");\n });\n child.stderr.resume();\n child.on(\"error\", () => { finish(null); });\n child.on(\"close\", (code) => { finish(code === 0 ? out.trim() : null); });\n });\n}\n"],"mappings":"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","names":["resolve","git","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/tracevals/commands/capture.ts","../src/tracevals/capture/build.ts"],"sourcesContent":["/**\n * `manni tracevals capture` — record what the project's instruction artifacts\n * said, and at which commit, at the moment a session started (ADR 01024).\n *\n * **This is the one write path `run` never takes.** CLAUDE.md states that\n * evaluation is read-only, so the manifest is written by a separate,\n * explicitly-invoked command — the same shape as `fill`. `run` only ever reads\n * a manifest, and degrades cleanly when there is none.\n *\n * Designed to be wired to a `SessionStart` hook, which constrains it in two\n * ways that are not obvious:\n *\n * - **Nothing goes to stdout in hook mode.** Claude Code adds a\n * SessionStart hook's stdout to the model's context, so a report printed\n * there would be a side effect on the very session being observed. In hook\n * mode the report goes to stderr, where an exit-0 hook's output is a debug\n * line and nothing more.\n * - **The transcript is never read.** `transcript_path` is recorded as a\n * correlation key only. At SessionStart the file barely exists, and the\n * reference warns that it lags the conversation in any case.\n */\nimport { resolve } from \"node:path\";\nimport { loadConfig } from \"../core/config.js\";\nimport { buildManifest } from \"../capture/build.js\";\nimport { manifestPathFor, writeManifest } from \"../capture/manifest.js\";\nimport type { SessionManifest } from \"../capture/types.js\";\nimport { parseHookPayload, readStdin } from \"../capture/hook.js\";\nimport type { SummaryFormat } from \"../reporters/index.js\";\nimport { TracevalsError } from \"../types.js\";\n\nexport interface CaptureCommandOptions {\n /**\n * The hook payload. Undefined means \"read stdin\"; an empty string means\n * \"there was none\", which is the hand-run path.\n */\n stdin?: string;\n /** Overrides the payload's `cwd` as the project root to scan. */\n project?: string;\n /** Overrides the payload's `session_id`. */\n sessionId?: string;\n /** Write here instead of `<project>/<capture.dir>/<session-id>.json`. */\n out?: string;\n /** Directory holding manni.config.yaml; defaults to the project root. */\n configDir?: string;\n /** `-c/--config`: read this file instead of discovering one. */\n config?: string;\n /** `--no-config`: skip discovery and run on the built-in defaults. */\n noConfig?: boolean;\n format?: SummaryFormat;\n /**\n * Version recorded in the manifest. Passed in rather than read from\n * package.json here: this module is bundled into an unpredictable chunk\n * path, so any relative require of it resolves differently in dist than in\n * src. The CLI, which is not bundled away, supplies it.\n */\n version?: string;\n}\n\nexport interface CaptureCommandResult {\n manifest: SessionManifest;\n /** Where the manifest was written. */\n path: string;\n /** The report, wherever it is destined for. */\n rendered: string;\n /** What the caller should print to stdout — empty in hook mode. */\n stdout: string;\n /** What the caller should print to stderr — the report, in hook mode. */\n stderr: string;\n exitCode: number;\n}\n\nexport async function runCapture(\n options: CaptureCommandOptions = {},\n): Promise<CaptureCommandResult> {\n const raw = options.stdin ?? (await readStdin());\n const hookMode = raw.trim().length > 0;\n const payload = hookMode ? parseHookPayload(raw) : {};\n\n const sessionId = options.sessionId ?? payload.sessionId;\n if (sessionId === undefined) {\n // Without an id the manifest has no name and no join key, and writing one\n // under a guessed name would produce evidence nothing could ever find.\n throw new TracevalsError(\n \"no session id: pipe a Claude Code hook payload on stdin, or pass --session-id\",\n );\n }\n\n const root = resolve(options.project ?? payload.cwd ?? process.cwd());\n const config = await loadConfig(options.configDir ?? root, {\n ...(options.config === undefined ? {} : { configPath: options.config }),\n ...(options.noConfig === undefined ? {} : { noConfig: options.noConfig }),\n });\n\n const manifest = await buildManifest({\n sessionId,\n root,\n hookEvent: payload.hookEvent ?? \"manual\",\n ...(payload.reason !== undefined ? { reason: payload.reason } : {}),\n ...(payload.transcriptPath !== undefined\n ? { transcriptPath: payload.transcriptPath }\n : {}),\n config,\n redact: config.judge.redact,\n ...(options.version !== undefined ? { version: options.version } : {}),\n });\n\n const path =\n options.out ??\n manifestPathFor(resolve(root, config.capture.dir), sessionId);\n try {\n await writeManifest(path, manifest);\n } catch (err) {\n throw new TracevalsError(\n `could not write ${path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n const rendered =\n options.format === \"json\"\n ? JSON.stringify({ path, manifest }, null, 2)\n : renderCapture(path, manifest);\n\n return {\n manifest,\n path,\n rendered,\n // The whole point of the split: a SessionStart hook's stdout becomes model\n // context, so hook mode writes none.\n stdout: hookMode ? \"\" : rendered,\n stderr: hookMode ? rendered : \"\",\n exitCode: 0,\n };\n}\n\nexport function renderCapture(\n path: string,\n manifest: SessionManifest,\n): string {\n const lines = [\n `Captured session ${manifest.sessionId}`,\n ` manifest ${path}`,\n ` artifacts ${manifest.artifacts.length} hashed`,\n ];\n if (manifest.git !== undefined) {\n lines.push(\n ` commit ${manifest.git.sha}${manifest.git.branch ? ` (${manifest.git.branch})` : \"\"}${\n manifest.git.dirty ? \" — working tree dirty\" : \"\"\n }`,\n );\n } else {\n lines.push(\" commit not a git repository, or git is unavailable\");\n }\n lines.push(` device ${manifest.device.id} (${manifest.device.platform})`);\n return lines.join(\"\\n\");\n}\n","/**\n * Building a session manifest (ADR 01024) — the producing half.\n *\n * Separate from `capture/manifest.ts` because this side reaches for\n * `discoverArtifacts`, which imports `artifacts/resolve.ts`, which consumes a\n * manifest. Producing and consuming therefore cannot share a module.\n */\nimport { spawn } from \"node:child_process\";\nimport { hostname, platform, userInfo } from \"node:os\";\nimport { resolve } from \"node:path\";\nimport { discoverArtifacts } from \"../artifacts/discover.js\";\nimport { makeRedactor, type Redactor } from \"../judge/redact.js\";\nimport { hashFile, relPosix, sha256Hex } from \"./manifest.js\";\nimport {\n MANIFEST_VERSION,\n type ManifestArtifact,\n type ManifestGit,\n type SessionManifest,\n} from \"./types.js\";\n\nexport interface BuildManifestOptions {\n sessionId: string;\n /** Project root to scan, and the base every artifact path is relative to. */\n root: string;\n hookEvent?: string;\n reason?: string;\n transcriptPath?: string;\n /** The resolved config section, recorded as provenance. */\n config?: unknown;\n /** `judge.redact` sources, applied to the manifest's free text (ADR 01020). */\n redact?: readonly string[];\n version?: string;\n /** Test seam: `false` skips shelling out to git. */\n git?: ManifestGit | false;\n}\n\n/**\n * Hash every instruction artifact the project holds, at the commit it holds\n * them at.\n *\n * The population is `discoverArtifacts`' — the same one `fill` authors against\n * — so capture and authoring never disagree about what an instruction artifact\n * is. That scope is **project-only** by its own design note, so a user-level or\n * plugin artifact is simply absent from the manifest, and its hash check at run\n * time degrades to the mtime heuristic rather than to a wrong answer.\n *\n * **Redaction covers the free text and never a join key.** `root`,\n * `transcriptPath`, `git.branch`, `reason` and the recorded `config` go through\n * the `judge.redact` redactor; `sessionId`, an artifact's `name` and `path`,\n * and every `sha256` do not. A redactor applied to a join key would turn an\n * exact check into a silent `skipped` — the one failure mode this whole feature\n * exists to remove — and those keys are the project's own vocabulary and its\n * repository-relative paths, not somewhere a credential lives. A secret in an\n * artifact path is a problem to fix in the path, the same call ADR 01020 makes\n * about a secret in a `SKILL.md`.\n */\nexport async function buildManifest(\n options: BuildManifestOptions,\n): Promise<SessionManifest> {\n const root = resolve(options.root);\n const redact = makeRedactor(options.redact ?? []);\n\n const discovered = await discoverArtifacts({ root });\n const artifacts: ManifestArtifact[] = [];\n for (const found of discovered.artifacts) {\n const rel = relPosix(root, found.artifact.path);\n if (rel === null) continue;\n const digest = await hashFile(found.artifact.path);\n // An artifact that cannot be read is one the manifest says nothing about,\n // which degrades to the mtime heuristic at run time. Never a crash.\n if (digest === null) continue;\n artifacts.push({\n name: found.artifact.name,\n type: found.artifact.type,\n path: rel,\n sha256: digest,\n bytes: Buffer.byteLength(found.artifact.content, \"utf-8\"),\n });\n }\n // Stable order, so two captures of an unchanged tree produce the same bytes.\n artifacts.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n\n const git =\n options.git === false ? undefined : (options.git ?? (await readGit(root)));\n\n return {\n version: MANIFEST_VERSION,\n sessionId: options.sessionId,\n capturedAt: new Date().toISOString(),\n hookEvent: options.hookEvent ?? \"manual\",\n ...(options.reason !== undefined ? { reason: redact(options.reason) } : {}),\n ...(options.transcriptPath !== undefined\n ? { transcriptPath: redact(options.transcriptPath) }\n : {}),\n root: redact(root),\n ...(git !== undefined\n ? {\n git: {\n sha: git.sha,\n ...(git.branch !== undefined ? { branch: redact(git.branch) } : {}),\n dirty: git.dirty,\n },\n }\n : {}),\n device: { id: deviceId(), platform: platform() },\n tool: { name: \"manni-tracevals\", version: options.version ?? \"unknown\" },\n artifacts,\n config: redactDeep(options.config ?? {}, redact),\n };\n}\n\n/**\n * A stable, opaque per-machine id. Not the hostname: \"was this captured here?\"\n * is the whole question, and answering it does not require shipping the name of\n * the machine into a file that travels with the repository.\n */\nexport function deviceId(): string {\n let user = \"\";\n try {\n user = userInfo().username;\n } catch {\n // A container with no passwd entry throws; the digest is still stable.\n }\n return sha256Hex(`${hostname()} ${user} ${platform()}`).slice(0, 16);\n}\n\n/**\n * Redact every string in a JSON-shaped value. Used for the recorded config\n * only — never for a join key.\n */\nexport function redactDeep(value: unknown, redact: Redactor): unknown {\n if (typeof value === \"string\") return redact(value);\n if (Array.isArray(value)) return value.map((v) => redactDeep(v, redact));\n if (value !== null && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [key, member] of Object.entries(value)) {\n out[key] = redactDeep(member, redact);\n }\n return out;\n }\n return value;\n}\n\n/**\n * What `git` says about `root`, or nothing. Every failure mode — git absent,\n * not a repository, a timeout — degrades to an absent block, because a manifest\n * without a SHA is still a manifest with hashes in it.\n */\nexport async function readGit(root: string): Promise<ManifestGit | undefined> {\n const sha = await git([\"rev-parse\", \"HEAD\"], root);\n if (sha === null || !/^[0-9a-f]{40}$/.test(sha)) return undefined;\n const branch = await git([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], root);\n const status = await git(\n [\"status\", \"--porcelain\", \"--untracked-files=no\"],\n root,\n );\n return {\n sha,\n // Detached HEAD reports the literal \"HEAD\", which is not a branch name.\n ...(branch !== null && branch !== \"HEAD\" ? { branch } : {}),\n dirty: status !== null && status.length > 0,\n };\n}\n\n/** One `git` invocation, argv-only and bounded — the shape ADR 01011 uses. */\nfunction git(\n args: string[],\n cwd: string,\n timeoutMs = 5000,\n): Promise<string | null> {\n return new Promise((settle) => {\n let done = false;\n let child;\n try {\n // shell:false — nothing here is ever parsed as shell syntax.\n child = spawn(\"git\", args, { cwd, shell: false, windowsHide: true });\n } catch {\n settle(null);\n return;\n }\n // `finish` is declared below the timer because it clears it; the timer\n // callback only runs after both exist.\n const timer = setTimeout(() => {\n child.kill();\n finish(null);\n }, timeoutMs);\n const finish = (value: string | null): void => {\n if (done) return;\n done = true;\n clearTimeout(timer);\n settle(value);\n };\n let out = \"\";\n child.stdout.on(\"data\", (d: Buffer) => {\n out += d.toString(\"utf-8\");\n });\n child.stderr.resume();\n child.on(\"error\", () => { finish(null); });\n child.on(\"close\", (code) => { finish(code === 0 ? out.trim() : null); });\n });\n}\n"],"mappings":"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","names":["resolve","git","resolve"]}
|
|
@@ -22,29 +22,27 @@ import {
|
|
|
22
22
|
runRelocate,
|
|
23
23
|
runVendorSchema,
|
|
24
24
|
terminalConfirm
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import {
|
|
27
|
-
collect,
|
|
28
|
-
configOption,
|
|
29
|
-
explicitFalse,
|
|
30
|
-
readStdin,
|
|
31
|
-
reportConfig,
|
|
32
|
-
rowsToFindings,
|
|
33
|
-
runValidate,
|
|
34
|
-
splitList
|
|
35
|
-
} from "./chunk-NAZRLJAK.js";
|
|
25
|
+
} from "./chunk-GREQKO6M.js";
|
|
36
26
|
import {
|
|
37
27
|
LOCATION_EXTERNAL_SCHEMA,
|
|
38
28
|
LOCATION_PAGE_SCHEMA,
|
|
39
29
|
Validator,
|
|
40
30
|
applyRelocation,
|
|
31
|
+
collect,
|
|
32
|
+
configOption,
|
|
33
|
+
explicitFalse,
|
|
41
34
|
isParamName,
|
|
42
35
|
keyHome,
|
|
43
36
|
offerPrompt,
|
|
44
37
|
planRelocation,
|
|
38
|
+
readStdin,
|
|
45
39
|
relocateFailed,
|
|
46
|
-
relocationContext
|
|
47
|
-
|
|
40
|
+
relocationContext,
|
|
41
|
+
reportConfig,
|
|
42
|
+
rowsToFindings,
|
|
43
|
+
runValidate,
|
|
44
|
+
splitList
|
|
45
|
+
} from "./chunk-TUAAR3MM.js";
|
|
48
46
|
import {
|
|
49
47
|
COMMON_FORMATS,
|
|
50
48
|
COMMON_FORMAT_LIST,
|
|
@@ -60,7 +58,7 @@ import {
|
|
|
60
58
|
isQueryFormat,
|
|
61
59
|
isReportFormat,
|
|
62
60
|
render
|
|
63
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-5G53XATW.js";
|
|
64
62
|
import {
|
|
65
63
|
DocmetaError,
|
|
66
64
|
STDIN_LABEL,
|
|
@@ -70,7 +68,7 @@ import {
|
|
|
70
68
|
schemaLoadOptions,
|
|
71
69
|
supportedExtensions,
|
|
72
70
|
toJsonText
|
|
73
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-KCOFEWV5.js";
|
|
74
72
|
import {
|
|
75
73
|
fail
|
|
76
74
|
} from "./chunk-YEUYKR62.js";
|
|
@@ -79,13 +77,15 @@ import {
|
|
|
79
77
|
shouldColor
|
|
80
78
|
} from "./chunk-RNVYGWIC.js";
|
|
81
79
|
import {
|
|
82
|
-
LOCAL_FLAG_HELP,
|
|
83
80
|
notice,
|
|
84
81
|
warn
|
|
85
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-HX44GB4Z.js";
|
|
83
|
+
import {
|
|
84
|
+
LOCAL_FLAG_HELP
|
|
85
|
+
} from "./chunk-QCHVR4ZM.js";
|
|
86
86
|
import {
|
|
87
87
|
package_default
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-PCFG7E6B.js";
|
|
89
89
|
import {
|
|
90
90
|
programName
|
|
91
91
|
} from "./chunk-OWBRDNRZ.js";
|
|
@@ -1523,4 +1523,4 @@ export {
|
|
|
1523
1523
|
parseQueryParams,
|
|
1524
1524
|
buildProgram
|
|
1525
1525
|
};
|
|
1526
|
-
//# sourceMappingURL=chunk-
|
|
1526
|
+
//# sourceMappingURL=chunk-3NWX34ZI.js.map
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
canonicalSchemaRef,
|
|
7
7
|
fingerprint,
|
|
8
8
|
isErrorSeverity
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KCOFEWV5.js";
|
|
10
10
|
import {
|
|
11
11
|
palette
|
|
12
12
|
} from "./chunk-RNVYGWIC.js";
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
} from "./chunk-MNH7QO4Z.js";
|
|
17
17
|
import {
|
|
18
18
|
findGitRoot
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-XKBEHKWO.js";
|
|
20
20
|
import {
|
|
21
21
|
package_default
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-PCFG7E6B.js";
|
|
23
23
|
|
|
24
24
|
// src/meta/reporters/rule-id.ts
|
|
25
25
|
var SYNTHETIC_SCHEMA = "(parse)";
|
|
@@ -385,4 +385,4 @@ export {
|
|
|
385
385
|
renderGithub,
|
|
386
386
|
render
|
|
387
387
|
};
|
|
388
|
-
//# sourceMappingURL=chunk-
|
|
388
|
+
//# sourceMappingURL=chunk-5G53XATW.js.map
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
PROVIDERS_KEY,
|
|
4
|
-
assertKnownProvider,
|
|
5
3
|
findConfigFileSync,
|
|
6
4
|
parseCollections,
|
|
7
|
-
parseProviders,
|
|
8
5
|
readConfigFileSync
|
|
9
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XKBEHKWO.js";
|
|
7
|
+
import {
|
|
8
|
+
PROVIDERS_KEY,
|
|
9
|
+
assertKnownProvider,
|
|
10
|
+
parseProviders
|
|
11
|
+
} from "./chunk-QCHVR4ZM.js";
|
|
10
12
|
import {
|
|
11
13
|
ToolError,
|
|
12
14
|
errorMessage
|
|
@@ -813,4 +815,4 @@ export {
|
|
|
813
815
|
assertCollectionWithoutPaths,
|
|
814
816
|
byCodeUnit
|
|
815
817
|
};
|
|
816
|
-
//# sourceMappingURL=chunk-
|
|
818
|
+
//# sourceMappingURL=chunk-6KKZXB2O.js.map
|