@hawkeyexl/manni 4.3.1 → 4.4.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 +9 -1
- package/dist/batch-DFRCLY77.js +36 -0
- package/dist/build-Q5C6SX5J.js +31 -0
- package/dist/calibrate-XQILKXS3.js +31 -0
- package/dist/capture-JQMOC3BW.js +32 -0
- package/dist/check-HYNGXYJV.js +18 -0
- package/dist/check-HYNGXYJV.js.map +1 -0
- package/dist/check-NFZQLJKN.js +27 -0
- package/dist/check-NFZQLJKN.js.map +1 -0
- package/dist/check-U54XV6BP.js +40 -0
- package/dist/check-U54XV6BP.js.map +1 -0
- package/dist/chunk-252LNOEG.js +622 -0
- package/dist/chunk-252LNOEG.js.map +1 -0
- package/dist/chunk-2H7UOFLK.js +11 -0
- package/dist/chunk-2H7UOFLK.js.map +1 -0
- package/dist/chunk-2U3ORT6D.js +230 -0
- package/dist/chunk-2U3ORT6D.js.map +1 -0
- package/dist/chunk-3AFUD75K.js +23 -0
- package/dist/chunk-3AFUD75K.js.map +1 -0
- package/dist/{chunk-3R23C5DT.js → chunk-4TSWU2SU.js} +2 -14
- package/dist/chunk-4TSWU2SU.js.map +1 -0
- package/dist/chunk-5KHIFVD2.js +1192 -0
- package/dist/chunk-5KHIFVD2.js.map +1 -0
- package/dist/chunk-5YXBLLAC.js +2165 -0
- package/dist/chunk-5YXBLLAC.js.map +1 -0
- package/dist/chunk-644JVKJ4.js +3872 -0
- package/dist/chunk-644JVKJ4.js.map +1 -0
- package/dist/chunk-6OYEI2VV.js +88 -0
- package/dist/chunk-6OYEI2VV.js.map +1 -0
- package/dist/chunk-77AINBYM.js +19 -0
- package/dist/chunk-77AINBYM.js.map +1 -0
- package/dist/chunk-77HX34KD.js +1287 -0
- package/dist/chunk-77HX34KD.js.map +1 -0
- package/dist/{chunk-CFDUZRM2.js → chunk-7QMCHA4N.js} +32 -240
- package/dist/chunk-7QMCHA4N.js.map +1 -0
- package/dist/chunk-BUXDLRDT.js +455 -0
- package/dist/chunk-BUXDLRDT.js.map +1 -0
- package/dist/chunk-C6OH6CNF.js +388 -0
- package/dist/chunk-C6OH6CNF.js.map +1 -0
- package/dist/chunk-CK7SKVHR.js +1042 -0
- package/dist/chunk-CK7SKVHR.js.map +1 -0
- package/dist/chunk-CYWHFSRT.js +6737 -0
- package/dist/chunk-CYWHFSRT.js.map +1 -0
- package/dist/chunk-ERMSO34F.js +17 -0
- package/dist/chunk-ERMSO34F.js.map +1 -0
- package/dist/{chunk-IOYXPBCL.js → chunk-G3T47CFV.js} +1 -7
- package/dist/{chunk-IOYXPBCL.js.map → chunk-G3T47CFV.js.map} +1 -1
- package/dist/chunk-G7NJSREW.js +979 -0
- package/dist/chunk-G7NJSREW.js.map +1 -0
- package/dist/chunk-GLP5PSXB.js +72 -0
- package/dist/chunk-GLP5PSXB.js.map +1 -0
- package/dist/chunk-H2DLH2JI.js +198 -0
- package/dist/chunk-H2DLH2JI.js.map +1 -0
- package/dist/chunk-H6FZ66XR.js +634 -0
- package/dist/chunk-H6FZ66XR.js.map +1 -0
- package/dist/{chunk-KJR7OVDX.js → chunk-IEQHSCZG.js} +56 -137
- package/dist/chunk-IEQHSCZG.js.map +1 -0
- package/dist/chunk-IKEWBMCN.js +98 -0
- package/dist/chunk-IKEWBMCN.js.map +1 -0
- package/dist/chunk-JOHKIAVH.js +5440 -0
- package/dist/chunk-JOHKIAVH.js.map +1 -0
- package/dist/chunk-JVTNMVYU.js +10921 -0
- package/dist/chunk-JVTNMVYU.js.map +1 -0
- package/dist/chunk-K3D6FPV6.js +164 -0
- package/dist/chunk-K3D6FPV6.js.map +1 -0
- package/dist/{chunk-UBMMXS2Y.js → chunk-KCGV52AM.js} +69 -48
- package/dist/{chunk-UBMMXS2Y.js.map → chunk-KCGV52AM.js.map} +1 -1
- package/dist/chunk-LAKAWRV5.js +1651 -0
- package/dist/chunk-LAKAWRV5.js.map +1 -0
- package/dist/chunk-LJ2RDH3F.js +49 -0
- package/dist/chunk-LJ2RDH3F.js.map +1 -0
- package/dist/chunk-M2JCK5F6.js +805 -0
- package/dist/chunk-M2JCK5F6.js.map +1 -0
- package/dist/chunk-MNH7QO4Z.js +15 -0
- package/dist/chunk-MNH7QO4Z.js.map +1 -0
- package/dist/{chunk-HAPTXWU2.js → chunk-MYC3O5EJ.js} +4 -4
- package/dist/chunk-MYMBCTDE.js +387 -0
- package/dist/chunk-MYMBCTDE.js.map +1 -0
- package/dist/chunk-NCPWXHDO.js +683 -0
- package/dist/chunk-NCPWXHDO.js.map +1 -0
- package/dist/chunk-NWZ2SLYL.js +2957 -0
- package/dist/chunk-NWZ2SLYL.js.map +1 -0
- package/dist/chunk-OBFENF3U.js +934 -0
- package/dist/chunk-OBFENF3U.js.map +1 -0
- package/dist/chunk-OWBRDNRZ.js +16 -0
- package/dist/chunk-OWBRDNRZ.js.map +1 -0
- package/dist/{chunk-KTSJ2ZHA.js → chunk-PAU352SV.js} +5 -3
- package/dist/{chunk-KTSJ2ZHA.js.map → chunk-PAU352SV.js.map} +1 -1
- package/dist/chunk-PCE7QHXJ.js +68 -0
- package/dist/chunk-PCE7QHXJ.js.map +1 -0
- package/dist/chunk-PCHZY2I7.js +299 -0
- package/dist/chunk-PCHZY2I7.js.map +1 -0
- package/dist/chunk-PHF3D7ER.js +1042 -0
- package/dist/chunk-PHF3D7ER.js.map +1 -0
- package/dist/chunk-Q35YIDBV.js +1202 -0
- package/dist/chunk-Q35YIDBV.js.map +1 -0
- package/dist/chunk-RLR4TKUZ.js +4398 -0
- package/dist/chunk-RLR4TKUZ.js.map +1 -0
- package/dist/chunk-RNVYGWIC.js +30 -0
- package/dist/chunk-RNVYGWIC.js.map +1 -0
- package/dist/chunk-SE4JN5XN.js +19 -0
- package/dist/chunk-SE4JN5XN.js.map +1 -0
- package/dist/chunk-TIUTIOFB.js +25 -0
- package/dist/chunk-TIUTIOFB.js.map +1 -0
- package/dist/chunk-TU2WUBVZ.js +2 -0
- package/dist/chunk-TU2WUBVZ.js.map +1 -0
- package/dist/chunk-TZOYZK2E.js +98 -0
- package/dist/chunk-TZOYZK2E.js.map +1 -0
- package/dist/chunk-UKZNLVJW.js +17 -0
- package/dist/chunk-UKZNLVJW.js.map +1 -0
- package/dist/chunk-UZC7LDAQ.js +178 -0
- package/dist/chunk-UZC7LDAQ.js.map +1 -0
- package/dist/chunk-V46OILVC.js +3090 -0
- package/dist/chunk-V46OILVC.js.map +1 -0
- package/dist/chunk-WQE54PNH.js +1975 -0
- package/dist/chunk-WQE54PNH.js.map +1 -0
- package/dist/chunk-X3BPBDGQ.js +52 -0
- package/dist/chunk-X3BPBDGQ.js.map +1 -0
- package/dist/chunk-XSLV76YK.js +54 -0
- package/dist/chunk-XSLV76YK.js.map +1 -0
- package/dist/{chunk-5HNHEUD5.js → chunk-XYLUCIKQ.js} +3 -3
- package/dist/chunk-YEUYKR62.js +72 -0
- package/dist/chunk-YEUYKR62.js.map +1 -0
- package/dist/{chunk-G5CM2VGQ.js → chunk-YFQBFNQS.js} +8 -94
- package/dist/chunk-YFQBFNQS.js.map +1 -0
- package/dist/chunk-YIL4XLLJ.js +1661 -0
- package/dist/chunk-YIL4XLLJ.js.map +1 -0
- package/dist/chunk-YNHZHSSM.js +41 -0
- package/dist/chunk-YNHZHSSM.js.map +1 -0
- package/dist/chunk-YTCZRLTU.js +96 -0
- package/dist/chunk-YTCZRLTU.js.map +1 -0
- package/dist/chunk-YYBFZLAJ.js +374 -0
- package/dist/chunk-YYBFZLAJ.js.map +1 -0
- package/dist/chunk-ZXRAE55H.js +31 -0
- package/dist/chunk-ZXRAE55H.js.map +1 -0
- package/dist/cli-2QPR2OZG.js +232 -0
- package/dist/cli-2QPR2OZG.js.map +1 -0
- package/dist/cli-4IOPGZHR.js +1203 -0
- package/dist/cli-4IOPGZHR.js.map +1 -0
- package/dist/cli-5FL73WHA.js +346 -0
- package/dist/cli-5FL73WHA.js.map +1 -0
- package/dist/cli-C262QOWM.js +739 -0
- package/dist/cli-C262QOWM.js.map +1 -0
- package/dist/cli-LJLLIQB2.js +423 -0
- package/dist/cli-LJLLIQB2.js.map +1 -0
- package/dist/cli-OFPZ5MAS.js +626 -0
- package/dist/cli-OFPZ5MAS.js.map +1 -0
- package/dist/cli-SHSMSRQY.js +28 -0
- package/dist/cli-SHSMSRQY.js.map +1 -0
- package/dist/cli-SRHFUZHA.js +473 -0
- package/dist/cli-SRHFUZHA.js.map +1 -0
- package/dist/cli-URZQXL4K.js +552 -0
- package/dist/cli-URZQXL4K.js.map +1 -0
- package/dist/cli.d.ts +12 -2
- package/dist/cli.js +109 -7661
- package/dist/cli.js.map +1 -1
- package/dist/docmeta.js +15 -3
- package/dist/docmeta.js.map +1 -1
- package/dist/github-FE6KCNYJ.js +27 -0
- package/dist/github-FE6KCNYJ.js.map +1 -0
- package/dist/github-QXL3VMK2.js +32 -0
- package/dist/github-QXL3VMK2.js.map +1 -0
- package/dist/index.d.ts +65 -3
- package/dist/index.js +407 -337
- package/dist/index.js.map +1 -1
- package/dist/json-7WV7KL6H.js +17 -0
- package/dist/json-7WV7KL6H.js.map +1 -0
- package/dist/json-SGZ6ZRFD.js +35 -0
- package/dist/json-SGZ6ZRFD.js.map +1 -0
- package/dist/lint-DL4LJRAY.js +28 -0
- package/dist/lint-DL4LJRAY.js.map +1 -0
- package/dist/list-6BAXTZUM.js +29 -0
- package/dist/list-6BAXTZUM.js.map +1 -0
- package/dist/list-7BKNYPSB.js +31 -0
- package/dist/list-7BKNYPSB.js.map +1 -0
- package/dist/page-3U2GCFNE.js +41 -0
- package/dist/page-3U2GCFNE.js.map +1 -0
- package/dist/picker-3XF36MJF.js +14 -0
- package/dist/picker-3XF36MJF.js.map +1 -0
- package/dist/pretty-2H57QVTY.js +43 -0
- package/dist/pretty-2H57QVTY.js.map +1 -0
- package/dist/pretty-N6DO4OOL.js +37 -0
- package/dist/pretty-N6DO4OOL.js.map +1 -0
- package/dist/reporters-M6LJ2IYU.js +21 -0
- package/dist/reporters-M6LJ2IYU.js.map +1 -0
- package/dist/reporters-N6GHXSS7.js +42 -0
- package/dist/reporters-N6GHXSS7.js.map +1 -0
- package/dist/reporters-UCNEV7PH.js +71 -0
- package/dist/reporters-UCNEV7PH.js.map +1 -0
- package/dist/run-XZDAREJE.js +33 -0
- package/dist/run-XZDAREJE.js.map +1 -0
- package/dist/term-5ICGKPC3.js +1592 -0
- package/dist/term-5ICGKPC3.js.map +1 -0
- package/dist/types-Y6TXHM7M.js +10 -0
- package/dist/types-Y6TXHM7M.js.map +1 -0
- package/dist/validate-GQRM77YN.js +16 -0
- package/dist/validate-GQRM77YN.js.map +1 -0
- package/package.json +1 -1
- package/plugin/manni/.claude-plugin/plugin.json +9 -0
- package/plugin/manni/hooks/hooks.json +52 -0
- package/plugin/manni/skills/check/SKILL.md +20 -0
- package/plugin/manni/skills/evals/SKILL.md +27 -0
- package/plugin/manni/skills/fix/SKILL.md +56 -0
- package/plugin/manni/skills/setup/SKILL.md +41 -0
- package/dist/batch-A5HZKYIW.js +0 -18
- package/dist/calibrate-S5K6QHUY.js +0 -13
- package/dist/capture-OZEZDABQ.js +0 -15
- package/dist/chunk-3R23C5DT.js.map +0 -1
- package/dist/chunk-CFDUZRM2.js.map +0 -1
- package/dist/chunk-G5CM2VGQ.js.map +0 -1
- package/dist/chunk-KJR7OVDX.js.map +0 -1
- package/dist/chunk-V4KUVE47.js +0 -27170
- package/dist/chunk-V4KUVE47.js.map +0 -1
- package/dist/chunk-ZQBTK3DO.js +0 -26518
- package/dist/chunk-ZQBTK3DO.js.map +0 -1
- package/dist/picker-6HRMETE7.js +0 -12
- package/plugin/tracevals/.claude-plugin/plugin.json +0 -9
- package/plugin/tracevals/hooks/hooks.json +0 -17
- /package/dist/{batch-A5HZKYIW.js.map → batch-DFRCLY77.js.map} +0 -0
- /package/dist/{calibrate-S5K6QHUY.js.map → build-Q5C6SX5J.js.map} +0 -0
- /package/dist/{capture-OZEZDABQ.js.map → calibrate-XQILKXS3.js.map} +0 -0
- /package/dist/{picker-6HRMETE7.js.map → capture-JQMOC3BW.js.map} +0 -0
- /package/dist/{chunk-HAPTXWU2.js.map → chunk-MYC3O5EJ.js.map} +0 -0
- /package/dist/{chunk-5HNHEUD5.js.map → chunk-XYLUCIKQ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tracevals/calibrate/labels.ts","../src/tracevals/calibrate/labels-schema.json","../src/tracevals/core/config.ts","../src/tracevals/core/config-schema.json","../src/tracevals/judge/redact.ts","../src/tracevals/capture/types.ts","../src/tracevals/capture/manifest.ts","../src/tracevals/trace/availability.ts","../src/tracevals/artifacts/availability.ts","../src/tracevals/artifacts/fs.ts","../src/tracevals/artifacts/resolve.ts","../src/tracevals/evals/schema.ts","../src/tracevals/evals/extract.ts"],"sourcesContent":["/**\n * The calibration labels sidecar (ADR 01022).\n *\n * A label is a human's answer for one `(trace, artifact, eval)`. It lives in\n * its own file rather than in the eval entry for two reasons: the vendored\n * `artifact-evals` vocabulary is docmeta's and `inlineEval` is closed to\n * additions (ADR 01010), and — more importantly — a label is a property of a\n * *corpus and a reviewer*, not of the artifact. Two teams calibrating the same\n * skill against different sessions hold different ground truth, and neither\n * belongs in the SKILL.md.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\nimport { Ajv2020 } from \"ajv/dist/2020.js\";\nimport { parse as parseYaml } from \"yaml\";\nimport labelsSchemaJson from \"./labels-schema.json\" with { type: \"json\" };\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { TracevalsError } from \"../types.js\";\nimport type { ArtifactType } from \"../artifacts/types.js\";\n\nconst labelsSchema = labelsSchemaJson as Record<string, unknown>;\n\n/** Conventional location inside a project; overridable with `--labels`. */\nexport const DEFAULT_LABELS_FILE = \"tracevals/labels.yaml\";\n\n/**\n * What a human decided. `needs-review` is a legitimate label, not a cop-out:\n * an eval you found genuinely ambiguous is the one that tells you whether the\n * review band is set sensibly, and the docs have always asked for a couple.\n */\nexport type LabelOutcome = \"pass\" | \"fail\" | \"needs-review\";\n\nexport interface EvalLabel {\n /** Path exactly as written in the file, for error messages. */\n trace: string;\n /** Resolved absolute path — the join key against the batch corpus. */\n traceFile: string;\n artifact: string;\n /** Only when the file disambiguates a name shared by two artifact kinds. */\n type?: ArtifactType;\n eval: string;\n expected: LabelOutcome;\n note?: string;\n}\n\nconst ajv = new Ajv2020({ allErrors: true });\nconst validate = ajv.compile(labelsSchema);\n\n/**\n * Stable identity for one label, and the duplicate-detection key.\n *\n * The separator is written as a backslash-u escape, never as a literal NUL:\n * the runtime value is identical, but a literal one makes git call the file\n * binary — its diff renders as `Bin 0 -> N bytes` and cannot be reviewed or\n * three-way merged, and `grep` answers `Binary file … matches` and stops.\n * `test/unit/source-text-safety.test.ts` holds the whole tree to this.\n */\nexport const labelKey = (\n traceFile: string,\n artifact: string,\n evalName: string,\n type?: ArtifactType,\n): string => `${traceFile}\\u0000${type ?? \"\"}\\u0000${artifact}\\u0000${evalName}`;\n\n/**\n * Validate a labels document and resolve its trace paths.\n *\n * `file` is the path the text came from; trace paths resolve against **its**\n * directory rather than the working directory, matching how `plugins` resolves\n * against the config file that names them. A labels file travels with its\n * corpus, so it must mean the same thing from any cwd.\n */\nexport function parseLabels(text: string, file: string): EvalLabel[] {\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (err) {\n throw new TracevalsError(\n `could not parse ${file}: ${errorMessage(err)}`,\n );\n }\n if (raw === null || raw === undefined) {\n throw new TracevalsError(`invalid labels file ${file}: it is empty`);\n }\n if (!validate(raw)) {\n const detail = (validate.errors ?? [])\n .map((e) => `${e.instancePath || \"/\"} ${e.message ?? \"invalid\"}`)\n .join(\"; \");\n // The empty-list case gets its own wording: \"must NOT have fewer than 1\n // items\" describes the schema, not the mistake.\n const empty = (validate.errors ?? []).some(\n (e) => e.instancePath === \"/labels\" && e.keyword === \"minItems\",\n );\n throw new TracevalsError(\n empty\n ? `invalid labels file ${file}: it must carry at least one label — an empty one measures nothing`\n : `invalid labels file ${file}: ${detail}`,\n );\n }\n\n const base = dirname(resolve(file));\n const labels: EvalLabel[] = [];\n const seen = new Set<string>();\n for (const entry of (raw as { labels: Record<string, string>[] }).labels) {\n const traceFile = resolve(base, entry.trace as string);\n const type = entry.type as ArtifactType | undefined;\n const key = labelKey(\n traceFile,\n entry.artifact as string,\n entry.eval as string,\n type,\n );\n if (seen.has(key)) {\n // Two answers for one question is not a merge problem to resolve at run\n // time — whichever won would silently decide the measurement.\n throw new TracevalsError(\n `invalid labels file ${file}: duplicate label for ${entry.artifact ?? \"?\"} › ${entry.eval ?? \"?\"} on ${entry.trace ?? \"?\"}`,\n );\n }\n seen.add(key);\n labels.push({\n trace: entry.trace as string,\n traceFile,\n artifact: entry.artifact as string,\n ...(type !== undefined ? { type } : {}),\n eval: entry.eval as string,\n expected: entry.expected as LabelOutcome,\n ...(entry.note !== undefined ? { note: entry.note } : {}),\n });\n }\n return labels;\n}\n\nexport async function loadLabels(file: string): Promise<EvalLabel[]> {\n let text: string;\n try {\n text = await readFile(file, \"utf-8\");\n } catch (err) {\n throw new TracevalsError(\n `could not read labels file ${file}: ${errorMessage(err)}`,\n );\n }\n return parseLabels(text, file);\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"manni:tracevals:calibration-labels\",\n \"title\": \"manni tracevals calibration labels\",\n \"description\": \"Ground truth for `manni tracevals calibrate`: what a human decided a given eval should have produced on a given trace. A sidecar rather than an eval field, because a label belongs to a corpus and a reviewer, not to the artifact — and because the eval vocabulary is docmeta's, vendored byte-identical, with `inlineEval` closed to additions (ADR 01010).\",\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"version\", \"labels\"],\n \"properties\": {\n \"version\": {\n \"const\": 1,\n \"description\": \"Format version. Pinned so a future shape change is an explicit migration rather than a silently-reinterpreted file.\"\n },\n \"labels\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"description\": \"One entry per (trace, artifact, eval) you have judged by hand.\",\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"trace\", \"artifact\", \"eval\", \"expected\"],\n \"properties\": {\n \"trace\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Path to the trace file, resolved against this file's own directory — not the working directory.\"\n },\n \"artifact\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Artifact name as the report shows it: a skill name, a subagent_type, or a project-rules filename such as CLAUDE.md.\"\n },\n \"type\": {\n \"enum\": [\"skill\", \"agent\", \"project-rules\", \"slash-command\"],\n \"description\": \"Optional disambiguator, needed when one name resolves to two kinds of artifact — a skill and an agent, or a skill and the slash command that types it. Every `ArtifactType` the resolver can produce belongs here: a label whose type this rejects has no way to name the artifact it means.\"\n },\n \"eval\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The eval's id. Shorthand entries with no declared id get a positional one (eval-1, eval-2, ...), so labelling those is only as stable as the order they are written in.\"\n },\n \"expected\": {\n \"enum\": [\"pass\", \"fail\", \"needs-review\"],\n \"description\": \"What you decided. `needs-review` means you found it genuinely ambiguous and want the tool to defer too.\"\n },\n \"note\": {\n \"type\": \"string\",\n \"description\": \"Why you decided that. Carried into the disagreement report, where it is the whole reason a disagreement is actionable.\"\n }\n }\n }\n }\n }\n}\n","/**\n * Config loading. Every knob flows config → Ajv validate → defaults → CLI\n * override (`??` at the read site) → runtime; parseConfig() fills every\n * default so downstream code never re-applies one.\n *\n * Settings live under a `tracevals:` key in `manni.config.yaml`, one file\n * shared by the whole manni family. Sibling keys belong to other tools and are\n * ignored here, so parseConfig() validates the section — never the file root.\n * Finding the file is the shared loader's job (`src/shared/config-file.ts`).\n */\nimport { Ajv2020 } from \"ajv/dist/2020.js\";\nimport configSchemaJson from \"./config-schema.json\" with { type: \"json\" };\nimport {\n FAMILY_CONFIG_NAMES,\n findConfigFileSync,\n readConfigFileSync,\n type ConfigFileOptions,\n} from \"../../shared/config-file.js\";\nimport type { CollectionConfig } from \"../../shared/collections.js\";\nimport {\n assertKnownProvider,\n type ProvidersConfig,\n} from \"../../shared/providers.js\";\nimport { compileRedactPatterns } from \"../judge/redact.js\";\nimport { DEFAULT_CAPTURE_DIR } from \"../capture/types.js\";\nimport { DEFAULT_LABELS_FILE } from \"../calibrate/labels.js\";\nimport { TracevalsError } from \"../types.js\";\nimport {\n configuredGrants,\n EXECUTION_GRANTS,\n isExecutionGrant,\n unknownGrantsMessage,\n type ExecutionGrant,\n} from \"../../shared/execution.js\";\n\nconst configSchema = configSchemaJson as Record<string, unknown>;\n\nexport const DEFAULT_CONFIG_FILENAME =\n FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\";\n\n/**\n * Top-level key holding this tool's settings inside the shared family config.\n * Sibling tools (meta, docevals) own their own keys in the same file.\n */\nexport const CONFIG_SECTION_KEY = \"tracevals\";\n\n/**\n * The section key as an error's instance path spells it. The schema describes\n * the section rather than the file, so Ajv's own paths start below it; a\n * message that said `/provider` would name a key nobody writes at the root.\n */\nconst CONFIG_SECTION_KEY_PATH = `/${CONFIG_SECTION_KEY}`;\n\n/**\n * No legacy filename. The family file is the only one read, so a file named\n * for the tool is not config however it is spelled, and nothing warns about\n * one because nothing looks for it.\n */\nconst CONFIG_FILE: ConfigFileOptions = {\n section: CONFIG_SECTION_KEY,\n legacyNames: [],\n toError: (message) => new TracevalsError(message),\n};\n\nexport interface TracevalsConfig {\n /**\n * Which provider judges, as `tracevals.provider` names it. `null` when the\n * key is absent, which defers to the family's `providers.provider`. The\n * connection settings are never here: they are `providers` below.\n */\n provider: string | null;\n /** The model within `provider`; `null` when unset. manni pins none. */\n model: string | null;\n /** The family's top-level `providers:` map, parsed by the shared loader. */\n providers: ProvidersConfig;\n /** The file as the user would name it, for messages. */\n configSource: string;\n judge: {\n ensembleRuns: number;\n temperature: number;\n zones: { autoPass: number; autoFail: number };\n cacheDir: string;\n /**\n * Ensemble runs this invocation may spend, or `null` for unbounded. A\n * cached ensemble spends none, and an eval the budget cannot cover is\n * `skipped` with the `turn budget` reason rather than dropped.\n */\n maxTurns: number | null;\n /**\n * Extra patterns scrubbed from the session digest before it reaches a\n * provider, applied *on top of* the built-in secret shapes (ADR 01020).\n * Always a list; validated for compilability at load time.\n */\n redact: string[];\n };\n render: {\n maxBlockChars: number;\n maxTotalChars: number;\n };\n /**\n * What content-authored code a run may execute: the grants it holds, every\n * one unless the operator narrows it (proposal 0075). A `command` eval runs\n * only under `frontmatter-commands`; `[]` runs none and reports them\n * `skipped`.\n */\n execution: { allow: ExecutionGrant[] };\n history: {\n file: string;\n };\n /**\n * Session manifests (ADR 01024). `capture` writes one here; `run` looks here\n * for the trace's own, and reports a `skipped` hash check when there is none.\n */\n capture: {\n /** Resolved against the project root, not the working directory. */\n dir: string;\n };\n fill: {\n /** Minimum self-reported confidence a proposal needs to be written. */\n confidenceThreshold: number;\n maxEvalsPerArtifact: number;\n temperature: number;\n cacheDir: string;\n /** Inference calls this invocation may spend, or `null` for unbounded. */\n maxTurns: number | null;\n };\n /**\n * `calibrate` — measuring the judge against a human's answers (ADR 01022).\n * The sweep grid lives here rather than behind flags because the useful\n * range is a property of a corpus, and a corpus outlives an invocation.\n */\n calibrate: {\n /** Labels sidecar, resolved against the config file's directory. */\n labels: string;\n /** Thresholds. Unset means the run measures without gating. */\n maxFalsePass?: number;\n maxFalseFail?: number;\n maxReview?: number;\n sweep: {\n ensembleRuns: number[];\n autoPass: number[];\n autoFail: number[];\n };\n };\n failOnReview: boolean;\n /**\n * Module specifiers imported before evals are planned, so a `registerGrader`\n * call from outside this package lands in time (ADR 01017). Resolved against\n * the config file's directory, in order — a later entry wins a colliding\n * kind. `--require` appends to this list rather than replacing it.\n */\n plugins: string[];\n /** List offered-but-unused artifacts in coverage, not just count them. */\n reportUnusedArtifacts: boolean;\n}\n\n// `verbose` puts the parent schema on each error, so an unknown key can be\n// checked against the keys its section does have.\nconst ajv = new Ajv2020({ allErrors: true, verbose: true });\nconst validate = ajv.compile(configSchema);\n\n/**\n * `; did you mean \"ensembleRuns\"?` when `key` is the kebab spelling of a key\n * its section has. Only the exact counterpart: a guess at a near miss is\n * advice that can be wrong, and the kebab spelling is the one mistake a\n * reader of the frontmatter vocabulary is likely to make here.\n */\nfunction camelCaseHint(key: string, parentSchema: unknown): string {\n const camel = key.replace(/-([a-z0-9])/g, (_, c: string) => c.toUpperCase());\n if (camel === key || parentSchema === null || typeof parentSchema !== \"object\") {\n return \"\";\n }\n const properties = (parentSchema as { properties?: unknown }).properties;\n return properties !== null &&\n typeof properties === \"object\" &&\n Object.hasOwn(properties, camel)\n ? `; did you mean \"${camel}\"?`\n : \"\";\n}\n\n/**\n * The hint on an old `provider:` object. The key used to hold a `default` and\n * a section per provider; it is now the provider's name, as `docevals.provider`\n * and `fill.provider` are, and the connection settings moved to the family's\n * top-level `providers:` map, which every tool reads. Ajv's own message says\n * it must be a string, which is true and leaves the reader to find out where\n * the settings went.\n */\nfunction movedProviderHint(instancePath: string, keyword: string): string {\n return instancePath === \"/provider\" && keyword === \"type\"\n ? `; \"provider\" is now a provider name; per-provider settings moved to the top-level providers: map`\n : \"\";\n}\n\n/**\n * The section as the schema admits it: every key optional, because\n * `parseConfig` supplies the defaults. Ajv has checked the document against\n * `config-schema.json` before it is read as this, so the one cast below is\n * where the validated document becomes a typed one.\n */\ninterface RawConfig {\n provider?: string;\n model?: string;\n judge?: {\n ensembleRuns?: number;\n temperature?: number;\n zones?: { autoPass?: number; autoFail?: number };\n cacheDir?: string;\n maxTurns?: number;\n redact?: string[];\n };\n render?: { maxBlockChars?: number; maxTotalChars?: number };\n execution?: { allow?: ExecutionGrant[] };\n history?: { file?: string };\n capture?: { dir?: string };\n fill?: {\n confidenceThreshold?: number;\n maxEvalsPerArtifact?: number;\n temperature?: number;\n cacheDir?: string;\n maxTurns?: number;\n };\n calibrate?: {\n labels?: string;\n maxFalsePass?: number;\n maxFalseFail?: number;\n maxReview?: number;\n sweep?: { ensembleRuns?: number[]; autoPass?: number[]; autoFail?: number[] };\n };\n failOnReview?: boolean;\n plugins?: string[];\n reportUnusedArtifacts?: boolean;\n}\n\n/** What the file the section came from carries beside it. */\nexport interface ConfigFileContext {\n /** The file as the user would name it, for messages. */\n source?: string;\n /** The file's top-level `providers:`; `{}` when it declares none. */\n providers?: ProvidersConfig;\n}\n\nexport function parseConfig(\n raw: unknown,\n file: ConfigFileContext = {},\n): TracevalsConfig {\n const source = file.source ?? DEFAULT_CONFIG_FILENAME;\n // Before the schema: Ajv's enum error names neither the value nor the\n // grants that exist, and a grant is the key where a misreading costs most.\n const unknownGrants = configuredGrants(raw).filter((g) => !isExecutionGrant(g));\n if (unknownGrants.length > 0) {\n throw new TracevalsError(`${source}: ${unknownGrantsMessage(unknownGrants)}`);\n }\n if (!validate(raw)) {\n const detail = (validate.errors ?? [])\n .map((e) => {\n // Ajv reports an unknown key against the *parent* object, so the bare\n // message (\"must NOT have additional properties\") leaves the reader to\n // diff their file against the schema to find which key it meant. Name\n // it: the common case is a removed key in an unmigrated config —\n // `judge.maxCostUsd` after the turn budget landed, say — and a\n // migration error that makes you guess is one people work around.\n const extra =\n e.keyword === \"additionalProperties\"\n ? (e.params as { additionalProperty?: string }).additionalProperty\n : undefined;\n return extra !== undefined\n ? `unknown key \"${extra}\"${camelCaseHint(extra, e.parentSchema)}`\n : `${CONFIG_SECTION_KEY_PATH}${e.instancePath} ${e.message ?? \"is invalid\"}` +\n movedProviderHint(e.instancePath, e.keyword);\n })\n .join(\"; \");\n throw new TracevalsError(`${source}: ${detail}`);\n }\n const r = raw as RawConfig;\n // Checked here, with the message every other tool in the family gives, so a\n // typo is caught by every verb and not only the ones that reach a model.\n // Whether a model has a provider to own it waits for the flags: a\n // `--provider`, or the family's `providers.provider`, can supply the\n // provider a configured model needs.\n const provider = r.provider ?? null;\n if (provider !== null) {\n assertKnownProvider(provider, (message) => new TracevalsError(message));\n }\n const config: TracevalsConfig = {\n provider,\n model: r.model ?? null,\n providers: file.providers ?? {},\n configSource: source,\n judge: {\n ensembleRuns: r.judge?.ensembleRuns ?? 3,\n temperature: r.judge?.temperature ?? 0,\n zones: {\n autoPass: r.judge?.zones?.autoPass ?? 0.8,\n autoFail: r.judge?.zones?.autoFail ?? 0.8,\n },\n cacheDir: r.judge?.cacheDir ?? \".manni/tracevals/cache\",\n // `null`, not a number: unbounded is a state, and any number here would\n // be a ceiling nobody asked for.\n maxTurns: r.judge?.maxTurns ?? null,\n // Always a list: the render site concatenates nothing onto it, but a\n // hole here would be a special case in every consumer.\n redact: [...(r.judge?.redact ?? [])],\n },\n render: {\n maxBlockChars: r.render?.maxBlockChars ?? 2000,\n maxTotalChars: r.render?.maxTotalChars ?? 150000,\n },\n execution: { allow: [...(r.execution?.allow ?? EXECUTION_GRANTS)] },\n history: {\n file: r.history?.file ?? \".manni/tracevals/history.jsonl\",\n },\n capture: {\n // Beside the judge cache, under the state directory that already travels\n // with the project — which is what puts a manifest next to its trace in\n // the CI patterns the docs describe.\n dir: r.capture?.dir ?? DEFAULT_CAPTURE_DIR,\n },\n fill: {\n // 0.7 matches the manuscript's calibration bar for judged agreement.\n confidenceThreshold: r.fill?.confidenceThreshold ?? 0.7,\n maxEvalsPerArtifact: r.fill?.maxEvalsPerArtifact ?? 8,\n temperature: r.fill?.temperature ?? 0,\n // Separate from the judge cache: different key scheme and value shape.\n cacheDir: r.fill?.cacheDir ?? \".manni/tracevals/cache/fill\",\n maxTurns: r.fill?.maxTurns ?? null,\n },\n calibrate: {\n labels: r.calibrate?.labels ?? DEFAULT_LABELS_FILE,\n sweep: {\n // Spans the range rather than filling it: the first sweep judges the\n // corpus at the largest value here, so a wide grid is the one part of\n // calibration that does cost money.\n ensembleRuns: [...(r.calibrate?.sweep?.ensembleRuns ?? [1, 3, 5])],\n autoPass: [\n ...(r.calibrate?.sweep?.autoPass ?? [0.5, 0.6, 0.7, 0.8, 0.9, 0.95]),\n ],\n autoFail: [\n ...(r.calibrate?.sweep?.autoFail ?? [0.5, 0.6, 0.7, 0.8, 0.9, 0.95]),\n ],\n },\n },\n failOnReview: r.failOnReview ?? true,\n // Always a list, never undefined: the read site concatenates `--require`\n // onto it, and a hole there would be a special case in every caller.\n plugins: [...(r.plugins ?? [])],\n // An observation, not a gate: listing it is opt-in because a real roster\n // runs to hundreds of skills (ADR 01016).\n reportUnusedArtifacts: r.reportUnusedArtifacts ?? false,\n };\n // Compilability is not expressible in JSON Schema, and a pattern that cannot\n // compile must fail here rather than at the moment a digest is about to be\n // sent — a dropped redaction pattern is a silent leak.\n compileRedactPatterns(config.judge.redact);\n // Left absent rather than defaulted to a number: `0` is a meaningful limit\n // (\"no false pass at all\"), so it cannot double as \"unset\".\n for (const key of [\"maxFalsePass\", \"maxFalseFail\", \"maxReview\"] as const) {\n if (typeof r.calibrate?.[key] === \"number\") {\n config.calibrate[key] = r.calibrate[key];\n }\n }\n return config;\n}\n\n/** This tool's config, and the directory its relative paths resolve from. */\nexport interface LoadedConfig {\n config: TracevalsConfig;\n /**\n * The directory holding the config file, or `dir` when none was found.\n * Plugin specifiers and the labels default resolve against it, so a\n * committed config means the same thing from any working directory.\n */\n dir: string;\n /**\n * The file's top-level `collections:` (proposal 0041); `[]` with no config.\n *\n * Collections never choose tracevals' inputs — `run` and `calibrate` take\n * traces, `fill` detects artifacts under `--project` — and there is no\n * `--collection`. What they say is *where a relocated `metadata` block\n * lives*, so a declared manifest is read for the evals an artifact no longer\n * carries inline (proposals 0047 and 0049 §1).\n */\n collections: CollectionConfig[];\n /**\n * The config file's absolute path; absent when there is none. A keyless\n * manifest owns what an artifact's schemas mark external (proposal 0068),\n * and those schemas are read from meta's section of this same file.\n */\n path?: string;\n}\n\n/** How a command was told to find its config: `-c` and `--no-config`. */\nexport interface ConfigLookup {\n /** `-c/--config`: read this file instead of discovering one. */\n configPath?: string;\n /** `--no-config`: skip discovery and run on the built-in defaults. */\n noConfig?: boolean;\n}\n\n/**\n * Discover the family config from `dir` (cwd by default) upward to the\n * repository root and return this tool's section (`src/shared/config-file.ts`:\n * `manni.config.yaml` read at its `tracevals:` key, with the family's\n * top-level `providers:` beside it). An absent file — or one that carries only\n * other tools' sections — yields defaults.\n *\n * `-c` names a file and skips the walk; `--no-config` skips the file\n * altogether and runs on the built-in defaults, with `dir` still anchoring\n * whatever the config would otherwise have anchored.\n */\nexport async function discoverConfig(\n dir = process.cwd(),\n lookup: ConfigLookup = {},\n): Promise<LoadedConfig> {\n if (lookup.noConfig === true) {\n // No config means no collections, so no manifest owns anything and every\n // artifact's evals are its own front matter's — the same rule cite states.\n return { config: parseConfig({}), dir, collections: [] };\n }\n const file = await Promise.resolve().then(() =>\n lookup.configPath === undefined\n ? findConfigFileSync(dir, CONFIG_FILE)\n : readConfigFileSync(lookup.configPath, dir, CONFIG_FILE),\n );\n if (file === null) return { config: parseConfig({}), dir, collections: [] };\n return {\n config: parseConfig(file.value ?? {}, {\n source: file.source,\n ...(file.providers !== undefined ? { providers: file.providers } : {}),\n }),\n dir: file.dir,\n collections: file.collections,\n path: file.path,\n };\n}\n\n/** `discoverConfig`, for callers that only want the settings. */\nexport async function loadConfig(\n dir = process.cwd(),\n lookup: ConfigLookup = {},\n): Promise<TracevalsConfig> {\n return (await discoverConfig(dir, lookup)).config;\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"manni:tracevals:config\",\n \"title\": \"tracevals section of manni.config.yaml\",\n \"description\": \"Settings for manni tracevals, held under the `tracevals` key of the config file shared by the manni family of tools. Sibling keys belong to other tools and are not validated here.\",\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"provider\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Which provider judges: auto, anthropic, openai, claude-cli, or llama-cpp. Overrides the family's top-level `providers.provider` for tracevals only. Connection settings — an endpoint, an API key's environment variable, the Claude CLI command — live in that top-level `providers:` map, never here.\"\n },\n \"model\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The model within `provider`, which must be named at this level. Unset, the inference library's default for the winning provider is used; manni pins no model id of its own.\"\n },\n \"judge\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"ensembleRuns\": { \"type\": \"integer\", \"minimum\": 1 },\n \"temperature\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 2 },\n \"zones\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"autoPass\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 },\n \"autoFail\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 }\n }\n },\n \"cacheDir\": { \"type\": \"string\" },\n \"maxTurns\": { \"type\": \"integer\", \"minimum\": 1, \"description\": \"Stop after this many ensemble runs. A cached ensemble spends none. Unset means unbounded; the remaining evals report `skipped` with the reason `turn budget` rather than aborting the run.\" },\n \"redact\": {\n \"type\": \"array\",\n \"description\": \"Extra regular expressions scrubbed from the session digest before it is sent to a judge provider. Applied on top of the built-in secret shapes, never instead of them; each source is compiled with the `g` flag, and a match is replaced with `[redacted]`. Pattern matching is best-effort — --deterministic-only is the only setting that guarantees nothing leaves the machine.\",\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n },\n \"execution\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"description\": \"Operator grant for executing content-authored code.\",\n \"properties\": {\n \"allow\": {\n \"type\": \"array\",\n \"items\": { \"enum\": [\"frontmatter-commands\"] },\n \"default\": [\"frontmatter-commands\"],\n \"description\": \"Which content-authored code a run may execute. Absent, every grant holds; list fewer to narrow it, or write [] to run none. frontmatter-commands lets `command` evals declared in an artifact's front matter run; without it they report `skipped` with a reason, never `pass`.\"\n }\n }\n },\n \"render\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"maxBlockChars\": { \"type\": \"integer\", \"minimum\": 100 },\n \"maxTotalChars\": {\n \"type\": \"integer\",\n \"minimum\": 1000,\n \"description\": \"Upper bound on the rendered digest, in characters. The timeline always keeps at least 200 characters, so a very long header can push the digest past this bound by up to 200.\"\n }\n }\n },\n \"history\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"file\": { \"type\": \"string\" }\n }\n },\n \"capture\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"description\": \"Session manifests — sha256 of every instruction artifact plus the git SHA, recorded at session start by `manni tracevals capture` and read back by `run` to make staleness exact instead of an mtime guess. See ADR 01024.\",\n \"properties\": {\n \"dir\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Directory manifests are written to and looked for, resolved against the project root. `run` also accepts one placed beside the trace as `<trace>.manifest.json`, and --manifest names one outright.\"\n }\n }\n },\n \"fill\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"confidenceThreshold\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 },\n \"maxEvalsPerArtifact\": { \"type\": \"integer\", \"minimum\": 1 },\n \"temperature\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 2 },\n \"cacheDir\": { \"type\": \"string\" },\n \"maxTurns\": { \"type\": \"integer\", \"minimum\": 1, \"description\": \"Stop after this many inference calls, one per artifact filled. A cached artifact spends none. Unset means unbounded.\" }\n }\n },\n \"calibrate\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"description\": \"Settings for `manni tracevals calibrate` — measuring the tool's verdicts against a human's answers. See ADR 01022.\",\n \"properties\": {\n \"labels\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Default labels sidecar, resolved against this config file's directory. Overridden by --labels.\"\n },\n \"maxFalsePass\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"description\": \"Fail the calibration run (exit 1) above this many false passes — labelled fail, judged pass. Unset by default: a calibration run is a measurement, not a gate.\"\n },\n \"maxFalseFail\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"description\": \"Fail the calibration run above this many false fails — labelled pass, judged fail.\"\n },\n \"maxReview\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"description\": \"Fail the calibration run above this many needs-review outcomes across the whole corpus.\"\n },\n \"sweep\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"description\": \"Values --sweep tries on each axis, one axis at a time with the others held at their configured value. The corpus is judged once at the largest ensembleRuns here and every cell is re-scored from those cached runs, so the grid costs nothing beyond that one run.\",\n \"properties\": {\n \"ensembleRuns\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": { \"type\": \"integer\", \"minimum\": 1 }\n },\n \"autoPass\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 }\n },\n \"autoFail\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 }\n }\n }\n }\n }\n },\n \"failOnReview\": { \"type\": \"boolean\" },\n \"plugins\": {\n \"type\": \"array\",\n \"description\": \"Modules imported before evals are planned, so one calling registerGrader() can add a grader kind the built-ins do not cover. A relative or absolute path resolves against this file's directory, not the working directory; a bare package name resolves the way an import from this file's directory would. Load order is significant: a later entry wins a colliding kind.\",\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n },\n \"reportUnusedArtifacts\": {\n \"type\": \"boolean\",\n \"description\": \"List every skill and agent the session was offered and never used, rather than only counting them. Off by default: a real roster runs to hundreds of skills.\"\n }\n }\n}\n","/**\n * Redaction for the judge digest (ADR 01020).\n *\n * `renderTrace` builds the only trace-derived text that leaves this machine,\n * and a session transcript routinely carries credentials: a `Bash` input with\n * an `Authorization` header, an `.env` file echoed into a message, a key pasted\n * into a prompt. Every block that enters the digest is filtered through here\n * first.\n *\n * This is **best-effort pattern matching, not a guarantee.** It recognizes\n * shapes — vendor key prefixes, auth schemes, secret-looking assignment names —\n * so it catches the common accidents and cannot catch an arbitrary secret that\n * looks like ordinary prose. `--deterministic-only` is the only setting that\n * guarantees nothing leaves the machine.\n *\n * Two properties the rest of the system leans on:\n *\n * - **Stable output.** A given input always redacts to the same text, so\n * `sha256(renderedTrace)` stays a usable judge cache key.\n * - **Idempotent.** Placeholders contain no `=`, no `:` inside quotes, and no\n * vendor prefix, so redacting redacted text is a no-op.\n */\nimport { TracevalsError } from \"../types.js\";\n\nexport interface RedactionPattern {\n /** Kebab name; appears in the placeholder so a reader knows what went. */\n label: string;\n pattern: RegExp;\n /** Replacement template; `$1`-style references into `pattern` are allowed. */\n replacement: string;\n}\n\n/**\n * Names that mark a value as secret, in the shapes they appear in shell\n * assignments and in JSON object members (tool inputs render as JSON).\n *\n * The whole name must match, which is what keeps `monkey` out of the `key`\n * alternative: the `(?:[A-Za-z0-9]+[_\\-.])*` prefix only consumes segments that\n * end in a separator. `api[_\\-.]?key` covers `apiKey` and `API_KEY` alike under\n * the `i` flag.\n */\nconst SECRET_NAME =\n \"(?:(?:[A-Za-z0-9]+[_\\\\-.])*(?:api[_\\\\-.]?key|access[_\\\\-.]?key|secret[_\\\\-.]?key|auth[_\\\\-.]?token|access[_\\\\-.]?token|refresh[_\\\\-.]?token|client[_\\\\-.]?secret|session[_\\\\-.]?token|key|token|secret|password|passwd|passphrase|credentials?|authorization)|AWS_[A-Za-z0-9_]+)\";\n\n/**\n * Applied in order. Broad structural shapes first (a private key block spans\n * lines and would otherwise be chewed up by the narrower rules), then vendor\n * prefixes, then name-driven assignment forms.\n */\nexport const REDACTION_PATTERNS: readonly RedactionPattern[] = [\n {\n label: \"private-key\",\n pattern:\n /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\\s\\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,\n replacement: \"[redacted:private-key]\",\n },\n {\n // `sk-`, `sk-ant-…`, `pk-`, `rk-`: the OpenAI/Anthropic/Stripe family.\n label: \"api-key\",\n pattern: /\\b[sprk]k-(?:[A-Za-z0-9]+-)*[A-Za-z0-9_-]{16,}/g,\n replacement: \"[redacted:api-key]\",\n },\n {\n label: \"aws-access-key-id\",\n pattern: /\\b(?:AKIA|ASIA|AROA|AIDA)[0-9A-Z]{16}\\b/g,\n replacement: \"[redacted:aws-access-key-id]\",\n },\n {\n label: \"github-token\",\n pattern: /\\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})\\b/g,\n replacement: \"[redacted:github-token]\",\n },\n {\n label: \"slack-token\",\n pattern: /\\bxox[abeoprs]-[A-Za-z0-9-]{10,}/g,\n replacement: \"[redacted:slack-token]\",\n },\n {\n label: \"google-api-key\",\n pattern: /\\bAIza[0-9A-Za-z_-]{35}\\b/g,\n replacement: \"[redacted:google-api-key]\",\n },\n {\n label: \"jwt\",\n pattern: /\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}/g,\n replacement: \"[redacted:jwt]\",\n },\n {\n // `Authorization: Bearer …`, `Basic …`, `Token …`. The scheme is kept so\n // the judge can still see that authentication happened.\n //\n // Deliberately *not* case-insensitive as a whole: `basic` and `token` are\n // ordinary English words, and `/i` would redact \"basic configuration\" as an\n // auth header. `bearer` is not, so it gets both spellings.\n label: \"auth-token\",\n pattern: /\\b([Bb]earer|Basic|Token)\\s+[A-Za-z0-9\\-._~+/]{12,}={0,2}/g,\n replacement: \"$1 [redacted:auth-token]\",\n },\n {\n // JSON member — the shape a tool input renders as.\n label: \"secret-member\",\n pattern: new RegExp(`(\"${SECRET_NAME}\"\\\\s*:\\\\s*)\"[^\"]*\"`, \"gi\"),\n replacement: '$1\"[redacted:secret-value]\"',\n },\n {\n // Shell / `.env` assignment. The variable name is kept: knowing that a\n // secret was set, and which one, is often the adherence question.\n label: \"secret-assignment\",\n pattern: new RegExp(\n `\\\\b(${SECRET_NAME})(\\\\s*=\\\\s*)(?:\"[^\"\\\\n]*\"|'[^'\\\\n]*'|[^\\\\s\"'\\\\n]+)`,\n \"gi\",\n ),\n replacement: \"$1$2[redacted:secret-value]\",\n },\n];\n\n/** Placeholder used for a pattern the config supplied; it has no label. */\nexport const CUSTOM_PLACEHOLDER = \"[redacted]\";\n\nexport type Redactor = (text: string) => string;\n\n/**\n * Build the redactor for a run. Configured patterns are applied **after** the\n * built-ins and never replace them: a project adding one pattern of its own\n * must not silently lose the whole floor, which is the same reasoning that\n * makes `--require` additive (ADR 01017).\n *\n * A pattern that will not compile is an operational error raised here, not a\n * throw from inside the judge and never a silent skip — a dropped pattern is a\n * silent leak.\n */\nexport function makeRedactor(extra: readonly string[] = []): Redactor {\n // Compiled once and reused across every block of a render. Safe with a `g`\n // regex because `String.prototype.replace` sets `lastIndex` to 0 before it\n // starts and leaves it at 0 — unlike `exec`/`test`, where the shared instance\n // state would make a reused pattern skip matches.\n const custom = compileRedactPatterns(extra).map(\n (pattern) => [pattern, CUSTOM_PLACEHOLDER] as const,\n );\n const all: ReadonlyArray<readonly [RegExp, string]> = [\n ...REDACTION_PATTERNS.map(\n ({ pattern, replacement }) => [pattern, replacement] as const,\n ),\n ...custom,\n ];\n return (text) => {\n let out = text;\n for (const [pattern, replacement] of all) {\n out = out.replace(pattern, replacement);\n }\n return out;\n };\n}\n\n/**\n * Compile configured pattern sources, or say which one is unusable. Exported so\n * `parseConfig()` can reject a bad pattern at load time rather than at the\n * moment a digest is about to be sent.\n */\nexport function compileRedactPatterns(sources: readonly string[]): RegExp[] {\n return sources.map((source) => {\n try {\n return new RegExp(source, \"g\");\n } catch (err) {\n throw new TracevalsError(\n `invalid config: judge.redact pattern ${JSON.stringify(source)} is not a valid regular expression: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n });\n}\n","/**\n * The session manifest: what the project's instruction artifacts said, and\n * which commit they said it at, **when the session started** (ADR 01024).\n *\n * ADR 01016 established that the availability roster — what the session was\n * offered — is recoverable from the transcript itself, retroactively and on any\n * machine. Two things are not: the artifact **bodies** and the **git SHA**. The\n * transcript injects skill instructions into the model's context without ever\n * recording their text, so \"the SKILL.md says X now; did it say X then?\" has no\n * answer inside the trace. ADR 01021 answers it with mtime, which is a\n * heuristic that a `git checkout` defeats wholesale.\n *\n * A manifest closes that gap by recording, at session start, a sha256 per\n * instruction artifact. `run` then compares — and a mismatch is exact where\n * mtime was a guess.\n *\n * **A manifest is a claim, not proof.** It is written by the capturing device\n * and travels with the repository, so it is evidence *about that device*. It\n * never reaches an eval outcome, never moves the exit code, and never turns a\n * `skipped` into a `pass`; the only thing it may quiet is the mtime warning,\n * whose own question it answers exactly.\n *\n * Types and constants only, with no dependency of its own beyond\n * `ArtifactType` — `artifacts/resolve.ts` consumes a manifest and\n * `capture/build.ts` produces one from `artifacts/discover.ts`, so anything\n * shared has to sit below both or the two would import each other.\n */\nimport type { ArtifactType } from \"../artifacts/types.js\";\n\n/**\n * Manifest format version. Bumped when the *shape* changes incompatibly; a\n * manifest from a higher version is ignored rather than half-read, because a\n * partial read of an evidence file is worse than no evidence.\n */\nexport const MANIFEST_VERSION = 1;\n\n/** Default directory, under the state directory the judge cache already uses. */\nexport const DEFAULT_CAPTURE_DIR = \".manni/tracevals/sessions\";\n\nexport interface ManifestArtifact {\n /** Reference name, spelled as the coverage table spells it. */\n name: string;\n type: ArtifactType;\n /**\n * Path relative to `root`, with POSIX separators — never absolute, so the\n * manifest still joins after the repository is checked out somewhere else.\n */\n path: string;\n /** Lowercase hex sha256 of the file's bytes at capture time. */\n sha256: string;\n bytes: number;\n}\n\n/** What `git` could answer about the project at capture time. */\nexport interface ManifestGit {\n /** The commit the session ran against. */\n sha: string;\n branch?: string;\n /** Tracked files differed from the commit, so `sha` alone is incomplete. */\n dirty: boolean;\n}\n\nexport interface SessionManifest {\n version: number;\n sessionId: string;\n /** When `capture` ran, ISO-8601. */\n capturedAt: string;\n /** The hook that supplied the payload, or `manual` for a direct run. */\n hookEvent: string;\n /** How the session started or why it ended, when the payload said so. */\n reason?: string;\n /** Where the session file will be written. A correlation key, never read. */\n transcriptPath?: string;\n /** Project root the artifact paths are relative to. */\n root: string;\n git?: ManifestGit;\n /**\n * Which machine captured this. An opaque digest rather than the hostname:\n * the question a reader has is \"same machine or not\", and that does not need\n * the name of the machine to answer.\n */\n device: { id: string; platform: string };\n tool: { name: string; version: string };\n artifacts: ManifestArtifact[];\n /** The resolved `tracevals:` section, redacted. Recorded, not consumed. */\n config: unknown;\n}\n\nexport type ContentCheckStatus = \"match\" | \"mismatch\" | \"skipped\";\n\n/**\n * Whether an artifact still says what the manifest recorded. Three-valued on\n * purpose: `skipped` is not a shade of `match`, and collapsing them would let\n * an absent manifest read as a clean bill of health.\n */\nexport interface ContentCheck {\n status: ContentCheckStatus;\n /** Why no comparison was possible. Present only on `skipped`. */\n reason?: string;\n /** The digest recorded at capture time. */\n expected?: string;\n /** The digest of the file as it is now. */\n actual?: string;\n}\n\n/** The manifest `run` consulted, summarised for the report. */\nexport interface ManifestReport {\n /** Where it was read from. */\n path: string;\n sessionId: string;\n capturedAt: string;\n /** The commit the session ran against, when git could answer. */\n gitSha?: string;\n /** Coverage rows the manifest could speak to, and what it said. */\n matched: number;\n changed: number;\n /** Rows it had nothing to say about; those keep the mtime heuristic. */\n unrecorded: number;\n}\n","/**\n * Reading, locating, and comparing session manifests (ADR 01024).\n *\n * The consuming half. Deliberately free of any dependency on\n * `artifacts/discover.ts`: `artifacts/resolve.ts` imports this module, and\n * discovery imports resolution, so producing and consuming a manifest have to\n * live in separate files or the two would form a cycle. Building one is\n * `capture/build.ts`.\n */\nimport { createHash } from \"node:crypto\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport {\n dirname,\n extname,\n isAbsolute,\n join,\n relative,\n resolve,\n sep,\n} from \"node:path\";\nimport {\n MANIFEST_VERSION,\n type ContentCheck,\n type SessionManifest,\n} from \"./types.js\";\n\nexport function sha256Hex(data: Buffer | string): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\n/** sha256 of a file's bytes, or null when it cannot be read. */\nexport async function hashFile(path: string): Promise<string | null> {\n try {\n // The bytes, not the decoded string: the digest has to mean \"this file\",\n // and a decode-then-re-encode would quietly normalize a BOM.\n return sha256Hex(await readFile(path));\n } catch {\n return null;\n }\n}\n\n/** `path` relative to `root`, POSIX-separated, or null when it escapes. */\nexport function relPosix(root: string, path: string): string | null {\n const rel = relative(resolve(root), resolve(path));\n if (rel === \"\" || rel.startsWith(\"..\") || isAbsolute(rel)) return null;\n return rel.split(sep).join(\"/\");\n}\n\n/**\n * A session id is a filename here, so it may not carry path syntax. Claude Code\n * writes UUIDs; a hand-passed `--session-id` is the case this guards, and a\n * `../` in one would write the manifest outside the directory it was aimed at.\n */\nexport function safeSessionId(sessionId: string): string {\n const cleaned = sessionId.replace(/[^A-Za-z0-9._-]/g, \"-\").replace(/^\\.+/, \"\");\n return cleaned.length > 0 ? cleaned.slice(0, 128) : \"session\";\n}\n\nexport function manifestPathFor(dir: string, sessionId: string): string {\n return join(dir, `${safeSessionId(sessionId)}.json`);\n}\n\n/** The `<trace>.manifest.json` sibling — a manifest placed beside its trace. */\nexport function siblingManifestPath(tracePath: string): string {\n const ext = extname(tracePath);\n const stem = ext === \"\" ? tracePath : tracePath.slice(0, -ext.length);\n return `${stem}.manifest.json`;\n}\n\n// ── Persisting ───────────────────────────────────────────────────\n\nexport async function writeManifest(\n path: string,\n manifest: SessionManifest,\n): Promise<void> {\n await mkdir(dirname(resolve(path)), { recursive: true });\n await writeFile(path, `${JSON.stringify(manifest, null, 2)}\\n`, \"utf-8\");\n}\n\n/**\n * Every member `run` actually consumes, checked one by one.\n *\n * A partial read is the dangerous failure here, not a loud one. An artifact\n * entry with no `path` puts `undefined` in the comparison map's key, and one\n * whose `sha256` is not a string puts a value no real digest can equal — so a\n * half-read manifest reports **`mismatch`**, \"this artifact changed since the\n * session\", which is the most alarming thing this feature can say and would be\n * said off nothing but the file's own corruption. A manifest is optional\n * evidence, so anything malformed has to read as *no* evidence.\n */\nfunction isManifestArtifact(value: unknown): boolean {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n const entry = value as Record<string, unknown>;\n return (\n typeof entry.path === \"string\" &&\n entry.path.length > 0 &&\n typeof entry.sha256 === \"string\" &&\n entry.sha256.length > 0 &&\n typeof entry.name === \"string\" &&\n typeof entry.type === \"string\" &&\n typeof entry.bytes === \"number\"\n );\n}\n\n/**\n * Read one manifest, or null. Absent, unreadable, unparseable, the wrong shape,\n * or written by a newer format version all produce null: consuming a manifest\n * is optional evidence-gathering, so every failure has to degrade to \"no\n * evidence\" rather than to a crash or, worse, to a partial read (ADR 01003).\n */\nexport async function readManifest(\n path: string,\n): Promise<SessionManifest | null> {\n let raw: string;\n try {\n raw = await readFile(path, \"utf-8\");\n } catch {\n return null;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return null;\n }\n const record = parsed as Record<string, unknown>;\n if (typeof record.version !== \"number\" || record.version > MANIFEST_VERSION) {\n return null;\n }\n if (typeof record.sessionId !== \"string\") return null;\n // `capturedAt` is printed in the report and `root` is a base the join is\n // keyed on; both are consumed, so neither may be half-there.\n if (typeof record.capturedAt !== \"string\") return null;\n if (typeof record.root !== \"string\") return null;\n if (!Array.isArray(record.artifacts)) return null;\n if (!record.artifacts.every(isManifestArtifact)) return null;\n return parsed as SessionManifest;\n}\n\nexport interface FindManifestOptions {\n tracePath: string;\n /** The trace's own session id, when it recorded one. */\n sessionId?: string;\n /** Project root; the canonical manifest lives under it. */\n projectDir: string;\n /** Directory manifests are written to, relative to the project root. */\n captureDir: string;\n /** An explicitly named manifest, which is used without searching. */\n explicit?: string;\n /**\n * Called for each candidate that was readable but refused, with why. A\n * refusal that leaves no trace is indistinguishable from never having\n * captured anything, which is the wrong thing for a reader to conclude.\n */\n onRefused?: (path: string, reason: string) => void;\n}\n\nexport interface FoundManifest {\n path: string;\n manifest: SessionManifest;\n}\n\n/**\n * Find the manifest for a trace, most-specific location first.\n *\n * 1. `<trace>.manifest.json` — someone put it there deliberately, which is a\n * stronger statement of intent than any convention.\n * 2. `<trace dir>/<captureDir>/<session-id>.json` — a trace copied out of the\n * session store together with the state directory.\n * 3. `<projectDir>/<captureDir>/<session-id>.json` — where `capture` writes.\n *\n * **A manifest that cannot be shown to belong to this trace is refused**, not\n * used. It is evidence about some other session, and letting it stand in here\n * would be the one way a manifest could produce a confidently wrong answer.\n *\n * Two ways that can happen, and the trace's own id decides which:\n *\n * - The ids **disagree** — refused outright, however the manifest was reached.\n * - The trace records **no id at all**. A Claude Code session file whose\n * records predate `sessionId`, or a `claude -p` stream-json transcript\n * captured without its `system`/`init` record, both parse fine and both\n * arrive here with nothing to check against. A manifest found *by\n * convention* beside such a trace is refused, because convention is not\n * provenance and the file could describe any session on the machine.\n *\n * An **explicitly named** `--manifest` is the exception to that second case,\n * and only that one. Naming a file is the caller's own assertion that it\n * belongs to this trace — the assertion the ADR already treats as\n * load-bearing when it makes an unusable named manifest an error rather than a\n * shrug — and it is the only assertion available for a trace format that\n * records no id. Refusing it would leave `--manifest` structurally unusable\n * there while buying no safety a discovered manifest does not already get.\n */\nexport async function findManifest(\n options: FindManifestOptions,\n): Promise<FoundManifest | null> {\n const explicit = options.explicit !== undefined;\n const candidates: string[] = [];\n if (options.explicit !== undefined) {\n candidates.push(options.explicit);\n } else {\n candidates.push(siblingManifestPath(options.tracePath));\n if (options.sessionId !== undefined) {\n candidates.push(\n manifestPathFor(\n resolve(dirname(options.tracePath), options.captureDir),\n options.sessionId,\n ),\n manifestPathFor(\n resolve(options.projectDir, options.captureDir),\n options.sessionId,\n ),\n );\n }\n }\n\n for (const path of candidates) {\n const manifest = await readManifest(path);\n if (manifest === null) continue;\n const refusal = refuse(manifest, options.sessionId, explicit);\n if (refusal !== null) {\n options.onRefused?.(path, refusal);\n continue;\n }\n return { path, manifest };\n }\n return null;\n}\n\n/** Why this manifest cannot be trusted for this trace, or null if it can. */\nfunction refuse(\n manifest: SessionManifest,\n sessionId: string | undefined,\n explicit: boolean,\n): string | null {\n if (sessionId === undefined) {\n if (explicit) return null;\n return (\n `the trace records no session id, so a manifest found by convention ` +\n `cannot be verified as belonging to it (it records \"${manifest.sessionId}\"). ` +\n `Pass --manifest to use it anyway.`\n );\n }\n if (manifest.sessionId !== sessionId) {\n return `it was recorded for a different session (\"${manifest.sessionId}\", not \"${sessionId}\")`;\n }\n return null;\n}\n\n// ── Comparing ────────────────────────────────────────────────────\n\n/**\n * Compare the files one coverage row covers against what the manifest recorded.\n *\n * `actual` maps each covered file's project-relative POSIX path to its current\n * sha256. A row usually covers one file; project rules aggregate several, which\n * is why the outcome is decided over a set:\n *\n * - **any** recorded file whose digest differs → `mismatch`. One changed file\n * makes the row's instructions different, whatever the others say.\n * - **every** covered file recorded and equal → `match`.\n * - otherwise → `skipped`, naming what the manifest could not speak to. A\n * partial answer is not a clean one.\n */\nexport function checkContent(\n manifest: SessionManifest,\n actual: ReadonlyMap<string, string>,\n): ContentCheck {\n const recorded = new Map(manifest.artifacts.map((a) => [a.path, a.sha256]));\n const missing: string[] = [];\n let matched = 0;\n /**\n * The first agreeing pair, captured where both halves are in hand. `expected`\n * means \"what the manifest claimed\" in every branch, so it has to be read off\n * the manifest in every branch — going back to `actual` afterwards would\n * report the file twice, and on a match the two are equal, so nothing would\n * ever catch it.\n */\n let agreed: { expected: string; actual: string } | undefined;\n\n for (const [path, digest] of actual) {\n const expected = recorded.get(path);\n if (expected === undefined) {\n missing.push(path);\n continue;\n }\n if (expected !== digest) {\n return { status: \"mismatch\", expected, actual: digest };\n }\n agreed ??= { expected, actual: digest };\n matched += 1;\n }\n\n if (matched === 0) {\n return {\n status: \"skipped\",\n reason:\n actual.size === 0\n ? \"no file to compare\"\n : \"not recorded in the session manifest\",\n };\n }\n if (missing.length > 0) {\n return {\n status: \"skipped\",\n reason: `not recorded in the session manifest: ${missing.join(\", \")}`,\n };\n }\n // Digests only for a row covering one file: an aggregated project-rules row\n // has no single pair to report, and picking one of several would be a claim\n // about the row that is not true of it.\n return {\n status: \"match\",\n ...(actual.size === 1 && agreed !== undefined ? agreed : {}),\n };\n}\n\nexport * from \"./types.js\";\n","/**\n * The availability roster (ADR 01016): what a session was *offered*, whether or\n * not it used any of it.\n *\n * Claude Code records the roster in the transcript as structured `attachment`\n * records rather than as the prose the model reads, so it is recoverable\n * deterministically and **retroactively, on every session already on disk**:\n *\n * | `attachment.type` | Carries |\n * |---|---|\n * | `skill_listing` | `names`, `skillCount`, `isInitial`, and `content` — one `- name: description` line per skill |\n * | `agent_listing_delta` | `addedTypes`, `addedLines` (description plus tool grants), `removedTypes`, `isInitial` |\n * | `deferred_tools_delta` | `addedNames`, `removedNames`, `readdedNames`, and the MCP server state lists |\n *\n * Two properties of the real data drive the shape of this module, both\n * confirmed across the 606 `skill_listing` records in a 281-session store:\n *\n * 1. **`content` is the description source, `names` is the identity source.**\n * A plugin skill is named `plugin:skill`, so splitting a listing line on its\n * first colon truncates the name; every line is instead matched against the\n * `names` array (longest match wins). On that corpus the rule leaves zero\n * lines unjoined. Descriptions also wrap onto continuation lines, and the\n * listing text is capped near 30,000 characters — past the cap Claude Code\n * emits bare `- name` lines, so a description is genuinely optional.\n * 2. **Deltas are not idempotent.** `isInitial: true` replaces the set;\n * `isInitial: false` adds (and, for agents and tools, removes). Replay is\n * therefore ordered by record index, and per-index history is kept so a\n * consumer can ask what was available when a window opened rather than only\n * what was available at some point.\n */\nimport type {\n AvailabilityEntry,\n AvailabilityKind,\n McpServerStatus,\n TraceAvailability,\n} from \"./types.js\";\n\nexport function newAvailability(): TraceAvailability {\n return { recorded: false, skills: [], agents: [], tools: [], mcpServers: [] };\n}\n\n/** Entries whose interval covers `index`. */\nexport function availableAt(\n entries: readonly AvailabilityEntry[],\n index: number,\n): AvailabilityEntry[] {\n return entries.filter(\n (e) => e.offeredAt <= index && (e.withdrawnAt === undefined || index < e.withdrawnAt),\n );\n}\n\n/** Every distinct name that was offered at any point. */\nexport function offeredNames(entries: readonly AvailabilityEntry[]): Set<string> {\n return new Set(entries.map((e) => e.name));\n}\n\n/**\n * Join a listing's `content` lines onto its `names`.\n *\n * A line belongs to the longest name it starts with, so `plugin:skill` survives\n * intact; a line that starts no name is a continuation of the description above\n * it. Names with no line at all keep an absent description.\n */\nexport function joinDescriptions(\n content: string,\n names: readonly string[],\n): Map<string, string | undefined> {\n const byName = new Map<string, string | undefined>(\n names.map((name) => [name, undefined]),\n );\n let current: string | undefined;\n for (const raw of content.split(\"\\n\")) {\n const line = raw.trimEnd();\n if (line.startsWith(\"- \")) {\n const body = line.slice(2);\n let best: string | undefined;\n for (const name of names) {\n if (body !== name && !body.startsWith(`${name}:`)) continue;\n if (best === undefined || name.length > best.length) best = name;\n }\n // A `- ` line that names nothing on the roster is not a skill entry, so\n // it must not become the target for the lines that follow it either.\n current = best;\n if (best === undefined) continue;\n const rest = body.slice(best.length).replace(/^:\\s*/, \"\").trim();\n byName.set(best, rest.length > 0 ? rest : undefined);\n continue;\n }\n if (current === undefined) continue;\n const continued = line.trim();\n if (continued.length === 0) continue;\n const previous = byName.get(current);\n byName.set(current, previous ? `${previous}\\n${continued}` : continued);\n }\n return byName;\n}\n\n/** `- name: description` in one string, as the agent-listing deltas ship it. */\nfunction describedLines(\n names: readonly string[],\n lines: readonly string[],\n): Map<string, string | undefined> {\n const byName = new Map<string, string | undefined>();\n names.forEach((name, i) => {\n const line = lines[i];\n if (typeof line !== \"string\") {\n byName.set(name, undefined);\n return;\n }\n const body = line.startsWith(\"- \") ? line.slice(2) : line;\n const rest = body.startsWith(`${name}:`)\n ? body.slice(name.length + 1).trim()\n : body === name\n ? \"\"\n : body.trim();\n byName.set(name, rest.length > 0 ? rest : undefined);\n });\n return byName;\n}\n\nconst asStrings = (value: unknown): string[] =>\n Array.isArray(value) ? value.filter((v): v is string => typeof v === \"string\") : [];\n\n/** Mutable replay state: the open interval per name, per kind. */\nexport interface AvailabilityReplay {\n roster: TraceAvailability;\n open: Map<AvailabilityKind, Map<string, AvailabilityEntry>>;\n}\n\nexport function newReplay(): AvailabilityReplay {\n return {\n roster: newAvailability(),\n open: new Map<AvailabilityKind, Map<string, AvailabilityEntry>>([\n [\"skill\", new Map()],\n [\"agent\", new Map()],\n [\"tool\", new Map()],\n [\"mcp-server\", new Map()],\n ]),\n };\n}\n\nfunction listFor(\n roster: TraceAvailability,\n kind: AvailabilityKind,\n): AvailabilityEntry[] {\n if (kind === \"skill\") return roster.skills;\n if (kind === \"agent\") return roster.agents;\n if (kind === \"tool\") return roster.tools;\n return roster.mcpServers;\n}\n\nfunction offer(\n replay: AvailabilityReplay,\n kind: AvailabilityKind,\n name: string,\n index: number,\n description?: string,\n status?: McpServerStatus,\n): void {\n const open = replay.open.get(kind) as Map<string, AvailabilityEntry>;\n const existing = open.get(name);\n if (existing !== undefined) {\n // Already offered: keep the one interval and let a later listing fill in a\n // description the earlier, truncated one omitted.\n if (existing.description === undefined && description !== undefined) {\n existing.description = description;\n }\n if (status !== undefined) existing.status = status;\n return;\n }\n const entry: AvailabilityEntry = { kind, name, offeredAt: index };\n if (description !== undefined) entry.description = description;\n if (status !== undefined) entry.status = status;\n open.set(name, entry);\n listFor(replay.roster, kind).push(entry);\n}\n\nfunction withdraw(\n replay: AvailabilityReplay,\n kind: AvailabilityKind,\n name: string,\n index: number,\n): void {\n const open = replay.open.get(kind) as Map<string, AvailabilityEntry>;\n const entry = open.get(name);\n if (entry === undefined) return;\n entry.withdrawnAt = index;\n open.delete(name);\n}\n\n/** Names currently offered for a kind, in offer order. */\nfunction openNames(replay: AvailabilityReplay, kind: AvailabilityKind): string[] {\n return [...(replay.open.get(kind) as Map<string, AvailabilityEntry>).keys()];\n}\n\n/**\n * Fold one `attachment` payload into the roster. Anything unrecognised, or\n * shaped unexpectedly, is ignored rather than thrown: a listing record is\n * bookkeeping, and losing one must never cost the run its trace (ADR 01003).\n *\n * Returns true when the record was a listing record — which is what makes\n * `recorded` mean \"a roster was present\", as opposed to \"the roster was empty\".\n */\nexport function applyAvailabilityRecord(\n replay: AvailabilityReplay,\n attachment: unknown,\n index: number,\n): boolean {\n if (typeof attachment !== \"object\" || attachment === null) return false;\n const record = attachment as Record<string, unknown>;\n const type = record.type;\n\n if (type === \"skill_listing\") {\n const names = asStrings(record.names);\n const content = typeof record.content === \"string\" ? record.content : \"\";\n // A skill listing carries no removal member of its own: an initial listing\n // is the set, and a delta only adds.\n if (record.isInitial === true) {\n for (const name of openNames(replay, \"skill\")) {\n if (!names.includes(name)) withdraw(replay, \"skill\", name, index);\n }\n }\n const described = joinDescriptions(content, names);\n for (const name of names) {\n offer(replay, \"skill\", name, index, described.get(name));\n }\n return true;\n }\n\n if (type === \"agent_listing_delta\") {\n const added = asStrings(record.addedTypes);\n const lines = asStrings(record.addedLines);\n if (record.isInitial === true) {\n for (const name of openNames(replay, \"agent\")) {\n if (!added.includes(name)) withdraw(replay, \"agent\", name, index);\n }\n }\n const described = describedLines(added, lines);\n for (const name of added) {\n offer(replay, \"agent\", name, index, described.get(name));\n }\n for (const name of asStrings(record.removedTypes)) {\n withdraw(replay, \"agent\", name, index);\n }\n return true;\n }\n\n if (type === \"deferred_tools_delta\") {\n // Tool deltas carry no `isInitial` at all — verified across 431 records —\n // so they are purely additive/subtractive.\n for (const name of asStrings(record.removedNames)) {\n withdraw(replay, \"tool\", name, index);\n }\n // `addedLines` is the tool's own name again rather than a description, and\n // is sometimes empty while `addedNames` is not; there is no description to\n // recover for a tool.\n // `readdedNames` is the shape a re-offer actually takes: a tool that was\n // withdrawn and is offered again arrives there, not in `addedNames`.\n // Reading only `addedNames` left it withdrawn for the rest of the\n // session, so `availableAt` answered false for a tool the session could\n // still call.\n for (const name of [\n ...asStrings(record.addedNames),\n ...asStrings(record.readdedNames),\n ]) {\n offer(replay, \"tool\", name, index);\n }\n const servers: Array<[string, McpServerStatus]> = [\n ...asStrings(record.pendingMcpServers).map(\n (n): [string, McpServerStatus] => [n, \"pending\"],\n ),\n ...asStrings(record.needsAuthMcpServers).map(\n (n): [string, McpServerStatus] => [n, \"needs-auth\"],\n ),\n ...asStrings(record.failedMcpServers).map(\n (n): [string, McpServerStatus] => [n, \"failed\"],\n ),\n ];\n for (const [name, status] of servers) {\n offer(replay, \"mcp-server\", name, index, undefined, status);\n }\n return true;\n }\n\n return false;\n}\n\n/** Shift every ordinal through a remap, for the sidecar splice (ADR 01014). */\nexport function remapAvailability(\n roster: TraceAvailability,\n at: (index: number) => number,\n): TraceAvailability {\n const shift = (entries: AvailabilityEntry[]): AvailabilityEntry[] =>\n entries.map((entry) => ({\n ...entry,\n offeredAt: at(entry.offeredAt),\n ...(entry.withdrawnAt !== undefined\n ? { withdrawnAt: at(entry.withdrawnAt) }\n : {}),\n }));\n return {\n recorded: roster.recorded,\n skills: shift(roster.skills),\n agents: shift(roster.agents),\n tools: shift(roster.tools),\n mcpServers: shift(roster.mcpServers),\n };\n}\n\n/**\n * Fold a subagent branch's own roster into the session's.\n *\n * A subagent is offered its own roster — every sidecar transcript checked\n * carries `skill_listing` and `deferred_tools_delta` records of its own — and\n * that roster is a *different* set from the parent's. Replaying it as if it\n * were the main chain's would churn the parent's intervals, since a sidecar's\n * listing is `isInitial: true` and would withdraw everything the parent had.\n *\n * So only names the session never saw at all are added, tagged with the branch\n * that saw them and never withdrawn. That keeps the main chain's intervals\n * exact while making \"was this ever on the menu?\" — the question coverage asks\n * — answer correctly for a skill only a subagent was offered.\n */\nexport function foldBranchAvailability(\n roster: TraceAvailability,\n branch: TraceAvailability,\n branchId: string,\n spawnIndex: number,\n): void {\n if (!branch.recorded) return;\n roster.recorded = true;\n const merge = (into: AvailabilityEntry[], from: AvailabilityEntry[]): void => {\n const known = offeredNames(into);\n for (const entry of from) {\n if (known.has(entry.name)) continue;\n known.add(entry.name);\n into.push({\n ...entry,\n offeredAt: spawnIndex,\n branchId,\n ...(entry.withdrawnAt !== undefined ? { withdrawnAt: undefined } : {}),\n });\n }\n };\n merge(roster.skills, branch.skills);\n merge(roster.agents, branch.agents);\n merge(roster.tools, branch.tools);\n merge(roster.mcpServers, branch.mcpServers);\n}\n","/**\n * Offered versus used (ADR 01016).\n *\n * Artifact resolution starts from what the trace *used*, so a skill that should\n * have been invoked and was not resolves to nothing and is reported nowhere.\n * The availability roster closes that blind spot without a filesystem scan:\n * the evidence travels inside the trace, so it works on any machine and on\n * every session already recorded.\n *\n * Three states, never collapsed:\n *\n * - **offered and used** — the ordinary case.\n * - **offered and not used** — a judgement call for a person to make. Counted\n * by default and listed only on request, because a real roster runs to\n * hundreds of skills and would drown the report.\n * - **not offered** — the session referenced it but it was never on the menu.\n * That is a *configuration* bug, not an adherence failure, and it is the\n * state that is invisible today.\n *\n * This is an observation. It never becomes an eval outcome and never moves the\n * exit code.\n *\n * `discoverArtifacts` is deliberately not used here: it scans the project tree\n * for authoring, and the roster makes a scan unnecessary anyway.\n */\nimport { offeredNames } from \"../trace/availability.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport type {\n AvailabilityCounts,\n AvailabilityReport,\n CoverageEntry,\n} from \"./types.js\";\n\nexport interface AvailabilityOptions {\n /** Include a coverage row per offered-but-unused artifact, not just a count. */\n listUnused?: boolean;\n}\n\nexport interface AvailabilityCoverage {\n report: AvailabilityReport;\n /** The rows handed in, annotated, plus the unused ones when listed. */\n coverage: CoverageEntry[];\n}\n\n/**\n * A fresh zero row per call. One shared object assigned to both `skills` and\n * `agents` would make a mutation of either silently move the other; every\n * caller is read-only today, which is exactly why it would go unnoticed.\n */\nconst empty = (): AvailabilityCounts => ({ offered: 0, used: 0, unused: 0 });\n\n/**\n * Kinds the roster says nothing about, so no row of theirs may carry a state.\n *\n * Project rules are never *offered* — they are in force from the first turn.\n * Slash commands have no listing record of any kind, so `not-offered` would be\n * a confident accusation drawn from evidence that was never collected — which\n * is precisely what a built-in command looked like before it had its own type\n * (ADR 01016's recorded limitation, closed by ADR 01023).\n */\nconst UNROSTERED = new Set<CoverageEntry[\"kind\"]>([\n \"project-rules\",\n \"slash-command\",\n]);\n\nexport function coverAvailability(\n trace: Trace,\n coverage: CoverageEntry[],\n options: AvailabilityOptions = {},\n): AvailabilityCoverage {\n const roster = trace.availability;\n if (!roster.recorded) {\n // No listing records: unknown, not zero. Every row says so rather than\n // implying the session was offered nothing.\n return {\n report: { recorded: false, skills: empty(), agents: empty(), listed: false },\n coverage: coverage.map((entry) =>\n UNROSTERED.has(entry.kind)\n ? entry\n : { ...entry, availability: \"unknown\" as const },\n ),\n };\n }\n\n const offeredSkills = offeredNames(roster.skills);\n const offeredAgents = offeredNames(roster.agents);\n const offeredFor = (kind: CoverageEntry[\"kind\"]): Set<string> =>\n kind === \"skill\" ? offeredSkills : offeredAgents;\n\n const usedSkills = new Set<string>();\n const usedAgents = new Set<string>();\n\n const annotated = coverage.map((entry) => {\n if (UNROSTERED.has(entry.kind)) return entry;\n const offered = offeredFor(entry.kind).has(entry.ref);\n if (offered) {\n (entry.kind === \"skill\" ? usedSkills : usedAgents).add(entry.ref);\n }\n return {\n ...entry,\n availability: offered ? (\"offered-and-used\" as const) : (\"not-offered\" as const),\n };\n });\n\n const listUnused = options.listUnused === true;\n const unusedRows: CoverageEntry[] = [];\n const collect = (kind: \"skill\" | \"agent\", used: Set<string>): number => {\n let unused = 0;\n // Ordered by first offer, and deduplicated: a name withdrawn and\n // re-offered is two intervals but one artifact.\n const seen = new Set<string>();\n for (const entry of kind === \"skill\" ? roster.skills : roster.agents) {\n if (seen.has(entry.name)) continue;\n seen.add(entry.name);\n if (used.has(entry.name)) continue;\n unused += 1;\n if (!listUnused) continue;\n unusedRows.push({\n ref: entry.name,\n kind,\n resolved: false,\n tried: [],\n note:\n entry.description === undefined\n ? \"offered, never used\"\n : `offered, never used — ${firstLine(entry.description)}`,\n availability: \"offered-not-used\",\n });\n }\n return unused;\n };\n\n const skillsUnused = collect(\"skill\", usedSkills);\n const agentsUnused = collect(\"agent\", usedAgents);\n\n return {\n report: {\n recorded: true,\n skills: {\n offered: offeredSkills.size,\n used: usedSkills.size,\n unused: skillsUnused,\n },\n agents: {\n offered: offeredAgents.size,\n used: usedAgents.size,\n unused: agentsUnused,\n },\n listed: listUnused,\n },\n coverage: [...annotated, ...unusedRows],\n };\n}\n\n/** Descriptions wrap over several lines; a table cell wants the first one. */\nfunction firstLine(description: string): string {\n const line = description.split(\"\\n\")[0] ?? \"\";\n return line.length > 160 ? `${line.slice(0, 157)}...` : line;\n}\n","/**\n * Filesystem helpers shared by trace-driven artifact resolution and static\n * artifact discovery. Every function degrades to null/empty rather than\n * throwing: a missing or unreadable path is a coverage note, never a crash.\n */\nimport { access, readdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname, join, resolve, sep } from \"node:path\";\n\n/**\n * Directory names never worth walking. `.git` alone can hold more entries than\n * the rest of a repo combined, and `node_modules` hides vendored skills that\n * are not the project's to edit.\n */\n/**\n * Path split into segments with separators normalised, so convention\n * matching (\"is this under `.claude/commands/`?\") agrees between\n * trace-driven resolution and static discovery. Both had their own\n * byte-identical copy; a drift between them would classify one file two\n * ways in `run` and `fill`.\n */\nexport function segments(path: string): string[] {\n return path.split(sep).join(\"/\").split(\"/\");\n}\n\nexport const PRUNED_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \"coverage\",\n \".manni\",\n \".tmp\",\n \".next\",\n \".venv\",\n]);\n\n/** Nearest ancestor containing `.git` (a directory *or* a worktree file). */\nexport async function findGitRoot(start: string): Promise<string | null> {\n let current = resolve(start);\n for (let depth = 0; depth < 64; depth += 1) {\n try {\n await access(join(current, \".git\"));\n return current;\n } catch {\n // keep walking\n }\n const parent = dirname(current);\n if (parent === current) return null;\n current = parent;\n }\n return null;\n}\n\nexport async function safeRead(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * Last-modified time of `path` as an ISO-8601 string, or null when it cannot\n * be read. Used for the staleness heuristic (ADR 01021); like everything else\n * here it degrades rather than throwing — an artifact whose mtime is\n * unreadable is simply one the report says nothing about.\n */\nexport async function safeMtime(path: string): Promise<string | null> {\n try {\n const info = await stat(path);\n return info.mtime.toISOString();\n } catch {\n return null;\n }\n}\n\n/** First file under `root` matching `match`, or null. */\nexport async function findInTree(\n root: string,\n match: (path: string) => boolean,\n): Promise<string | null> {\n let entries;\n try {\n entries = await readdir(root, { withFileTypes: true, recursive: true });\n } catch {\n return null;\n }\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n const full = join(entry.parentPath, entry.name);\n if (match(full)) return full;\n }\n return null;\n}\n\nexport interface ListOptions {\n /** Directory names to skip; defaults to PRUNED_DIRS. */\n prune?: Set<string>;\n maxDepth?: number;\n}\n\n/**\n * Every file under `root` matching `match`, sorted for stable output.\n *\n * Hand-rolled rather than `readdir({recursive:true})` because pruning has to\n * happen *during* the walk — a recursive readdir would enumerate all of\n * `node_modules` before we could filter it. Symlinked directories report\n * `isDirectory() === false`, so loops are not followed.\n */\nexport async function listInTree(\n root: string,\n match: (path: string) => boolean,\n options: ListOptions = {},\n): Promise<string[]> {\n const prune = options.prune ?? PRUNED_DIRS;\n const maxDepth = options.maxDepth ?? 24;\n const found: string[] = [];\n\n async function walk(dir: string, depth: number): Promise<void> {\n if (depth > maxDepth) return;\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return; // unreadable directory is a skip, not a failure\n }\n for (const entry of entries) {\n const full = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (prune.has(entry.name)) continue;\n await walk(full, depth + 1);\n } else if (entry.isFile() && match(full)) {\n found.push(full);\n }\n }\n }\n\n await walk(resolve(root), 0);\n return found.sort();\n}\n","/**\n * Deterministic artifact resolution: map every skill/agent/project-rule\n * reference in a trace to a file on disk. Trace content + filesystem lookup\n * only — no LLM guessing. Unresolved refs degrade to coverage entries and\n * warnings, never a crash (ADR 01003).\n */\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { configDir } from \"../trace/discover.js\";\nimport { coverAvailability } from \"./availability.js\";\nimport { findGitRoot, findInTree, safeMtime, safeRead, segments } from \"./fs.js\";\nimport { checkContent, hashFile, relPosix } from \"../capture/manifest.js\";\nimport type { SessionManifest } from \"../capture/types.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport type {\n CoverageEntry,\n ResolvedArtifact,\n ResolvedArtifacts,\n} from \"./types.js\";\n\nexport interface ResolveOptions {\n /** Overrides the trace's recorded cwd (for deleted workspaces). */\n projectDir?: string;\n /** Ceiling for the parent-directory walk; defaults to the git root. */\n projectRoot?: string;\n env?: Record<string, string | undefined>;\n /**\n * List every offered-but-unused artifact in the coverage table rather than\n * only counting them (ADR 01016). Off by default: a real roster runs to\n * hundreds of skills.\n */\n reportUnusedArtifacts?: boolean;\n /**\n * The session manifest for this trace, when one was found (ADR 01024). It\n * makes staleness exact for the artifacts it recorded and changes nothing\n * else — no eval outcome, no exit code, no resolution decision.\n */\n manifest?: SessionManifest;\n}\n\n/**\n * Project-rules filenames, in the order they are checked. Different agent\n * tools use different names for the same artifact; all are read the same way.\n */\nexport const PROJECT_RULES_FILENAMES = [\n \"CLAUDE.md\",\n \"AGENTS.md\",\n \"GEMINI.md\",\n] as const;\n\n/** Agents that ship with Claude Code and have no definition file on disk. */\nconst BUILTIN_AGENTS = new Set([\n \"general-purpose\",\n \"claude\",\n \"Explore\",\n \"Plan\",\n \"statusline-setup\",\n \"fork\",\n]);\n\nexport async function resolveArtifacts(\n trace: Trace,\n options: ResolveOptions = {},\n): Promise<ResolvedArtifacts> {\n const projectDir = resolve(options.projectDir ?? trace.cwd);\n const userDir = configDir(options.env);\n const projectRoot = resolve(\n options.projectRoot ?? (await findGitRoot(projectDir)) ?? projectDir,\n );\n\n const artifacts: ResolvedArtifact[] = [];\n const coverage: CoverageEntry[] = [];\n const warnings: string[] = [];\n const seenPaths = new Set<string>();\n const seenRefs = new Set<string>();\n\n const add = (artifact: ResolvedArtifact): void => {\n if (seenPaths.has(artifact.path)) return;\n seenPaths.add(artifact.path);\n artifacts.push(artifact);\n };\n\n /** Record a resolved skill once, however many refs reached it. */\n const addSkill = (\n name: string,\n artifact: ResolvedArtifact,\n tried: string[],\n ): void => {\n const refKey = `skill:${name}`;\n if (seenRefs.has(refKey)) return;\n seenRefs.add(refKey);\n add(artifact);\n coverage.push({\n ref: name,\n kind: \"skill\",\n resolved: true,\n path: artifact.path,\n tried,\n });\n };\n\n for (const invocation of trace.skillInvocations) {\n // A `<command-name>` injection is the slash-command mechanism, and a slash\n // command is one of three things: a `.claude/commands/*.md` file, a skill\n // surfaced under its slash form, or a built-in with no file anywhere. Only\n // the filesystem can say which, so the shape of the reference decides\n // nothing on its own (ADR 01023).\n if (invocation.via === \"command-injection\") {\n const refKey = `command:${invocation.name}`;\n if (seenRefs.has(refKey)) continue;\n seenRefs.add(refKey);\n\n const command = await resolveSlashCommand(\n invocation.name,\n projectDir,\n userDir,\n );\n if (command.artifact) {\n add(command.artifact);\n coverage.push({\n ref: invocation.name,\n kind: \"slash-command\",\n resolved: true,\n path: command.artifact.path,\n tried: command.tried,\n });\n continue;\n }\n\n const skill = await resolveSkill(invocation.name, projectDir, userDir);\n if (skill.artifact) {\n addSkill(invocation.name, skill.artifact, skill.tried);\n // Resolved as a skill, so the slash-command lookup below must not\n // also record it — one reference yields one coverage row.\n continue;\n }\n\n // No definition file in any place a command or a skill could live. Claude\n // Code's own commands (`/model`, `/compact`) have no file by design, so\n // this is reported rather than warned about — and reported as what it is\n // rather than as a skill that went missing, which is the defect ADR 01016\n // recorded. A hard-coded list of built-in names was rejected: it would go\n // stale with every Claude Code release.\n coverage.push({\n ref: invocation.name,\n kind: \"slash-command\",\n resolved: false,\n tried: [...command.tried, ...skill.tried],\n note: \"built-in slash command, or not installed here (no definition file)\",\n });\n continue;\n }\n\n // A `Skill` tool call is unambiguous: it names a skill.\n const refKey = `skill:${invocation.name}`;\n if (seenRefs.has(refKey)) continue;\n const { artifact, tried } = await resolveSkill(\n invocation.name,\n projectDir,\n userDir,\n );\n if (artifact) {\n addSkill(invocation.name, artifact, tried);\n } else {\n seenRefs.add(refKey);\n coverage.push({ ref: invocation.name, kind: \"skill\", resolved: false, tried });\n warnings.push(\n `skill \"${invocation.name}\" was invoked but no SKILL.md was found (${tried.length} location(s) tried)`,\n );\n }\n }\n\n for (const spawn of trace.agentSpawns) {\n const refKey = `agent:${spawn.subagentType}`;\n if (seenRefs.has(refKey)) continue;\n seenRefs.add(refKey);\n if (BUILTIN_AGENTS.has(spawn.subagentType)) {\n coverage.push({\n ref: spawn.subagentType,\n kind: \"agent\",\n resolved: false,\n tried: [],\n note: \"built-in agent (no definition file)\",\n });\n continue;\n }\n const { artifact, tried } = await resolveAgent(\n spawn.subagentType,\n projectDir,\n userDir,\n );\n if (artifact) {\n add(artifact);\n coverage.push({\n ref: spawn.subagentType,\n kind: \"agent\",\n resolved: true,\n path: artifact.path,\n tried,\n });\n } else {\n coverage.push({\n ref: spawn.subagentType,\n kind: \"agent\",\n resolved: false,\n tried,\n });\n warnings.push(\n `agent \"${spawn.subagentType}\" was spawned but no definition file was found (${tried.length} location(s) tried)`,\n );\n }\n }\n\n const rules = await resolveProjectRules(projectDir, projectRoot);\n for (const rule of rules.artifacts) add(rule);\n const rulesEntry: CoverageEntry = {\n ref: \"project rules\",\n kind: \"project-rules\",\n resolved: rules.artifacts.length > 0,\n tried: rules.tried,\n ...(rules.artifacts.length === 0\n ? { note: \"no CLAUDE.md or AGENTS.md found\" }\n : {}),\n };\n coverage.push(rulesEntry);\n\n // One aggregated entry covers several files, so it has no single `path` to\n // stat; name them explicitly. Every other entry stats the file it resolved to.\n //\n // Before the roster pass, not after: staleness only has something to say\n // about rows that resolved to a file, and the roster's own offered-but-unused\n // rows never do. Annotating first also keeps these flags on the entries the\n // roster copies forward.\n await annotateStaleness(\n trace,\n coverage,\n new Map([[rulesEntry, rules.artifacts.map((a) => a.path)]]),\n warnings,\n projectRoot,\n projectDir,\n options.manifest,\n );\n\n // What the session was *offered* is the other half of coverage: resolution\n // only ever sees what it used (ADR 01016).\n const availability = coverAvailability(trace, coverage, {\n ...(options.reportUnusedArtifacts !== undefined\n ? { listUnused: options.reportUnusedArtifacts }\n : {}),\n });\n\n return {\n artifacts,\n coverage: availability.coverage,\n availability: availability.report,\n warnings,\n };\n}\n\n// ── Staleness ────────────────────────────────────────────────────\n\n/**\n * Say, for every resolved artifact, whether it is still the one the session\n * followed. Evals are read from the artifact *as it is now* while the session\n * followed it *as it was then*, so editing a SKILL.md after a session grades\n * that session against instructions it never saw.\n *\n * Two sources of evidence, and the better one wins **only on its own question**:\n *\n * - **A session manifest** (ADR 01024) recorded a sha256 per artifact when the\n * session started. A digest that differs is an exact \"this changed\"; a digest\n * that matches is an exact \"this did not\". Either one settles the row.\n * - **mtime** (ADR 01021) is the fallback, and a soft one: it is not content\n * identity, a fresh clone rewrites every mtime, and an unreadable mtime says\n * nothing.\n *\n * A manifest may therefore quiet the mtime warning for an artifact it covers —\n * that is the entire point, since a checkout otherwise flags everything in CI —\n * and it may do nothing else. It never reaches an eval outcome, never moves the\n * exit code, and it cannot silence a row it has no entry for. The observation\n * itself (`modifiedAt`) is reported either way, so nothing is hidden; only the\n * conclusion drawn from it changes.\n */\nasync function annotateStaleness(\n trace: Trace,\n coverage: CoverageEntry[],\n extraPaths: Map<CoverageEntry, string[]>,\n warnings: string[],\n projectRoot: string,\n projectDir: string,\n manifest?: SessionManifest,\n): Promise<void> {\n // No session end means no ground for the *heuristic* to stand on, and\n // guessing one would manufacture a warning out of no evidence. A manifest\n // supplies its own ground, so it still has something to say here.\n const endedAt =\n trace.endedAt !== undefined ? Date.parse(trace.endedAt) : Number.NaN;\n const haveEnd = Number.isFinite(endedAt);\n if (!haveEnd && manifest === undefined) return;\n\n const base =\n manifest === undefined\n ? projectRoot\n : joinBase(manifest, coverage, extraPaths, [\n projectDir,\n projectRoot,\n manifest.root,\n ]);\n\n /** Refs still resting on the mtime guess. */\n const guessed: string[] = [];\n /** Refs the manifest proved changed. */\n const changed: string[] = [];\n /** Whether the manifest spoke to any row at all. */\n let joined = false;\n\n for (const entry of coverage) {\n if (!entry.resolved) continue;\n const paths = extraPaths.get(entry) ?? (entry.path ? [entry.path] : []);\n if (paths.length === 0) continue;\n\n let newest: string | undefined;\n let outside = false;\n const digests = new Map<string, string>();\n for (const path of paths) {\n const mtime = await safeMtime(path);\n if (mtime !== null && (newest === undefined || mtime > newest)) {\n newest = mtime;\n }\n if (manifest === undefined) continue;\n // Keyed on the path relative to the base **both sides agree on**, so the\n // manifest still joins after the repository has been checked out\n // somewhere else. An artifact outside that base — a user-level or plugin\n // skill — has no relative path, and `capture` is project-scoped, so it\n // was never recordable in the first place. That is a different sentence\n // from \"it changed\" and gets one.\n const rel = relPosix(base, path);\n if (rel === null) {\n outside = true;\n continue;\n }\n const digest = await hashFile(path);\n if (digest !== null) digests.set(rel, digest);\n }\n if (newest !== undefined) entry.modifiedAt = newest;\n\n const check =\n manifest === undefined\n ? ({\n status: \"skipped\",\n reason: \"no session manifest for this trace\",\n } as const)\n : outside && digests.size === 0\n ? ({\n status: \"skipped\",\n reason:\n \"outside the project root, so no session manifest could record it\",\n } as const)\n : checkContent(manifest, digests);\n entry.contentCheck = check;\n if (check.status !== \"skipped\") joined = true;\n\n if (check.status === \"mismatch\") {\n entry.stale = true;\n changed.push(entry.ref);\n continue;\n }\n if (check.status === \"match\") {\n // Exact, and it answers mtime's own question — so the guess does not run.\n entry.stale = false;\n continue;\n }\n if (!haveEnd || newest === undefined) continue;\n entry.stale = Date.parse(newest) > endedAt;\n if (entry.stale) guessed.push(entry.ref);\n }\n\n if (changed.length > 0) {\n warnings.push(\n `${changed.length} artifact(s) changed since the session started ` +\n `(${changed.join(\", \")}) — the session manifest recorded a different ` +\n `sha256, so their evals are not the instructions this session followed.`,\n );\n }\n if (guessed.length > 0) {\n // One warning, not one per artifact: a fresh checkout flags everything, and\n // a wall of identical lines is how a real signal gets tuned out.\n warnings.push(\n `${guessed.length} artifact(s) were modified after the session ended ` +\n `(${guessed.join(\", \")}) — their evals may not be the instructions ` +\n `this session followed. mtime is a heuristic, not content identity.`,\n );\n }\n // A manifest that speaks to nothing is a different problem from a manifest\n // with a gap in it, and it degrades row by row into the same sentence — the\n // one an absent manifest produces. Say it once, at the top.\n //\n // Only when it recorded something: a manifest with no artifacts in it — a\n // project whose instruction files all live outside the capture scope — has\n // nothing to match, which is not a join failure.\n if (manifest !== undefined && manifest.artifacts.length > 0 && !joined) {\n warnings.push(\n `the session manifest matched no artifact in this run — it recorded ` +\n `${manifest.artifacts.length} artifact(s) relative to \"${manifest.root}\", ` +\n `and nothing resolved here lines up with them, so every hash check ` +\n `fell back to the mtime heuristic. Check that --project names the ` +\n `directory the session ran in.`,\n );\n }\n}\n\n/**\n * Pick the base to key the manifest join on.\n *\n * `capture` writes each path relative to *its* project root — the session's\n * cwd — while resolution keys on the git root when `--project` is absent. In a\n * monorepo those are different directories, so one file gets two different\n * relative paths and every hash check silently degraded to `skipped`: exactly\n * the guesswork a manifest exists to remove, and quietly, row by row.\n *\n * Rather than pick a side, ask the data. Each candidate base is scored by how\n * many resolved artifacts it turns into a path the manifest actually recorded,\n * and the best score wins — with candidate order as the tiebreak, so a tie\n * keeps today's behaviour. `manifest.root` joins the candidates because it is\n * the capturing machine's own answer; it may have been redacted, or the\n * repository may have moved since, in which case it simply scores zero.\n */\nfunction joinBase(\n manifest: SessionManifest,\n coverage: CoverageEntry[],\n extraPaths: Map<CoverageEntry, string[]>,\n candidates: string[],\n): string {\n const recorded = new Set(manifest.artifacts.map((a) => a.path));\n const paths = coverage\n .filter((entry) => entry.resolved)\n .flatMap((entry) => extraPaths.get(entry) ?? (entry.path ? [entry.path] : []));\n\n let best = candidates[0] as string;\n let bestScore = -1;\n for (const candidate of candidates) {\n if (typeof candidate !== \"string\" || candidate.length === 0) continue;\n let score = 0;\n for (const path of paths) {\n let rel: string | null;\n try {\n rel = relPosix(candidate, path);\n } catch {\n // A redacted `root` can be anything, including something `resolve`\n // refuses. A candidate that cannot be used simply does not win.\n continue;\n }\n if (rel !== null && recorded.has(rel)) score += 1;\n }\n if (score > bestScore) {\n best = candidate;\n bestScore = score;\n }\n }\n return best;\n}\n\n// ── Skills ───────────────────────────────────────────────────────\n\nasync function resolveSkill(\n name: string,\n projectDir: string,\n userDir: string,\n): Promise<{ artifact: ResolvedArtifact | null; tried: string[] }> {\n const tried: string[] = [];\n // `plugin:skill` refs look up the skill by its short name inside the\n // user plugin store; plain refs check project dirs then the user store.\n const [pluginName, shortName] = splitPluginRef(name);\n\n const candidates: Array<{ path: string; origin: ResolvedArtifact[\"origin\"] }> =\n [];\n if (pluginName === null) {\n for (const dir of [\"skills\", join(\"src\", \"skills\"), join(\".claude\", \"skills\")]) {\n candidates.push({\n path: join(projectDir, dir, shortName, \"SKILL.md\"),\n origin: \"project\",\n });\n }\n candidates.push({\n path: join(userDir, \"skills\", shortName, \"SKILL.md\"),\n origin: \"user\",\n });\n }\n\n for (const candidate of candidates) {\n tried.push(candidate.path);\n const content = await safeRead(candidate.path);\n if (content !== null) {\n return {\n artifact: {\n name,\n type: \"skill\",\n path: candidate.path,\n content,\n origin: candidate.origin,\n },\n tried,\n };\n }\n }\n\n // Plugin store: ~/.claude/plugins/**/skills/<shortName>/SKILL.md. The store\n // layout varies (marketplace caches nest deeper), so search recursively.\n const pluginRoot = join(userDir, \"plugins\");\n tried.push(join(pluginRoot, \"**\", \"skills\", shortName, \"SKILL.md\"));\n const found = await findInTree(\n pluginRoot,\n (path) =>\n basename(path) === \"SKILL.md\" &&\n basename(dirname(path)) === shortName &&\n (pluginName === null || hasPathSegment(path, pluginName)),\n );\n if (found) {\n const content = await safeRead(found);\n if (content !== null) {\n return {\n artifact: { name, type: \"skill\", path: found, content, origin: \"plugin\" },\n tried,\n };\n }\n }\n\n return { artifact: null, tried };\n}\n\n// ── Slash commands ───────────────────────────────────────────────\n\n/**\n * `.claude/commands/<name>.md`, in the three places Claude Code reads them:\n * the project, the user's config directory, and the plugin store.\n *\n * Two shapes matter and neither is guessed at. Subdirectories under\n * `commands/` **organize** rather than namespace — `commands/release/tag.md`\n * is still invoked as `/tag` — so a plain name falls back to a recursive\n * search after the direct hit misses. A `plugin:command` name is plugin\n * namespacing and is looked up in the store by its short name, exactly as\n * `resolveSkill` does for `plugin:skill`; project and user directories are not\n * checked, because a namespace is not something a local file can claim.\n */\nasync function resolveSlashCommand(\n name: string,\n projectDir: string,\n userDir: string,\n): Promise<{ artifact: ResolvedArtifact | null; tried: string[] }> {\n const tried: string[] = [];\n const [pluginName, shortName] = splitPluginRef(name);\n\n const made = (\n path: string,\n content: string,\n origin: ResolvedArtifact[\"origin\"],\n ): { artifact: ResolvedArtifact; tried: string[] } => ({\n artifact: { name, type: \"slash-command\", path, content, origin },\n tried,\n });\n\n if (pluginName === null) {\n const dirs: Array<{ dir: string; origin: ResolvedArtifact[\"origin\"] }> = [\n { dir: join(projectDir, \".claude\", \"commands\"), origin: \"project\" },\n { dir: join(userDir, \"commands\"), origin: \"user\" },\n ];\n for (const { dir, origin } of dirs) {\n const path = join(dir, `${shortName}.md`);\n tried.push(path);\n const content = await safeRead(path);\n if (content !== null) return made(path, content, origin);\n }\n for (const { dir, origin } of dirs) {\n tried.push(join(dir, \"**\", `${shortName}.md`));\n const found = await findInTree(\n dir,\n (path) => basename(path) === `${shortName}.md`,\n );\n if (found === null) continue;\n const content = await safeRead(found);\n if (content !== null) return made(found, content, origin);\n }\n return { artifact: null, tried };\n }\n\n const pluginRoot = join(userDir, \"plugins\");\n tried.push(join(pluginRoot, \"**\", \"commands\", `${shortName}.md`));\n const found = await findInTree(\n pluginRoot,\n (path) =>\n basename(path) === `${shortName}.md` &&\n segments(path).includes(\"commands\") &&\n hasPathSegment(path, pluginName),\n );\n if (found !== null) {\n const content = await safeRead(found);\n if (content !== null) return made(found, content, \"plugin\");\n }\n return { artifact: null, tried };\n}\n\n/** Path segments, separator-normalized, for convention matching. */\n/**\n * Split `plugin:name` into its two halves.\n *\n * On the **first** colon, keeping the remainder: `split(\":\", 2)` throws away\n * everything past the second field, so `myplugin:release:tag` resolved as a\n * lookup for `release` — a different artifact, reported as if it were the one\n * asked for. The namespace is the part before the first colon; everything\n * after it is the name, whatever it contains.\n */\nfunction splitPluginRef(name: string): [string | null, string] {\n const at = name.indexOf(\":\");\n if (at === -1) return [null, name];\n return [name.slice(0, at), name.slice(at + 1)];\n}\n\n/**\n * True when `pluginName` is a *segment* of `path`.\n *\n * `path.includes(pluginName)` was unanchored over the whole absolute path, so\n * a plugin named `docs` matched `~/.claude/plugins/other-plugin/commands/\n * docs-helper/x.md` — and, on Windows, matched every path under a home\n * directory of `C:\\Users\\docs\\`. A plugin is a directory, so the test is\n * whether the path passes through a directory of that name.\n */\nfunction hasPathSegment(path: string, pluginName: string): boolean {\n return segments(path).includes(pluginName);\n}\n\n// ── Agents ───────────────────────────────────────────────────────\n\nasync function resolveAgent(\n subagentType: string,\n projectDir: string,\n userDir: string,\n): Promise<{ artifact: ResolvedArtifact | null; tried: string[] }> {\n const tried: string[] = [];\n // Plugin agents are referenced as `plugin:agent`; the file is the short name.\n const shortName = splitPluginRef(subagentType)[1];\n\n const candidates: Array<{ path: string; origin: ResolvedArtifact[\"origin\"] }> = [\n { path: join(projectDir, \".claude\", \"agents\", `${shortName}.md`), origin: \"project\" },\n { path: join(projectDir, \"agents\", `${shortName}.md`), origin: \"project\" },\n { path: join(userDir, \"agents\", `${shortName}.md`), origin: \"user\" },\n ];\n\n for (const candidate of candidates) {\n tried.push(candidate.path);\n const content = await safeRead(candidate.path);\n if (content !== null) {\n return {\n artifact: {\n name: subagentType,\n type: \"agent\",\n path: candidate.path,\n content,\n origin: candidate.origin,\n },\n tried,\n };\n }\n }\n return { artifact: null, tried };\n}\n\n// ── Project rules ────────────────────────────────────────────────\n\nasync function resolveProjectRules(\n projectDir: string,\n projectRoot: string,\n): Promise<{ artifacts: ResolvedArtifact[]; tried: string[] }> {\n const artifacts: ResolvedArtifact[] = [];\n const tried: string[] = [];\n\n // Walk from the cwd up to the project root (inclusive), then check .claude/.\n const dirs: string[] = [];\n let current = projectDir;\n for (let depth = 0; depth < 32; depth += 1) {\n dirs.push(current);\n if (current === projectRoot) break;\n const parent = dirname(current);\n if (parent === current) break;\n current = parent;\n }\n dirs.push(join(projectRoot, \".claude\"));\n\n for (const dir of dirs) {\n for (const filename of PROJECT_RULES_FILENAMES) {\n const path = join(dir, filename);\n tried.push(path);\n const content = await safeRead(path);\n if (content !== null) {\n artifacts.push({\n name: filename,\n type: \"project-rules\",\n path,\n content,\n origin: \"project\",\n });\n }\n }\n }\n return { artifacts, tried };\n}\n\n// Filesystem helpers live in ./fs.js, shared with static discovery.\n","/**\n * The artifact vocabulary `manni tracevals` implements:\n * `manni:artifact-evals:1.1.0`, the built-in the metadata tool registers\n * under `src/meta/schemas/` (proposal 0076). Artifacts are validated against\n * that schema itself, imported and bundled into the build, so tracevals and\n * `manni meta validate` read the same bytes and the built CLI never reads a\n * `schemas/` directory at runtime.\n *\n * 1.1.0 rather than 1.0.0 because it names `tool-order`, a grader this tool\n * ships. The open vocabulary accepts any kebab grader name at either version.\n *\n * tracevals ships no copy of the schema. A copy is a second artifact to keep\n * in step, and the two it used to publish had drifted: they kept\n * `eval-provenance` and the `info` severity after 0046 removed both. A\n * consumer who wants to validate artifacts names `manni:artifact-evals:1.1.0`\n * to `manni meta validate`, or validates against the object below.\n *\n * The validator is this tool's own Ajv rather than meta's `Validator`, which\n * takes refs it can load rather than a schema object. Violations are converted\n * to `FieldError` here so everything downstream — the planner, the reporters —\n * sees the one finding shape the family reports.\n */\nimport { Ajv2020 } from \"ajv/dist/2020.js\";\nimport type { DefinedError, ErrorObject } from \"ajv\";\nimport type { FieldError } from \"../../meta/index.js\";\nimport schema from \"../../meta/schemas/artifact-evals/1.1.0.json\" with { type: \"json\" };\n\n/** The artifact-evals vocabulary, for validators that accept an inline schema. */\nexport const artifactEvalsSchema = schema as unknown as Record<string, unknown>;\n\n/** The vocabulary's `$id`: `manni:artifact-evals:1.1.0`. */\nexport const ARTIFACT_EVALS_SCHEMA_ID: string = schema.$id;\n\nconst ajv = new Ajv2020({ allErrors: true, allowUnionTypes: true });\n// The vocabulary marks `metadata` `x-manni-location: external` (0047). The\n// mark is an annotation for `manni meta relocate`, not a constraint, so it is\n// registered rather than validated — but it has to be registered, or Ajv's\n// strict mode refuses to compile the schema at all.\najv.addKeyword({ keyword: \"x-manni-location\" });\nconst validateArtifact = ajv.compile(artifactEvalsSchema);\n\n/**\n * The stable identifier inside a violation, when its keyword names a *thing*.\n * Keywords whose parameter is a schema-authored value (`pattern`'s regex,\n * `enum`'s list) are deliberately left without one: including those would\n * change a finding's identity every time the schema author edited the rule.\n */\nfunction subjectOf(e: DefinedError): string | undefined {\n switch (e.keyword) {\n case \"required\":\n return e.params.missingProperty;\n case \"additionalProperties\":\n return e.params.additionalProperty;\n case \"format\":\n return e.params.format;\n case \"type\":\n return e.params.type;\n default:\n return undefined;\n }\n}\n\n/**\n * Validate an artifact's whole front matter against the vocabulary. The schema is\n * document-rooted — `metadata` stays open so other tools' members pass\n * untouched — which is why it is handed the entire object rather than the\n * `evals` value alone.\n */\nexport function artifactEvalsErrors(\n data: Record<string, unknown>,\n lineFor: (pointer: string) => number | undefined,\n): FieldError[] {\n if (validateArtifact(data)) return [];\n const errors: FieldError[] = [];\n for (const raw of validateArtifact.errors ?? []) {\n errors.push(toFieldError(raw, lineFor));\n }\n return errors;\n}\n\nfunction toFieldError(\n e: ErrorObject,\n lineFor: (pointer: string) => number | undefined,\n): FieldError {\n const subject = subjectOf(e as DefinedError);\n // `required` and `additionalProperties` point `instancePath` at the *parent*\n // and name the property in the message, so the property is spelled out\n // rather than left to the reader to find.\n const message =\n subject !== undefined && (e.keyword === \"required\" || e.keyword === \"additionalProperties\")\n ? `${e.message ?? \"is invalid\"} (\"${subject}\")`\n : (e.message ?? \"is invalid\");\n const line = lineFor(e.instancePath);\n return {\n schema: ARTIFACT_EVALS_SCHEMA_ID,\n instancePath: e.instancePath,\n message,\n keyword: e.keyword,\n ...(subject !== undefined ? { subject } : {}),\n ...(line !== undefined ? { line } : {}),\n };\n}\n","/**\n * Eval extraction: read the `metadata.evals` block from an artifact via the\n * metadata library and validate the artifact's whole front matter against\n * `manni:artifact-evals:1.1.0`. Invalid blocks are reported as errors with\n * source line numbers, never silently ignored (ADR 01002).\n *\n * The vocabulary is the metadata tool's registered built-in; this tool\n * implements behavior against it (ADR 01010) and bundles it rather than\n * shipping a copy — see `schema.ts`. The schema is document-rooted, which is\n * why validation is handed the entire front matter object rather than the\n * `evals` value alone.\n */\nimport {\n extractFrontmatter,\n type ExtractedMetadata,\n type FieldError,\n} from \"../../meta/index.js\";\nimport { metaProvenanceEntries } from \"../../meta/internal.js\";\nimport type { ResolvedArtifact } from \"../artifacts/types.js\";\nimport type { TraceTarget } from \"../core/target.js\";\nimport { ARTIFACT_EVALS_SCHEMA_ID, artifactEvalsErrors } from \"./schema.js\";\n\nexport { ARTIFACT_EVALS_SCHEMA_ID };\n\n/**\n * The family scale (`src/shared/severity.ts`): `notice | warning | error`.\n * proposal.2 spelled the quietest level `info`; proposal.4 spells it the way\n * every other manni tool does, so a finding reads the same everywhere.\n */\nexport type { Severity } from \"../../shared/severity.js\";\nimport type { Severity } from \"../../shared/severity.js\";\n\n/**\n * `capability` probes a boundary and is expected to fail sometimes;\n * `regression` protects behavior that already works. Reported, not enforced.\n */\nexport type EvalType = \"capability\" | \"regression\";\n\nexport interface EvalEntry {\n /** Stable identifier. Required by the schema on object entries. */\n id: string;\n /** Absent on graders whose options say everything. */\n assertion?: string;\n type: EvalType;\n /** \"ai\", \"human\", \"command\", or a deterministic grader kind. */\n grader: string;\n /** Overrides the configured judge provider for this eval only. */\n provider?: string;\n /** Overrides the judge model for this eval only; a CLI --model still wins. */\n model?: string;\n /** Ensemble runs for this eval only; a CLI --runs still wins. */\n runs?: number;\n /** Which bytes the grader receives. Absent means the whole transcript. */\n target?: TraceTarget;\n /** Relative contribution to the run's pass rate. Never changes the outcome. */\n weight?: number;\n options?: Record<string, unknown>;\n severity: Severity;\n evidence?: string;\n examples?: { pass?: string[]; fail?: string[] };\n /** Per-entry opt-out; reported as skipped, never silently dropped. */\n skip?: boolean;\n /**\n * Maps a `tool:*` grader's own severities onto eval severities. Accepted so\n * one entry vocabulary ports across both docmeta eval schemas; ignored here,\n * because this repo implements no `tool:*` graders.\n */\n severityMap?: Record<string, Severity>;\n /** Command-graded evals: argv, with `{trace}` substituted at grade time. */\n command?: string[];\n successExitCodes?: number[];\n timeoutMs?: number;\n /** sha256 of `assertion` when the check script was generated. */\n generatedAssertionHash?: string;\n}\n\nexport interface ExtractedEvals {\n evals: EvalEntry[];\n /** Schema violations in the front matter, with line numbers when known. */\n errors: FieldError[];\n /** Whether a `metadata.evals` block was present. */\n declared: boolean;\n /** `metadata.eval-skip` — skip this artifact's evals entirely. */\n skip: boolean;\n /**\n * Which model proposed each eval, by eval id, from\n * `metadata.meta-provenance` — the family's attribution record (0046),\n * written by `fill` through the same merge `manni meta fill` uses. Reading\n * it is what lets the judge notice it is grading an assertion it wrote\n * itself, which is bias on the *criterion* rather than on the session.\n *\n * Names are bare model names, the same spelling a provider's `modelName()`\n * returns, so the two sides of that comparison can actually match.\n *\n * A list because one id may appear under several `generated-by` entries —\n * a re-fill by a second model extends the block rather than replacing it.\n */\n proposedBy: Map<string, string[]>;\n}\n\n/**\n * Members of `metadata` this vocabulary claims. The schema cannot reject the\n * rest: `metadata` is the host tool's extension bag and must stay open, so a\n * misspelled `eval-skpi` would validate and quietly do nothing. Reserving the\n * `eval-` prefix at run time restores the closed block's loud-typo property.\n */\nconst CLAIMED_KEYS = [\"evals\", \"eval-skip\", \"meta-provenance\"] as const;\n\n/**\n * The one member under the reserved prefix this vocabulary keeps. proposal.4\n * narrowed the guard to `^eval-(?!skip$)`, so `eval-provenance` — proposal.2's\n * name for the attribution trail — is now an error rather than a member\n * everything downstream would silently ignore.\n */\nconst PREFIX_EXCEPTION = \"eval-skip\";\n\n/** A YAML mapping, as opposed to a list, a scalar, or null. */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * `metadata` and everything under it, for one artifact.\n *\n * `supplied` is the seam for the external trail (`evals/external.ts`): the\n * artifact's front matter with a manifest-supplied `metadata` block already\n * merged in, by meta's own merge. It is the whole extraction rather than the\n * block alone, because the schema is document-rooted and validates the entire\n * front matter — handing it the block would validate the wrong document.\n * Omitted, the artifact's own front matter is read, which is what every caller\n * with no collections does.\n */\nexport function extractEvals(\n artifact: ResolvedArtifact,\n supplied?: ExtractedMetadata,\n): ExtractedEvals {\n const extracted = supplied ?? extractFrontmatter(artifact.content, \"markdown\");\n const metadata = extracted.data.metadata;\n // The schema types `metadata` as an object. Anything else — a string, a\n // list, a number — is a fault the validator must report, so it is kept\n // distinct from \"absent\" rather than folded into it.\n const bag = isPlainObject(metadata) ? metadata : undefined;\n const declared = bag !== undefined && bag.evals !== undefined;\n\n // `present` describes the *page*, and the merge leaves it alone. An artifact\n // with no front matter at all whose block a manifest supplies therefore reads\n // as absent unless the merged `metadata` is consulted too — the case a\n // relocated `CLAUDE.md` is in, since project rules rarely carry front matter.\n if (!extracted.present && metadata === undefined) {\n return { evals: [], errors: [], declared: false, skip: false, proposedBy: new Map() };\n }\n\n const typoErrors = reservedPrefixErrors(bag, extracted.lineFor);\n if (typoErrors.length > 0) {\n return { evals: [], errors: typoErrors, declared, skip: false, proposedBy: new Map() };\n }\n\n // Skip the validator only for an artifact this vocabulary has nothing to say\n // about: `metadata` absent, or a well-formed object claiming none of its\n // keys. A `metadata` that is not an object still has to be validated (the\n // schema types it), and so does one carrying only `meta-provenance` — the\n // block is malformed-or-not either way, and a malformed one is never\n // silently ignored.\n const wellFormed = metadata === undefined || bag !== undefined;\n const claimsNothing =\n bag === undefined ||\n !CLAIMED_KEYS.some((key) => bag[key] !== undefined);\n if (wellFormed && claimsNothing) {\n return {\n evals: [],\n errors: [],\n declared: false,\n skip: false,\n proposedBy: new Map(),\n };\n }\n\n const errors = artifactEvalsErrors(extracted.data, extracted.lineFor);\n if (errors.length > 0) {\n return { evals: [], errors, declared, skip: false, proposedBy: new Map() };\n }\n\n // Validation passed, so `metadata` is an object if it is present at all.\n const valid = bag ?? {};\n const skip = valid[\"eval-skip\"] === true;\n return {\n evals: normalizeBlock(valid.evals),\n errors: [],\n declared,\n skip,\n proposedBy: readProvenance(valid[\"meta-provenance\"]),\n };\n}\n\n/**\n * `metadata.meta-provenance` as eval id → the models that proposed it.\n *\n * The entries come from `metaProvenanceEntries`, the family's reader (0046),\n * so the block is read exactly the way `fill` wrote it and the way docevals\n * reads its own. Tolerant by design: the block has already passed the schema,\n * and a shape it did not constrain is not worth failing a run over — the worst\n * outcome of ignoring a malformed entry is one missing bias warning, while the\n * worst outcome of throwing is a run that will not start.\n */\nfunction readProvenance(raw: unknown): Map<string, string[]> {\n const out = new Map<string, string[]>();\n for (const entry of metaProvenanceEntries(raw)) {\n const by = entry[\"generated-by\"];\n for (const id of entry.evals) {\n const list = out.get(id) ?? [];\n if (!list.includes(by)) list.push(by);\n out.set(id, list);\n }\n }\n return out;\n}\n\n/**\n * A key inside `metadata` under the reserved `eval-` prefix that is not the\n * one member this vocabulary claims there. Reported against the offending key\n * so the fix is obvious.\n *\n * proposal.4's guard is `^eval-(?!skip$)`: `eval-provenance`, which proposal.2\n * excepted, now lands here rather than being read by nothing.\n */\nfunction reservedPrefixErrors(\n bag: Record<string, unknown> | undefined,\n lineFor: (pointer: string) => number | undefined,\n): FieldError[] {\n if (bag === undefined) return [];\n const errors: FieldError[] = [];\n for (const key of Object.keys(bag)) {\n // Detection is case-insensitive while the exception is not, deliberately:\n // YAML keys are case-sensitive, so `Eval-skip` is never a valid spelling of\n // `eval-skip` and should be reported rather than accepted. Do not \"fix\" the\n // asymmetry by matching the exception case-insensitively — that would\n // silently accept exactly the misspellings this guard exists to catch.\n if (!/^eval-/i.test(key) || key === PREFIX_EXCEPTION) continue;\n const line = lineFor(`/metadata/${key}`);\n errors.push({\n schema: ARTIFACT_EVALS_SCHEMA_ID,\n instancePath: `/metadata/${key}`,\n message:\n `unrecognized \"eval-\" key; the only one this vocabulary claims under ` +\n `that prefix is ${PREFIX_EXCEPTION} (its other members are ` +\n `${CLAIMED_KEYS.filter((k) => k !== PREFIX_EXCEPTION).join(\" and \")})`,\n keyword: \"additionalProperties\",\n subject: key,\n ...(line !== undefined ? { line } : {}),\n });\n }\n return errors;\n}\n\n/**\n * The block is one assertion as a string, or a list of entries. An absent key\n * yields nothing — an artifact with no evals omits it rather than declaring an\n * empty list, which the schema also refuses.\n */\nfunction normalizeBlock(raw: unknown): EvalEntry[] {\n if (typeof raw === \"string\") return [normalizeEntry(raw, 0)];\n if (!Array.isArray(raw)) return [];\n return raw.map((entry, index) => normalizeEntry(entry, index));\n}\n\nfunction normalizeEntry(raw: unknown, index: number): EvalEntry {\n // The string shorthand is the legitimately id-less form, so its identity is\n // positional. Object entries carry a required `id` precisely because a\n // position-derived name breaks the history join whenever entries move.\n if (typeof raw === \"string\") {\n return {\n id: `eval-${index + 1}`,\n assertion: raw,\n type: \"regression\",\n grader: \"ai\",\n severity: \"error\",\n };\n }\n\n const obj = raw as Record<string, unknown>;\n const entry: EvalEntry = {\n id: obj.id as string,\n // Optional since artifact-evals proposal.2: a `tool-usage` criterion says\n // everything in `options`, and demanding a sentence no grader reads was\n // the one place this vocabulary disagreed with the page side. The schema\n // still requires it for `ai`, `human`, and a bare entry (which defaults to\n // `ai`), so anything that actually needs an assertion still has one.\n ...(typeof obj.assertion === \"string\" ? { assertion: obj.assertion } : {}),\n type: (obj.type as EvalType | undefined) ?? \"regression\",\n grader: typeof obj.grader === \"string\" ? obj.grader : \"ai\",\n severity: (obj.severity as Severity | undefined) ?? \"error\",\n };\n if (typeof obj.provider === \"string\") entry.provider = obj.provider;\n if (typeof obj.model === \"string\") entry.model = obj.model;\n if (typeof obj.runs === \"number\") entry.runs = obj.runs;\n if (typeof obj.weight === \"number\") entry.weight = obj.weight;\n if (typeof obj.target === \"string\" || (obj.target && typeof obj.target === \"object\")) {\n entry.target = obj.target as TraceTarget;\n }\n if (obj.options && typeof obj.options === \"object\") {\n entry.options = obj.options as Record<string, unknown>;\n }\n if (typeof obj.evidence === \"string\") entry.evidence = obj.evidence;\n if (obj.examples && typeof obj.examples === \"object\") {\n entry.examples = normalizeExamples(obj.examples as Record<string, unknown>);\n }\n if (obj.skip === true) entry.skip = true;\n if (obj[\"severity-map\"] && typeof obj[\"severity-map\"] === \"object\") {\n entry.severityMap = obj[\"severity-map\"] as Record<string, Severity>;\n }\n if (Array.isArray(obj.command)) entry.command = obj.command as string[];\n if (Array.isArray(obj[\"success-exit-codes\"])) {\n entry.successExitCodes = obj[\"success-exit-codes\"] as number[];\n }\n if (typeof obj[\"timeout-ms\"] === \"number\") {\n entry.timeoutMs = obj[\"timeout-ms\"];\n }\n if (typeof obj[\"generated-assertion-hash\"] === \"string\") {\n entry.generatedAssertionHash = obj[\"generated-assertion-hash\"];\n }\n return entry;\n}\n\n/** Anchors are one example or a list of them; downstream sees only the list. */\nfunction normalizeExamples(\n raw: Record<string, unknown>,\n): { pass?: string[]; fail?: string[] } {\n const out: { pass?: string[]; fail?: string[] } = {};\n const pass = anchorList(raw.pass);\n const fail = anchorList(raw.fail);\n if (pass) out.pass = pass;\n if (fail) out.fail = fail;\n return out;\n}\n\nfunction anchorList(raw: unknown): string[] | undefined {\n if (typeof raw === \"string\") return [raw];\n if (Array.isArray(raw)) return raw.filter((e): e is string => typeof e === \"string\");\n return undefined;\n}\n"],"mappings":"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","names":["empty","Ajv2020","ajv","Ajv2020","validate","readFile","dirname","resolve","readFile","resolve","dirname","readFile","dirname","join","resolve","sep","dirname","join","resolve","resolve","refKey","join","dirname","found","Ajv2020","ajv","Ajv2020"]}
|