@hawkeyexl/manni 4.7.0 → 4.8.1

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.
Files changed (172) hide show
  1. package/README.md +1 -1
  2. package/dist/{batch-U6S2JUUN.js → batch-QMHYWGUA.js} +12 -12
  3. package/dist/{build-4RN6WBCP.js → build-ZGA3O3P4.js} +9 -9
  4. package/dist/{calibrate-6VIZYR4L.js → calibrate-KBMFGKP3.js} +13 -13
  5. package/dist/{capture-DP3NXAZE.js → capture-C46UXFRK.js} +12 -12
  6. package/dist/{check-IWHUPAZM.js → check-CORYIW76.js} +28 -28
  7. package/dist/check-CORYIW76.js.map +1 -0
  8. package/dist/{check-STHXZIZO.js → check-LLQ6PJV3.js} +9 -9
  9. package/dist/{check-ERVNGKLC.js → check-UMI5ACCE.js} +10 -10
  10. package/dist/{chunk-IOL74S4J.js → chunk-3FG2UU3H.js} +4 -4
  11. package/dist/{chunk-K52CS4KT.js → chunk-4VQBHTGA.js} +5 -5
  12. package/dist/{chunk-MIBWI5H7.js → chunk-5LAKRYXU.js} +3 -3
  13. package/dist/{chunk-MSMB6XOS.js → chunk-6HMLYFEU.js} +2 -2
  14. package/dist/{chunk-4Z2MN5FR.js → chunk-6MNOMHFI.js} +10 -10
  15. package/dist/{chunk-UZKQSWHJ.js → chunk-6QBJHRFC.js} +2 -2
  16. package/dist/{chunk-B5CMM57M.js → chunk-6ZR24A4S.js} +2 -2
  17. package/dist/{chunk-WTEILBKC.js → chunk-77L5GNVO.js} +2 -2
  18. package/dist/{chunk-D6RO54QD.js → chunk-7LC4YJJ3.js} +4 -4
  19. package/dist/chunk-7LC4YJJ3.js.map +1 -0
  20. package/dist/{chunk-6URSCTTX.js → chunk-AO66Q66S.js} +2 -2
  21. package/dist/{chunk-NIFEEIGQ.js → chunk-BYVH727K.js} +2 -2
  22. package/dist/{chunk-PNX43DYW.js → chunk-C2JPBQCJ.js} +21 -3
  23. package/dist/{chunk-PNX43DYW.js.map → chunk-C2JPBQCJ.js.map} +1 -1
  24. package/dist/{chunk-GCC52YZD.js → chunk-F734HIHT.js} +3 -3
  25. package/dist/{chunk-CEVU3GFF.js → chunk-FEALEYSE.js} +4 -4
  26. package/dist/{chunk-QQNPVW3J.js → chunk-GQBVZS5G.js} +6 -6
  27. package/dist/{chunk-D2LBN44V.js → chunk-HNMXL2OE.js} +3 -3
  28. package/dist/chunk-HNMXL2OE.js.map +1 -0
  29. package/dist/{chunk-NZ6TNSCU.js → chunk-HWNSIEZK.js} +5 -5
  30. package/dist/{chunk-LDKIIZDW.js → chunk-K43X5VDR.js} +5 -5
  31. package/dist/{chunk-TPVOOTMN.js → chunk-KPXOJMQ6.js} +16 -13
  32. package/dist/chunk-KPXOJMQ6.js.map +1 -0
  33. package/dist/{chunk-ZPP75QWG.js → chunk-LAU6SVTJ.js} +8 -8
  34. package/dist/{chunk-ZNE25EAR.js → chunk-LF6FOF6U.js} +4 -4
  35. package/dist/{chunk-YSCZL4U5.js → chunk-N7J5C35C.js} +2 -2
  36. package/dist/{chunk-YSCZL4U5.js.map → chunk-N7J5C35C.js.map} +1 -1
  37. package/dist/{chunk-6VDBP5UV.js → chunk-NB4ILZMQ.js} +6 -6
  38. package/dist/{chunk-BWCWTHYS.js → chunk-NGTVREIH.js} +4 -4
  39. package/dist/chunk-NGTVREIH.js.map +1 -0
  40. package/dist/{chunk-AMEILOVV.js → chunk-NNFSIRVE.js} +4 -4
  41. package/dist/{chunk-LXJEAV2V.js → chunk-PO5W6JAP.js} +5 -5
  42. package/dist/{chunk-OOEMKOX6.js → chunk-POGYWOJ2.js} +3 -3
  43. package/dist/{chunk-LONRQBGV.js → chunk-Q3GFZJTY.js} +4 -4
  44. package/dist/{chunk-ZKAKA54B.js → chunk-RCS5YFY2.js} +2 -2
  45. package/dist/{chunk-C2TJG5KV.js → chunk-SV6UEQCU.js} +4 -4
  46. package/dist/{chunk-2ZWTSRE5.js → chunk-SXODK43S.js} +4 -4
  47. package/dist/{chunk-7XZ6INKO.js → chunk-UWY4B2PM.js} +4 -4
  48. package/dist/{chunk-PAOVVHQX.js → chunk-VD3EQSBI.js} +2 -2
  49. package/dist/{chunk-CI55ABCK.js → chunk-VQK4VHLF.js} +8 -8
  50. package/dist/chunk-VQK4VHLF.js.map +1 -0
  51. package/dist/{chunk-IZBBXKMJ.js → chunk-VSOYZ7QH.js} +3 -3
  52. package/dist/{chunk-CR3HZERW.js → chunk-WBETAXO2.js} +4 -4
  53. package/dist/{chunk-5UB47BEV.js → chunk-WT6HMEEF.js} +2 -2
  54. package/dist/{chunk-IIFADWWI.js → chunk-WUFP4V7B.js} +3 -3
  55. package/dist/{chunk-7EL5LLKD.js → chunk-WUXD6VBD.js} +2 -2
  56. package/dist/{chunk-ZKCNPKUO.js → chunk-XDS3KQCK.js} +3 -3
  57. package/dist/{chunk-5VWDIWOH.js → chunk-YVVMC4SZ.js} +3 -3
  58. package/dist/{chunk-ZEXGGGLW.js → chunk-Z27GYQOY.js} +7 -7
  59. package/dist/{chunk-QP5X66TO.js → chunk-ZIGIJBXG.js} +9 -9
  60. package/dist/{cli-37SRAYNE.js → cli-4B5RWL7P.js} +11 -11
  61. package/dist/{cli-IRHPPUFJ.js → cli-5AML7QR2.js} +10 -10
  62. package/dist/{cli-NM6FZ54R.js → cli-I4GBPLRM.js} +2 -2
  63. package/dist/{cli-YL3IDR52.js → cli-MNNOXWYU.js} +7 -7
  64. package/dist/{cli-XIODOEUG.js → cli-QR3ZQZA4.js} +20 -20
  65. package/dist/{cli-MTDGQIIV.js → cli-SBJY2NQH.js} +14 -14
  66. package/dist/{cli-ZQUJYQBA.js → cli-UB5W75GJ.js} +11 -11
  67. package/dist/{cli-KIID535Y.js → cli-WWDARAWS.js} +13 -13
  68. package/dist/{cli-HXWYUKGJ.js → cli-XIQKPNA7.js} +35 -34
  69. package/dist/cli-XIQKPNA7.js.map +1 -0
  70. package/dist/cli.js +11 -11
  71. package/dist/{config-O6UBGEDK.js → config-YWSNBFEE.js} +3 -3
  72. package/dist/docmeta.js +6 -6
  73. package/dist/{github-UCYLM3DR.js → github-TIZ3ZR3D.js} +9 -9
  74. package/dist/{github-VEJFO6JJ.js → github-WKOJRW7P.js} +11 -11
  75. package/dist/index.d.ts +16 -6
  76. package/dist/index.js +32 -32
  77. package/dist/{json-6F52FSXZ.js → json-4FUOZ3XX.js} +9 -9
  78. package/dist/{lint-X2GNINK6.js → lint-7VQFESHK.js} +9 -9
  79. package/dist/{list-DP3O3CWB.js → list-7U2MBDIM.js} +9 -9
  80. package/dist/{list-P77RZFZF.js → list-W6EUAOBV.js} +9 -9
  81. package/dist/{page-WQCMBNRD.js → page-WZLBKSCD.js} +8 -8
  82. package/dist/{prepare-52QOK7M4.js → prepare-FPEWAHJH.js} +17 -17
  83. package/dist/prepare-FPEWAHJH.js.map +1 -0
  84. package/dist/{pretty-H4DQREMW.js → pretty-7M4X4TCY.js} +9 -9
  85. package/dist/{pretty-5MMMNSWF.js → pretty-CUCMQU5R.js} +10 -10
  86. package/dist/{provider-AMGRDY6V.js → provider-527CO4DM.js} +2 -2
  87. package/dist/{release-CTYRHZL4.js → release-3D5PK6M7.js} +2 -2
  88. package/dist/release-3D5PK6M7.js.map +1 -0
  89. package/dist/{reporters-SU3VUKKX.js → reporters-DQVSDXV6.js} +4 -4
  90. package/dist/{reporters-WIHBEMPG.js → reporters-KYJE54JS.js} +8 -8
  91. package/dist/{run-L2DWJ26K.js → run-ABGXGOGQ.js} +9 -9
  92. package/dist/{conformance-ALLPNGEQ.js → runtime-7QE3DW6S.js} +2 -2
  93. package/dist/{term-PJIJQZNF.js → term-HTIG3YDC.js} +13 -13
  94. package/dist/{validate-XCDSPURG.js → validate-HWNU3MDY.js} +4 -4
  95. package/package.json +1 -1
  96. package/plugin/manni/.claude-plugin/plugin.json +1 -1
  97. package/dist/check-IWHUPAZM.js.map +0 -1
  98. package/dist/chunk-BWCWTHYS.js.map +0 -1
  99. package/dist/chunk-CI55ABCK.js.map +0 -1
  100. package/dist/chunk-D2LBN44V.js.map +0 -1
  101. package/dist/chunk-D6RO54QD.js.map +0 -1
  102. package/dist/chunk-TPVOOTMN.js.map +0 -1
  103. package/dist/cli-HXWYUKGJ.js.map +0 -1
  104. package/dist/prepare-52QOK7M4.js.map +0 -1
  105. package/dist/release-CTYRHZL4.js.map +0 -1
  106. /package/dist/{batch-U6S2JUUN.js.map → batch-QMHYWGUA.js.map} +0 -0
  107. /package/dist/{build-4RN6WBCP.js.map → build-ZGA3O3P4.js.map} +0 -0
  108. /package/dist/{calibrate-6VIZYR4L.js.map → calibrate-KBMFGKP3.js.map} +0 -0
  109. /package/dist/{capture-DP3NXAZE.js.map → capture-C46UXFRK.js.map} +0 -0
  110. /package/dist/{check-ERVNGKLC.js.map → check-LLQ6PJV3.js.map} +0 -0
  111. /package/dist/{check-STHXZIZO.js.map → check-UMI5ACCE.js.map} +0 -0
  112. /package/dist/{chunk-IOL74S4J.js.map → chunk-3FG2UU3H.js.map} +0 -0
  113. /package/dist/{chunk-K52CS4KT.js.map → chunk-4VQBHTGA.js.map} +0 -0
  114. /package/dist/{chunk-MIBWI5H7.js.map → chunk-5LAKRYXU.js.map} +0 -0
  115. /package/dist/{chunk-MSMB6XOS.js.map → chunk-6HMLYFEU.js.map} +0 -0
  116. /package/dist/{chunk-4Z2MN5FR.js.map → chunk-6MNOMHFI.js.map} +0 -0
  117. /package/dist/{chunk-UZKQSWHJ.js.map → chunk-6QBJHRFC.js.map} +0 -0
  118. /package/dist/{chunk-B5CMM57M.js.map → chunk-6ZR24A4S.js.map} +0 -0
  119. /package/dist/{chunk-WTEILBKC.js.map → chunk-77L5GNVO.js.map} +0 -0
  120. /package/dist/{chunk-6URSCTTX.js.map → chunk-AO66Q66S.js.map} +0 -0
  121. /package/dist/{chunk-NIFEEIGQ.js.map → chunk-BYVH727K.js.map} +0 -0
  122. /package/dist/{chunk-GCC52YZD.js.map → chunk-F734HIHT.js.map} +0 -0
  123. /package/dist/{chunk-CEVU3GFF.js.map → chunk-FEALEYSE.js.map} +0 -0
  124. /package/dist/{chunk-QQNPVW3J.js.map → chunk-GQBVZS5G.js.map} +0 -0
  125. /package/dist/{chunk-NZ6TNSCU.js.map → chunk-HWNSIEZK.js.map} +0 -0
  126. /package/dist/{chunk-LDKIIZDW.js.map → chunk-K43X5VDR.js.map} +0 -0
  127. /package/dist/{chunk-ZPP75QWG.js.map → chunk-LAU6SVTJ.js.map} +0 -0
  128. /package/dist/{chunk-ZNE25EAR.js.map → chunk-LF6FOF6U.js.map} +0 -0
  129. /package/dist/{chunk-6VDBP5UV.js.map → chunk-NB4ILZMQ.js.map} +0 -0
  130. /package/dist/{chunk-AMEILOVV.js.map → chunk-NNFSIRVE.js.map} +0 -0
  131. /package/dist/{chunk-LXJEAV2V.js.map → chunk-PO5W6JAP.js.map} +0 -0
  132. /package/dist/{chunk-OOEMKOX6.js.map → chunk-POGYWOJ2.js.map} +0 -0
  133. /package/dist/{chunk-LONRQBGV.js.map → chunk-Q3GFZJTY.js.map} +0 -0
  134. /package/dist/{chunk-ZKAKA54B.js.map → chunk-RCS5YFY2.js.map} +0 -0
  135. /package/dist/{chunk-C2TJG5KV.js.map → chunk-SV6UEQCU.js.map} +0 -0
  136. /package/dist/{chunk-2ZWTSRE5.js.map → chunk-SXODK43S.js.map} +0 -0
  137. /package/dist/{chunk-7XZ6INKO.js.map → chunk-UWY4B2PM.js.map} +0 -0
  138. /package/dist/{chunk-PAOVVHQX.js.map → chunk-VD3EQSBI.js.map} +0 -0
  139. /package/dist/{chunk-IZBBXKMJ.js.map → chunk-VSOYZ7QH.js.map} +0 -0
  140. /package/dist/{chunk-CR3HZERW.js.map → chunk-WBETAXO2.js.map} +0 -0
  141. /package/dist/{chunk-5UB47BEV.js.map → chunk-WT6HMEEF.js.map} +0 -0
  142. /package/dist/{chunk-IIFADWWI.js.map → chunk-WUFP4V7B.js.map} +0 -0
  143. /package/dist/{chunk-7EL5LLKD.js.map → chunk-WUXD6VBD.js.map} +0 -0
  144. /package/dist/{chunk-ZKCNPKUO.js.map → chunk-XDS3KQCK.js.map} +0 -0
  145. /package/dist/{chunk-5VWDIWOH.js.map → chunk-YVVMC4SZ.js.map} +0 -0
  146. /package/dist/{chunk-ZEXGGGLW.js.map → chunk-Z27GYQOY.js.map} +0 -0
  147. /package/dist/{chunk-QP5X66TO.js.map → chunk-ZIGIJBXG.js.map} +0 -0
  148. /package/dist/{cli-37SRAYNE.js.map → cli-4B5RWL7P.js.map} +0 -0
  149. /package/dist/{cli-IRHPPUFJ.js.map → cli-5AML7QR2.js.map} +0 -0
  150. /package/dist/{cli-NM6FZ54R.js.map → cli-I4GBPLRM.js.map} +0 -0
  151. /package/dist/{cli-YL3IDR52.js.map → cli-MNNOXWYU.js.map} +0 -0
  152. /package/dist/{cli-XIODOEUG.js.map → cli-QR3ZQZA4.js.map} +0 -0
  153. /package/dist/{cli-MTDGQIIV.js.map → cli-SBJY2NQH.js.map} +0 -0
  154. /package/dist/{cli-ZQUJYQBA.js.map → cli-UB5W75GJ.js.map} +0 -0
  155. /package/dist/{cli-KIID535Y.js.map → cli-WWDARAWS.js.map} +0 -0
  156. /package/dist/{config-O6UBGEDK.js.map → config-YWSNBFEE.js.map} +0 -0
  157. /package/dist/{conformance-ALLPNGEQ.js.map → github-TIZ3ZR3D.js.map} +0 -0
  158. /package/dist/{github-UCYLM3DR.js.map → github-WKOJRW7P.js.map} +0 -0
  159. /package/dist/{github-VEJFO6JJ.js.map → json-4FUOZ3XX.js.map} +0 -0
  160. /package/dist/{json-6F52FSXZ.js.map → lint-7VQFESHK.js.map} +0 -0
  161. /package/dist/{lint-X2GNINK6.js.map → list-7U2MBDIM.js.map} +0 -0
  162. /package/dist/{list-DP3O3CWB.js.map → list-W6EUAOBV.js.map} +0 -0
  163. /package/dist/{list-P77RZFZF.js.map → page-WZLBKSCD.js.map} +0 -0
  164. /package/dist/{page-WQCMBNRD.js.map → pretty-7M4X4TCY.js.map} +0 -0
  165. /package/dist/{pretty-5MMMNSWF.js.map → pretty-CUCMQU5R.js.map} +0 -0
  166. /package/dist/{pretty-H4DQREMW.js.map → provider-527CO4DM.js.map} +0 -0
  167. /package/dist/{provider-AMGRDY6V.js.map → reporters-DQVSDXV6.js.map} +0 -0
  168. /package/dist/{reporters-SU3VUKKX.js.map → reporters-KYJE54JS.js.map} +0 -0
  169. /package/dist/{reporters-WIHBEMPG.js.map → run-ABGXGOGQ.js.map} +0 -0
  170. /package/dist/{run-L2DWJ26K.js.map → runtime-7QE3DW6S.js.map} +0 -0
  171. /package/dist/{term-PJIJQZNF.js.map → term-HTIG3YDC.js.map} +0 -0
  172. /package/dist/{validate-XCDSPURG.js.map → validate-HWNU3MDY.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tracevals/rules/turn.ts","../src/tracevals/rules/sources.ts"],"sourcesContent":["/**\n * The turn a Stop or SubagentStop judges (proposal 0079). A turn starts at the\n * last prompt the user typed; tool results and hook feedback do not start one.\n * Under SubagentStop the turn is the subagent's whole run.\n *\n * Which user records are typed prompts is read from the record shape Claude\n * Code writes, not guessed from wording alone:\n *\n * - `isMeta: true` marks harness injections: a skill's \"Base directory\" body,\n * `<local-command-caveat>`, peer and scheduled messages, hook feedback.\n * - `isCompactSummary: true` is the \"session is being continued\" summary.\n * - `origin.kind` is `human` for a typed prompt and `task-notification` or\n * `peer` otherwise. Older records carry only `turnOrigin`, whose non-typed\n * values are `task_notification`, `scheduled` and `peer`.\n * - A record whose text is nothing but `<system-reminder>`,\n * `<task-notification>`, `<ci-monitor-event>` or `<local-command-*>` blocks\n * is an injection. A typed prompt Claude Code prefixed with a reminder keeps\n * the text after it, so it still counts.\n * - `Stop hook feedback:` and `[Request interrupted by user…]` are markers,\n * never prompts.\n *\n * A `<command-name>` record is a slash command someone typed, so it counts.\n */\nimport {\n emptyWindow,\n materialize,\n type TraceWindow,\n} from \"../graders/util.js\";\nimport type { Trace, TraceEvent } from \"../trace/types.js\";\n\nexport interface TurnSlice {\n window: TraceWindow;\n /** Ordinal in `trace.events` of the turn's first event. */\n from: number;\n /** Ordinal of its last event, inclusive. Less than `from` when there is no turn. */\n to: number;\n /** Typed prompts in the whole session, which `turn-count-above` reads. */\n sessionTurnCount: number;\n}\n\nconst INJECTED =\n /<(system-reminder|task-notification|ci-monitor-event|local-command-stdout|local-command-stderr|local-command-caveat)>[\\s\\S]*?<\\/\\1>/g;\nconst MARKER =\n /^(?:Stop hook feedback:|SubagentStop hook feedback:|\\[Request interrupted by user)/;\n/**\n * Origins of a prompt a person sent: typed in the CLI, or sent through the SDK.\n * Both record formats name it, as `origin.kind` or the older `turnOrigin`,\n * and both are read against this one set.\n */\nconst TYPED_TURN_ORIGINS = new Set([\"human\", \"sdk\"]);\nconst WORK = new Set<TraceEvent[\"kind\"]>([\"assistant\", \"tool_call\", \"tool_result\"]);\n\nexport function isTypedPrompt(event: TraceEvent): boolean {\n if (event.kind !== \"user\" || event.text === undefined) return false;\n const { raw } = event;\n if (raw.isMeta === true || raw.isCompactSummary === true) return false;\n const origin = raw.origin;\n if (\n typeof origin === \"object\" &&\n origin !== null &&\n \"kind\" in origin &&\n typeof origin.kind === \"string\"\n ) {\n if (!TYPED_TURN_ORIGINS.has(origin.kind)) return false;\n } else if (\n typeof raw.turnOrigin === \"string\" &&\n !TYPED_TURN_ORIGINS.has(raw.turnOrigin)\n ) {\n return false;\n }\n const rest = event.text.replace(INJECTED, \"\").trim();\n return rest !== \"\" && !MARKER.test(rest);\n}\n\n/** The last turn of a session: its last typed prompt to the end of the trace. */\nexport function lastTurn(trace: Trace): TurnSlice {\n const prompts = trace.events.filter((e) => e.sidechain !== true && isTypedPrompt(e));\n const sessionTurnCount = prompts.length;\n const to = trace.events.length - 1;\n const last = prompts.at(-1);\n if (last === undefined) {\n return {\n window: emptyWindow(\"turn\", \"last turn\", \"the trace holds no prompt the user typed\"),\n from: to + 1,\n to,\n sessionTurnCount,\n };\n }\n return slice(trace, last.index, [last], new Set([undefined]), sessionTurnCount, {\n label: \"last turn\",\n reason: \"nothing happened after the last prompt the user typed\",\n });\n}\n\n/**\n * A subagent's sidecar transcript parsed alone. Every record is a sidechain,\n * so the parser keeps no prompts; the turn is the whole run, and its prompts\n * are the task the subagent was given.\n */\nexport function subagentTurn(trace: Trace): TurnSlice {\n const prompts = trace.events.filter(isTypedPrompt);\n return slice(\n trace,\n 0,\n prompts,\n new Set(trace.events.map((e) => e.branchId)),\n prompts.length,\n { label: \"subagent run\", reason: \"the subagent recorded no work\" },\n );\n}\n\nfunction slice(\n trace: Trace,\n from: number,\n prompts: TraceEvent[],\n own: Set<string | undefined>,\n sessionTurnCount: number,\n words: { label: string; reason: string },\n): TurnSlice {\n const to = trace.events.length - 1;\n const worked = trace.events.some((e) => e.index > from && WORK.has(e.kind));\n if (!worked) {\n return {\n window: emptyWindow(\"turn\", words.label, words.reason),\n from,\n to,\n sessionTurnCount,\n };\n }\n const window = materialize(\n trace,\n \"turn\",\n words.label,\n [{ start: from, end: Number.POSITIVE_INFINITY }],\n undefined,\n own,\n );\n // Only typed prompts are prompts here, and `turnCount` is the session's,\n // because the one condition that reads it counts session turns.\n window.userMessages = prompts.map((p) => p.text ?? \"\");\n window.turnCount = sessionTurnCount;\n return { window, from, to, sessionTurnCount };\n}\n","/**\n * Which files govern the agent in a turn (proposal 0079, \"Rule sources and\n * their triggers\"). Resolution is deterministic, from the filesystem and the\n * trace; no model decides which files count.\n *\n * The list of formats is closed. Reading a file never makes it a source: a\n * README or a product docs page describes other systems, so only the known\n * formats, files named by `include`, and what a skill or an `@path` import\n * pulls in are ever returned. `exclude` removes a file from every row.\n *\n * To touch a file is to Read, Write or Edit it, anywhere in the session up to\n * the turn's end, which is Claude Code's own trigger for path-scoped rules.\n *\n * Six more formats say what the session was asked (proposal 0080): the typed\n * prompts, the approved plan, a touched Spec Kit feature, Kiro spec or live\n * OpenSpec change, and a touched file `conformance.plans` names. None is known\n * at session start, so only a turn resolves them, and none declares evals.\n *\n * Two are read from the transcript itself (proposal 0081): the system prompt\n * of the last prompt snapshot, and a user output style. Claude Code's own\n * prompt is reported and never blocks; a prompt the user wrote blocks.\n */\nimport { createHash } from \"node:crypto\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport picomatch from \"picomatch\";\nimport { extractFrontmatter } from \"../../meta/extractors/frontmatter.js\";\nimport type { ExtractedMetadata } from \"../../meta/types.js\";\nimport { resolveArtifacts } from \"../artifacts/resolve.js\";\nimport { findGitRoot, listInTree, safeRead } from \"../artifacts/fs.js\";\nimport { extractEvals } from \"../evals/extract.js\";\nimport { windowOf } from \"../graders/util.js\";\nimport { makeRedactor } from \"../judge/redact.js\";\nimport { configDir } from \"../trace/discover.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport { isTypedPrompt } from \"./turn.js\";\n\nexport type RuleFormat =\n | \"claude-md\"\n | \"claude-rule\"\n | \"agents-md\"\n | \"gemini-md\"\n | \"cursor-rule\"\n | \"kiro-steering\"\n | \"speckit-constitution\"\n | \"openspec-project\"\n | \"import\"\n | \"skill\"\n | \"slash-command\"\n | \"agent\"\n | \"designated\"\n | \"prompt\"\n | \"plan\"\n | \"speckit-spec\"\n | \"kiro-spec\"\n | \"openspec-change\"\n | \"plans\"\n | \"system-prompt\"\n | \"output-style\";\n\n/** An `ai` eval a source declares; its assertion is the rule (proposal 0079). */\nexport interface DeclaredRule {\n id: string;\n text: string;\n when?: Record<string, unknown>;\n}\n\nexport interface RuleSource {\n /** Absolute path on disk, or `\"\"` for the typed prompts, an inline plan and the system prompt. */\n path: string;\n /** Relative to the project root with forward slashes, or `~/…` under home. */\n displayPath: string;\n format: RuleFormat;\n /** Why the file is in scope, in words: `always`, `read`, `touched src/a.ts`. */\n trigger: string;\n content: string;\n /** sha256 of `content`, hex. */\n sha256: string;\n /** The skill a `skill` source belongs to. */\n skill?: string;\n /** Present when the file declares `ai` evals; they replace extraction. */\n declaredRules?: DeclaredRule[];\n /** False for Claude Code's default system prompt, whose rules are reported and never block. */\n blocks: boolean;\n}\n\nexport interface SourceOptions {\n /** The session's working directory, where the ancestor walk starts. */\n projectDir: string;\n /** Ceiling for the ancestor walk and base of `displayPath`; default the git root. */\n projectRoot?: string;\n /** `CLAUDE_CONFIG_DIR` finds `~/.claude`; `HOME` / `USERPROFILE` find `~/.gemini` and `~/.kiro`. */\n env?: Record<string, string | undefined>;\n /** `conformance.include`: globs, relative to the project root, in scope once read. */\n include?: string[];\n /** `conformance.exclude`: globs never treated as sources, in any row, and source names. */\n exclude?: string[];\n /** `judge.redact`: patterns scrubbed from what the transcript records of the system prompt. */\n redact?: string[];\n /** `conformance.plans`: globs, relative to the project root, in scope once touched. */\n plans?: string[];\n /** Set under SubagentStop: the subagent type whose definition governs the run. */\n agentType?: string;\n}\n\nexport interface ResolvedSources {\n sources: RuleSource[];\n warnings: string[];\n}\n\n/** The turn's ordinal bounds in `trace.events`, inclusive. `lastTurn` returns them. */\nexport interface TurnBounds {\n from: number;\n to: number;\n}\n\n/** Imports followed from a `claude-md` or `gemini-md` file, as Claude Code does. */\nconst MAX_IMPORT_HOPS = 4;\n\ntype Trigger =\n | { kind: \"always\" }\n | { kind: \"read\" }\n | { kind: \"globs\"; key: string; patterns: string[] };\n\ninterface Candidate {\n path: string;\n format: RuleFormat;\n trigger: Trigger;\n}\n\ninterface Touch {\n abs: string;\n rel: string | null;\n read: boolean;\n}\n\nclass Collector {\n readonly sources: RuleSource[] = [];\n readonly warnings: string[] = [];\n private readonly seen = new Set<string>();\n private readonly parsed = new Map<string, ExtractedMetadata | null>();\n private readonly excluded: (path: string) => boolean;\n /** Whether `exclude` lists, as it is, the name of a source with no file, such as `prompt`. */\n readonly excludedName: (name: string) => boolean;\n\n constructor(\n readonly cwd: string,\n readonly root: string,\n readonly home: string,\n exclude: string[],\n ) {\n const match = exclude.length > 0 ? picomatch(exclude, { dot: true }) : null;\n this.excluded = (path) => match !== null && match(this.display(path));\n // The whole name, never a glob: `**` names files, and keeps the prompt.\n this.excludedName = (name) => exclude.includes(name);\n }\n\n display(path: string): string {\n const inRoot = relPosix(this.root, path);\n if (inRoot !== null) return inRoot;\n const inHome = relPosix(this.home, path);\n if (inHome !== null) return `~/${inHome}`;\n return path.split(sep).join(\"/\");\n }\n\n has(path: string): boolean {\n return this.seen.has(key(path));\n }\n\n /** The file's front matter, or null when it has none or it does not parse. */\n front(path: string, content: string): ExtractedMetadata | null {\n const k = key(path);\n if (this.parsed.has(k)) return this.parsed.get(k) ?? null;\n let parsed: ExtractedMetadata | null = null;\n try {\n const fm = extractFrontmatter(content, \"markdown\");\n parsed = fm.present ? fm : null;\n } catch (err) {\n const loose = isCursorRule(path) ? cursorFront(content) : null;\n if (loose !== null) {\n this.parsed.set(k, loose);\n return loose;\n }\n const first = (err instanceof Error ? err.message : String(err)).split(\"\\n\")[0] ?? \"\";\n this.warnings.push(\n `${this.display(path)}: front matter does not parse (${first}), so it is read as having none`,\n );\n }\n this.parsed.set(k, parsed);\n return parsed;\n }\n\n /** Adds a source once. Returns it, or null when excluded or already listed. */\n add(\n path: string,\n content: string,\n format: RuleFormat,\n trigger: string,\n skill?: string,\n ): RuleSource | null {\n if (this.has(path) || this.excluded(path)) return null;\n this.seen.add(key(path));\n const source: RuleSource = {\n path,\n displayPath: this.display(path),\n format,\n trigger,\n content,\n sha256: createHash(\"sha256\").update(content).digest(\"hex\"),\n blocks: true,\n };\n if (skill !== undefined) source.skill = skill;\n const declared = this.declared(path, content);\n if (declared !== undefined) source.declaredRules = declared;\n this.sources.push(source);\n return source;\n }\n\n /**\n * Adds a source that says what the session was asked, or one the transcript\n * recorded. These never declare evals. With no file, its display path is its\n * format, and `exclude` matches that name.\n */\n addRequest(\n file: string | null,\n content: string,\n format: RuleFormat,\n trigger: string,\n blocks = true,\n ): void {\n // A named source goes by its name whether or not a file holds it, so\n // `exclude: [plan]` drops a plan file as it drops an inline plan.\n if (EXCLUDABLE_BY_NAME.has(format) && this.excludedName(format)) return;\n if (file !== null) {\n if (this.has(file) || this.excluded(file)) return;\n this.seen.add(key(file));\n }\n this.sources.push({\n path: file ?? \"\",\n displayPath: file === null ? format : this.display(file),\n format,\n trigger,\n content,\n sha256: createHash(\"sha256\").update(content).digest(\"hex\"),\n blocks,\n });\n }\n\n private declared(path: string, content: string): DeclaredRule[] | undefined {\n const fm = this.front(path, content);\n if (fm === null) return undefined;\n const extracted = extractEvals(\n { name: basename(path), type: \"project-rules\", path, content, origin: \"project\" },\n fm,\n );\n if (extracted.errors.length > 0) {\n this.warnings.push(\n `${this.display(path)}: metadata.evals does not validate (${extracted.errors[0]?.message ?? \"invalid\"}), so it declares no rules`,\n );\n return undefined;\n }\n const rules: DeclaredRule[] = [];\n for (const entry of extracted.evals) {\n if (entry.grader !== \"ai\" || entry.assertion === undefined) continue;\n const rule: DeclaredRule = { id: entry.id, text: entry.assertion };\n const when = entry.options?.when;\n if (isRecord(when)) rule.when = when;\n rules.push(rule);\n }\n return rules.length > 0 ? rules : undefined;\n }\n}\n\n/** Every source whose trigger is \"always\", without a trace (for `prepare`). */\nexport async function resolveAlwaysSources(opts: SourceOptions): Promise<ResolvedSources> {\n const c = await collector(opts);\n for (const candidate of await catalog(c, opts)) {\n if (candidate.trigger.kind === \"always\") await addWithImports(c, candidate, \"always\");\n }\n await addDesignated(c, opts);\n return { sources: c.sources, warnings: c.warnings };\n}\n\n/** Every source in scope for one turn of `trace`. */\nexport async function resolveTurnSources(\n trace: Trace,\n turn: TurnBounds,\n opts: SourceOptions,\n): Promise<ResolvedSources> {\n const c = await collector(opts);\n const touches: Touch[] = trace.fileAccesses\n .filter((a) => a.index <= turn.to)\n .map((a) => {\n const abs = resolve(c.cwd, a.path);\n return { abs, rel: relPosix(c.root, abs), read: a.op === \"read\" };\n });\n const wasRead = new Set(touches.filter((t) => t.read).map((t) => key(t.abs)));\n\n for (const candidate of await catalog(c, opts)) {\n const { trigger } = candidate;\n if (trigger.kind === \"always\") {\n await addWithImports(c, candidate, \"always\");\n } else if (trigger.kind === \"read\") {\n if (wasRead.has(key(candidate.path))) await addWithImports(c, candidate, \"read\");\n } else {\n const match = picomatch(trigger.patterns, { dot: true });\n const hit = touches.find((t) => t.rel !== null && match(t.rel));\n if (hit !== undefined && hit.rel !== null) {\n await addWithImports(c, candidate, `${trigger.key} matched ${hit.rel}`);\n }\n }\n }\n\n // A subdirectory's memory file applies once a file under it is touched.\n // Farther directories come first, so the nearest file reads last.\n const nested = new Map<string, string>();\n for (const touch of touches) {\n if (touch.rel === null) continue;\n for (const dir of dirsBelowCwd(c, dirname(touch.abs))) {\n if (!nested.has(dir)) nested.set(dir, touch.rel);\n }\n }\n const dirs = [...nested.keys()].sort((a, b) => a.length - b.length);\n for (const dir of dirs) {\n const touched = nested.get(dir) ?? \"\";\n for (const [name, format] of NESTED_FILES) {\n const path = join(dir, name);\n const content = await safeRead(path);\n if (content !== null) {\n await addWithImports(c, { path, format, trigger: { kind: \"always\" } }, `touched ${touched}`, content);\n }\n }\n }\n\n await addWindowed(c, trace, turn, touches, opts);\n\n await addDesignated(c, opts);\n\n addPrompts(c, trace, turn);\n await addPlan(c, trace, turn, opts);\n await addSpecs(c, touches, opts.plans ?? []);\n await addSystemPrompt(c, trace, turn, opts);\n return { sources: c.sources, warnings: c.warnings };\n}\n\n// ── What the transcript recorded of the prompt ───────────────────\n\n/** The sources `conformance.exclude` matches by name (proposals 0080 and 0081). */\nconst EXCLUDABLE_BY_NAME: ReadonlySet<RuleFormat> = new Set<RuleFormat>([\"prompt\", \"plan\", \"system-prompt\"]);\n\n/** Claude Code's own block in its default prompt; a replaced prompt has none. */\nconst BOUNDARY_MARKER = \"__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__\";\n\ninterface Recorded {\n index: number;\n record: Record<string, unknown>;\n attachment: Record<string, unknown>;\n}\n\n/** The last attachment of `type` at or before the turn's end, with its record. */\nfunction lastAttachment(trace: Trace, turn: TurnBounds, type: string): Recorded | undefined {\n for (let i = trace.events.length - 1; i >= 0; i -= 1) {\n const event = trace.events[i];\n if (event === undefined || event.kind !== \"meta\" || event.index > turn.to) continue;\n const attachment = event.raw.attachment;\n if (event.raw.type === \"attachment\" && isRecord(attachment) && attachment.type === type) {\n return { index: event.index, record: event.raw, attachment };\n }\n }\n return undefined;\n}\n\n/**\n * The system prompt of the last `prompt_snapshot`, and the last output style.\n * A style a user file defines is its own source, holding the text the agent\n * saw; a built-in style's text joins the system prompt. The prompt is custom,\n * and blocks, when Claude Code's boundary marker is missing.\n */\nasync function addSystemPrompt(c: Collector, trace: Trace, turn: TurnBounds, opts: SourceOptions): Promise<void> {\n const scrub = makeRedactor(opts.redact ?? []);\n const style = lastAttachment(trace, turn, \"output_style_instructions\")?.attachment.style;\n const styleName = isRecord(style) && typeof style.name === \"string\" ? style.name : undefined;\n const stylePrompt = isRecord(style) && typeof style.prompt === \"string\" ? style.prompt : undefined;\n let builtIn: string | undefined;\n if (styleName !== undefined && stylePrompt !== undefined) {\n const file = await userStyleFile(c, opts, styleName);\n if (file === undefined) builtIn = stylePrompt;\n else c.addRequest(file, scrub(stylePrompt), \"output-style\", `style ${styleName}`);\n }\n\n const snapshot = lastAttachment(trace, turn, \"prompt_snapshot\");\n const recorded: unknown = snapshot?.attachment.systemPrompt;\n if (snapshot === undefined || !Array.isArray(recorded)) return;\n const blocks = recorded.filter((b): b is string => typeof b === \"string\");\n const custom = !blocks.includes(BOUNDARY_MARKER);\n const content = scrub([...blocks, ...(builtIn !== undefined ? [builtIn] : [])].join(\"\\n\\n\"));\n const { version } = snapshot.record;\n const by = typeof version === \"string\" ? `, Claude Code ${version}` : \"\";\n const trigger = `recorded at turn ${String(snapshot.index)}${by}${custom ? \", custom\" : \"\"}`;\n // A prompt the user replaced blocks; Claude Code's own default only reports.\n c.addRequest(null, content, \"system-prompt\", trigger, /* blocks= */ custom);\n}\n\n/**\n * The user file that defines output style `name`: under the project's\n * `.claude/output-styles/`, then the user's. Its front matter `name`, or\n * its base name, matches.\n */\nasync function userStyleFile(c: Collector, opts: SourceOptions, name: string): Promise<string | undefined> {\n // Where Claude Code reads styles: the project (cwd first, then the git root)\n // and the user. No ancestor walk, since Claude Code does none for styles.\n const dirs = [...new Set([c.cwd, c.root])].map((b) => join(b, \".claude\", \"output-styles\"));\n dirs.push(join(configDir(opts.env), \"output-styles\"));\n for (const dir of dirs) {\n for (const path of await listInTree(dir, (p) => p.endsWith(\".md\"), { maxDepth: 0 })) {\n const declared = (await frontOf(c, path))?.name;\n if ((typeof declared === \"string\" ? declared : basename(path, \".md\")) === name) return path;\n }\n }\n return undefined;\n}\n\n// ── What the session was asked ───────────────────────────────────\n\n/**\n * Every prompt typed up to the turn's end, as one numbered sequence. A\n * subagent's own run has only sidechain prompts, and its task is its request.\n */\nfunction addPrompts(c: Collector, trace: Trace, turn: TurnBounds): void {\n const typed = trace.events.filter((e) => e.index <= turn.to && isTypedPrompt(e));\n const main = typed.filter((e) => e.sidechain !== true);\n const prompts = main.length > 0 ? main : typed;\n if (prompts.length === 0) return;\n const content = prompts\n .map((p, i) => `${String(i + 1)}. ${(p.text ?? \"\").trim()}`)\n .join(\"\\n\\n\");\n c.addRequest(null, content, \"prompt\", `typed prompts 1-${String(prompts.length)}`);\n}\n\n/**\n * The plan of the last approved `ExitPlanMode` at or before the turn's end.\n * A call is approved when its result is not an error. The plan is the call's\n * `plan` input, or else the file the session last wrote under the user's\n * `plans/` directory before the call.\n */\nasync function addPlan(c: Collector, trace: Trace, turn: TurnBounds, opts: SourceOptions): Promise<void> {\n const approved = trace.toolCalls\n .filter((call) => call.name === \"ExitPlanMode\" && call.index <= turn.to)\n .filter((call) => isApproved(trace, call.index, turn.to))\n .at(-1);\n if (approved === undefined) return;\n const trigger = `approved at turn ${String(approved.index)}`;\n const plan = approved.input.plan;\n if (typeof plan === \"string\" && plan.trim() !== \"\") {\n c.addRequest(null, plan, \"plan\", trigger);\n return;\n }\n const plansDir = join(configDir(opts.env), \"plans\");\n const file = trace.fileAccesses\n .filter((a) => a.op !== \"read\" && a.index < approved.index)\n .map((a) => resolve(c.cwd, a.path))\n .filter((abs) => relPosix(plansDir, abs) !== null)\n .at(-1);\n if (file === undefined) return;\n const content = await safeRead(file);\n if (content !== null) c.addRequest(file, content, \"plan\", trigger);\n}\n\n/**\n * Whether the tool call at `index` has a result by `to` that is not an error.\n * A plan approved only after the turn ends is not yet a source; the next turn,\n * whose bounds include the result, picks it up.\n */\nfunction isApproved(trace: Trace, index: number, to: number): boolean {\n const id = trace.events.find((e) => e.index === index)?.raw.id;\n if (typeof id !== \"string\") return false;\n for (const event of trace.events) {\n if (event.kind !== \"tool_result\" || event.index <= index || event.index > to) continue;\n const message = event.raw.message;\n const blocks: unknown = isRecord(message) ? message.content : undefined;\n if (!Array.isArray(blocks)) continue;\n for (const block of blocks as unknown[]) {\n if (isRecord(block) && block.type === \"tool_result\" && block.tool_use_id === id) {\n return block.is_error !== true;\n }\n }\n }\n return false;\n}\n\n/** The files each spec format reads from a touched directory. */\nconst SPEC_FILES: Record<\"speckit-spec\" | \"kiro-spec\", string[]> = {\n \"speckit-spec\": [\"spec.md\", \"plan.md\", \"tasks.md\"],\n \"kiro-spec\": [\"requirements.md\", \"design.md\", \"tasks.md\"],\n};\n\n/** The spec directory a project-relative path lies under, and its format. */\nfunction specDirOf(rel: string): { dir: string; format: \"speckit-spec\" | \"kiro-spec\" | \"openspec-change\" } | null {\n const parts = rel.split(\"/\");\n const [first, second, third] = parts;\n if (first === \"specs\" && second !== undefined && parts.length > 2) {\n return { dir: `specs/${second}`, format: \"speckit-spec\" };\n }\n if (first === \".kiro\" && second === \"specs\" && third !== undefined && parts.length > 3) {\n return { dir: `.kiro/specs/${third}`, format: \"kiro-spec\" };\n }\n // An archived change is done, so it never counts.\n if (first === \"openspec\" && second === \"changes\" && third !== undefined && third !== \"archive\" && parts.length > 3) {\n return { dir: `openspec/changes/${third}`, format: \"openspec-change\" };\n }\n return null;\n}\n\n/** A touched spec brings in its directory's files; a touched `plans` file brings in itself. */\nasync function addSpecs(c: Collector, touches: Touch[], plans: string[]): Promise<void> {\n const isPlan = plans.length > 0 ? picomatch(plans, { dot: true }) : null;\n const done = new Set<string>();\n for (const touch of touches) {\n const { rel } = touch;\n if (rel === null) continue;\n const trigger = `touched ${rel}`;\n const spec = specDirOf(rel);\n if (spec !== null && !done.has(spec.dir)) {\n done.add(spec.dir);\n const dir = join(c.root, ...spec.dir.split(\"/\"));\n const files =\n spec.format === \"openspec-change\"\n ? await listInTree(dir, (p) => p.endsWith(\".md\"))\n : SPEC_FILES[spec.format].map((name) => join(dir, name));\n for (const file of files) {\n const content = await safeRead(file);\n if (content !== null) c.addRequest(file, content, spec.format, trigger);\n }\n }\n if (isPlan?.(rel) === true) {\n const content = await safeRead(touch.abs);\n if (content !== null) c.addRequest(touch.abs, content, \"plans\", trigger);\n }\n }\n}\n\n/**\n * Files named in `conformance.include`. A person chose each one to govern the\n * agent, so it applies to every turn, as a `CLAUDE.md` does. Waiting for the\n * agent to read one would let a turn that skipped it escape its rules.\n */\nasync function addDesignated(c: Collector, opts: SourceOptions): Promise<void> {\n const include = opts.include ?? [];\n if (include.length === 0) return;\n const match = picomatch(include, { dot: true });\n const found = await listInTree(c.root, (abs) => {\n const rel = relPosix(c.root, abs);\n return rel !== null && match(rel);\n });\n for (const abs of found) {\n if (c.has(abs)) continue;\n const content = await safeRead(abs);\n if (content === null) {\n c.warnings.push(`${c.display(abs)}: matched conformance.include but could not be read`);\n continue;\n }\n c.add(abs, content, \"designated\", \"always\");\n }\n}\n\n// ── Skills, slash commands and the agent ─────────────────────────\n\nasync function addWindowed(\n c: Collector,\n trace: Trace,\n turn: TurnBounds,\n touches: Touch[],\n opts: SourceOptions,\n): Promise<void> {\n // The existing resolver settles which file a skill, command or agent names.\n // Agents spawned in a main session govern their own runs, not this turn, so\n // only the agent this run is (under SubagentStop) is asked for.\n const { artifacts } = await resolveArtifacts(\n {\n ...trace,\n agentSpawns:\n opts.agentType === undefined ? [] : [{ subagentType: opts.agentType, index: 0 }],\n },\n { projectDir: c.cwd, projectRoot: c.root, ...(opts.env ? { env: opts.env } : {}) },\n );\n for (const artifact of artifacts) {\n if (artifact.type === \"agent\") {\n c.add(artifact.path, artifact.content, \"agent\", \"subagent run\");\n continue;\n }\n if (artifact.type !== \"skill\" && artifact.type !== \"slash-command\") continue;\n // In scope from the first invocation to the end of the session (proposal\n // 0080): a skill's procedure spans the turns after it, and the skills it\n // calls partway through do not end it. Batch `run` keeps ADR 01015's window.\n const window = windowOf(trace, artifact);\n if (!window.events.some((e) => e.index <= turn.to)) continue;\n if (artifact.type === \"slash-command\") {\n c.add(artifact.path, artifact.content, \"slash-command\", \"slash command window\");\n continue;\n }\n c.add(artifact.path, artifact.content, \"skill\", \"skill window\", artifact.name);\n const skillDir = dirname(artifact.path);\n for (const touch of touches) {\n if (!touch.read || relPosix(skillDir, touch.abs) === null || c.has(touch.abs)) continue;\n const content = await safeRead(touch.abs);\n if (content !== null) {\n c.add(touch.abs, content, \"skill\", `read under skill ${artifact.name}`, artifact.name);\n }\n }\n }\n}\n\n// ── The catalog of known formats ─────────────────────────────────\n\n/** Memory files read at cwd, each ancestor up to the root, and in their `.claude/`. */\nconst ANCESTOR_FILES: [string, RuleFormat][] = [\n [\"CLAUDE.md\", \"claude-md\"],\n [\"CLAUDE.local.md\", \"claude-md\"],\n [join(\".claude\", \"CLAUDE.md\"), \"claude-md\"],\n [\"AGENTS.md\", \"agents-md\"],\n [join(\".claude\", \"AGENTS.md\"), \"agents-md\"],\n [\"GEMINI.md\", \"gemini-md\"],\n];\n\n/** Memory files a touch under a subdirectory brings in. */\nconst NESTED_FILES: [string, RuleFormat][] = [\n [\"CLAUDE.md\", \"claude-md\"],\n [\"AGENTS.md\", \"agents-md\"],\n [\"GEMINI.md\", \"gemini-md\"],\n];\n\nasync function catalog(c: Collector, opts: SourceOptions): Promise<Candidate[]> {\n const out: Candidate[] = [];\n const userClaude = configDir(opts.env);\n const always: Trigger = { kind: \"always\" };\n\n out.push({ path: join(userClaude, \"CLAUDE.md\"), format: \"claude-md\", trigger: always });\n out.push({ path: join(c.home, \".gemini\", \"GEMINI.md\"), format: \"gemini-md\", trigger: always });\n for (const dir of ancestors(c.cwd, c.root).reverse()) {\n for (const [name, format] of ANCESTOR_FILES) {\n out.push({ path: join(dir, name), format, trigger: always });\n }\n }\n\n // Project-level directories live at the root; a cwd below it is checked too.\n const bases = c.cwd === c.root ? [c.root] : [c.root, c.cwd];\n\n for (const dir of [join(userClaude, \"rules\"), ...bases.map((b) => join(b, \".claude\", \"rules\"))]) {\n for (const path of await listInTree(dir, (p) => p.endsWith(\".md\"))) {\n out.push({ path, format: \"claude-rule\", trigger: await claudeRuleTrigger(c, path) });\n }\n }\n\n for (const base of bases) {\n const dir = join(base, \".cursor\", \"rules\");\n for (const path of await listInTree(dir, (p) => p.endsWith(\".mdc\") || p.endsWith(\".md\"))) {\n const trigger = await cursorTrigger(c, path);\n if (trigger !== null) out.push({ path, format: \"cursor-rule\", trigger });\n }\n }\n\n for (const dir of [join(c.home, \".kiro\", \"steering\"), ...bases.map((b) => join(b, \".kiro\", \"steering\"))]) {\n for (const path of await listInTree(dir, (p) => p.endsWith(\".md\"), { maxDepth: 0 })) {\n out.push({ path, format: \"kiro-steering\", trigger: await kiroTrigger(c, path) });\n }\n }\n\n for (const base of bases) {\n out.push({\n path: join(base, \".specify\", \"memory\", \"constitution.md\"),\n format: \"speckit-constitution\",\n trigger: always,\n });\n out.push({ path: join(base, \"openspec\", \"project.md\"), format: \"openspec-project\", trigger: { kind: \"read\" } });\n }\n return out;\n}\n\nasync function frontOf(c: Collector, path: string): Promise<Record<string, unknown> | null> {\n const content = await safeRead(path);\n if (content === null) return null;\n return c.front(path, content)?.data ?? null;\n}\n\nasync function claudeRuleTrigger(c: Collector, path: string): Promise<Trigger> {\n const patterns = globList((await frontOf(c, path))?.paths);\n return patterns.length > 0 ? { kind: \"globs\", key: \"paths\", patterns } : { kind: \"always\" };\n}\n\n/** Null for a `.md` file with no front matter, which Cursor does not read as a rule. */\nasync function cursorTrigger(c: Collector, path: string): Promise<Trigger | null> {\n const fm = await frontOf(c, path);\n if (fm === null && !path.endsWith(\".mdc\")) return null;\n if (fm?.alwaysApply === true) return { kind: \"always\" };\n const patterns = globList(fm?.globs);\n return patterns.length > 0 ? { kind: \"globs\", key: \"globs\", patterns } : { kind: \"read\" };\n}\n\nasync function kiroTrigger(c: Collector, path: string): Promise<Trigger> {\n const fm = await frontOf(c, path);\n const inclusion = fm?.inclusion;\n if (inclusion === undefined || inclusion === \"always\") return { kind: \"always\" };\n if (inclusion === \"fileMatch\") {\n const patterns = globList(fm?.fileMatchPattern);\n if (patterns.length > 0) return { kind: \"globs\", key: \"fileMatchPattern\", patterns };\n }\n return { kind: \"read\" };\n}\n\n// ── Imports ──────────────────────────────────────────────────────\n\n/** Adds a candidate and, for a memory file, what its `@path` lines import. */\nasync function addWithImports(\n c: Collector,\n candidate: Candidate,\n trigger: string,\n known?: string,\n): Promise<void> {\n if (c.has(candidate.path)) return;\n const content = known ?? (await safeRead(candidate.path));\n if (content === null) return;\n const added = c.add(candidate.path, content, candidate.format, trigger);\n if (added === null || (candidate.format !== \"claude-md\" && candidate.format !== \"gemini-md\")) {\n return;\n }\n let frontier = [added];\n for (let hop = 1; hop <= MAX_IMPORT_HOPS && frontier.length > 0; hop += 1) {\n const next: RuleSource[] = [];\n for (const importer of frontier) {\n for (const ref of importsOf(importer.content)) {\n const path = ref.startsWith(\"~/\")\n ? join(c.home, ref.slice(2))\n : resolve(dirname(importer.path), ref);\n if (c.has(path)) continue;\n const body = await safeRead(path);\n if (body === null) continue;\n const source = c.add(path, body, \"import\", `imported by ${importer.displayPath}`);\n if (source !== null) next.push(source);\n }\n }\n frontier = next;\n }\n}\n\n/** `@path` references outside code fences and code spans. */\nfunction importsOf(content: string): string[] {\n const refs: string[] = [];\n // The open fence's character and length: CommonMark closes a fence only\n // with the same character, at least as long, so a backtick line inside a\n // tilde fence is text.\n let fence: { char: string; length: number } | null = null;\n for (const line of content.split(/\\r?\\n/)) {\n const marker = /^\\s*(`{3,}|~{3,})/.exec(line)?.[1];\n if (marker !== undefined) {\n const char = marker.charAt(0);\n if (fence === null) {\n fence = { char, length: marker.length };\n continue;\n }\n if (char === fence.char && marker.length >= fence.length && line.trim() === marker) {\n fence = null;\n continue;\n }\n }\n if (fence !== null) continue;\n const prose = line.replace(/`[^`]*`/g, \"\");\n for (const m of prose.matchAll(/(?:^|\\s)@([^\\s`]+)/g)) {\n const ref = m[1]?.replace(/[.,;:!?)\\]]+$/, \"\");\n if (ref) refs.push(ref);\n }\n }\n return refs;\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nasync function collector(opts: SourceOptions): Promise<Collector> {\n const cwd = resolve(opts.projectDir);\n const root = resolve(opts.projectRoot ?? (await findGitRoot(cwd)) ?? cwd);\n return new Collector(cwd, root, homeDir(opts.env), opts.exclude ?? []);\n}\n\nfunction homeDir(env: Record<string, string | undefined> = process.env): string {\n const set = process.platform === \"win32\" ? (env.USERPROFILE ?? env.HOME) : env.HOME;\n return resolve(set ?? homedir());\n}\n\n/** cwd and each ancestor up to the root, nearest first. */\nfunction ancestors(cwd: string, root: string): string[] {\n const dirs: string[] = [];\n let current = cwd;\n for (let depth = 0; depth < 32; depth += 1) {\n dirs.push(current);\n if (current === root) break;\n const parent = dirname(current);\n if (parent === current) break;\n current = parent;\n }\n return dirs;\n}\n\n/** `dir` and its ancestors inside the root that are not cwd or above it. */\nfunction dirsBelowCwd(c: Collector, dir: string): string[] {\n const dirs: string[] = [];\n let current = dir;\n for (let depth = 0; depth < 64; depth += 1) {\n if (relPosix(c.root, current) === null || relPosix(current, c.cwd) !== null) break;\n dirs.push(current);\n const parent = dirname(current);\n if (parent === current) break;\n current = parent;\n }\n return dirs;\n}\n\n/** One glob, a comma-separated string, or a list. Commas inside braces stay. */\nfunction isCursorRule(path: string): boolean {\n return path.split(sep).join(\"/\").includes(\"/.cursor/rules/\");\n}\n\n/**\n * Cursor reads its front matter line by line, so `globs: **\\/*.ts` is a rule\n * there and invalid YAML (an alias) here. This reads the three keys Cursor\n * defines the way Cursor does, as `key: rest of line`.\n */\nfunction cursorFront(content: string): ExtractedMetadata | null {\n const block = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/.exec(content)?.[1];\n if (block === undefined) return null;\n const data: Record<string, unknown> = {};\n for (const line of block.split(/\\r?\\n/)) {\n const m = /^(description|globs|alwaysApply):\\s*(.*)$/.exec(line);\n const name = m?.[1];\n const value = m?.[2]?.trim();\n if (name === undefined || value === undefined) continue;\n data[name] = name === \"alwaysApply\" ? value === \"true\" : value;\n }\n if (Object.keys(data).length === 0) return null;\n return { data, present: true, format: \"markdown\", lineFor: () => undefined };\n}\n\nfunction globList(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.filter((v): v is string => typeof v === \"string\" && v.trim() !== \"\").map((v) => v.trim());\n }\n if (typeof value !== \"string\") return [];\n const out: string[] = [];\n let depth = 0;\n let current = \"\";\n for (const ch of value) {\n if (ch === \"{\") depth += 1;\n if (ch === \"}\") depth = Math.max(0, depth - 1);\n if (ch === \",\" && depth === 0) {\n out.push(current);\n current = \"\";\n } else {\n current += ch;\n }\n }\n out.push(current);\n return out.map((p) => p.trim()).filter((p) => p !== \"\");\n}\n\n/** `path` relative to `base` with forward slashes, or null when outside it. */\nfunction relPosix(base: string, path: string): string | null {\n const rel = relative(base, path);\n if (rel === \"\") return \"\";\n if (rel.startsWith(\"..\") || isAbsolute(rel)) return null;\n return rel.split(sep).join(\"/\");\n}\n\nfunction key(path: string): string {\n const abs = resolve(path);\n return process.platform === \"win32\" ? abs.toLowerCase() : abs;\n}\n\n/** A path as sources compare it: absolute, and case-folded on Windows. */\nexport const pathKey = key;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tracevals/core/config.ts","../src/tracevals/core/config-schema.json","../src/tracevals/calibrate/labels.ts","../src/tracevals/calibrate/labels-schema.json"],"sourcesContent":["/**\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 { JEV, JEV_OUT_OF_LOOP } from \"../judge/provider.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 * Checking each turn against its rule sources (proposal 0079). `null` when\n * the section is absent, which keeps tracevals out of every hook; `{}` puts\n * it in play with these defaults.\n */\n conformance: ConformanceConfig | null;\n}\n\nexport interface ConformanceConfig {\n /** The in-loop judge. `null` falls back to `tracevals.provider` / `model`. */\n hook: { provider: string | null; model: string | null; runs: number };\n /** Globs of designated rule sources, in scope once read. */\n include: string[];\n /** Globs never treated as rule sources. */\n exclude: string[];\n /** Globs of files that say what to build, in scope once touched (proposal 0080). */\n plans: string[];\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 conformance?: {\n hook?: { provider?: string; model?: string; runs?: number };\n include?: string[];\n exclude?: string[];\n plans?: string[];\n };\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 // jev only decides. Out of the loop a provider extracts rules and writes\n // verdicts, which are generations.\n if (provider === JEV) throw new TracevalsError(JEV_OUT_OF_LOOP);\n assertKnownProvider(provider, (message) => new TracevalsError(message));\n }\n const hookProvider = r.conformance?.hook?.provider ?? null;\n if (hookProvider !== null) {\n assertKnownProvider(hookProvider, (message) => new TracevalsError(message), { decisions: true });\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 conformance:\n r.conformance === undefined\n ? null\n : {\n hook: {\n provider: hookProvider,\n model: r.conformance.hook?.model ?? null,\n runs: r.conformance.hook?.runs ?? 1,\n },\n include: [...(r.conformance.include ?? [])],\n exclude: [...(r.conformance.exclude ?? [])],\n plans: [...(r.conformance.plans ?? [])],\n },\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 out of the loop, and extracts rules: auto, anthropic, openai, claude-cli, or llama-cpp. jev only decides, so it is refused here; name it as conformance.hook.provider. 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 \"conformance\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"description\": \"Checking each turn against the rules the files that govern the agent declare. Present, even as {}, it puts tracevals in play under Claude Code hooks; absent, tracevals stays out of them.\",\n \"properties\": {\n \"hook\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"description\": \"The judge inside a Stop or SubagentStop hook. Each key falls back to the top-level one of the same name.\",\n \"properties\": {\n \"provider\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The provider that judges inside a hook. Default: tracevals.provider. jev is accepted here, and only here.\"\n },\n \"model\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The model that judges inside a hook. Default: tracevals.model.\"\n },\n \"runs\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"description\": \"Judge calls per rule inside a hook. A rule blocks only when every run scores it not followed at the bar. jev makes one call and ignores it. Default 1.\"\n }\n }\n },\n \"include\": {\n \"type\": \"array\",\n \"description\": \"Globs, relative to the project root, naming files that govern agents beyond the known formats. Each applies to every turn.\",\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n },\n \"exclude\": {\n \"type\": \"array\",\n \"description\": \"Globs, relative to the project root, naming files never treated as rule sources, in any format. It removes plan, spec and output style files too. It also matches the sources `prompt`, `plan` and `system-prompt` by name.\",\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n },\n \"plans\": {\n \"type\": \"array\",\n \"default\": [],\n \"description\": \"Globs, relative to the project root, naming files that say what to build, beyond the known spec formats. Each is a rule source once the session touches it.\",\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\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 * 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"],"mappings":"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","names":["Ajv2020","ajv","Ajv2020","validate"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/family/cli.ts","../src/family/core/envelope.ts","../src/family/core/in-play.ts","../src/family/commands/check.ts","../src/family/core/changed.ts","../src/family/core/said-once.ts","../src/family/commands/status.ts"],"sourcesContent":["/**\n * The two family verbs, `manni check` and `manni status`, mounted on the\n * umbrella with `addCommand`. They are the only verbs it carries: each\n * orchestrates other domains' command cores and owns no checks of its own.\n *\n * Run by hand or in CI they follow the family contract: 0 clean, 1 errors, 2\n * operational, the report on stdout and notices on stderr. Under a Claude\n * Code hook envelope on stdin they speak the hook protocol instead, which\n * changes where output goes and what the exit code means, never what is\n * checked beyond the scope.\n */\nimport { resolve } from \"node:path\";\nimport { Command, Option } from \"commander\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { errorMessage } from \"../shared/errors.js\";\nimport { programName } from \"../shared/program-name.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport { readEnvelope, type Envelope } from \"./core/envelope.js\";\nimport { FamilyError, labelFrom } from \"./core/in-play.js\";\nimport {\n CHECK_FORMATS,\n EDIT_TOOLS,\n exitCodeFor,\n hookFailure,\n hookReply,\n render,\n runFamilyCheck,\n runTurnCheck,\n turnReply,\n type CheckFormat,\n type FamilyCheckRun,\n type HookReply,\n type Scope,\n} from \"./commands/check.js\";\nimport {\n STATUS_FORMATS,\n agentLines,\n exportGeneratedBy,\n renderStatus,\n runStatus,\n type StatusFormat,\n} from \"./commands/status.js\";\n\ninterface CheckCliOptions {\n config?: string;\n format: CheckFormat;\n /** `--no-color`: `false` when given. */\n color: boolean;\n}\n\ninterface StatusCliOptions {\n config?: string;\n format: StatusFormat;\n}\n\nfunction send(reply: HookReply): void {\n if (reply.stdout !== undefined) process.stdout.write(reply.stdout);\n if (reply.stderr !== undefined) process.stderr.write(reply.stderr);\n process.exitCode = reply.exitCode;\n}\n\n/**\n * The file checks a hook asks for, or `undefined` when this event runs none.\n * A SubagentStop runs none: its subagent's turn is judged alone.\n */\nexport function hookScope(envelope: Envelope, cwd: string): { scope: Scope; file?: string } | undefined {\n if (envelope.event === \"Stop\") return { scope: { kind: \"changed\" } };\n if (envelope.event !== \"PostToolUse\") return undefined;\n if (envelope.toolName === undefined || !EDIT_TOOLS.includes(envelope.toolName)) return undefined;\n if (envelope.filePath === undefined) return undefined;\n const file = labelFrom(cwd, resolve(cwd, envelope.filePath));\n return { scope: { kind: \"paths\", paths: [file] }, file };\n}\n\n/** The events that end a turn, which tracevals judges (proposal 0079). */\nconst TURN_EVENTS: readonly string[] = [\"Stop\", \"SubagentStop\"];\n\nasync function checkUnderHook(paths: string[], options: CheckCliOptions, envelope: Envelope): Promise<void> {\n const cwd = resolve(envelope.cwd ?? process.cwd());\n // Positional paths win over the envelope's own scope.\n const asked: { scope: Scope; file?: string } | undefined =\n paths.length > 0 ? { scope: { kind: \"paths\", paths }, file: paths.join(\", \") } : hookScope(envelope, cwd);\n const turnEvent = TURN_EVENTS.includes(envelope.event);\n if (asked === undefined && !turnEvent) return;\n let run: FamilyCheckRun | undefined;\n if (asked !== undefined) {\n try {\n run = await runFamilyCheck({\n cwd,\n scope: asked.scope,\n allowMissing: true,\n ...(options.config === undefined ? {} : { configPath: options.config }),\n // stdout and stderr are the hook's channels; a notice is not for the agent.\n onNotice: () => undefined,\n });\n } catch (err) {\n // Nothing set up for the file checks is not the end of a turn's judgement.\n if (!(err instanceof FamilyError && err.quiet) && !turnEvent) {\n send(hookFailure(errorMessage(err), envelope, asked.file));\n return;\n }\n }\n }\n if (!turnEvent) {\n if (run !== undefined) send(hookReply(run, envelope));\n return;\n }\n send(turnReply(run, await runTurnCheck(envelope, cwd), envelope));\n}\n\nexport function buildCheck(): Command {\n return new Command(\"check\")\n .description(\"Run every check this repository has set up, and nothing else\")\n .argument(\"[paths...]\", \"files, directories, or globs; the per-file checks run on the collection members among them\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .addOption(\n new Option(\"-f, --format <format>\", \"output (not read under a hook)\")\n .choices(CHECK_FORMATS)\n .default(\"pretty\"),\n )\n .option(\"--no-color\", \"disable colored output\")\n .showHelpAfterError(\"(add --help for usage)\")\n .exitOverride()\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni check # every in-play check, the CI gate\",\n \" manni check docs/limits.md # per-file checks on one page\",\n \" manni check -f github # in a GitHub workflow\",\n \" manni check docs/ -f json # scripting form\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: CheckCliOptions) => {\n const envelope = await readEnvelope();\n if (envelope !== undefined) {\n await checkUnderHook(paths, options, envelope);\n return;\n }\n try {\n const run = await runFamilyCheck({\n scope: paths.length > 0 ? { kind: \"paths\", paths } : { kind: \"all\" },\n ...(options.config === undefined ? {} : { configPath: options.config }),\n onNotice: notice,\n });\n for (const check of run.checks) {\n if (check.status === \"error\") {\n process.stderr.write(`${programName()} ${check.command} could not run: ${check.message}\\n`);\n }\n }\n const color = shouldColor({ noColor: !options.color, isTTY: process.stdout.isTTY });\n const text = render(run, options.format, color);\n if (text.length > 0) process.stdout.write(`${text}\\n`);\n process.exitCode = exitCodeFor(run);\n } catch (err) {\n fail(err);\n }\n });\n}\n\nexport function buildStatus(): Command {\n return new Command(\"status\")\n .description(\"Say what is set up here, and so what manni check runs\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .addOption(\n new Option(\"-f, --format <format>\", \"output\").choices(STATUS_FORMATS).default(\"pretty\"),\n )\n .showHelpAfterError(\"(add --help for usage)\")\n .exitOverride()\n .action(async (options: StatusCliOptions) => {\n const envelope = await readEnvelope();\n const configOption = options.config === undefined ? {} : { configPath: options.config };\n if (envelope?.event === \"SessionStart\") {\n try {\n const report = await runStatus({ cwd: resolve(envelope.cwd ?? process.cwd()), ...configOption });\n // The agent lines promise checks, so they need a domain in play to be true.\n const lines = report.domains.some((d) => d.status === \"in-play\") ? `\\n\\n${agentLines(report)}` : \"\";\n process.stdout.write(`${renderStatus(report, \"pretty\")}${lines}\\n`);\n exportGeneratedBy(envelope);\n } catch {\n // No config, or one that cannot be read: the session starts without a word.\n }\n return;\n }\n try {\n const report = await runStatus(configOption);\n process.stdout.write(`${renderStatus(report, options.format)}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n}\n","/**\n * The Claude Code hook envelope, detected rather than switched.\n *\n * A hook command gets one JSON object on stdin, and Claude Code closes the\n * stream after it. When stdin is not a terminal and parses as an object with a\n * string `hook_event_name`, `manni check` and `manni status` speak the hook\n * protocol. Anything else is a run by hand, and stdin is left unread beyond\n * that one look. The look never hangs: `readStdin` gives up on a stream that\n * stays silent, which is what an inherited pipe nobody writes to looks like.\n */\nimport { readStdin } from \"../../tracevals/capture/hook.js\";\n\nexport interface Envelope {\n /** `hook_event_name`: `PostToolUse`, `Stop`, `SessionStart`, … */\n event: string;\n /** The directory the hook fired in; relative paths resolve from it. */\n cwd?: string;\n /** `tool_name`, on a tool event. */\n toolName?: string;\n /** `tool_input.file_path`, or `tool_input.notebook_path` for a notebook. */\n filePath?: string;\n /** `stop_hook_active`: this stop already follows one repair pass. */\n stopHookActive: boolean;\n /** `model`, on `SessionStart`: a string, or an object carrying `id`. */\n model?: string;\n /** `session_id`. */\n sessionId?: string;\n /** `transcript_path`: the session's own transcript. */\n transcriptPath?: string;\n /** `agent_transcript_path`, on `SubagentStop`: the subagent's own transcript. */\n agentTranscriptPath?: string;\n /** `agent_id`, on `SubagentStop`. */\n agentId?: string;\n /** `agent_type`, on `SubagentStop`. */\n agentType?: string;\n /** `last_assistant_message`, on `Stop` and `SubagentStop`. */\n lastAssistantMessage?: string;\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** The envelope in `text`, or `undefined` when `text` is not one. */\nexport function parseEnvelope(text: string): Envelope | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n const doc = record(parsed);\n const event = str(doc?.hook_event_name);\n if (doc === undefined || event === undefined) return undefined;\n const input = record(doc.tool_input);\n const filePath = str(input?.file_path) ?? str(input?.notebook_path);\n const cwd = str(doc.cwd);\n const toolName = str(doc.tool_name);\n const model = str(doc.model) ?? str(record(doc.model)?.id);\n const strings = {\n sessionId: str(doc.session_id),\n transcriptPath: str(doc.transcript_path),\n agentTranscriptPath: str(doc.agent_transcript_path),\n agentId: str(doc.agent_id),\n agentType: str(doc.agent_type),\n lastAssistantMessage: str(doc.last_assistant_message),\n };\n const given = Object.fromEntries(Object.entries(strings).filter(([, v]) => v !== undefined)) as Partial<\n Record<keyof typeof strings, string>\n >;\n return {\n event,\n stopHookActive: doc.stop_hook_active === true,\n ...(cwd === undefined ? {} : { cwd }),\n ...(toolName === undefined ? {} : { toolName }),\n ...(filePath === undefined ? {} : { filePath }),\n ...(model === undefined ? {} : { model }),\n ...given,\n };\n}\n\n/** The envelope on stdin, or `undefined` for a run by hand. */\nexport async function readEnvelope(\n stream: NodeJS.ReadStream = process.stdin,\n): Promise<Envelope | undefined> {\n if (stream.isTTY) return undefined;\n try {\n return parseEnvelope(await readStdin(stream));\n } catch {\n // Too large to be an envelope: a run by hand with something piped in.\n return undefined;\n }\n}\n","/**\n * What is set up, and so what `manni check` runs.\n *\n * There are no keys of the family's own. A domain is in play when its own\n * section of `manni.config.yaml` exists, or when the content carries its\n * declarations. Nothing manni would apply by default counts as set up:\n *\n * | Domain | In play when |\n * |---|---|\n * | meta | a file's schema set is more than the built-in defaults: `meta:` covers it, or it names its own `$schema` |\n * | cite | a page carries citations |\n * | lint | `lint:` exists |\n * | docevals | a page resolves evals, from `docevals:` or its own declarations |\n * | term | the collections hold a term |\n * | graph | `graph:` exists |\n * | tracevals | `tracevals.conformance` exists; it judges the turn a Stop or SubagentStop hook ends |\n * | a11y | never run by `check`: it needs a running site |\n *\n * Only members of a declared collection are file-checked. tracevals judges a\n * turn, not files, so it needs no collection.\n */\nimport { relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { CollectionConfig } from \"../../shared/collections.js\";\nimport {\n findFamilyConfigFile,\n readFamilyConfigFile,\n type ConfigFile,\n} from \"../../shared/config-file.js\";\nimport { ToolError } from \"../../shared/errors.js\";\nimport { memberOf, retainMembers } from \"../../meta/core/collections.js\";\nimport { resolveTargetSet } from \"../../meta/internal.js\";\n\n/** An operational error of `manni check` or `manni status`: exit 2. */\nexport class FamilyError extends ToolError {\n constructor(\n message: string,\n /** Set for the two conditions a hook answers with silence. */\n readonly quiet = false,\n ) {\n super(message);\n this.name = \"FamilyError\";\n }\n}\n\nexport function noConfigError(cwd: string): FamilyError {\n return new FamilyError(\n `No manni.config.yaml found from ${cwd} up to the repository root. manni check runs the checks it sets up.`,\n true,\n );\n}\n\nexport function nothingSetUpError(): FamilyError {\n return new FamilyError(\n \"Nothing is set up to check in manni.config.yaml. manni status says what each domain needs.\",\n true,\n );\n}\n\n/** The domains `check` can run, in the order it runs and reports them. */\nexport const DOMAINS = [\"meta\", \"cite\", \"lint\", \"docevals\", \"term\", \"graph\"] as const;\nexport type Domain = (typeof DOMAINS)[number];\n\n/** Each domain's check, as `check` names it. */\nexport const COMMANDS: Readonly<Record<Domain, string>> = {\n meta: \"meta validate\",\n cite: \"cite check\",\n lint: \"lint check\",\n docevals: \"docevals run\",\n term: \"term check\",\n graph: \"graph check\",\n};\n\n/** Why a domain is not in play, as both `check` and `status` say it. */\nexport const NOT_SET_UP: Readonly<Record<Domain, string>> = {\n meta: \"no meta: section\",\n cite: \"no page carries citations\",\n lint: \"no lint: section\",\n docevals: \"no page resolves any evals\",\n term: \"no terms in any collection\",\n graph: \"no graph: section\",\n};\n\n/** Why `meta` skips files when `meta:` exists but covers none of them. */\nexport const META_DEFAULTS_ONLY = \"only the built-in default schemas cover these files\";\n\n/**\n * The domains `check` does not run here, and what to run instead. tracevals\n * leaves this list when `tracevals.conformance` exists (`Family.conformance`).\n */\nexport const NOT_CHECKED: ReadonlyArray<readonly [string, string]> = [\n [\"a11y\", \"run manni a11y check against a running site\"],\n [\"tracevals\", \"run manni tracevals run over sessions\"],\n];\n\n/** `1 page`, `2 pages`. */\nexport function plural(n: number, one: string, many = `${one}s`): string {\n return `${String(n)} ${n === 1 ? one : many}`;\n}\n\nexport interface Family {\n file: ConfigFile;\n /**\n * The config each domain core is handed, so every one reads this file\n * rather than discovering its own: as typed, or as discovery found it,\n * relative to `cwd`.\n */\n configPath: string;\n /** The top-level keys of the file: `meta`, `lint`, `graph`, … */\n sections: ReadonlySet<string>;\n /** `tracevals.conformance` exists: tracevals judges each turn under the hooks. */\n conformance: boolean;\n collections: readonly CollectionConfig[];\n}\n\nfunction toError(message: string): FamilyError {\n return new FamilyError(message);\n}\n\nexport async function loadFamily(cwd: string, configPath?: string): Promise<Family> {\n const file =\n configPath === undefined\n ? await findFamilyConfigFile(cwd, toError)\n : await readFamilyConfigFile(configPath, cwd, toError);\n if (file === null) throw noConfigError(cwd);\n // Already parsed once by the loader, which would have thrown on bad YAML.\n const doc = parseYaml(file.text) as unknown;\n const top = record(doc);\n const sections = new Set(top === undefined ? [] : Object.keys(top));\n const conformance = record(top?.tracevals)?.conformance !== undefined;\n return { file, configPath: configPath ?? file.source, sections, conformance, collections: file.collections };\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** A path as a label relative to `cwd`, posix, the way the domains print one. */\nexport function labelFrom(cwd: string, path: string): string {\n return relative(cwd, path).split(sep).join(\"/\");\n}\n\n/** The collections a file at `label` (relative to `cwd`) belongs to. */\nexport function collectionsOf(family: Family, cwd: string, label: string): string[] {\n return memberOf(family.collections, family.file.dir, cwd, label);\n}\n\n/** Every member of every collection, labelled from `cwd`. */\nexport async function listMembers(family: Family, cwd: string): Promise<string[]> {\n const dir = family.file.dir;\n const { files } = await resolveTargetSet({\n inputs: family.collections.flatMap((c) => c.paths),\n cwd: dir,\n allowEmpty: true,\n });\n return retainMembers(files, (label) => memberOf(family.collections, dir, dir, label)).map(\n (label) => labelFrom(cwd, resolve(dir, label)),\n );\n}\n","/**\n * `manni check`: every check the repository has set up, and nothing else.\n *\n * It owns no checks. Each one is a domain's own command core, run in process\n * with the family config handed to it, and each report is that domain's own\n * reporter's output. What this adds is the choice of what runs (`in-play.ts`),\n * the scope, and one verdict over all of it.\n *\n * Scope:\n *\n * - `all`: every in-play check over every collection, per-file and set-wide.\n * Each domain runs bare, exactly as its own CI step would.\n * - `paths`: the per-file checks on the collection members among the paths.\n * - `changed`: the per-file checks on the git working tree's changes, plus\n * `cite` set-wide. `term` runs set-wide too when a collection document\n * changed or was removed. `graph` never runs here; only `all` checks it.\n * A clean tree runs nothing.\n *\n * `cite` is per-file on paths and set-wide otherwise: a source edit can drift\n * any page's citation, so after a session the whole set is what is checked.\n */\nimport { basename, extname, resolve } from \"node:path\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport { ToolError, errorMessage } from \"../../shared/errors.js\";\nimport { warn } from \"../../shared/warn.js\";\nimport { resolveTargetSet } from \"../../meta/internal.js\";\nimport { supportedExtensions } from \"../../meta/extractors/index.js\";\nimport type { TurnCheckInput, TurnCheckResult } from \"../../tracevals/commands/check.js\";\nimport { changedFiles } from \"../core/changed.js\";\nimport { sayOnce } from \"../core/said-once.js\";\nimport type { Envelope } from \"../core/envelope.js\";\nimport {\n COMMANDS,\n DOMAINS,\n META_DEFAULTS_ONLY,\n NOT_SET_UP,\n collectionsOf,\n labelFrom,\n listMembers,\n loadFamily,\n nothingSetUpError,\n plural,\n type Domain,\n type Family,\n} from \"../core/in-play.js\";\nimport { withSharedWalks } from \"../../meta/core/load-files.js\";\n\nexport const CHECK_FORMATS = [\"pretty\", \"json\", \"github\"] as const;\nexport type CheckFormat = (typeof CHECK_FORMATS)[number];\n\nexport type Scope =\n | { kind: \"all\" }\n | { kind: \"paths\"; paths: string[] }\n | { kind: \"changed\" };\n\nexport interface FamilyCheckOptions {\n /** Where paths resolve and the domains run. Default `process.cwd()`. */\n cwd?: string;\n /** `-c, --config`. */\n configPath?: string;\n scope: Scope;\n /**\n * Leave out a named path that does not exist, rather than failing on it. A\n * hook names a file the edit may have just removed.\n */\n allowMissing?: boolean;\n /** Diagnostics: the outside-every-collection notice, and the domains' own. */\n onNotice?: (message: string) => void;\n}\n\n/** A check that ran. `render` is the domain's own reporter. */\nexport interface RanCheck {\n command: string;\n status: \"pass\" | \"fail\";\n render: (format: CheckFormat, color: boolean) => string;\n}\n\n/** A check that did not run: not in play, or it could not. */\nexport interface NotRunCheck {\n command: string;\n status: \"skipped\" | \"error\";\n message: string;\n}\n\nexport type CheckOutcome = RanCheck | NotRunCheck;\n\nexport interface FamilyCheckRun {\n status: \"pass\" | \"fail\";\n /** The collection members the per-file checks covered, labelled from `cwd`. */\n files: string[];\n checks: CheckOutcome[];\n}\n\ntype Outcome =\n | { skipped: string }\n | { failed: boolean; render: (format: CheckFormat, color: boolean) => string };\n\ninterface Context {\n family: Family;\n cwd: string;\n /** The per-file inputs, or `[]` for a bare run over the collections. */\n inputs: string[];\n onNotice: (message: string) => void;\n}\n\n/**\n * Each domain's command core and reporter are imported where it runs: a hook\n * checks one page with four domains, and the other two (the RDF stack among\n * them) are worth not loading.\n */\nasync function runDomain(domain: Domain, ctx: Context): Promise<Outcome> {\n const { family, cwd, inputs, onNotice } = ctx;\n const configPath = family.configPath;\n switch (domain) {\n case \"meta\": {\n const [{ runValidate }, { render: renderMeta }] = await Promise.all([\n import(\"../../meta/commands/validate.js\"),\n import(\"../../meta/reporters/index.js\"),\n ]);\n const run = await runValidate({ inputs, configPath, cwd, skipDefaultOnly: true, onNotice });\n if (run.results.length === 0) {\n return { skipped: family.sections.has(\"meta\") ? META_DEFAULTS_ONLY : NOT_SET_UP.meta };\n }\n return {\n failed: run.summary.failed > 0,\n render: (format, color) =>\n renderMeta(format, run.results, run.summary, { color, quiet: true, frame: run.frame, onNotice }),\n };\n }\n case \"cite\": {\n const [{ runCheck: runCite }, { renderCheckPretty: citePretty }, { renderCheckJson: citeJson }, { renderCheckGithub: citeGithub }] =\n await Promise.all([\n import(\"../../cite/commands/check.js\"),\n import(\"../../cite/reporters/pretty.js\"),\n import(\"../../cite/reporters/json.js\"),\n import(\"../../cite/reporters/github.js\"),\n ]);\n const run = await runCite({ inputs, configPath, cwd, onNotice });\n if (!run.pages.some((p) => p.citations.length > 0 || p.findings.length > 0)) {\n return { skipped: NOT_SET_UP.cite };\n }\n return {\n failed: run.summary.failed > 0,\n render: (format, color) =>\n format === \"json\"\n ? citeJson(run)\n : format === \"github\"\n ? citeGithub(run)\n : citePretty(run, { color, quiet: true }),\n };\n }\n case \"lint\": {\n if (!family.sections.has(\"lint\")) return { skipped: NOT_SET_UP.lint };\n const [{ runLint }, { render: renderLint }] = await Promise.all([\n import(\"../../lint/commands/lint.js\"),\n import(\"../../lint/reporters/index.js\"),\n ]);\n const run = await runLint({ inputs, configPath, cwd, onNotice });\n return {\n failed: run.summary.failed > 0,\n render: (format, color) => renderLint(run, format, { color }),\n };\n }\n case \"docevals\": {\n const [{ runRun: runDocevals }, { render: renderDocevals }, { DocevalsError }] = await Promise.all([\n import(\"../../docevals/commands/run.js\"),\n import(\"../../docevals/reporters/index.js\"),\n import(\"../../docevals/types.js\"),\n ]);\n let report;\n try {\n report = await runDocevals(inputs, {\n config: configPath,\n cwd,\n deterministicOnly: true,\n generate: false,\n execution: false,\n toolVersion: pkg.version,\n });\n } catch (err) {\n if (err instanceof DocevalsError && err.code === \"nothing-resolved\") {\n return { skipped: NOT_SET_UP.docevals };\n }\n throw err;\n }\n return {\n failed: report.exitCode !== 0,\n render: (format, color) => renderDocevals(report, format, { color }),\n };\n }\n case \"term\": {\n const [{ runCheck: runTerm }, { renderFindingsPretty: termPretty }, { renderFindingsJson: termJson }, { renderFindingsGithub: termGithub }] =\n await Promise.all([\n import(\"../../term/commands/check.js\"),\n import(\"../../term/reporters/pretty.js\"),\n import(\"../../term/reporters/json.js\"),\n import(\"../../term/reporters/github.js\"),\n ]);\n const report = await runTerm({ inputs, configPath, cwd, allowEmpty: true, onNotice });\n if (report.terms === 0) return { skipped: NOT_SET_UP.term };\n return {\n failed: report.summary.failed > 0,\n render: (format, color) =>\n format === \"json\"\n ? termJson(report)\n : format === \"github\"\n ? termGithub(report)\n : termPretty(report, { color, references: true }),\n };\n }\n case \"graph\": {\n if (!family.sections.has(\"graph\")) return { skipped: NOT_SET_UP.graph };\n const [{ buildGraph }, { runCheck: runGraph, renderCheck: renderGraph }] = await Promise.all([\n import(\"../../graph/commands/build.js\"),\n import(\"../../graph/commands/check.js\"),\n ]);\n const built = await buildGraph({ config: configPath, cwd });\n for (const warning of built.warnings) onNotice(warning);\n const report = await runGraph({ config: configPath, cwd, turtle: built.turtle });\n return {\n failed: report.exitCode !== 0,\n render: (format) => renderGraph(report, format),\n };\n }\n }\n}\n\nasync function outcome(domain: Domain, ctx: Context): Promise<CheckOutcome> {\n const command = COMMANDS[domain];\n try {\n const result = await runDomain(domain, ctx);\n if (\"skipped\" in result) return { command, status: \"skipped\", message: result.skipped };\n return { command, status: result.failed ? \"fail\" : \"pass\", render: result.render };\n } catch (err) {\n return { command, status: \"error\", message: errorMessage(err) };\n }\n}\n\n/** A hook or a git status names files by any extension; a walk keeps the documents. */\nfunction isDocument(label: string): boolean {\n return supportedExtensions().includes(extname(label).toLowerCase());\n}\n\n/** Every domain walks the same collections, so the run shares one walk per target set. */\nexport function runFamilyCheck(opts: FamilyCheckOptions): Promise<FamilyCheckRun> {\n return withSharedWalks(() => checkUnshared(opts));\n}\n\nasync function checkUnshared(opts: FamilyCheckOptions): Promise<FamilyCheckRun> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const onNotice = opts.onNotice ?? ((): void => undefined);\n const family = await loadFamily(cwd, opts.configPath);\n if (family.collections.length === 0) throw nothingSetUpError();\n const isMember = (label: string): boolean => collectionsOf(family, cwd, label).length > 0;\n\n let files: string[];\n let domains: Domain[];\n let inputs: string[];\n switch (opts.scope.kind) {\n case \"all\":\n files = await listMembers(family, cwd);\n inputs = [];\n domains = [...DOMAINS];\n break;\n case \"paths\": {\n const { files: named } = await resolveTargetSet({\n inputs: opts.scope.paths,\n cwd,\n ...(opts.allowMissing === true ? { allowEmpty: true } : {}),\n });\n const outside = named.filter((label) => !isMember(label));\n if (outside.length > 0) {\n onNotice(`Skipped ${plural(outside.length, \"file\")} outside every collection: ${outside.join(\", \")}`);\n }\n // A collection globbed wide holds assets too; only documents are checked.\n files = named.filter((label) => isMember(label) && isDocument(label));\n inputs = files;\n domains = files.length > 0 ? [\"meta\", \"cite\", \"lint\", \"docevals\"] : [];\n break;\n }\n case \"changed\": {\n const changed = await changedFiles(cwd);\n if (!changed.dirty) return { status: \"pass\", files: [], checks: [] };\n const memberDocuments = (paths: string[]): string[] =>\n paths.map((path) => labelFrom(cwd, path)).filter((l) => isDocument(l) && isMember(l));\n files = memberDocuments(changed.files);\n inputs = files;\n // term reads only collection documents, so a session that changed or\n // removed none of them leaves the glossary as it was. graph never runs\n // here: it is the slowest set-wide check, and its findings span pages\n // rather than the one an agent just wrote, so a bare run (CI) owns it.\n const pageChanged = files.length > 0 || memberDocuments(changed.removed).length > 0;\n domains = [\n ...(files.length > 0 ? ([\"meta\", \"lint\", \"docevals\"] as const) : []),\n \"cite\",\n ...(pageChanged ? ([\"term\"] as const) : []),\n ];\n break;\n }\n }\n\n const checks: CheckOutcome[] = [];\n for (const domain of domains) {\n // The set-wide checks run bare, over every collection, whatever the scope.\n const setWide = domain === \"term\" || domain === \"graph\" || (domain === \"cite\" && opts.scope.kind !== \"paths\");\n checks.push(await outcome(domain, { family, cwd, inputs: setWide ? [] : inputs, onNotice }));\n }\n if (opts.scope.kind === \"all\" && checks.every((c) => c.status === \"skipped\")) {\n throw nothingSetUpError();\n }\n return { status: checks.some((c) => c.status === \"fail\") ? \"fail\" : \"pass\", files, checks };\n}\n\n/** The exit code a run by hand ends with: 2 when a check could not run. */\nexport function exitCodeFor(run: FamilyCheckRun): 0 | 1 | 2 {\n if (run.checks.some((c) => c.status === \"error\")) return 2;\n return run.status === \"fail\" ? 1 : 0;\n}\n\nfunction isRan(check: CheckOutcome): check is RanCheck {\n return check.status === \"pass\" || check.status === \"fail\";\n}\n\n/** The first line of a message, for a one-line context. */\nfunction firstLine(message: string): string {\n return message.split(\"\\n\", 1)[0] ?? \"\";\n}\n\n/** What an agent is handed when a hook blocks: the failing checks' reports, nothing else. */\nfunction renderFailures(run: FamilyCheckRun): string {\n return run.checks\n .filter((c): c is RanCheck => c.status === \"fail\")\n .map((c) => `${c.command}\\n${c.render(\"pretty\", false)}`)\n .join(\"\\n\\n\");\n}\n\nexport function renderPretty(run: FamilyCheckRun, color: boolean): string {\n const blocks: string[] = [];\n for (const check of run.checks) {\n if (isRan(check)) blocks.push(`${check.command}\\n${check.render(\"pretty\", color)}`);\n }\n const notRun = run.checks.filter((c): c is NotRunCheck => !isRan(c));\n if (notRun.length > 0) {\n const width = Math.max(...notRun.map((c) => c.command.length)) + 3;\n blocks.push(\n notRun\n .map((c) => `${c.status.padEnd(9)}${c.command.padEnd(width)}${firstLine(c.message)}`)\n .join(\"\\n\"),\n );\n }\n const count = (status: CheckOutcome[\"status\"]): number =>\n run.checks.filter((c) => c.status === status).length;\n const errors = count(\"error\");\n blocks.push(\n `${plural(run.checks.length, \"check\")} over ${plural(run.files.length, \"file\")}: ` +\n `${String(count(\"fail\"))} failed, ${String(count(\"skipped\"))} skipped` +\n (errors > 0 ? `, ${String(errors)} could not run` : \"\"),\n );\n return blocks.join(\"\\n\\n\");\n}\n\n/** A check's JSON entry: its own report, or why there is none. */\nfunction jsonEntry(c: CheckOutcome): object {\n if (!isRan(c)) return { command: c.command, status: c.status, message: c.message };\n try {\n return { command: c.command, status: c.status, report: JSON.parse(c.render(\"json\", false)) as unknown };\n } catch {\n // One reporter's bad output must not take the other checks' reports with it.\n // `error` on purpose, whatever the run's own status: with no report to\n // embed, a `pass` or `fail` here would be a verdict nobody can inspect.\n // The reference documents `error` for this case too.\n return { command: c.command, status: \"error\", message: `${c.command} -f json printed output that is not JSON` };\n }\n}\n\nexport function renderJson(run: FamilyCheckRun): string {\n return JSON.stringify(\n {\n status: run.status,\n files: run.files,\n checks: run.checks.map(jsonEntry),\n },\n null,\n 2,\n );\n}\n\nexport function renderGithub(run: FamilyCheckRun): string {\n return run.checks\n .filter(isRan)\n .map((c) => c.render(\"github\", false))\n .filter((text) => text.length > 0)\n .join(\"\\n\");\n}\n\nexport function render(run: FamilyCheckRun, format: CheckFormat, color: boolean): string {\n return format === \"json\" ? renderJson(run) : format === \"github\" ? renderGithub(run) : renderPretty(run, color);\n}\n\n/** What a hook command ends with: its exit code, and what it prints where. */\nexport interface HookReply {\n exitCode: 0 | 2;\n stdout?: string;\n stderr?: string;\n}\n\n/** The PostToolUse tools whose edit `check` answers. */\nexport const EDIT_TOOLS: readonly string[] = [\"Edit\", \"Write\", \"MultiEdit\", \"NotebookEdit\"];\n\n/**\n * The hook protocol's answer to a run. Never exit 2 for a check that could\n * not run: 2 means \"block\" to Claude Code, and an operational error is not\n * the agent's to fix.\n */\nexport function hookReply(run: FamilyCheckRun, envelope: Envelope): HookReply {\n const failed = run.status === \"fail\";\n if (envelope.event === \"PostToolUse\") {\n const files = run.files.join(\", \");\n if (failed) {\n return {\n exitCode: 2,\n stderr: `manni found errors in ${files}. Fix them before you continue.\\n\\n${renderFailures(run)}\\n`,\n };\n }\n const errors = run.checks.filter((c): c is NotRunCheck => c.status === \"error\");\n if (errors.length === 0) return { exitCode: 0 };\n const additionalContext = errors\n .map((c) => `manni ${c.command} could not check ${files}: ${firstLine(c.message)}`)\n .join(\"\\n\");\n return {\n exitCode: 0,\n stdout: `${JSON.stringify({ hookSpecificOutput: { hookEventName: \"PostToolUse\", additionalContext } })}\\n`,\n };\n }\n if (envelope.event === \"Stop\") return turnReply(run, undefined, envelope);\n return { exitCode: 0 };\n}\n\n/** What tracevals found in the turn a Stop or SubagentStop ended, for the reply. */\nexport interface TurnVerdict {\n /** Rules broken with a confident verdict: how many, the report, the trace judged. */\n broken?: { rules: number; report: string; trace: string };\n /** A skip not yet said this session. */\n skipMessage?: string;\n}\n\n/**\n * The reply to a Stop or a SubagentStop: 0078's file checks first, then the\n * turn. One block carries both reasons; after the repair pass, one message\n * carries both sentences. Always exit 0, as 0078's Stop is.\n */\nexport function turnReply(\n run: FamilyCheckRun | undefined,\n turn: TurnVerdict | undefined,\n envelope: Envelope,\n): HookReply {\n const reasons: string[] = [];\n const messages: string[] = [];\n if (run?.status === \"fail\") {\n if (envelope.stopHookActive) {\n messages.push(\"manni still reports errors after one repair pass. Run manni check to see them.\");\n } else {\n reasons.push(`manni found errors in the files you changed. Fix them, then finish.\\n\\n${renderFailures(run)}`);\n }\n }\n if (turn?.broken !== undefined) {\n const { rules, report, trace } = turn.broken;\n if (envelope.stopHookActive) {\n messages.push(\n `tracevals still finds broken rules after one repair pass. Run manni tracevals check ${trace} to see them.`,\n );\n } else {\n reasons.push(\n `This turn broke ${plural(rules, \"rule\")} from the files and requests that governed it. ` +\n `Fix the work, or say why the rule does not apply here, then finish.\\n\\n${report}`,\n );\n }\n }\n if (turn?.skipMessage !== undefined) messages.push(turn.skipMessage);\n if (reasons.length === 0 && messages.length === 0) return { exitCode: 0 };\n const reply = {\n ...(reasons.length > 0 ? { decision: \"block\", reason: reasons.join(\"\\n\\n\") } : {}),\n ...(messages.length > 0 ? { systemMessage: messages.join(\" \") } : {}),\n };\n return { exitCode: 0, stdout: `${JSON.stringify(reply)}\\n` };\n}\n\n/** Test seams `checkTurn` takes; production builds each from config. */\nexport type TurnSeams = Partial<Pick<TurnCheckInput, \"judge\" | \"extractor\" | \"localModels\" | \"env\">>;\n\n/**\n * Judge the turn a Stop or SubagentStop ended, with every gate of proposal\n * 0079. Silent (`undefined`) when tracevals is not in play, the turn is clean\n * or only needs review, a skip was already said this session, or the run\n * could not happen: an operational failure is not the agent's to fix.\n */\nexport async function runTurnCheck(\n envelope: Envelope,\n cwd: string,\n seams: TurnSeams = {},\n): Promise<TurnVerdict | undefined> {\n const subagent = envelope.event === \"SubagentStop\";\n const judged = subagent ? envelope.agentTranscriptPath : envelope.transcriptPath;\n if (judged === undefined) return undefined;\n const trace = resolve(cwd, judged);\n const sessionId = envelope.sessionId ?? basename(trace, \".jsonl\");\n let result: TurnCheckResult;\n let renderTurn: (typeof import(\"../../tracevals/reporters/conformance.js\"))[\"renderCheck\"];\n try {\n // Loaded here, as every domain is, so a run that never judges a turn never\n // loads tracevals.\n const [{ checkTurn }, reporters] = await Promise.all([\n import(\"../../tracevals/commands/check.js\"),\n import(\"../../tracevals/reporters/conformance.js\"),\n ]);\n renderTurn = reporters.renderCheck;\n result = await checkTurn({\n transcriptPath: resolve(cwd, envelope.transcriptPath ?? judged),\n ...(subagent ? { agentTranscriptPath: trace } : {}),\n ...(subagent && envelope.agentId !== undefined ? { agentId: envelope.agentId } : {}),\n ...(subagent && envelope.agentType !== undefined ? { agentType: envelope.agentType } : {}),\n ...(envelope.lastAssistantMessage !== undefined\n ? { lastAssistantMessage: envelope.lastAssistantMessage }\n : {}),\n sessionId,\n cwd,\n inLoop: true,\n ...seams,\n });\n } catch (err) {\n // An operational failure is not the agent's to fix, so it stays silent, as\n // 0078's Stop failures do. Anything else is a bug: say so on stderr, which\n // a hook that exits 0 sends to the debug log, and still never block.\n if (!(err instanceof ToolError)) warn(`the turn check failed unexpectedly: ${errorMessage(err)}`);\n return undefined;\n }\n const { skipped } = result;\n if (skipped?.message !== undefined) {\n return sayOnce(cwd, sessionId, skipped.gate) ? { skipMessage: skipped.message } : undefined;\n }\n if (result.exitCode !== 1 || result.report === undefined) return undefined;\n return {\n broken: {\n rules: result.report.summary.fail,\n report: renderTurn(result.report, { color: false }),\n trace: judged,\n },\n };\n}\n\n/** The reply when the run itself could not happen, under a hook. */\nexport function hookFailure(message: string, envelope: Envelope, file: string | undefined): HookReply {\n if (envelope.event !== \"PostToolUse\" || file === undefined) return { exitCode: 0 };\n const additionalContext = `manni check could not check ${file}: ${firstLine(message)}`;\n return {\n exitCode: 0,\n stdout: `${JSON.stringify({ hookSpecificOutput: { hookEventName: \"PostToolUse\", additionalContext } })}\\n`,\n };\n}\n","/**\n * The files a session changed: the git working tree against `HEAD`.\n *\n * Modified, added, renamed (by the new name) and untracked files, staged or\n * not. A deleted file, or a renamed one's old name, is named apart, since\n * there is nothing left to check. Paths come back absolute, resolved from\n * `cwd`: porcelain status names them from the repository root whatever\n * directory git ran in.\n */\nimport { execFile } from \"node:child_process\";\nimport { posix, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst run = promisify(execFile);\n\nasync function git(args: string[], cwd: string): Promise<string> {\n // shell:false: nothing here is ever parsed as shell syntax.\n const { stdout } = await run(\"git\", args, {\n cwd,\n shell: false,\n windowsHide: true,\n maxBuffer: 64 * 1024 * 1024,\n });\n return stdout;\n}\n\n/** Parse `git status --porcelain=v1 -z` into repository-relative paths. */\nexport function parsePorcelain(output: string): { files: string[]; removed: string[] } {\n const fields = output.split(\"\\0\");\n const files: string[] = [];\n const removed: string[] = [];\n for (let i = 0; i < fields.length; i++) {\n const entry = fields[i] ?? \"\";\n if (entry.length < 4) continue;\n const xy = entry.slice(0, 2);\n const path = entry.slice(3);\n // A rename or copy is followed by its old name, which is not a change to\n // check. A rename's old name is gone; a copy's is still there.\n if (xy.includes(\"R\") || xy.includes(\"C\")) {\n i++;\n if (xy.includes(\"R\")) removed.push(fields[i] ?? \"\");\n }\n // `RD`, a staged rename then deleted in the tree, removes both names:\n // the old one above and the new one here. Two files, not one twice.\n if (xy.includes(\"D\")) removed.push(path);\n else files.push(path);\n }\n return { files, removed };\n}\n\nexport interface ChangedTree {\n /** The changed files left to check, absolute. */\n files: string[];\n /** The files the tree no longer has: deleted, or renamed away. Absolute. */\n removed: string[];\n /**\n * Whether the tree differs from `HEAD` at all. A deletion alone leaves no\n * file to check, but it can still break a citation to what it removed.\n */\n dirty: boolean;\n}\n\nexport async function changedFiles(cwd: string): Promise<ChangedTree> {\n // Rebased through `cwd`'s own prefix rather than resolved from the\n // top-level git prints: on Windows that is the long spelling of a path the\n // caller may hold in its 8.3 short form, and the two would never compare.\n const prefix = (await git([\"rev-parse\", \"--show-prefix\"], cwd)).trim();\n const status = await git(\n [\"status\", \"--porcelain=v1\", \"-z\", \"--untracked-files=all\"],\n cwd,\n );\n const { files, removed } = parsePorcelain(status);\n const absolute = (path: string): string => resolve(cwd, posix.relative(prefix, path));\n return { files: files.map(absolute), removed: removed.map(absolute), dirty: status.length > 0 };\n}\n","/**\n * What a hook has already told the user this session (proposal 0079: \"A skip\n * message is said once per session\").\n *\n * Each hook is a process of its own, and parallel subagents end in parallel\n * SubagentStop hooks, so the memory is one marker file per message, created\n * exclusively. The process whose create succeeds is the one that says it, so\n * no two hooks can both read \"not said yet\".\n */\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { DEFAULT_CAPTURE_DIR } from \"../../tracevals/capture/types.js\";\nimport { idHash } from \"../../tracevals/rules/ledger.js\";\n\n/**\n * `<project>/.manni/tracevals/sessions/<session hash>.<key>.said`. The session\n * id is hashed, so nothing in it can climb out of the directory and two ids\n * never share a marker. The key is a gate name, which is already safe.\n */\nexport function saidPath(projectDir: string, sessionId: string, key: string): string {\n return join(projectDir, DEFAULT_CAPTURE_DIR, `${idHash(sessionId)}.${key}.said`);\n}\n\n/**\n * True the first time `key` comes up in a session, and records it. A marker\n * that cannot be written says the message rather than lose it.\n */\nexport function sayOnce(projectDir: string, sessionId: string, key: string): boolean {\n const path = saidPath(projectDir, sessionId, key);\n try {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, \"\", { flag: \"wx\" });\n return true;\n } catch (err) {\n // EEXIST: another hook said it first. Anything else is an unwritable\n // project, which repeats the message each stop rather than lose it.\n return (err as NodeJS.ErrnoException).code !== \"EEXIST\";\n }\n}\n","/**\n * `manni status`: what is set up here, and so what `manni check` runs.\n *\n * It reads the same table `check` does (`in-play.ts`), counting what the\n * content declares where a domain is in play by declaration: the pages that\n * name their own `$schema`, carry citations or resolve evals, and the terms.\n * It checks nothing, so it exits 0 whatever it finds.\n */\nimport { appendFileSync, existsSync, readFileSync } from \"node:fs\";\nimport { extname, resolve } from \"node:path\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { extractorForExtension } from \"../../meta/extractors/index.js\";\nimport type { HostStatus } from \"../../tracevals/rules/host.js\";\nimport type { Envelope } from \"../core/envelope.js\";\nimport {\n COMMANDS,\n DOMAINS,\n NOT_CHECKED,\n NOT_SET_UP,\n collectionsOf,\n listMembers,\n loadFamily,\n plural,\n type Domain,\n type Family,\n} from \"../core/in-play.js\";\nimport { withSharedWalks } from \"../../meta/core/load-files.js\";\n\nexport const STATUS_FORMATS = [\"pretty\", \"json\"] as const;\nexport type StatusFormat = (typeof STATUS_FORMATS)[number];\n\nexport type DomainState = \"in-play\" | \"not-set-up\" | \"not-checked\" | \"unknown\";\n\nexport interface ModelRole {\n provider: string;\n model: string;\n}\n\nexport interface DomainRow {\n name: string;\n status: DomainState;\n reason: string;\n /** tracevals in play: the model judging inside a hook, and the one extracting rules. */\n models?: { hook: ModelRole; extraction: ModelRole };\n /** tracevals in play with a model host running: each model it holds. */\n host?: HostStatus[\"models\"];\n}\n\nexport interface StatusReport {\n version: string;\n /** The config file, as discovery found it or as it was typed. */\n config: string;\n collections: { name: string; files: number }[];\n domains: DomainRow[];\n}\n\nexport interface StatusOptions {\n cwd?: string;\n configPath?: string;\n /** Test seam: the running model host. Default: ask the inference library. */\n hostStatus?: () => Promise<HostStatus | null>;\n}\n\n/**\n * tracevals' row when `tracevals.conformance` exists: both models, resolved\n * the way `check` and `prepare` resolve them, and the host when one runs.\n */\nasync function tracevalsRow(cwd: string, opts: StatusOptions): Promise<DomainRow> {\n try {\n const [\n { discoverConfig },\n { assertProviderSelection, resolveSelectionIdentity, selectHookProvider, selectProvider },\n { hostStatus },\n ] = await Promise.all([\n import(\"../../tracevals/core/config.js\"),\n import(\"../../tracevals/judge/provider.js\"),\n import(\"../../tracevals/rules/host.js\"),\n ]);\n const { config } = await discoverConfig(cwd, opts.configPath === undefined ? {} : { configPath: opts.configPath });\n const hook = await resolveSelectionIdentity(config, selectHookProvider(config));\n const selection = selectProvider(config);\n assertProviderSelection(selection);\n const extraction = await resolveSelectionIdentity(config, selection);\n const host = await (opts.hostStatus ?? hostStatus)().catch(() => null);\n return {\n name: \"tracevals\",\n status: \"in-play\",\n reason: `hook: ${hook.provider} ${hook.model} · extraction: ${extraction.provider} ${extraction.model}`,\n models: {\n hook: { provider: hook.provider, model: hook.model },\n extraction: { provider: extraction.provider, model: extraction.model },\n },\n ...(host === null || host.models.length === 0 ? {} : { host: host.models }),\n };\n } catch (err) {\n const message = errorMessage(err).split(\"\\n\", 1)[0] ?? \"\";\n return { name: \"tracevals\", status: \"unknown\", reason: `manni tracevals check could not run: ${message}` };\n }\n}\n\n/** `1 page names`, `3 pages name`: a count and the verb that agrees with it. */\nfunction pages(n: number, one: string, many: string): string {\n return n === 1 ? `1 page ${one}` : `${String(n)} pages ${many}`;\n}\n\n/** The pages naming their own `$schema`, read the way `meta validate` extracts them. */\nfunction ownSchemaCount(cwd: string, members: readonly string[]): number {\n let n = 0;\n for (const label of members) {\n const extractor = extractorForExtension(extname(label));\n if (extractor === undefined) continue;\n try {\n const { data } = extractor.extract(readFileSync(resolve(cwd, label), \"utf8\"), label);\n if (data.$schema !== undefined) n++;\n } catch {\n // A page that does not parse names nothing; `meta validate` reports it.\n }\n }\n return n;\n}\n\n/**\n * The pages carrying citations, read the way `cite check` reads them: its\n * targets, its manifests, its entry rules. Nothing is classified, so no claim\n * or source is looked at and no git history is read.\n */\nasync function citedPages(cwd: string, configPath: string): Promise<number> {\n // Imported where they run, so `manni check` never loads them.\n const { prepareRun, readTarget } = await import(\"../../cite/commands/check.js\");\n const { readPage } = await import(\"../../cite/core/page.js\");\n const prepared = await prepareRun({ inputs: [], configPath, cwd, checkSources: false }, \"checked\", \"check\");\n let n = 0;\n for (const file of prepared.files) {\n const content = await readTarget(prepared.run, file);\n const { citations } = (await prepared.setupFor(file, content)).options;\n const read = readPage(file, content, { markers: false, ...(citations === undefined ? {} : { citations }) });\n if (read.citations.length > 0) n++;\n }\n return n;\n}\n\nasync function row(domain: Domain, family: Family, cwd: string, members: readonly string[]): Promise<DomainRow> {\n const configPath = family.configPath;\n const inPlay = (reason: string): DomainRow => ({ name: domain, status: \"in-play\", reason });\n const notSetUp: DomainRow = { name: domain, status: \"not-set-up\", reason: NOT_SET_UP[domain] };\n const section = family.sections.has(domain);\n switch (domain) {\n case \"meta\": {\n if (section) return inPlay(\"meta: section\");\n const n = ownSchemaCount(cwd, members);\n return n > 0 ? inPlay(pages(n, \"names its own $schema\", \"name their own $schema\")) : notSetUp;\n }\n case \"cite\": {\n const n = await citedPages(cwd, configPath);\n return n > 0 ? inPlay(pages(n, \"carries citations\", \"carry citations\")) : notSetUp;\n }\n case \"docevals\": {\n const { runList: listEvals } = await import(\"../../docevals/commands/list.js\");\n const { plans } = await listEvals([], { config: configPath, cwd });\n const n = plans.filter((p) => !p.skip && p.evals.length > 0).length;\n if (n === 0) return notSetUp;\n return inPlay(section ? \"docevals: section\" : pages(n, \"declares evals\", \"declare evals\"));\n }\n case \"term\": {\n const { runList: listTerms } = await import(\"../../term/commands/list.js\");\n const { terms } = await listTerms({ inputs: [], configPath, cwd, allowEmpty: true });\n return terms.length > 0 ? inPlay(plural(terms.length, \"term\")) : notSetUp;\n }\n case \"lint\":\n case \"graph\":\n return section ? inPlay(`${domain}: section`) : notSetUp;\n }\n}\n\n/** Every domain walks the same collections, so the run shares one walk per target set. */\nexport function runStatus(opts: StatusOptions = {}): Promise<StatusReport> {\n return withSharedWalks(() => statusUnshared(opts));\n}\n\nasync function statusUnshared(opts: StatusOptions): Promise<StatusReport> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const family = await loadFamily(cwd, opts.configPath);\n const members = family.collections.length === 0 ? [] : await listMembers(family, cwd);\n const domains: DomainRow[] = [];\n for (const domain of DOMAINS) {\n // `check` only reads collection members, so with no collections every\n // domain has nothing to check, whatever sections the config carries.\n if (family.collections.length === 0) {\n domains.push({ name: domain, status: \"not-set-up\", reason: \"no collections: in manni.config.yaml\" });\n continue;\n }\n try {\n domains.push(await row(domain, family, cwd, members));\n } catch (err) {\n // Status checks nothing, so a domain that cannot read its own setup is\n // reported in its row rather than ending the run, as unknown: whether it is\n // set up is the thing it could not read.\n const message = errorMessage(err).split(\"\\n\", 1)[0] ?? \"\";\n domains.push({ name: domain, status: \"unknown\", reason: `manni ${COMMANDS[domain]} could not run: ${message}` });\n }\n }\n for (const [name, reason] of NOT_CHECKED) {\n domains.push(\n name === \"tracevals\" && family.conformance\n ? await tracevalsRow(cwd, opts)\n : { name, status: \"not-checked\", reason },\n );\n }\n return {\n version: pkg.version,\n config: family.file.source,\n collections: family.collections.map((c) => ({\n name: c.name,\n files: members.filter((label) => collectionsOf(family, cwd, label).includes(c.name)).length,\n })),\n domains,\n };\n}\n\nconst STATE_LABEL: Readonly<Record<DomainState, string>> = {\n \"in-play\": \"in play\",\n \"not-set-up\": \"not set up\",\n \"not-checked\": \"not checked\",\n unknown: \"unknown\",\n};\n\nexport function renderStatus(report: StatusReport, format: StatusFormat): string {\n if (format === \"json\") return JSON.stringify(report, null, 2);\n const head = [\n `manni ${report.version}`,\n `config ${report.config}`,\n ...report.collections.map((c) => `collection ${c.name} (${plural(c.files, \"file\")})`),\n ].join(\" \");\n // tracevals in play judges each turn, which is what its row says.\n const label = (d: DomainRow): string => (d.models !== undefined ? \"judges each turn\" : STATE_LABEL[d.status]);\n const width = Math.max(14, ...report.domains.map((d) => label(d).length + 3));\n const rows = report.domains.flatMap((d) => [\n `${d.name.padEnd(11)}${label(d).padEnd(width)}${d.reason}`,\n ...(d.host ?? []).map(\n (m) =>\n `${\"\".padEnd(11)}${\"model host\".padEnd(width)}${m.model} loaded, ${plural(m.sessions, \"session\")}, ` +\n `idle ${String(Math.floor(m.idleMs / 60_000))}m`,\n ),\n ]);\n return [head, \"\", ...rows].join(\"\\n\");\n}\n\n/**\n * The plugin skill the briefing points an agent at, as `<plugin>:<skill>`.\n * `test/plugin.test.ts` checks both halves against `plugin/manni`.\n */\nexport const FIX_SKILL = \"manni:fix\";\n\n/** The set-wide checks a stop runs when a collection document changed, as the briefing names them. */\nconst PAGE_WIDE: ReadonlyArray<readonly [Domain, string]> = [[\"term\", \"the glossary\"]];\n\n/** `a`, `a or b`, `a, b or c`: a list in prose, joined by `conjunction`. */\nfunction prose(items: readonly string[], conjunction: string): string {\n return items.length <= 1\n ? (items[0] ?? \"\")\n : `${items.slice(0, -1).join(\", \")} ${conjunction} ${items.at(-1) ?? \"\"}`;\n}\n\n/** What an agent is told at the start of a session, after the table. */\nexport function agentLines(report: StatusReport): string {\n const names = prose(report.collections.map((c) => c.name), \"or\");\n const inPlay = new Set(report.domains.filter((d) => d.status === \"in-play\").map((d) => d.name));\n // A stop checks every citation whenever the tree changed: a source edit can drift any of them.\n const plus = inPlay.has(\"cite\") ? \", plus every citation\" : \"\";\n const pageWide = PAGE_WIDE.filter(([domain]) => inPlay.has(domain)).map(([, what]) => what);\n const also = pageWide.length === 0 ? \"\" : ` It checks ${prose(pageWide, \"and\")} too when you changed a page.`;\n return [\n `After you edit a file in ${names}, manni check runs on it, and errors come back to you at once.`,\n `Before you finish, manni check runs on every file you changed${plus}.${also} You get one repair pass.`,\n `The ${FIX_SKILL} skill says how to repair each finding.`,\n ].join(\"\\n\");\n}\n\n/** A model id as Claude Code spells one, and nothing a shell would read as more. */\nconst MODEL_ID = /^[A-Za-z0-9._:/@-]+$/;\n\n/**\n * Append `export MANNI_GENERATED_BY=<model>` to `$CLAUDE_ENV_FILE`, so every\n * command the session runs records which model wrote what. Only when the\n * envelope names the model, the file is offered, and nobody set the variable.\n */\nexport function exportGeneratedBy(envelope: Envelope, env: NodeJS.ProcessEnv = process.env): boolean {\n const file = env.CLAUDE_ENV_FILE;\n // A context-window suffix such as `[1m]` is a session setting, not the model.\n const model = envelope.model?.replace(/\\[[^\\]]*\\]$/, \"\");\n if (model === undefined || !MODEL_ID.test(model)) return false;\n if (file === undefined || file === \"\" || env.MANNI_GENERATED_BY !== undefined) return false;\n const existing = existsSync(file) ? readFileSync(file, \"utf8\") : \"\";\n const lead = existing === \"\" || existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n appendFileSync(file, `${lead}export MANNI_GENERATED_BY=${model}\\n`, \"utf8\");\n return true;\n}\n"],"mappings":"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","names":["resolve","record","resolve","resolve","run","resolve","extname","resolve","extname","resolve","resolve","run"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tracevals/commands/prepare.ts"],"sourcesContent":["/**\n * `manni tracevals prepare`: fetch what judging needs and warm the rules\n * cache (proposal 0079). The SessionStart hook runs it in the background, and\n * a person or a CI runner can too.\n *\n * Under a hook envelope nothing goes to stdout, because a SessionStart hook's\n * stdout becomes model context. The report goes to stderr instead, as\n * `capture` does.\n */\nimport { resolve } from \"node:path\";\nimport type { InferenceProvider } from \"@hawkeyexl/inference\";\nimport { DEFAULT_KEEP_ALIVE_MS } from \"../../shared/providers.js\";\nimport { parseHookPayload, readStdin } from \"../capture/hook.js\";\nimport { discoverConfig } from \"../core/config.js\";\nimport { resolveSelectionIdentity, selectHookProvider } from \"../judge/provider.js\";\nimport { NOT_SET_UP, renderPrepare } from \"../reporters/conformance.js\";\nimport type { SummaryFormat } from \"../reporters/index.js\";\nimport { hostSetting, warmModel, type HostApi } from \"../rules/host.js\";\nimport { libraryLocalModels, type LocalModels } from \"../rules/local.js\";\nimport { resolveAlwaysSources } from \"../rules/sources.js\";\nimport { TracevalsError } from \"../types.js\";\nimport {\n extraction,\n firstLine,\n isNetworkProvider,\n rulesCacheFor,\n type Identity,\n} from \"./conformance.js\";\n\nexport interface PrepareModel {\n role: \"hook\" | \"extraction\";\n provider: string;\n model: string;\n state: \"downloaded\" | \"ready\" | \"loaded\" | \"hosted\";\n /** Size on disk; null for a hosted model. */\n bytes: number | null;\n}\n\nexport interface PrepareReport {\n models: PrepareModel[];\n /** Null when not set up, or under `--offline` with a hosted extraction model. */\n extraction: {\n provider: string;\n model: string;\n extracted: number;\n cached: number;\n rules: number;\n } | null;\n warnings: string[];\n exitCode: number;\n}\n\nexport interface PrepareOptions {\n /** The hook payload. Undefined reads stdin; \"\" means there was none. */\n stdin?: string;\n /** Project root; default the envelope's cwd, else the current directory. */\n project?: string;\n noCache?: boolean;\n /** Refuse network providers, so only local models are fetched. */\n offline?: boolean;\n format?: SummaryFormat;\n /** Directory holding manni.config.yaml; defaults to the project root. */\n configDir?: string;\n config?: string;\n noConfig?: boolean;\n env?: Record<string, string | undefined>;\n /** Test seams. */\n localModels?: LocalModels;\n extractor?: InferenceProvider;\n /** The model host's calls, in place of the library's. */\n hostApi?: HostApi;\n}\n\nexport interface PrepareResult {\n report: PrepareReport;\n rendered: string;\n /** Empty under a hook envelope. */\n stdout: string;\n /** The report, under a hook envelope. */\n stderr: string;\n exitCode: number;\n}\n\nexport async function runPrepare(options: PrepareOptions = {}): Promise<PrepareResult> {\n const raw = options.stdin ?? (await readStdin());\n const hookMode = raw.trim() !== \"\";\n const payload = hookMode ? parseHookPayload(raw) : {};\n const root = resolve(options.project ?? payload.cwd ?? process.cwd());\n const { config, dir: configDir } = await discoverConfig(options.configDir ?? root, {\n ...(options.config === undefined ? {} : { configPath: options.config }),\n ...(options.noConfig === undefined ? {} : { noConfig: options.noConfig }),\n });\n\n const finish = (report: PrepareReport, prose: string): PrepareResult => {\n const rendered = options.format === \"json\" ? JSON.stringify(report, null, 2) : prose;\n return {\n report,\n rendered,\n stdout: hookMode ? \"\" : rendered,\n stderr: hookMode ? rendered : \"\",\n exitCode: report.exitCode,\n };\n };\n\n const conformance = config.conformance;\n if (conformance === null) {\n return finish({ models: [], extraction: null, warnings: [NOT_SET_UP], exitCode: 0 }, NOT_SET_UP);\n }\n\n const local = options.localModels ?? libraryLocalModels(config.providers);\n const keepAlive = config.providers[\"llama-cpp\"]?.keepAlive;\n const ex = await extraction(\n config,\n rulesCacheFor(config, configDir, options.noCache === true),\n options.extractor,\n hostSetting(hookMode, payload.sessionId, keepAlive),\n );\n const roles: [PrepareModel[\"role\"], Identity][] = [\n [\"hook\", await resolveSelectionIdentity(config, selectHookProvider(config))],\n [\"extraction\", ex.identity],\n ];\n\n // Step 1: each local model on disk, fetched once however many roles use it.\n const ensured = new Map<string, ReturnType<LocalModels[\"ensure\"]>>();\n const models: PrepareModel[] = [];\n for (const [role, id] of roles) {\n if (id.provider !== \"llama-cpp\") {\n models.push({ role, provider: id.provider, model: id.model, state: \"hosted\", bytes: null });\n continue;\n }\n let fetching = ensured.get(id.model);\n if (fetching === undefined) {\n fetching = local.ensure(id.model);\n ensured.set(id.model, fetching);\n }\n let result: Awaited<typeof fetching>;\n try {\n result = await fetching;\n } catch (err) {\n throw new TracevalsError(`could not download ${id.model}: ${firstLine(err)}`);\n }\n const entry: PrepareModel = { role, provider: id.provider, model: id.model, state: result.state, bytes: result.bytes };\n // Step 2: under SessionStart, the session's lease and a warm model.\n if (\n role === \"hook\" &&\n payload.hookEvent === \"SessionStart\" &&\n payload.sessionId !== undefined &&\n (await warmModel(\n {\n sessionId: payload.sessionId,\n model: id.model,\n keepAliveMs: keepAlive ?? DEFAULT_KEEP_ALIVE_MS,\n ...(config.providers[\"llama-cpp\"]?.modelsDir !== undefined\n ? { modelsDirectory: config.providers[\"llama-cpp\"].modelsDir }\n : {}),\n },\n options.hostApi,\n ))\n ) {\n entry.state = \"loaded\";\n }\n models.push(entry);\n }\n\n // Step 3: the rules of every source that applies to every session.\n const report: PrepareReport = { models, extraction: null, warnings: [], exitCode: 0 };\n if (options.offline !== true || !isNetworkProvider(ex.identity.provider)) {\n const resolved = await resolveAlwaysSources({\n projectDir: root,\n ...(options.project !== undefined ? { projectRoot: root } : {}),\n ...(options.env !== undefined ? { env: options.env } : {}),\n include: conformance.include,\n exclude: conformance.exclude,\n });\n report.warnings.push(...resolved.warnings);\n const summary = { provider: ex.identity.provider, model: ex.identity.model, extracted: 0, cached: 0, rules: 0 };\n for (const source of resolved.sources) {\n if (source.declaredRules !== undefined) continue;\n if (!ex.needs(source)) {\n summary.cached += 1;\n continue;\n }\n const { rules } = await ex.rulesOf(source);\n summary.extracted += 1;\n summary.rules += rules.length;\n }\n report.extraction = summary;\n }\n return finish(report, renderPrepare(report));\n}\n"],"mappings":"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","names":["report"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tracevals/commands/release.ts"],"sourcesContent":["/**\n * `manni tracevals release`: return a session's lease on the model host\n * (proposal 0079). The SessionEnd hook runs it with the envelope on stdin, and\n * then nothing goes to stdout. A person runs it with `--all` to free the\n * memory now.\n */\nimport { parseHookPayload, readStdin } from \"../capture/hook.js\";\nimport { renderRelease } from \"../reporters/conformance.js\";\nimport type { SummaryFormat } from \"../reporters/index.js\";\nimport { releaseHost, type HostApi, type ReleaseResult } from \"../rules/host.js\";\nimport { TracevalsError } from \"../types.js\";\n\nexport interface ReleaseReport extends ReleaseResult {\n exitCode: number;\n}\n\nexport interface ReleaseOptions {\n /** The hook payload. Undefined reads stdin; \"\" means there was none. */\n stdin?: string;\n /** Drop every lease, unload every model and stop the host. */\n all?: boolean;\n format?: SummaryFormat;\n /** The model host's calls, in place of the library's. */\n hostApi?: HostApi;\n}\n\nexport interface ReleaseCommandResult {\n report: ReleaseReport;\n rendered: string;\n /** Empty under a hook envelope. */\n stdout: string;\n exitCode: number;\n}\n\nexport async function runRelease(options: ReleaseOptions = {}): Promise<ReleaseCommandResult> {\n const raw = options.stdin ?? (await readStdin());\n const hookMode = raw.trim() !== \"\";\n const sessionId = hookMode ? parseHookPayload(raw).sessionId : undefined;\n let result: ReleaseResult;\n if (options.all === true) result = await releaseHost({ all: true }, options.hostApi);\n else if (sessionId !== undefined) result = await releaseHost({ sessionId }, options.hostApi);\n else throw new TracevalsError(\"release needs a session from a SessionEnd hook, or --all\");\n const report: ReleaseReport = { ...result, exitCode: 0 };\n const rendered =\n options.format === \"json\" ? JSON.stringify(report, null, 2) : renderRelease(report);\n return { report, rendered, stdout: hookMode ? \"\" : rendered, exitCode: 0 };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkCA,eAAsB,WAAW,UAA0B,CAAC,GAAkC;AAC5F,QAAM,MAAM,QAAQ,SAAU,MAAM,UAAU;AAC9C,QAAM,WAAW,IAAI,KAAK,MAAM;AAChC,QAAM,YAAY,WAAW,iBAAiB,GAAG,EAAE,YAAY;AAC/D,MAAI;AACJ,MAAI,QAAQ,QAAQ,KAAM,UAAS,MAAM,YAAY,EAAE,KAAK,KAAK,GAAG,QAAQ,OAAO;AAAA,WAC1E,cAAc,OAAW,UAAS,MAAM,YAAY,EAAE,UAAU,GAAG,QAAQ,OAAO;AAAA,MACtF,OAAM,IAAI,eAAe,0DAA0D;AACxF,QAAM,SAAwB,EAAE,GAAG,QAAQ,UAAU,EAAE;AACvD,QAAM,WACJ,QAAQ,WAAW,SAAS,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,cAAc,MAAM;AACpF,SAAO,EAAE,QAAQ,UAAU,QAAQ,WAAW,KAAK,UAAU,UAAU,EAAE;AAC3E;","names":[]}