@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.
- package/README.md +1 -1
- package/dist/{batch-U6S2JUUN.js → batch-QMHYWGUA.js} +12 -12
- package/dist/{build-4RN6WBCP.js → build-ZGA3O3P4.js} +9 -9
- package/dist/{calibrate-6VIZYR4L.js → calibrate-KBMFGKP3.js} +13 -13
- package/dist/{capture-DP3NXAZE.js → capture-C46UXFRK.js} +12 -12
- package/dist/{check-IWHUPAZM.js → check-CORYIW76.js} +28 -28
- package/dist/check-CORYIW76.js.map +1 -0
- package/dist/{check-STHXZIZO.js → check-LLQ6PJV3.js} +9 -9
- package/dist/{check-ERVNGKLC.js → check-UMI5ACCE.js} +10 -10
- package/dist/{chunk-IOL74S4J.js → chunk-3FG2UU3H.js} +4 -4
- package/dist/{chunk-K52CS4KT.js → chunk-4VQBHTGA.js} +5 -5
- package/dist/{chunk-MIBWI5H7.js → chunk-5LAKRYXU.js} +3 -3
- package/dist/{chunk-MSMB6XOS.js → chunk-6HMLYFEU.js} +2 -2
- package/dist/{chunk-4Z2MN5FR.js → chunk-6MNOMHFI.js} +10 -10
- package/dist/{chunk-UZKQSWHJ.js → chunk-6QBJHRFC.js} +2 -2
- package/dist/{chunk-B5CMM57M.js → chunk-6ZR24A4S.js} +2 -2
- package/dist/{chunk-WTEILBKC.js → chunk-77L5GNVO.js} +2 -2
- package/dist/{chunk-D6RO54QD.js → chunk-7LC4YJJ3.js} +4 -4
- package/dist/chunk-7LC4YJJ3.js.map +1 -0
- package/dist/{chunk-6URSCTTX.js → chunk-AO66Q66S.js} +2 -2
- package/dist/{chunk-NIFEEIGQ.js → chunk-BYVH727K.js} +2 -2
- package/dist/{chunk-PNX43DYW.js → chunk-C2JPBQCJ.js} +21 -3
- package/dist/{chunk-PNX43DYW.js.map → chunk-C2JPBQCJ.js.map} +1 -1
- package/dist/{chunk-GCC52YZD.js → chunk-F734HIHT.js} +3 -3
- package/dist/{chunk-CEVU3GFF.js → chunk-FEALEYSE.js} +4 -4
- package/dist/{chunk-QQNPVW3J.js → chunk-GQBVZS5G.js} +6 -6
- package/dist/{chunk-D2LBN44V.js → chunk-HNMXL2OE.js} +3 -3
- package/dist/chunk-HNMXL2OE.js.map +1 -0
- package/dist/{chunk-NZ6TNSCU.js → chunk-HWNSIEZK.js} +5 -5
- package/dist/{chunk-LDKIIZDW.js → chunk-K43X5VDR.js} +5 -5
- package/dist/{chunk-TPVOOTMN.js → chunk-KPXOJMQ6.js} +16 -13
- package/dist/chunk-KPXOJMQ6.js.map +1 -0
- package/dist/{chunk-ZPP75QWG.js → chunk-LAU6SVTJ.js} +8 -8
- package/dist/{chunk-ZNE25EAR.js → chunk-LF6FOF6U.js} +4 -4
- package/dist/{chunk-YSCZL4U5.js → chunk-N7J5C35C.js} +2 -2
- package/dist/{chunk-YSCZL4U5.js.map → chunk-N7J5C35C.js.map} +1 -1
- package/dist/{chunk-6VDBP5UV.js → chunk-NB4ILZMQ.js} +6 -6
- package/dist/{chunk-BWCWTHYS.js → chunk-NGTVREIH.js} +4 -4
- package/dist/chunk-NGTVREIH.js.map +1 -0
- package/dist/{chunk-AMEILOVV.js → chunk-NNFSIRVE.js} +4 -4
- package/dist/{chunk-LXJEAV2V.js → chunk-PO5W6JAP.js} +5 -5
- package/dist/{chunk-OOEMKOX6.js → chunk-POGYWOJ2.js} +3 -3
- package/dist/{chunk-LONRQBGV.js → chunk-Q3GFZJTY.js} +4 -4
- package/dist/{chunk-ZKAKA54B.js → chunk-RCS5YFY2.js} +2 -2
- package/dist/{chunk-C2TJG5KV.js → chunk-SV6UEQCU.js} +4 -4
- package/dist/{chunk-2ZWTSRE5.js → chunk-SXODK43S.js} +4 -4
- package/dist/{chunk-7XZ6INKO.js → chunk-UWY4B2PM.js} +4 -4
- package/dist/{chunk-PAOVVHQX.js → chunk-VD3EQSBI.js} +2 -2
- package/dist/{chunk-CI55ABCK.js → chunk-VQK4VHLF.js} +8 -8
- package/dist/chunk-VQK4VHLF.js.map +1 -0
- package/dist/{chunk-IZBBXKMJ.js → chunk-VSOYZ7QH.js} +3 -3
- package/dist/{chunk-CR3HZERW.js → chunk-WBETAXO2.js} +4 -4
- package/dist/{chunk-5UB47BEV.js → chunk-WT6HMEEF.js} +2 -2
- package/dist/{chunk-IIFADWWI.js → chunk-WUFP4V7B.js} +3 -3
- package/dist/{chunk-7EL5LLKD.js → chunk-WUXD6VBD.js} +2 -2
- package/dist/{chunk-ZKCNPKUO.js → chunk-XDS3KQCK.js} +3 -3
- package/dist/{chunk-5VWDIWOH.js → chunk-YVVMC4SZ.js} +3 -3
- package/dist/{chunk-ZEXGGGLW.js → chunk-Z27GYQOY.js} +7 -7
- package/dist/{chunk-QP5X66TO.js → chunk-ZIGIJBXG.js} +9 -9
- package/dist/{cli-37SRAYNE.js → cli-4B5RWL7P.js} +11 -11
- package/dist/{cli-IRHPPUFJ.js → cli-5AML7QR2.js} +10 -10
- package/dist/{cli-NM6FZ54R.js → cli-I4GBPLRM.js} +2 -2
- package/dist/{cli-YL3IDR52.js → cli-MNNOXWYU.js} +7 -7
- package/dist/{cli-XIODOEUG.js → cli-QR3ZQZA4.js} +20 -20
- package/dist/{cli-MTDGQIIV.js → cli-SBJY2NQH.js} +14 -14
- package/dist/{cli-ZQUJYQBA.js → cli-UB5W75GJ.js} +11 -11
- package/dist/{cli-KIID535Y.js → cli-WWDARAWS.js} +13 -13
- package/dist/{cli-HXWYUKGJ.js → cli-XIQKPNA7.js} +35 -34
- package/dist/cli-XIQKPNA7.js.map +1 -0
- package/dist/cli.js +11 -11
- package/dist/{config-O6UBGEDK.js → config-YWSNBFEE.js} +3 -3
- package/dist/docmeta.js +6 -6
- package/dist/{github-UCYLM3DR.js → github-TIZ3ZR3D.js} +9 -9
- package/dist/{github-VEJFO6JJ.js → github-WKOJRW7P.js} +11 -11
- package/dist/index.d.ts +16 -6
- package/dist/index.js +32 -32
- package/dist/{json-6F52FSXZ.js → json-4FUOZ3XX.js} +9 -9
- package/dist/{lint-X2GNINK6.js → lint-7VQFESHK.js} +9 -9
- package/dist/{list-DP3O3CWB.js → list-7U2MBDIM.js} +9 -9
- package/dist/{list-P77RZFZF.js → list-W6EUAOBV.js} +9 -9
- package/dist/{page-WQCMBNRD.js → page-WZLBKSCD.js} +8 -8
- package/dist/{prepare-52QOK7M4.js → prepare-FPEWAHJH.js} +17 -17
- package/dist/prepare-FPEWAHJH.js.map +1 -0
- package/dist/{pretty-H4DQREMW.js → pretty-7M4X4TCY.js} +9 -9
- package/dist/{pretty-5MMMNSWF.js → pretty-CUCMQU5R.js} +10 -10
- package/dist/{provider-AMGRDY6V.js → provider-527CO4DM.js} +2 -2
- package/dist/{release-CTYRHZL4.js → release-3D5PK6M7.js} +2 -2
- package/dist/release-3D5PK6M7.js.map +1 -0
- package/dist/{reporters-SU3VUKKX.js → reporters-DQVSDXV6.js} +4 -4
- package/dist/{reporters-WIHBEMPG.js → reporters-KYJE54JS.js} +8 -8
- package/dist/{run-L2DWJ26K.js → run-ABGXGOGQ.js} +9 -9
- package/dist/{conformance-ALLPNGEQ.js → runtime-7QE3DW6S.js} +2 -2
- package/dist/{term-PJIJQZNF.js → term-HTIG3YDC.js} +13 -13
- package/dist/{validate-XCDSPURG.js → validate-HWNU3MDY.js} +4 -4
- package/package.json +1 -1
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/dist/check-IWHUPAZM.js.map +0 -1
- package/dist/chunk-BWCWTHYS.js.map +0 -1
- package/dist/chunk-CI55ABCK.js.map +0 -1
- package/dist/chunk-D2LBN44V.js.map +0 -1
- package/dist/chunk-D6RO54QD.js.map +0 -1
- package/dist/chunk-TPVOOTMN.js.map +0 -1
- package/dist/cli-HXWYUKGJ.js.map +0 -1
- package/dist/prepare-52QOK7M4.js.map +0 -1
- package/dist/release-CTYRHZL4.js.map +0 -1
- /package/dist/{batch-U6S2JUUN.js.map → batch-QMHYWGUA.js.map} +0 -0
- /package/dist/{build-4RN6WBCP.js.map → build-ZGA3O3P4.js.map} +0 -0
- /package/dist/{calibrate-6VIZYR4L.js.map → calibrate-KBMFGKP3.js.map} +0 -0
- /package/dist/{capture-DP3NXAZE.js.map → capture-C46UXFRK.js.map} +0 -0
- /package/dist/{check-ERVNGKLC.js.map → check-LLQ6PJV3.js.map} +0 -0
- /package/dist/{check-STHXZIZO.js.map → check-UMI5ACCE.js.map} +0 -0
- /package/dist/{chunk-IOL74S4J.js.map → chunk-3FG2UU3H.js.map} +0 -0
- /package/dist/{chunk-K52CS4KT.js.map → chunk-4VQBHTGA.js.map} +0 -0
- /package/dist/{chunk-MIBWI5H7.js.map → chunk-5LAKRYXU.js.map} +0 -0
- /package/dist/{chunk-MSMB6XOS.js.map → chunk-6HMLYFEU.js.map} +0 -0
- /package/dist/{chunk-4Z2MN5FR.js.map → chunk-6MNOMHFI.js.map} +0 -0
- /package/dist/{chunk-UZKQSWHJ.js.map → chunk-6QBJHRFC.js.map} +0 -0
- /package/dist/{chunk-B5CMM57M.js.map → chunk-6ZR24A4S.js.map} +0 -0
- /package/dist/{chunk-WTEILBKC.js.map → chunk-77L5GNVO.js.map} +0 -0
- /package/dist/{chunk-6URSCTTX.js.map → chunk-AO66Q66S.js.map} +0 -0
- /package/dist/{chunk-NIFEEIGQ.js.map → chunk-BYVH727K.js.map} +0 -0
- /package/dist/{chunk-GCC52YZD.js.map → chunk-F734HIHT.js.map} +0 -0
- /package/dist/{chunk-CEVU3GFF.js.map → chunk-FEALEYSE.js.map} +0 -0
- /package/dist/{chunk-QQNPVW3J.js.map → chunk-GQBVZS5G.js.map} +0 -0
- /package/dist/{chunk-NZ6TNSCU.js.map → chunk-HWNSIEZK.js.map} +0 -0
- /package/dist/{chunk-LDKIIZDW.js.map → chunk-K43X5VDR.js.map} +0 -0
- /package/dist/{chunk-ZPP75QWG.js.map → chunk-LAU6SVTJ.js.map} +0 -0
- /package/dist/{chunk-ZNE25EAR.js.map → chunk-LF6FOF6U.js.map} +0 -0
- /package/dist/{chunk-6VDBP5UV.js.map → chunk-NB4ILZMQ.js.map} +0 -0
- /package/dist/{chunk-AMEILOVV.js.map → chunk-NNFSIRVE.js.map} +0 -0
- /package/dist/{chunk-LXJEAV2V.js.map → chunk-PO5W6JAP.js.map} +0 -0
- /package/dist/{chunk-OOEMKOX6.js.map → chunk-POGYWOJ2.js.map} +0 -0
- /package/dist/{chunk-LONRQBGV.js.map → chunk-Q3GFZJTY.js.map} +0 -0
- /package/dist/{chunk-ZKAKA54B.js.map → chunk-RCS5YFY2.js.map} +0 -0
- /package/dist/{chunk-C2TJG5KV.js.map → chunk-SV6UEQCU.js.map} +0 -0
- /package/dist/{chunk-2ZWTSRE5.js.map → chunk-SXODK43S.js.map} +0 -0
- /package/dist/{chunk-7XZ6INKO.js.map → chunk-UWY4B2PM.js.map} +0 -0
- /package/dist/{chunk-PAOVVHQX.js.map → chunk-VD3EQSBI.js.map} +0 -0
- /package/dist/{chunk-IZBBXKMJ.js.map → chunk-VSOYZ7QH.js.map} +0 -0
- /package/dist/{chunk-CR3HZERW.js.map → chunk-WBETAXO2.js.map} +0 -0
- /package/dist/{chunk-5UB47BEV.js.map → chunk-WT6HMEEF.js.map} +0 -0
- /package/dist/{chunk-IIFADWWI.js.map → chunk-WUFP4V7B.js.map} +0 -0
- /package/dist/{chunk-7EL5LLKD.js.map → chunk-WUXD6VBD.js.map} +0 -0
- /package/dist/{chunk-ZKCNPKUO.js.map → chunk-XDS3KQCK.js.map} +0 -0
- /package/dist/{chunk-5VWDIWOH.js.map → chunk-YVVMC4SZ.js.map} +0 -0
- /package/dist/{chunk-ZEXGGGLW.js.map → chunk-Z27GYQOY.js.map} +0 -0
- /package/dist/{chunk-QP5X66TO.js.map → chunk-ZIGIJBXG.js.map} +0 -0
- /package/dist/{cli-37SRAYNE.js.map → cli-4B5RWL7P.js.map} +0 -0
- /package/dist/{cli-IRHPPUFJ.js.map → cli-5AML7QR2.js.map} +0 -0
- /package/dist/{cli-NM6FZ54R.js.map → cli-I4GBPLRM.js.map} +0 -0
- /package/dist/{cli-YL3IDR52.js.map → cli-MNNOXWYU.js.map} +0 -0
- /package/dist/{cli-XIODOEUG.js.map → cli-QR3ZQZA4.js.map} +0 -0
- /package/dist/{cli-MTDGQIIV.js.map → cli-SBJY2NQH.js.map} +0 -0
- /package/dist/{cli-ZQUJYQBA.js.map → cli-UB5W75GJ.js.map} +0 -0
- /package/dist/{cli-KIID535Y.js.map → cli-WWDARAWS.js.map} +0 -0
- /package/dist/{config-O6UBGEDK.js.map → config-YWSNBFEE.js.map} +0 -0
- /package/dist/{conformance-ALLPNGEQ.js.map → github-TIZ3ZR3D.js.map} +0 -0
- /package/dist/{github-UCYLM3DR.js.map → github-WKOJRW7P.js.map} +0 -0
- /package/dist/{github-VEJFO6JJ.js.map → json-4FUOZ3XX.js.map} +0 -0
- /package/dist/{json-6F52FSXZ.js.map → lint-7VQFESHK.js.map} +0 -0
- /package/dist/{lint-X2GNINK6.js.map → list-7U2MBDIM.js.map} +0 -0
- /package/dist/{list-DP3O3CWB.js.map → list-W6EUAOBV.js.map} +0 -0
- /package/dist/{list-P77RZFZF.js.map → page-WZLBKSCD.js.map} +0 -0
- /package/dist/{page-WQCMBNRD.js.map → pretty-7M4X4TCY.js.map} +0 -0
- /package/dist/{pretty-5MMMNSWF.js.map → pretty-CUCMQU5R.js.map} +0 -0
- /package/dist/{pretty-H4DQREMW.js.map → provider-527CO4DM.js.map} +0 -0
- /package/dist/{provider-AMGRDY6V.js.map → reporters-DQVSDXV6.js.map} +0 -0
- /package/dist/{reporters-SU3VUKKX.js.map → reporters-KYJE54JS.js.map} +0 -0
- /package/dist/{reporters-WIHBEMPG.js.map → run-ABGXGOGQ.js.map} +0 -0
- /package/dist/{run-L2DWJ26K.js.map → runtime-7QE3DW6S.js.map} +0 -0
- /package/dist/{term-PJIJQZNF.js.map → term-HTIG3YDC.js.map} +0 -0
- /package/dist/{validate-XCDSPURG.js.map → validate-HWNU3MDY.js.map} +0 -0
|
@@ -26,8 +26,8 @@ import {
|
|
|
26
26
|
renderSarif,
|
|
27
27
|
ruleIdFor,
|
|
28
28
|
xmlEscape
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-
|
|
29
|
+
} from "./chunk-YVVMC4SZ.js";
|
|
30
|
+
import "./chunk-6HMLYFEU.js";
|
|
31
31
|
import "./chunk-RNVYGWIC.js";
|
|
32
32
|
import {
|
|
33
33
|
escapeWorkflowCommandMessage,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
import "./chunk-XKBEHKWO.js";
|
|
37
37
|
import "./chunk-HX44GB4Z.js";
|
|
38
38
|
import "./chunk-QCHVR4ZM.js";
|
|
39
|
-
import "./chunk-
|
|
39
|
+
import "./chunk-N7J5C35C.js";
|
|
40
40
|
import "./chunk-OWBRDNRZ.js";
|
|
41
41
|
import "./chunk-G3T47CFV.js";
|
|
42
42
|
import "./chunk-2H7UOFLK.js";
|
|
@@ -70,4 +70,4 @@ export {
|
|
|
70
70
|
ruleIdFor,
|
|
71
71
|
xmlEscape
|
|
72
72
|
};
|
|
73
|
-
//# sourceMappingURL=reporters-
|
|
73
|
+
//# sourceMappingURL=reporters-DQVSDXV6.js.map
|
|
@@ -9,22 +9,22 @@ import {
|
|
|
9
9
|
renderTemplates,
|
|
10
10
|
renderTools,
|
|
11
11
|
toValidationResults
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-UWY4B2PM.js";
|
|
13
13
|
import "./chunk-GLP5PSXB.js";
|
|
14
14
|
import "./chunk-TBAMBLF3.js";
|
|
15
15
|
import "./chunk-YGFIQ6Y5.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-XDS3KQCK.js";
|
|
17
|
+
import "./chunk-WBETAXO2.js";
|
|
18
|
+
import "./chunk-WT6HMEEF.js";
|
|
19
|
+
import "./chunk-YVVMC4SZ.js";
|
|
20
|
+
import "./chunk-6HMLYFEU.js";
|
|
21
21
|
import "./chunk-YEUYKR62.js";
|
|
22
22
|
import "./chunk-RNVYGWIC.js";
|
|
23
23
|
import "./chunk-MNH7QO4Z.js";
|
|
24
24
|
import "./chunk-XKBEHKWO.js";
|
|
25
25
|
import "./chunk-HX44GB4Z.js";
|
|
26
26
|
import "./chunk-QCHVR4ZM.js";
|
|
27
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-N7J5C35C.js";
|
|
28
28
|
import "./chunk-OWBRDNRZ.js";
|
|
29
29
|
import "./chunk-G3T47CFV.js";
|
|
30
30
|
import "./chunk-2H7UOFLK.js";
|
|
@@ -39,4 +39,4 @@ export {
|
|
|
39
39
|
renderTools,
|
|
40
40
|
toValidationResults
|
|
41
41
|
};
|
|
42
|
-
//# sourceMappingURL=reporters-
|
|
42
|
+
//# sourceMappingURL=reporters-KYJE54JS.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runRun
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-4VQBHTGA.js";
|
|
5
|
+
import "./chunk-K43X5VDR.js";
|
|
6
6
|
import "./chunk-XG6PVB5S.js";
|
|
7
7
|
import "./chunk-YNHZHSSM.js";
|
|
8
8
|
import {
|
|
@@ -10,18 +10,18 @@ import {
|
|
|
10
10
|
} from "./chunk-NCPWXHDO.js";
|
|
11
11
|
import "./chunk-ZXRAE55H.js";
|
|
12
12
|
import "./chunk-SE4JN5XN.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-XDS3KQCK.js";
|
|
14
|
+
import "./chunk-WBETAXO2.js";
|
|
15
|
+
import "./chunk-WT6HMEEF.js";
|
|
16
|
+
import "./chunk-YVVMC4SZ.js";
|
|
17
|
+
import "./chunk-6HMLYFEU.js";
|
|
18
18
|
import "./chunk-YEUYKR62.js";
|
|
19
19
|
import "./chunk-RNVYGWIC.js";
|
|
20
20
|
import "./chunk-MNH7QO4Z.js";
|
|
21
21
|
import "./chunk-XKBEHKWO.js";
|
|
22
22
|
import "./chunk-HX44GB4Z.js";
|
|
23
23
|
import "./chunk-QCHVR4ZM.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-N7J5C35C.js";
|
|
25
25
|
import "./chunk-OWBRDNRZ.js";
|
|
26
26
|
import "./chunk-G3T47CFV.js";
|
|
27
27
|
import "./chunk-2H7UOFLK.js";
|
|
@@ -29,4 +29,4 @@ export {
|
|
|
29
29
|
render,
|
|
30
30
|
runRun
|
|
31
31
|
};
|
|
32
|
-
//# sourceMappingURL=run-
|
|
32
|
+
//# sourceMappingURL=run-ABGXGOGQ.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
renderCheck,
|
|
6
6
|
renderPrepare,
|
|
7
7
|
renderRelease
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HNMXL2OE.js";
|
|
9
9
|
import "./chunk-RNVYGWIC.js";
|
|
10
10
|
import "./chunk-2H7UOFLK.js";
|
|
11
11
|
export {
|
|
@@ -15,4 +15,4 @@ export {
|
|
|
15
15
|
renderPrepare,
|
|
16
16
|
renderRelease
|
|
17
17
|
};
|
|
18
|
-
//# sourceMappingURL=
|
|
18
|
+
//# sourceMappingURL=runtime-7QE3DW6S.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
renderFormatsJson,
|
|
5
5
|
renderGetJson,
|
|
6
6
|
renderListJson
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VD3EQSBI.js";
|
|
8
8
|
import {
|
|
9
9
|
renderFindingsPretty,
|
|
10
10
|
renderFormatsPretty,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
renderListPretty,
|
|
13
13
|
renderValeWiring,
|
|
14
14
|
renderWritePretty
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-6QBJHRFC.js";
|
|
16
16
|
import {
|
|
17
17
|
FINDING_FORMATS,
|
|
18
18
|
JUNIT_CLASSNAME,
|
|
@@ -24,14 +24,14 @@ import {
|
|
|
24
24
|
runCheck,
|
|
25
25
|
summarize,
|
|
26
26
|
toResults
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-Q3GFZJTY.js";
|
|
28
28
|
import {
|
|
29
29
|
LIST_FORMATS,
|
|
30
30
|
runList
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-6ZR24A4S.js";
|
|
32
32
|
import {
|
|
33
33
|
renderFindingsGithub
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-BYVH727K.js";
|
|
35
35
|
import {
|
|
36
36
|
DITA_HOLDS,
|
|
37
37
|
DOCBOOK_HOLDS,
|
|
@@ -62,28 +62,28 @@ import {
|
|
|
62
62
|
valeConfigFor,
|
|
63
63
|
xmlAttribute,
|
|
64
64
|
xmlText
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-WUFP4V7B.js";
|
|
66
66
|
import "./chunk-77AINBYM.js";
|
|
67
67
|
import "./chunk-IKEWBMCN.js";
|
|
68
|
-
import "./chunk-
|
|
68
|
+
import "./chunk-XDS3KQCK.js";
|
|
69
69
|
import {
|
|
70
70
|
registerTermLabelSource
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-WBETAXO2.js";
|
|
72
72
|
import {
|
|
73
73
|
collect,
|
|
74
74
|
readStdin,
|
|
75
75
|
splitList
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-WT6HMEEF.js";
|
|
77
77
|
import {
|
|
78
78
|
OMITTED_WHEN_CLEAN,
|
|
79
79
|
renderJunit,
|
|
80
80
|
renderSarif
|
|
81
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-YVVMC4SZ.js";
|
|
82
82
|
import {
|
|
83
83
|
STDIN_TOKEN,
|
|
84
84
|
extractorByName,
|
|
85
85
|
extractorForExtension
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-6HMLYFEU.js";
|
|
87
87
|
import {
|
|
88
88
|
fail
|
|
89
89
|
} from "./chunk-YEUYKR62.js";
|
|
@@ -98,7 +98,7 @@ import {
|
|
|
98
98
|
import "./chunk-QCHVR4ZM.js";
|
|
99
99
|
import {
|
|
100
100
|
package_default
|
|
101
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-N7J5C35C.js";
|
|
102
102
|
import "./chunk-OWBRDNRZ.js";
|
|
103
103
|
import {
|
|
104
104
|
errorMessage
|
|
@@ -1588,4 +1588,4 @@ export {
|
|
|
1588
1588
|
TermError,
|
|
1589
1589
|
buildProgram
|
|
1590
1590
|
};
|
|
1591
|
-
//# sourceMappingURL=term-
|
|
1591
|
+
//# sourceMappingURL=term-HTIG3YDC.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runValidate
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-WT6HMEEF.js";
|
|
5
|
+
import "./chunk-6HMLYFEU.js";
|
|
6
6
|
import "./chunk-YEUYKR62.js";
|
|
7
7
|
import "./chunk-XKBEHKWO.js";
|
|
8
8
|
import "./chunk-HX44GB4Z.js";
|
|
9
9
|
import "./chunk-QCHVR4ZM.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-N7J5C35C.js";
|
|
11
11
|
import "./chunk-OWBRDNRZ.js";
|
|
12
12
|
import "./chunk-G3T47CFV.js";
|
|
13
13
|
import "./chunk-2H7UOFLK.js";
|
|
14
14
|
export {
|
|
15
15
|
runValidate
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=validate-
|
|
17
|
+
//# sourceMappingURL=validate-HWNU3MDY.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hawkeyexl/manni",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.1",
|
|
4
4
|
"description": "One command line for documentation that is meant to be checked. `manni meta` validates the presence and format of document metadata (Markdown frontmatter and more) against JSON Schema, built for CI. Formerly docmeta.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "manni",
|
|
3
3
|
"description": "Checks the docs an agent edits against everything the repository set up in manni, blocks on errors, and records the session manifest tracevals reads.",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.8.1",
|
|
5
5
|
"author": { "name": "hawkeyexl" },
|
|
6
6
|
"homepage": "https://hawkeyexl.github.io/manni/",
|
|
7
7
|
"repository": "https://github.com/hawkeyexl/manni",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracevals/commands/check.ts","../src/tracevals/rules/judge.ts","../src/tracevals/rules/judge-prompt.ts","../src/tracevals/rules/timeline.ts"],"sourcesContent":["/**\n * `manni tracevals check <trace>`: judge the last turn of one session against\n * the rules that governed it (proposal 0079). `checkTurn` is the same\n * judgement inside a Stop or SubagentStop hook, with the hook's model and\n * every gate of \"When tracevals stays out of the way\".\n *\n * Both are read-only over the trace and the sources. What they write is the\n * rules cache and the verdict cache, under `judge.cacheDir`. The hook also\n * writes the session ledger, for every turn it parses, which `check` by hand\n * only reads and sums up.\n */\nimport { writeFile } from \"node:fs/promises\";\nimport { basename, resolve } from \"node:path\";\nimport type { InferenceProvider, ProviderName } from \"@hawkeyexl/inference\";\nimport { discoverConfig, type TracevalsConfig } from \"../core/config.js\";\nimport {\n constructProvider,\n resolveSelectionIdentity,\n selectHookProvider,\n selectProvider,\n type ProviderSelection,\n} from \"../judge/provider.js\";\nimport { renderCheck } from \"../reporters/conformance.js\";\nimport type { SummaryFormat } from \"../reporters/index.js\";\nimport { hostHolds, hostSetting, queued, QUEUE_WAIT_MS, type HostApi } from \"../rules/host.js\";\nimport {\n allVerdictsCached,\n applicableRules,\n judgeTurn,\n StateLimits,\n TurnCache,\n type TurnFinding,\n type TurnJudgement,\n type TurnRule,\n} from \"../rules/judge.js\";\nimport { ruleKey } from \"../rules/judge-prompt.js\";\nimport {\n ledgerPath,\n readLedger,\n recordFacts,\n recordTurn,\n rollup,\n turnFacts,\n writeLedger,\n type Ledger,\n type LedgerOutcome,\n type SessionRollup,\n} from \"../rules/ledger.js\";\nimport { warn } from \"../../shared/warn.js\";\nimport { libraryLocalModels, type LocalModels } from \"../rules/local.js\";\nimport { mockTurnJudge } from \"../rules/mock.js\";\nimport { resolveTurnSources, type RuleSource } from \"../rules/sources.js\";\nimport { lastTurn, subagentTurn, type TurnSlice } from \"../rules/turn.js\";\nimport { parseTraceFile } from \"../trace/claude.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport { TracevalsError } from \"../types.js\";\nimport {\n assertDownloaded,\n conformanceOf,\n extraction,\n firstLine,\n isNetworkProvider,\n JUDGE_ENV,\n localGate,\n markJudgeProcess,\n offlineRefusal,\n rulesCacheFor,\n type GateSkip,\n type Identity,\n type LocalGate,\n} from \"./conformance.js\";\n\n/** Why a judgement stopped short, as the report's `skipped` names it. */\nexport type CheckSkip = \"empty-turn\" | \"no-sources\" | \"not-applicable\";\n\n/** Every gate a hook can stop at, in the proposal's order. */\nexport type HookGate =\n | \"not-in-play\"\n | \"judge-session\"\n | CheckSkip\n | LocalGate\n | \"busy\";\n\nexport interface CheckSourceEntry {\n path: string;\n format: RuleSource[\"format\"];\n skill?: string;\n trigger: string;\n rules: number;\n origin: \"declared\" | \"extracted\";\n}\n\nexport interface CheckReport {\n trace: string;\n sessionId: string;\n /** The subagent a SubagentStop judged, or null for the main session. */\n agentId: string | null;\n turn: { from: number; to: number };\n /** Null when the run stopped before a judge was asked. */\n judge: { provider: string; model: string; mode: TurnJudgement[\"mode\"]; runs: number } | null;\n /** Null when no source needed the extraction model. */\n extraction: { provider: string; model: string } | null;\n sources: CheckSourceEntry[];\n /** Only `fail` and `needs-review`. */\n findings: TurnFinding[];\n /** `fail` counts `error` breaks; `reported` counts `warning` ones, which never fail a turn. */\n summary: {\n sources: number;\n rules: number;\n notApplicable: number;\n fail: number;\n needsReview: number;\n reported: number;\n };\n /** By hand, the session ledger summed up per rule. Null when it holds nothing, and under a hook. */\n session: SessionRollup | null;\n skipped: CheckSkip | null;\n warnings: string[];\n exitCode: number;\n}\n\n/** Test seams; production builds every one of these from config. */\ninterface Seams {\n /** The judge, in place of the selected provider. */\n judge?: InferenceProvider;\n /** The extraction model, in place of the out-of-loop provider. */\n extractor?: InferenceProvider;\n localModels?: LocalModels;\n /** The model host's calls, in place of the library's. */\n hostApi?: HostApi;\n}\n\ninterface Params extends Seams {\n config: TracevalsConfig;\n configDir: string;\n trace: Trace;\n turn: TurnSlice;\n sessionId: string;\n agentId: string | null;\n agentType?: string;\n projectDir: string;\n projectRoot?: string;\n env?: Record<string, string | undefined>;\n judgeSelection: ProviderSelection;\n runs: number;\n inLoop: boolean;\n noCache: boolean;\n offline: boolean;\n lastAssistantMessage?: string;\n}\n\ntype Outcome =\n | { kind: \"report\"; report: CheckReport; judgement?: TurnJudgement }\n | { kind: \"gate\"; skip: GateSkip<HookGate> };\n\nconst idOf = (p: InferenceProvider): Identity => ({\n provider: p.provider() as ProviderName,\n model: p.modelName(),\n});\n\nconst LEDGER_OUTCOME: Record<TurnJudgement[\"verdicts\"][number][\"outcome\"], LedgerOutcome> = {\n fail: \"broken\",\n followed: \"followed\",\n \"needs-review\": \"needs-review\",\n \"not-applicable\": \"not-applicable\",\n};\n\n/** How far a run got, for the ledger. */\ninterface Seen {\n sources: RuleSource[];\n judgement?: TurnJudgement;\n}\n\n/**\n * The pipeline both modes run, with the session ledger around it. The hook\n * records every turn it parses, judged or not. By hand the ledger is only\n * read, and summed up for the report.\n */\nasync function conform(p: Params): Promise<Outcome> {\n const ledgerFile = ledgerPath(p.projectDir, p.sessionId, p.agentId);\n const ledger = await readLedger(ledgerFile);\n const seen: Seen = { sources: [] };\n const outcome = await judgeTurnOf(p, ledger, seen);\n if (p.inLoop) await record(p, ledgerFile, ledger, seen);\n else if (outcome.kind === \"report\") outcome.report.session = rollup(ledger);\n return outcome;\n}\n\n/** This turn's facts, and its verdicts when it was judged. A failed write warns. */\nasync function record(p: Params, file: string, ledger: Ledger, seen: Seen): Promise<void> {\n const facts = turnFacts(p.trace, p.turn, seen.sources, {\n cwd: p.projectDir,\n root: p.projectRoot ?? p.projectDir,\n redact: p.config.judge.redact,\n });\n let next = recordFacts(ledger, facts);\n if (seen.judgement !== undefined) {\n next = recordTurn(\n next,\n p.turn.from,\n seen.judgement.verdicts.map((v) => ({\n key: ruleKey(v.source, v.rule),\n text: v.text,\n outcome: LEDGER_OUTCOME[v.outcome],\n note: v.reasoning ?? \"\",\n })),\n );\n }\n try {\n await writeLedger(file, next);\n } catch (err) {\n warn(`could not write the session ledger ${file}: ${firstLine(err)}`);\n }\n}\n\n/** Sources, extraction, the judge. */\nasync function judgeTurnOf(p: Params, ledger: Ledger, seen: Seen): Promise<Outcome> {\n const { config, turn } = p;\n const conformance = conformanceOf(config);\n const local = p.localModels ?? libraryLocalModels(config.providers);\n const report: CheckReport = {\n trace: p.trace.file,\n sessionId: p.sessionId,\n agentId: p.agentId,\n turn: { from: turn.from, to: turn.to },\n judge: null,\n extraction: null,\n sources: [],\n findings: [],\n summary: { sources: 0, rules: 0, notApplicable: 0, fail: 0, needsReview: 0, reported: 0 },\n session: null,\n skipped: null,\n warnings: [...p.trace.warnings],\n exitCode: 0,\n };\n const stop = (skipped: CheckSkip): Outcome => {\n report.skipped = skipped;\n return { kind: \"report\", report };\n };\n\n // Gate 3.\n if (turn.window.empty) return stop(\"empty-turn\");\n\n // Gate 4.\n const resolved = await resolveTurnSources(p.trace, turn, {\n projectDir: p.projectDir,\n ...(p.projectRoot !== undefined ? { projectRoot: p.projectRoot } : {}),\n ...(p.env !== undefined ? { env: p.env } : {}),\n include: conformance.include,\n exclude: conformance.exclude,\n plans: conformance.plans,\n redact: config.judge.redact,\n ...(p.agentType !== undefined ? { agentType: p.agentType } : {}),\n });\n report.warnings.push(...resolved.warnings);\n // Under a hook a source that never blocks (Claude Code's default system\n // prompt) could only add judge calls, so it is neither extracted nor judged.\n // By hand it is, and its breaks are reported.\n const sources = p.inLoop ? resolved.sources.filter((s) => s.blocks) : resolved.sources;\n seen.sources = sources;\n report.summary.sources = sources.length;\n if (sources.length === 0) return stop(\"no-sources\");\n\n const judgeId = p.judge !== undefined ? idOf(p.judge) : await resolveSelectionIdentity(config, p.judgeSelection);\n const judgeIsLocal = judgeId.provider === \"llama-cpp\";\n\n // Gate 5, for the judge. Extraction's own model is asked below, only when a\n // source needs it.\n if (p.inLoop && judgeIsLocal) {\n const skip = await localGate(local, judgeId.model, [\"downloading\"]);\n if (skip !== undefined) return { kind: \"gate\", skip };\n }\n\n // Extraction, between gates 4 and 6, with the out-of-loop model always.\n const host = hostSetting(p.inLoop, p.sessionId, config.providers[\"llama-cpp\"]?.keepAlive);\n const ex = await extraction(config, rulesCacheFor(config, p.configDir, p.noCache), p.extractor, host);\n if (sources.some((s) => ex.needs(s))) {\n report.extraction = { provider: ex.identity.provider, model: ex.identity.model };\n if (p.offline && isNetworkProvider(ex.identity.provider)) {\n throw offlineRefusal(\"extraction\", ex.identity);\n }\n if (ex.identity.provider === \"llama-cpp\") {\n if (p.inLoop) {\n const skip = await localGate(\n local,\n ex.identity.model,\n [\"downloading\", \"not-downloaded\", \"memory\"],\n () => hostHolds(ex.identity.model, p.hostApi),\n );\n if (skip !== undefined) return { kind: \"gate\", skip };\n } else {\n await assertDownloaded(local, ex.identity.model);\n }\n }\n }\n const rules: TurnRule[] = [];\n for (const source of sources) {\n const { rules: found, origin } = await ex.rulesOf(source);\n report.sources.push({\n path: source.displayPath,\n format: source.format,\n ...(source.skill !== undefined ? { skill: source.skill } : {}),\n trigger: source.trigger,\n rules: found.length,\n origin,\n });\n for (const rule of found) rules.push({ source, rule });\n }\n report.summary.rules = rules.length;\n\n // Gate 6.\n const { applicable } = applicableRules(rules, turn.window);\n if (applicable.length === 0) {\n report.summary.notApplicable = rules.length;\n return stop(\"not-applicable\");\n }\n\n if (p.offline && isNetworkProvider(judgeId.provider)) {\n throw offlineRefusal(\"the judge\", judgeId);\n }\n const cacheRoot = resolve(p.configDir, config.judge.cacheDir);\n const limits = new StateLimits(resolve(cacheRoot, \"limits\"), !p.noCache);\n const plan = {\n trace: p.trace,\n turn,\n rules,\n runs: p.runs,\n temperature: config.judge.temperature,\n zones: config.judge.zones,\n render: {\n maxBlockChars: config.render.maxBlockChars,\n maxTotalChars: config.render.maxTotalChars,\n redact: config.judge.redact,\n },\n ...(p.lastAssistantMessage !== undefined ? { lastAssistantMessage: p.lastAssistantMessage } : {}),\n ledger,\n project: { cwd: p.projectDir, root: p.projectRoot ?? p.projectDir },\n cache: new TurnCache(resolve(cacheRoot, \"turns\"), !p.noCache),\n };\n\n // Gates 7 and 8, model on disk and memory. The memory probe is skipped when\n // the model will not be loaded or is loaded already: every applicable\n // rule's verdict is cached (gate 9, read from the remembered state limit\n // without a provider), or the host holds the model. The verdict cache is\n // otherwise read inside judgeTurn, once the provider reports its limit.\n if (judgeIsLocal) {\n if (p.inLoop) {\n const skip = await localGate(\n local,\n judgeId.model,\n [\"not-downloaded\", \"memory\"],\n async () =>\n allVerdictsCached({ ...plan, limits }, judgeId) || (await hostHolds(judgeId.model, p.hostApi)),\n );\n if (skip !== undefined) return { kind: \"gate\", skip };\n } else {\n await assertDownloaded(local, judgeId.model);\n }\n }\n\n markJudgeProcess();\n const provider =\n p.judge ??\n (judgeId.provider === \"mock\"\n ? mockTurnJudge(judgeId.model)\n : constructProvider(config, judgeId, { host }));\n let ran: Awaited<ReturnType<typeof queued<TurnJudgement>>>;\n try {\n ran = await queued(judgeId.model, () =>\n judgeTurn({ ...plan, provider, limits }),\n );\n } catch (err) {\n if (err instanceof TracevalsError) throw err;\n throw new TracevalsError(`could not judge the last turn: ${firstLine(err)}`);\n }\n if (ran.busy) {\n return {\n kind: \"gate\",\n skip: {\n gate: \"busy\",\n message: `tracevals skipped this turn: ${judgeId.model} was busy with other judgements for ${String(QUEUE_WAIT_MS / 60_000)} minutes.`,\n },\n };\n }\n const judgement = ran.value;\n seen.judgement = judgement;\n report.judge = {\n provider: judgeId.provider,\n model: judgeId.model,\n mode: judgement.mode,\n runs: judgement.runs,\n };\n report.findings = judgement.findings;\n report.summary.notApplicable = judgement.notApplicable;\n const fails = judgement.findings.filter((f) => f.outcome === \"fail\");\n report.summary.fail = fails.filter((f) => f.severity === \"error\").length;\n // `reported` is confirmed breaks from sources that never block. A\n // needs-review verdict from any source, those included, stays in needsReview.\n report.summary.reported = fails.length - report.summary.fail;\n report.summary.needsReview = judgement.findings.length - fails.length;\n report.warnings.push(...judgement.warnings);\n report.exitCode = report.summary.fail > 0 ? 1 : 0;\n return { kind: \"report\", report, judgement };\n}\n\nasync function readTrace(path: string): Promise<Trace> {\n try {\n return await parseTraceFile(path);\n } catch (err) {\n throw new TracevalsError(`cannot read trace ${path}: ${firstLine(err)}`);\n }\n}\n\n// ── By hand ──────────────────────────────────────────────────────\n\nexport interface CheckOptions extends Seams {\n tracePath: string;\n /** Project root for resolving sources; default the trace's recorded cwd. */\n project?: string;\n provider?: string;\n model?: string;\n local?: boolean;\n /** Overrides `judge.ensembleRuns`. */\n runs?: number;\n noCache?: boolean;\n offline?: boolean;\n format?: SummaryFormat;\n output?: string;\n color?: boolean;\n /** Directory holding manni.config.yaml; defaults to cwd. */\n configDir?: string;\n config?: string;\n noConfig?: boolean;\n env?: Record<string, string | undefined>;\n}\n\nexport interface CheckResult {\n report: CheckReport;\n rendered: string;\n}\n\nexport async function runCheck(options: CheckOptions): Promise<CheckResult> {\n const { config, dir: configDir } = await discoverConfig(options.configDir ?? process.cwd(), {\n ...(options.config === undefined ? {} : { configPath: options.config }),\n ...(options.noConfig === undefined ? {} : { noConfig: options.noConfig }),\n });\n const judgeSelection = selectProvider(config, {\n ...(options.provider !== undefined ? { provider: options.provider } : {}),\n ...(options.model !== undefined ? { model: options.model } : {}),\n ...(options.local !== undefined ? { local: options.local } : {}),\n });\n const trace = await readTrace(options.tracePath);\n const outcome = await conform({\n config,\n configDir,\n trace,\n turn: lastTurn(trace),\n sessionId: trace.sessionId ?? basename(trace.file).replace(/\\.jsonl$/, \"\"),\n agentId: null,\n projectDir: options.project ?? trace.cwd,\n ...(options.project !== undefined ? { projectRoot: options.project } : {}),\n ...(options.env !== undefined ? { env: options.env } : {}),\n judgeSelection,\n runs: options.runs ?? config.judge.ensembleRuns,\n inLoop: false,\n noCache: options.noCache === true,\n offline: options.offline === true,\n ...seamsOf(options),\n });\n // By hand only the report's own skips exist; the other gates act under a hook.\n if (outcome.kind === \"gate\") throw new TracevalsError(outcome.skip.message);\n const { report } = outcome;\n const rendered =\n options.format === \"json\"\n ? JSON.stringify(report, null, 2)\n : renderCheck(report, { color: options.color === true });\n if (options.output !== undefined) await writeFile(options.output, rendered, \"utf-8\");\n return { report, rendered };\n}\n\nfunction seamsOf(s: Seams): Seams {\n return {\n ...(s.judge !== undefined ? { judge: s.judge } : {}),\n ...(s.extractor !== undefined ? { extractor: s.extractor } : {}),\n ...(s.localModels !== undefined ? { localModels: s.localModels } : {}),\n ...(s.hostApi !== undefined ? { hostApi: s.hostApi } : {}),\n };\n}\n\n// ── Inside a hook ────────────────────────────────────────────────\n\n/** What a Stop or SubagentStop envelope carries, as the family hook passes it. */\nexport interface TurnCheckInput extends Seams {\n transcriptPath: string;\n /** SubagentStop: the subagent's own transcript, judged alone. */\n agentTranscriptPath?: string;\n agentId?: string;\n /** SubagentStop: the subagent type, whose definition governs the run. */\n agentType?: string;\n /** Appended when the transcript lags the Stop. */\n lastAssistantMessage?: string;\n sessionId: string;\n cwd: string;\n inLoop: true;\n /** Defaults to `process.env`; gate 2 and the source walk read it. */\n env?: Record<string, string | undefined>;\n}\n\nexport interface TurnCheckResult {\n /** The gate that ended the run. A message is set where the proposal says one. */\n skipped?: { gate: HookGate; message?: string };\n judgement?: TurnJudgement;\n /** Only `fail` and `needs-review`; empty when skipped. */\n findings: TurnFinding[];\n /** Absent for gates 1, 2, 5, 8, 9 and a busy host. */\n report?: CheckReport;\n /** 1 when a rule was broken with a confident verdict. */\n exitCode: 0 | 1;\n}\n\n/**\n * Gates 1 to 9 for one turn, then the judgement. The skip messages are said\n * once per session by the caller, which knows the session. An operational\n * failure throws a `TracevalsError`.\n */\nexport async function checkTurn(input: TurnCheckInput): Promise<TurnCheckResult> {\n const { config, dir: configDir } = await discoverConfig(input.cwd);\n // Gate 1. The transcript is not parsed.\n if (config.conformance === null) {\n return { skipped: { gate: \"not-in-play\" }, findings: [], exitCode: 0 };\n }\n // Gate 2: a judge's own session.\n const env = input.env ?? process.env;\n if ((env[JUDGE_ENV] ?? \"\") !== \"\") {\n return { skipped: { gate: \"judge-session\" }, findings: [], exitCode: 0 };\n }\n const subagent = input.agentTranscriptPath !== undefined;\n const trace = await readTrace(input.agentTranscriptPath ?? input.transcriptPath);\n const outcome = await conform({\n config,\n configDir,\n trace,\n turn: subagent ? subagentTurn(trace) : lastTurn(trace),\n sessionId: input.sessionId,\n agentId: input.agentId ?? null,\n ...(input.agentType !== undefined ? { agentType: input.agentType } : {}),\n projectDir: input.cwd,\n ...(input.env !== undefined ? { env: input.env } : {}),\n judgeSelection: selectHookProvider(config),\n runs: config.conformance.hook.runs,\n inLoop: true,\n noCache: false,\n offline: false,\n ...(input.lastAssistantMessage !== undefined\n ? { lastAssistantMessage: input.lastAssistantMessage }\n : {}),\n ...seamsOf(input),\n });\n if (outcome.kind === \"gate\") {\n return { skipped: outcome.skip, findings: [], exitCode: 0 };\n }\n const { report, judgement } = outcome;\n if (report.skipped !== null) {\n return { skipped: { gate: report.skipped }, findings: [], report, exitCode: 0 };\n }\n return {\n ...(judgement !== undefined ? { judgement } : {}),\n findings: report.findings,\n report,\n exitCode: report.exitCode === 1 ? 1 : 0,\n };\n}\n","/**\n * The turn judge (proposal 0079, \"The judge, decisions first\" and \"The block\n * bar\"). It checks one turn against the rules that governed it.\n *\n * Each rule is judged on its own, against the rendered turn. Which path runs\n * is detected from the provider, never configured. A decision-only provider\n * gets one `decide` call, one question per rule, branching from the turn.\n * Every provider that generates gets `runs` calls of `completeJSONShared`, one\n * item per rule, each answered with a sentence of reasoning and then three\n * independent scores. Both share what earlier turns of the transcript did,\n * and a scored rule's item carries what the session ledger holds for it.\n *\n * Only a confident violation blocks. Everything short of that is\n * `needs-review`, and an errored rule can only go there, never to a silent\n * pass and never to a fail.\n */\nimport {\n JsonCache,\n buildCacheKey,\n canDecide,\n completeJSONShared,\n sha256,\n type DecideAnswer,\n type DecisionProvider,\n type InferenceProvider,\n type ZoneThresholds,\n} from \"@hawkeyexl/inference\";\nimport { DECISION_ONLY_PROVIDERS } from \"../../shared/providers.js\";\nimport type { Severity } from \"../../shared/severity.js\";\nimport type { TraceWindow } from \"../graders/util.js\";\nimport { evaluateWhen } from \"../graders/when.js\";\nimport { makeRedactor } from \"../judge/redact.js\";\nimport { renderTrace } from \"../judge/render.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport type { Rule } from \"./extract.js\";\nimport {\n TURN_JUDGE_PROMPT_VERSION,\n TURN_JUDGE_SYSTEM_PROMPT,\n TURN_SCORES,\n buildDecisionState,\n buildRuleItem,\n buildTurnShared,\n questionFor,\n ruleKey,\n TURN_SCHEMA,\n type TurnScore,\n} from \"./judge-prompt.js\";\nimport { historyBlock, type Ledger } from \"./ledger.js\";\nimport type { RuleSource } from \"./sources.js\";\nimport { timelineBlock } from \"./timeline.js\";\nimport type { TurnSlice } from \"./turn.js\";\n\n/** Default location, under the tool's per-project cache directory. */\nexport const DEFAULT_TURN_CACHE_DIR = \".manni/tracevals/cache/turns\";\n\n/**\n * Characters per token when fitting a provider's state limit. Prose and code\n * run near 4 characters a token in common tokenizers, and dense text such as\n * JSON, paths and hashes runs lower. 3 errs toward a smaller render, which\n * costs evidence; erring the other way costs the request.\n */\nexport const CHARS_PER_TOKEN = 3;\n\nexport interface TurnRule {\n /**\n * `path` lets the earlier turns say the session read the source. A source\n * whose `blocks` is false gives warnings; one that leaves it out blocks.\n */\n source: Pick<RuleSource, \"displayPath\"> & Partial<Pick<RuleSource, \"path\" | \"blocks\">>;\n rule: Rule;\n}\n\nexport interface TurnJudgeInput {\n trace: Trace;\n turn: TurnSlice;\n /** Every in-scope rule, sources ordered farthest to nearest. */\n rules: TurnRule[];\n provider: InferenceProvider;\n /** Scored runs. A decision-only provider makes one call and reports 1. */\n runs: number;\n temperature: number;\n zones: ZoneThresholds;\n render: { maxBlockChars: number; maxTotalChars: number; redact: string[] };\n /** The Stop payload's `last_assistant_message`, appended when the transcript lags. */\n lastAssistantMessage?: string;\n /**\n * The session's earlier verdicts, and which earlier turns had no rule in\n * scope. Only a scored rule's item carries its own history.\n */\n ledger?: Ledger;\n /** Where paths in earlier turns are made relative; the trace's cwd by default. */\n project?: { cwd: string; root: string };\n cache?: TurnCache;\n}\n\nexport interface TurnFinding {\n source: string;\n rule: string;\n text: string;\n outcome: \"fail\" | \"needs-review\";\n /** `error` when the rule's source blocks, `warning` when it is only reported. */\n severity: Severity;\n observed: string;\n confidence: number;\n /** The judge's reasoning. A decision-only provider gives none. */\n reasoning?: string;\n}\n\n/** Every rule sent to the judge, with where its verdict landed. */\nexport interface TurnVerdict {\n source: string;\n rule: string;\n text: string;\n outcome: Outcome;\n reasoning?: string;\n}\n\nexport interface TurnJudgement {\n mode: \"decision\" | \"generative\";\n runs: number;\n /** Only `fail` and `needs-review`; a rule left out passed or did not apply. */\n findings: TurnFinding[];\n /** One per rule sent to the judge, whatever its outcome. */\n verdicts: TurnVerdict[];\n /** Rules sent to the judge. */\n judged: number;\n /** Rules whose `when` failed over the turn, plus those scored not applicable. */\n notApplicable: number;\n /** Every rule's verdict came from the cache. */\n cached: boolean;\n warnings: string[];\n}\n\ntype Scores = Record<TurnScore, number> & { reasoning?: string };\n\n/** One rule's answers: a score set per run that answered. */\ninterface Verdict {\n runs: Scores[];\n error?: string;\n}\n\nexport type Outcome = \"fail\" | \"not-applicable\" | \"followed\" | \"needs-review\";\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n\nfunction isScores(v: unknown): v is Scores {\n return isRecord(v) && TURN_SCORES.every((s) => typeof v[s] === \"number\");\n}\n\n/**\n * Raw scores per rule and turn, before the block bar is applied, so a change\n * of `zones` reuses them. A rule with an errored run is never written.\n */\nexport class TurnCache {\n private readonly store: JsonCache<unknown>;\n\n constructor(dir: string = DEFAULT_TURN_CACHE_DIR, enabled = true) {\n this.store = new JsonCache<unknown>(dir, enabled, \"manni-tracevals\");\n }\n\n /** An entry of any other shape, from an older version, is a miss. */\n get(key: string): Scores[] | undefined {\n const v = this.store.get(key);\n if (!isRecord(v) || !Array.isArray(v.runs) || v.runs.length === 0) return undefined;\n const runs: unknown[] = v.runs;\n return runs.every(isScores) ? runs : undefined;\n }\n\n set(key: string, runs: Scores[]): void {\n this.store.set(key, { runs });\n }\n}\n\nexport interface ModelId {\n provider: string;\n model: string;\n}\n\n/**\n * What a provider's `stateLimit()` last said, per provider and model, with\n * `null` for one that has no limit. A local model loads to report it, and the\n * limit sets how much of the turn is rendered, which the verdict key hashes. So\n * \"is every verdict cached?\" could not be answered without loading the model\n * until this remembered the answer. A stale limit costs a miss, never a wrong\n * verdict, because a hit is keyed by the text it was scored on.\n */\nexport class StateLimits {\n private readonly store: JsonCache<unknown>;\n\n constructor(dir: string, enabled = true) {\n this.store = new JsonCache<unknown>(dir, enabled, \"manni-tracevals\");\n }\n\n get(id: ModelId): number | null | undefined {\n const v = this.store.get(buildCacheKey([id.provider, id.model]));\n return isRecord(v) && (v.limit === null || typeof v.limit === \"number\") ? v.limit : undefined;\n }\n\n set(id: ModelId, limit: number | null): void {\n this.store.set(buildCacheKey([id.provider, id.model]), { limit });\n }\n}\n\n/** Gate 6: a rule whose `when` fails over the turn is skipped, never passed. */\nexport function applicableRules(\n rules: TurnRule[],\n window: TraceWindow,\n): { applicable: TurnRule[]; notApplicable: number } {\n const applicable = rules.filter(\n (r) => evaluateWhen({ when: r.rule.when }, window).armed,\n );\n return { applicable, notApplicable: rules.length - applicable.length };\n}\n\ninterface Planned {\n /** Decision question id: source index among every input source, then rule id. */\n qid: string;\n source: string;\n id: string;\n text: string;\n severity: Severity;\n /** The ledger's block for this rule, \"\" for none and on the decision path. */\n history: string;\n /** The scored path's item for this rule. */\n item: string;\n}\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n/** Decision-only providers decide; every provider that generates is scored. */\nfunction decisionOnly(provider: InferenceProvider): DecisionProvider | undefined {\n return DECISION_ONLY_PROVIDERS.has(provider.provider()) && canDecide(provider)\n ? provider\n : undefined;\n}\n\n/** The input without the provider, which a gate can use before one is built. */\nexport type TurnPlanInput = Omit<TurnJudgeInput, \"provider\">;\n\ninterface Plan {\n planned: Planned[];\n turnText: string;\n /** The transcript's account of earlier turns, \"\" for none. */\n earlier: string;\n warnings: string[];\n hits: Map<Planned, Verdict>;\n todo: Planned[];\n keyOf: (p: Planned) => string;\n}\n\n/**\n * Everything short of the model call: each rule's item, the turn rendered to\n * `limit` (undefined for no limit), and the verdict cache read. `decisionOnly`\n * and `limit` are all that come from the provider, so a caller that knows both\n * can plan without one.\n */\nfunction planTurn(\n input: TurnPlanInput,\n id: ModelId,\n decisionOnly: boolean,\n limit: number | undefined,\n): Plan {\n const runs = decisionOnly ? 1 : input.runs;\n const { applicable } = applicableRules(input.rules, input.turn.window);\n const warnings: string[] = [];\n const hits = new Map<Planned, Verdict>();\n\n // Indexed over every input source, so a question id does not move when a\n // farther source's rules happen not to apply.\n const sourceIndex = new Map<string, number>();\n for (const r of input.rules) {\n const path = r.source.displayPath;\n if (!sourceIndex.has(path)) sourceIndex.set(path, sourceIndex.size);\n }\n const planned: Planned[] = applicable.map(({ source, rule }) => {\n const history =\n !decisionOnly && input.ledger !== undefined\n ? historyBlock(input.ledger, ruleKey(source.displayPath, rule.id), rule.text, input.turn.from)\n : \"\";\n return {\n qid: `${String(sourceIndex.get(source.displayPath))}:${rule.id}`,\n source: source.displayPath,\n id: rule.id,\n text: rule.text,\n severity: source.blocks === false ? \"warning\" : \"error\",\n history,\n item: buildRuleItem(source.displayPath, rule, history),\n };\n });\n if (planned.length === 0) {\n return { planned, turnText: \"\", earlier: \"\", warnings, hits, todo: [], keyOf: () => \"\" };\n }\n\n // Render the turn, to the state limit when there is one. Every rule counts\n // toward the longest, cached or not, so the render and its key stay put.\n const tail = lastMessageLine(input);\n let budget = input.render.maxTotalChars;\n let byLimit = false;\n if (limit !== undefined) {\n const longest = Math.max(\n ...planned.map((p) =>\n decisionOnly ? JSON.stringify(questionFor(p.source, p)).length : p.item.length,\n ),\n );\n const fixed = decisionOnly\n ? buildDecisionState(\"\").length\n : TURN_JUDGE_SYSTEM_PROMPT.length + buildTurnShared(\"\").length;\n const fit = limit * CHARS_PER_TOKEN - longest - fixed;\n if (fit < budget) {\n budget = fit;\n byLimit = true;\n }\n }\n // Earlier turns share the budget with the turn, and take at most a quarter\n // of it, so the turn itself is never crowded out.\n const sources = [\n ...new Map(\n input.rules.flatMap(({ source: { path, displayPath } }) =>\n // A source with no file (the typed prompts, an inline plan, the system\n // prompt) is never read.\n path !== undefined && path !== \"\" ? [[displayPath, { path, displayPath }] as const] : [],\n ),\n ).values(),\n ];\n const earlier = timelineBlock(input.trace, input.turn.from, {\n cwd: input.project?.cwd ?? input.trace.cwd,\n root: input.project?.root ?? input.trace.cwd,\n redact: input.render.redact,\n sources,\n ...(input.ledger !== undefined ? { ledger: input.ledger } : {}),\n maxChars: Math.floor(budget / 4),\n });\n budget -= buildTurnShared(\"\", earlier).length - buildTurnShared(\"\").length;\n const cut = { happened: false };\n const turnText =\n renderTrace(input.trace, {\n maxBlockChars: input.render.maxBlockChars,\n maxTotalChars: budget - tail.length,\n redact: input.render.redact,\n window: input.turn.window,\n onTruncated: () => {\n cut.happened = true;\n },\n }) + tail;\n if (cut.happened) {\n warnings.push(\n byLimit\n ? `the turn was cut to fit the state limit of ${String(limit)} tokens of ${id.provider}/${id.model}; the judge saw its head and tail`\n : `the turn was cut to the render cap of ${String(input.render.maxTotalChars)} characters; the judge saw its head and tail`,\n );\n }\n\n // Gate 9: the same turn, rule and model reuse the verdict.\n const base = [\n id.provider,\n id.model,\n decisionOnly ? \"decision\" : \"generative\",\n `r${String(runs)}`,\n `t${String(input.temperature)}`,\n `turn-v${String(TURN_JUDGE_PROMPT_VERSION)}`,\n sha256(turnText),\n sha256(earlier),\n ];\n const keyOf = (p: Planned): string =>\n buildCacheKey([...base, sha256(JSON.stringify([p.source, p.id, p.text, p.history]))]);\n const todo: Planned[] = [];\n for (const p of planned) {\n const hit = input.cache?.get(keyOf(p));\n if (hit !== undefined) hits.set(p, { runs: hit });\n else todo.push(p);\n }\n return { planned, turnText, earlier, warnings, hits, todo, keyOf };\n}\n\n/**\n * Whether every applicable rule already has its verdict, answered without a\n * provider and so without loading a local model. The render depends on the\n * provider's state limit, which `StateLimits` remembers from the last\n * judgement, so a model never judged with is unknown and the answer is no.\n * A decision-only provider is never asked here: it is not a local model.\n */\nexport function allVerdictsCached(\n input: TurnPlanInput & { limits: StateLimits },\n id: ModelId,\n): boolean {\n const limit = input.limits.get(id);\n if (limit === undefined || DECISION_ONLY_PROVIDERS.has(id.provider)) return false;\n const plan = planTurn(input, id, false, limit ?? undefined);\n return plan.planned.length > 0 && plan.todo.length === 0;\n}\n\nexport async function judgeTurn(\n input: TurnJudgeInput & { limits?: StateLimits },\n): Promise<TurnJudgement> {\n const { provider, zones } = input;\n const decider = decisionOnly(provider);\n const mode = decider !== undefined ? \"decision\" : \"generative\";\n const runs = decider !== undefined ? 1 : input.runs;\n const id: ModelId = { provider: provider.provider(), model: provider.modelName() };\n const { applicable, notApplicable } = applicableRules(input.rules, input.turn.window);\n const result: TurnJudgement = {\n mode,\n runs,\n findings: [],\n verdicts: [],\n judged: applicable.length,\n notApplicable,\n cached: false,\n warnings: [],\n };\n if (applicable.length === 0) return result;\n\n // The provider's limit, remembered. A remembered one lets a fully cached\n // turn finish without asking the provider at all; any miss asks for the real\n // one, which refreshes the memory, and plans again if it moved.\n const fresh = async (): Promise<number | null> => {\n const real = canDecide(provider) ? await provider.stateLimit() : null;\n input.limits?.set(id, real);\n return real;\n };\n const remembered = input.limits?.get(id);\n let limit = remembered ?? (await fresh());\n let plan = planTurn(input, id, decider !== undefined, limit ?? undefined);\n if (remembered !== undefined && plan.todo.length > 0) {\n const real = await fresh();\n if (real !== limit) {\n limit = real;\n plan = planTurn(input, id, decider !== undefined, limit ?? undefined);\n }\n }\n const { planned, hits: verdicts, todo, keyOf, turnText, earlier } = plan;\n const warnings = plan.warnings;\n result.warnings = warnings;\n result.cached = todo.length === 0;\n if (todo.length > 0) {\n const scored =\n decider !== undefined\n ? await decide(decider, todo, buildDecisionState(turnText, earlier))\n : await score(provider, todo, buildTurnShared(turnText, earlier), runs, input.temperature);\n if (scored.every((v) => v.runs.length === 0)) {\n throw new Error(scored.find((v) => v.error !== undefined)?.error ?? \"every judge call errored\");\n }\n const errored = scored.filter((v) => v.error !== undefined);\n if (errored.length > 0) {\n warnings.push(\n `the judge errored on ${String(errored.length)} of ${String(todo.length)} rules, so they need review: ${errored[0]?.error ?? \"\"}`,\n );\n }\n todo.forEach((p, i) => {\n const v = scored[i] ?? { runs: [], error: \"the judge returned nothing\" };\n verdicts.set(p, v);\n if (v.error === undefined) input.cache?.set(keyOf(p), v.runs);\n });\n }\n\n for (const p of planned) {\n const v = verdicts.get(p) ?? { runs: [], error: \"the judge returned nothing\" };\n const outcome = outcomeOf(v, runs, zones);\n const reasoning = v.runs.find((r) => typeof r.reasoning === \"string\")?.reasoning;\n result.verdicts.push({\n source: p.source,\n rule: p.id,\n text: p.text,\n outcome,\n ...(reasoning !== undefined ? { reasoning } : {}),\n });\n if (outcome === \"not-applicable\") result.notApplicable += 1;\n else if (outcome !== \"followed\") result.findings.push(findingOf(p, outcome, v, runs));\n }\n return result;\n}\n\n/** One `decide` call; each option's probability becomes its score. */\nasync function decide(\n decider: DecisionProvider,\n todo: Planned[],\n state: string,\n): Promise<Verdict[]> {\n const response = await decider.decide({\n state,\n questions: Object.fromEntries(todo.map((p) => [p.qid, questionFor(p.source, p)])),\n });\n const answers: Record<string, DecideAnswer | undefined> = response.answers;\n return todo.map((p) => {\n const answer = answers[p.qid];\n if (answer === undefined) return { runs: [], error: \"the judge returned no answer for this rule\" };\n const pct = (s: TurnScore): number => Math.round((answer.probabilities[s] ?? 0) * 100);\n return {\n runs: [\n {\n followed: pct(\"followed\"),\n \"not-followed\": pct(\"not-followed\"),\n \"not-applicable\": pct(\"not-applicable\"),\n },\n ],\n };\n });\n}\n\n/** `runs` shared-prefix calls, one item per rule. */\nasync function score(\n provider: InferenceProvider,\n todo: Planned[],\n shared: string,\n runs: number,\n temperature: number,\n): Promise<Verdict[]> {\n const verdicts: Verdict[] = todo.map(() => ({ runs: [] }));\n const errors = todo.map(() => 0);\n for (let run = 0; run < runs; run++) {\n const response = await completeJSONShared(provider, {\n system: TURN_JUDGE_SYSTEM_PROMPT,\n shared,\n items: todo.map((p) => p.item),\n schema: TURN_SCHEMA,\n temperature,\n });\n verdicts.forEach((v, i) => {\n const answer = response.answers[i];\n if (answer !== undefined && \"json\" in answer && isScores(answer.json)) {\n v.runs.push(answer.json);\n return;\n }\n errors[i] = (errors[i] ?? 0) + 1;\n v.error ??= answer !== undefined && \"error\" in answer ? answer.error : \"the judge returned nothing\";\n });\n }\n return verdicts.map((v, i) =>\n v.error === undefined || v.runs.length === 0\n ? v\n : { ...v, error: `${String(errors[i] ?? 0)} of ${String(runs)} runs errored: ${v.error}` },\n );\n}\n\nfunction classify(s: Scores, zones: ZoneThresholds): Outcome {\n // An integer over 100 lands on the same double as the zone's literal, where\n // the zone times 100 can miss it (0.7 * 100 is 70.00000000000001).\n if (s[\"not-followed\"] / 100 >= zones.autoFail) return \"fail\";\n if (s[\"not-applicable\"] / 100 >= zones.autoPass) return \"not-applicable\";\n if (s.followed / 100 >= zones.autoPass) return \"followed\";\n return \"needs-review\";\n}\n\n/** Every run has to agree: a split ensemble, or any error, is review. */\nfunction outcomeOf(v: Verdict, runs: number, zones: ZoneThresholds): Outcome {\n if (v.error !== undefined || v.runs.length < runs) return \"needs-review\";\n const each = v.runs.map((s) => classify(s, zones));\n if (each.every((c) => c === \"fail\")) return \"fail\";\n if (each.every((c) => c === \"not-applicable\")) return \"not-applicable\";\n if (each.every((c) => c === \"not-applicable\" || c === \"followed\")) return \"followed\";\n return \"needs-review\";\n}\n\nfunction findingOf(\n p: Planned,\n outcome: TurnFinding[\"outcome\"],\n v: Verdict,\n runs: number,\n): TurnFinding {\n const base = { source: p.source, rule: p.id, text: p.text, outcome, severity: p.severity };\n if (v.runs.length === 0) {\n return {\n ...base,\n observed: `the judge returned no answer for this rule: ${v.error ?? \"\"}`,\n confidence: 0,\n };\n }\n const mean = (s: TurnScore): number =>\n Math.round(v.runs.reduce((sum, r) => sum + r[s], 0) / v.runs.length);\n const scores = `not-followed ${String(mean(\"not-followed\"))}, followed ${String(mean(\"followed\"))}, not-applicable ${String(mean(\"not-applicable\"))}`;\n const errored = v.error !== undefined && runs > 1 ? `; ${v.error}` : \"\";\n const reasoning = v.runs.find((r) => typeof r.reasoning === \"string\")?.reasoning;\n return {\n ...base,\n observed: `${scores}${errored}${reasoning !== undefined ? `. ${reasoning}` : \"\"}`,\n confidence: round(mean(\"not-followed\") / 100),\n ...(reasoning !== undefined ? { reasoning } : {}),\n };\n}\n\n/**\n * The transcript is written asynchronously, so its last message can lag the\n * Stop. The payload's copy is appended when the window does not end with it,\n * scrubbed and clipped as every rendered block is.\n */\nfunction lastMessageLine(input: TurnPlanInput): string {\n const message = input.lastAssistantMessage?.trim();\n if (message === undefined || message === \"\") return \"\";\n if (input.turn.window.assistantTexts.at(-1)?.trim() === message) return \"\";\n const safe = makeRedactor(input.render.redact)(message);\n const max = input.render.maxBlockChars;\n const clipped =\n safe.length <= max\n ? safe\n : `${safe.slice(0, max)} [... truncated ${String(safe.length - max)} chars ...]`;\n return `\\n[assistant] ${clipped}`;\n}\n","/**\n * The turn judge's prompt surface (proposal 0079, \"The judge, decisions\n * first\", reworded by proposal 0080 to judge the last turn against the\n * session). Each rule is judged on its own: the shared part is what earlier\n * turns did and the rendered turn, and each rule is one item appended to it. A decision-only provider\n * gets the same text as its state and one question per rule.\n */\nimport type { DecideQuestion } from \"@hawkeyexl/inference\";\n\n/**\n * Part of the turn verdict cache key: bump whenever anything in this file that\n * reaches a provider changes. `test/tracevals/unit/rules-judge.test.ts` pins it\n * to a digest of the surface, so the pair has to move together.\n */\nexport const TURN_JUDGE_PROMPT_VERSION = 8;\n\nexport const TURN_JUDGE_SYSTEM_PROMPT = [\n \"You check the last turn of an AI coding agent's session against one rule.\",\n \"The last turn starts at the last prompt the user typed and runs to the end of the transcript.\",\n \"The transcript shows the user's prompts, the agent's tool calls with their inputs, and its replies.\",\n '\"Earlier in this session\" lists what the session did before the last turn.',\n \"\",\n \"A prompt the user typed overrides any rule. Doing what the user explicitly asked is never a violation.\",\n \"A rule from the system prompt is a default. An instruction file, or a prompt the user typed, overrides it.\",\n \"\",\n \"Judge only from what the transcript and the earlier turns show. Do not guess.\",\n \"A rule applies only once the session does the kind of work it covers.\",\n \"Score it broken only for what the last turn did, or for the last turn saying the work is done without it.\",\n].join(\"\\n\");\n\n/** The three scores, each independent of the others, 0 to 100. */\nexport const TURN_SCORES = [\"not-applicable\", \"followed\", \"not-followed\"] as const;\nexport type TurnScore = (typeof TURN_SCORES)[number];\n\nconst SCORE = { type: \"integer\", minimum: 0, maximum: 100 } as const;\n\n/**\n * `reasoning` is declared first and always required, so a model writing the\n * object in order says what it saw before it commits to a score. It is not\n * length-capped: a 240-character cap was measured, and a model cut off\n * mid-reasoning committed to wrong scores on the fixtures.\n */\nexport const TURN_SCHEMA = {\n type: \"object\",\n required: [\"reasoning\", ...TURN_SCORES],\n additionalProperties: false,\n properties: {\n reasoning: { type: \"string\" },\n \"not-applicable\": SCORE,\n followed: SCORE,\n \"not-followed\": SCORE,\n },\n};\n\n/** Decision-only providers: the three options, one per score. */\nexport const TURN_CRITERIA: Record<TurnScore, string> = {\n followed: \"The session does what the rule asks.\",\n \"not-followed\":\n \"The last turn did what the rule forbids, skipped what it requires, or said the work is done without it.\",\n \"not-applicable\": \"The rule does not apply yet, or the last turn did nothing it covers.\",\n};\n\n/** How a rule is named to a model. */\nexport function ruleKey(displayPath: string, id: string): string {\n return `${displayPath}#${id}`;\n}\n\n/**\n * The part every rule's call shares: what earlier turns of the transcript\n * did, when any did something, then the turn.\n */\nexport function buildTurnShared(turn: string, earlier = \"\"): string {\n return `${earlier !== \"\" ? `${earlier}\\n\\n` : \"\"}# The turn\\n\\n${turn}\\n\\n`;\n}\n\n/**\n * One rule's item, appended to the shared part as it is. `history` is the\n * ledger's block for the rule, or \"\" when earlier turns have nothing to say.\n */\nexport function buildRuleItem(\n displayPath: string,\n rule: { id: string; text: string },\n history = \"\",\n): string {\n return [\n \"# The rule\",\n \"\",\n `${ruleKey(displayPath, rule.id)}: ${rule.text}`,\n \"\",\n ...(history !== \"\" ? [history, \"\"] : []),\n \"First say in one or two sentences what the session shows about this rule. Then score each as a whole number from 0 to 100: \" +\n \"the rule does not apply yet, or the last turn did nothing it covers; the session follows it; the last turn broke it, or the last turn says the work is done without it.\",\n ].join(\"\\n\");\n}\n\n/** A decision-only provider's state: the system prompt, then the shared part. */\nexport function buildDecisionState(turn: string, earlier = \"\"): string {\n return `${TURN_JUDGE_SYSTEM_PROMPT}\\n\\n${buildTurnShared(turn, earlier)}`;\n}\n\nexport function questionFor(\n displayPath: string,\n rule: { id: string; text: string },\n): DecideQuestion {\n return {\n type: \"choice\",\n instructions: `Did this turn follow ${ruleKey(displayPath, rule.id)}? The rule: ${rule.text}`,\n criteria: { ...TURN_CRITERIA },\n };\n}\n","/**\n * \"# Earlier in this session\", read from the transcript (proposal 0080,\n * \"Earlier in this session, from the transcript\"). Every turn before the\n * judged one that did something gets a line, newest last, so a rule about a\n * procedure that spans turns is judged with the whole session behind it. The\n * ledger only says which of those turns had no rule in scope.\n */\nimport { makeRedactor } from \"../judge/redact.js\";\nimport { materialize } from \"../graders/util.js\";\nimport type { Trace } from \"../trace/types.js\";\nimport { clipTo, projectPath, turnFacts, type Ledger } from \"./ledger.js\";\nimport type { RuleSource } from \"./sources.js\";\nimport { isTypedPrompt } from \"./turn.js\";\n\nconst HEAD = \"# Earlier in this session\\n\\n\";\nconst RESULT_CHARS = 120;\nconst TICK_CHARS = 60;\nconst SPAWNS = 10;\n/** A task line in Spec Kit, Kiro and OpenSpec task lists. */\nconst TASK = /^\\s*-\\s+\\[([ xX])\\]\\s+(.+?)\\s*$/;\n/** A task's leading id: `T014`, `FR-001`, `1.2`. */\nconst TASK_ID = /^(?:[A-Z]+(?:-[A-Z]+)*-?\\d+(?:\\.\\d+)*|\\d+(?:\\.\\d+)*)(?=[\\s:.)\\]]|$)/;\n\nexport interface TimelineOptions {\n cwd: string;\n root: string;\n redact: readonly string[];\n /** The rule sources a `read` fact names; others' reads are left out. */\n sources: Pick<RuleSource, \"path\" | \"displayPath\">[];\n /** Marks a turn it recorded with no rules in scope. */\n ledger?: Ledger;\n maxChars?: number;\n}\n\ninterface ToolResult {\n text: string;\n isError: boolean;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n\n/** Every tool_result block in the trace, by the id of the call it answers. */\nfunction toolResults(trace: Trace): Map<string, ToolResult> {\n const out = new Map<string, ToolResult>();\n for (const e of trace.events) {\n if (e.kind !== \"tool_result\") continue;\n const message = e.raw.message;\n const content: unknown = isRecord(message) ? message.content : undefined;\n if (!Array.isArray(content)) continue;\n for (const block of content as unknown[]) {\n if (!isRecord(block) || block.type !== \"tool_result\" || typeof block.tool_use_id !== \"string\") continue;\n const body: unknown = block.content;\n const text =\n typeof body === \"string\"\n ? body\n : Array.isArray(body)\n ? (body as unknown[])\n .flatMap((b) => (isRecord(b) && typeof b.text === \"string\" ? [b.text] : []))\n .join(\"\\n\")\n : \"\";\n out.set(block.tool_use_id, { text, isError: block.is_error === true });\n }\n }\n return out;\n}\n\n/** The `tool_use` id of the call at `index`, read from its event. */\nfunction callId(trace: Trace, index: number): string | undefined {\n // Find by ordinal: the event array need not hold one event per ordinal.\n const id = trace.events.find((e) => e.index === index)?.raw.id;\n return typeof id === \"string\" ? id : undefined;\n}\n\n/** Texts of the task lines in `text` whose box is ticked (`x`) or not (` `). */\nfunction tasks(text: string, ticked: boolean): string[] {\n return text.split(/\\r?\\n/).flatMap((line) => {\n const m = TASK.exec(line);\n const box = m?.[1];\n const body = m?.[2];\n if (box === undefined || body === undefined) return [];\n return (box !== \" \") === ticked ? [body] : [];\n });\n}\n\n/** The tasks an edit ticks: unticked in its old string, ticked with the same text in its new. */\nfunction ticks(oldText: unknown, newText: unknown): string[] {\n if (typeof oldText !== \"string\" || typeof newText !== \"string\") return [];\n const now = new Set(tasks(newText, true));\n return tasks(oldText, false).filter((t) => now.has(t));\n}\n\nconst list = (verb: string, items: string[]): string[] =>\n items.length > 0 ? [`${verb} ${items.join(\", \")}`] : [];\n\n/**\n * The block for the turns before `before`, or \"\" when none did anything.\n * Over `maxChars`, the oldest lines go first, and a marker line says which.\n */\nexport function timelineBlock(trace: Trace, before: number, opts: TimelineOptions): string {\n const scrub = makeRedactor(opts.redact);\n const results = toolResults(trace);\n const starts = trace.events\n .filter((e) => e.index < before && e.sidechain !== true && isTypedPrompt(e))\n .map((e) => e.index);\n\n const lines = starts.flatMap((from, i) => {\n const end = starts[i + 1] ?? before;\n const window = materialize(trace, \"turn\", \"earlier turn\", [{ start: from, end }], undefined, new Set([undefined]));\n // turnFacts reads only the window and bounds; 0 just satisfies TurnSlice.\n const facts = turnFacts(trace, { window, from, to: end - 1, sessionTurnCount: 0 }, opts.sources, opts);\n const spawns = trace.agentSpawns\n .filter((a) => a.index >= from && a.index < end)\n .slice(0, SPAWNS)\n .map((a) => {\n const result = results.get(a.toolUseId ?? callId(trace, a.index) ?? \"\");\n // Redact, then clip, so a cap never lands mid-secret.\n const first = scrub(result?.text ?? \"\").trim().split(/\\r?\\n/)[0]?.trim() ?? \"\";\n return first === \"\"\n ? `spawned ${a.subagentType}`\n : `spawned ${a.subagentType}, which returned ${clipTo(first, RESULT_CHARS)}`;\n });\n const calls = window.toolCalls;\n const asked = calls.some((c) => c.name === \"AskUserQuestion\") ? [\"asked the user\"] : [];\n const ticked = calls.flatMap((c) => {\n if (typeof c.input.file_path !== \"string\") return [];\n const edits: unknown[] =\n c.name === \"Edit\" ? [c.input] : c.name === \"MultiEdit\" && Array.isArray(c.input.edits) ? c.input.edits : [];\n const path = scrub(projectPath(c.input.file_path, opts.cwd, opts.root));\n return edits.flatMap((e) =>\n isRecord(e)\n ? ticks(e.old_string, e.new_string).map((t) => {\n const safe = scrub(t);\n return `ticked ${TASK_ID.exec(safe)?.[0] ?? clipTo(safe, TICK_CHARS)} in ${path}`;\n })\n : [],\n );\n });\n const approved = calls.some((c) => {\n if (c.name !== \"ExitPlanMode\") return false;\n const result = results.get(callId(trace, c.index) ?? \"\");\n return result !== undefined && !result.isError;\n })\n ? [\"had a plan approved\"]\n : [];\n const parts = [\n ...list(\"ran\", facts.commands),\n ...list(\"wrote\", facts.wrote),\n ...list(\"read\", facts.read),\n ...facts.skills.map((s) => `ran skill ${s}`),\n ...spawns,\n ...asked,\n ...[...new Set(ticked)],\n ...approved,\n ];\n if (parts.length === 0) return [];\n const out = opts.ledger?.turns.find((t) => t.turn === from)?.inScope === false;\n return [{ turn: from, line: `- turn ${String(from)}: ${parts.join(\"; \")}${out ? \" (no rules in scope)\" : \"\"}` }];\n });\n\n // Drop the oldest until the block fits, the marker's length included.\n const max = opts.maxChars ?? Number.POSITIVE_INFINITY;\n const marker = (n: number): string => {\n const a = String(lines[0]?.turn);\n const b = String(lines[n - 1]?.turn);\n return n === 1 ? `- (turn ${a}: 1 line left out)` : `- (turns ${a}–${b}: ${String(n)} lines left out)`;\n };\n let kept = lines.reduce((sum, l) => sum + l.line.length + 1, HEAD.length - 1);\n let dropped = 0;\n const size = (): number => kept + (dropped > 0 ? marker(dropped).length + 1 : 0);\n while (dropped < lines.length && size() > max) {\n kept -= (lines[dropped]?.line.length ?? 0) + 1;\n dropped += 1;\n }\n if (dropped === lines.length) return \"\";\n const shown = lines.slice(dropped).map((l) => l.line);\n return `${HEAD}${[...(dropped > 0 ? [marker(dropped)] : []), ...shown].join(\"\\n\")}`;\n}\n"],"mappings":"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","names":["isRecord","decisionOnly"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracevals/judge/provider.ts"],"sourcesContent":["/**\n * Choosing the provider and model, and building the shared inference\n * library's `ProviderSpec` for it.\n *\n * The providers themselves live in `@hawkeyexl/inference` (ADR 01006). The\n * names a provider may have, the two refusals, `--local`, the detection call,\n * the level-bound precedence and the mapping of the family's `providers:`\n * connection settings are `src/shared/providers.ts`, the same code\n * `manni meta fill` and `manni docevals` run. What stays here is what only\n * manni tracevals can decide: which levels it reads (a flag, an eval's own\n * `provider:`/`model:`, `tracevals.provider`/`model`, then the family's\n * `providers:`), and the judge-shaped options a verdict call wants.\n *\n * No model id is named in this file. A model the tool pinned would go stale\n * the week the provider shipped a better one, and would override the default\n * the library keeps current.\n */\nimport {\n makeProvider as makeInferenceProvider,\n mockVerdict,\n type InferenceProvider,\n type MockResponse,\n type ProviderName as ConcreteProvider,\n type ProviderSelector,\n type ProviderSpec,\n} from \"@hawkeyexl/inference\";\nimport { TracevalsError } from \"../types.js\";\nimport type { HostSetting } from \"../rules/host.js\";\nimport type { TracevalsConfig } from \"../core/config.js\";\nimport {\n assertKnownProvider,\n assertLocalFlag,\n assertModelHasProvider,\n localNotice,\n providerSpecFor as sharedProviderSpecFor,\n resolveIdentity,\n selectProvider as selectFromLevels,\n type ProviderChoice,\n type ProviderFlags,\n type ProviderSelection,\n} from \"../../shared/providers.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { noticeOnce } from \"../../shared/warn.js\";\n\nexport type { MockResponse, ProviderChoice, ProviderFlags, ProviderSelection };\n\n/** The decide-only provider (proposal 0079). */\nexport const JEV = \"jev\";\n\n/** Why jev cannot serve out of the loop, and where it goes instead. */\nexport const JEV_OUT_OF_LOOP =\n \"jev answers decisions only, so it cannot extract rules or write verdicts. Use it as tracevals.conformance.hook.provider.\";\n\n/** The key a tracevals user writes, named by the refusal a bare model gets. */\nconst CONFIG_KEY = \"tracevals.provider\";\n\nconst toTracevalsError = (message: string): Error => new TracevalsError(message);\n\n/** What a caller wants of the provider beyond which one it is. */\nexport interface JudgeProviderOptions {\n /**\n * Responses for the `mock` seam. The default is verdict-shaped, which suits\n * judging; callers with a different response schema (criteria proposals,\n * say) must supply their own. `mock` is accepted when named but never\n * offered, so nothing that lists providers mentions it.\n */\n mockResponses?: MockResponse[];\n /**\n * How a `llama-cpp` provider reaches the model host. Unset, it connects to\n * a running host and never starts one, which is every run by hand.\n */\n host?: HostSetting;\n}\n\n/**\n * The provider and model in force: a flag, then the eval's own choice, then\n * `tracevals.provider`/`model`, then the family's `providers.provider`/`model`,\n * then `auto`. A model is carried only to the provider its own level names, so\n * an eval that names a different provider takes that provider's default\n * instead of a model it cannot run (`selectProvider` in the shared module).\n *\n * `--local` runs llama-cpp over all of them. A `--provider` it contradicts is\n * refused here, so no path selects past it. `ev.origin` names the eval in the\n * notice for a provider `--local` replaced; the caller knows its artifact.\n */\nexport function selectProvider(\n config: TracevalsConfig,\n flags: ProviderFlags = {},\n ev: ProviderChoice = {},\n): ProviderSelection {\n assertLocalFlag(flags, toTracevalsError);\n return selectFromLevels(flags, [\n {\n ...(ev.provider !== undefined ? { provider: ev.provider } : {}),\n ...(ev.model !== undefined ? { model: ev.model } : {}),\n ...(ev.origin !== undefined ? { origin: ev.origin } : {}),\n },\n ...configLevels(config),\n ]);\n}\n\n/**\n * The judge inside a hook (proposal 0079, \"Two model roles\"):\n * `conformance.hook.provider`/`model`, then `tracevals.provider`/`model`, then\n * the family's `providers:`, then `auto`. No flag reaches it, because a hook\n * has no command line. A hook level naming only a model lends it to whichever\n * provider wins, as every level does.\n */\nexport function selectHookProvider(config: TracevalsConfig): ProviderSelection {\n const hook = config.conformance?.hook;\n return selectFromLevels({}, [\n {\n ...(hook?.provider != null ? { provider: hook.provider } : {}),\n ...(hook?.model != null ? { model: hook.model } : {}),\n origin: \"tracevals.conformance.hook.provider\",\n },\n ...configLevels(config),\n ]);\n}\n\n/** `tracevals.provider`/`model`, then the family's `providers:`. */\nfunction configLevels(config: TracevalsConfig): ProviderChoice[] {\n return [\n {\n ...(config.provider !== null ? { provider: config.provider } : {}),\n ...(config.model !== null ? { model: config.model } : {}),\n origin: CONFIG_KEY,\n },\n {\n ...(config.providers.provider !== undefined\n ? { provider: config.providers.provider }\n : {}),\n ...(config.providers.model !== undefined ? { model: config.providers.model } : {}),\n origin: \"providers.provider\",\n },\n ];\n}\n\n/**\n * Say what `--local` set aside, once per source. Called where a selection is\n * about to be used, never where it is only checked, so a run that sends\n * nothing to a model says nothing.\n */\nexport function announceSelection(selection: ProviderSelection): void {\n const message = localNotice(selection);\n if (message !== undefined) noticeOnce(message);\n}\n\n/**\n * Refuse a selection that cannot be right, with `manni meta fill`'s messages:\n * an unknown name, or a model under `auto`. Both are `TracevalsError`s, which\n * is what maps them to exit 2.\n */\nexport function assertProviderSelection(selection: ProviderSelection): void {\n // Every caller of this check generates: `run`'s and `calibrate`'s verdicts,\n // `fill`'s proposals, and rule extraction. Only the turn judge may decide.\n if (selection.provider === JEV) throw new TracevalsError(JEV_OUT_OF_LOOP);\n assertKnownProvider(selection.provider, toTracevalsError);\n assertModelHasProvider(selection.provider, selection.model, CONFIG_KEY, toTracevalsError);\n}\n\n/**\n * The spec for a selection, with the family's connection settings for the\n * provider it names, and under `auto` the settings detection reads.\n */\nexport function providerSpecFor(\n config: TracevalsConfig,\n selection: { provider: ProviderSelector; model: string | null },\n options: JudgeProviderOptions = {},\n): ProviderSpec {\n const spec = sharedProviderSpecFor(config.providers, selection);\n switch (selection.provider) {\n case \"anthropic\":\n // A verdict-shaped tool name steers the model better than a generic\n // one, and it is free to keep.\n return { ...spec, anthropic: { toolName: \"record_verdict\" } };\n case \"openai\":\n return { ...spec, openai: { schemaName: \"verdict\" } };\n case \"llama-cpp\":\n return {\n ...spec,\n llamaCpp: { ...spec.llamaCpp, ...(options.host ?? { host: \"connect\" }) },\n };\n case \"mock\":\n return {\n ...spec,\n mockResponses: options.mockResponses ?? [mockVerdict(\"pass\", 0.95)],\n };\n default:\n return spec;\n }\n}\n\n/**\n * The concrete provider and model, WITHOUT constructing the provider: cache\n * keys need it, and a fully cached run must not require an API key.\n *\n * Under `auto` this is where detection runs, exactly as `manni meta fill` runs\n * it, seeing the same connection settings. The model is the RESOLVED one (the\n * provider's default when none was named, a llama-cpp tier's concrete\n * weights), so a library default that changes changes every cache key built\n * from it.\n */\nexport async function resolveProviderIdentity(\n config: TracevalsConfig,\n flags: ProviderFlags = {},\n ev: ProviderChoice = {},\n): Promise<{ provider: ConcreteProvider; model: string }> {\n // Every caller of this generates, so jev is refused here as well as where\n // a command checks its selection up front.\n const selection = selectProvider(config, flags, ev);\n assertProviderSelection(selection);\n return resolveSelectionIdentity(config, selection);\n}\n\n/** `resolveProviderIdentity` for a selection already made. */\nexport async function resolveSelectionIdentity(\n config: TracevalsConfig,\n selection: ProviderSelection,\n): Promise<{ provider: ConcreteProvider; model: string }> {\n const { provider, model } = selection;\n // Generating callers refused jev in assertProviderSelection; reaching here\n // with it means the turn judge, which decides.\n assertKnownProvider(provider, toTracevalsError, { decisions: true });\n assertModelHasProvider(provider, model, CONFIG_KEY, toTracevalsError);\n announceSelection(selection);\n return resolveIdentity(\n providerSpecFor(config, { provider, model: model ?? null }),\n toTracevalsError,\n );\n}\n\n/** Construct a provider for an identity already resolved. */\nexport function constructProvider(\n config: TracevalsConfig,\n identity: { provider: ConcreteProvider; model: string },\n options: JudgeProviderOptions = {},\n): InferenceProvider {\n if (identity.provider === JEV) {\n // Checked here, so the message names the variable a user sets rather than\n // the library's wording for it.\n const keyEnv = config.providers.jev?.apiKeyEnv ?? \"TYPESAFE_API_KEY\";\n const key = process.env[keyEnv];\n if (key === undefined || key === \"\") {\n throw new TracevalsError(`jev needs an API key in ${keyEnv}`);\n }\n }\n try {\n return makeInferenceProvider(providerSpecFor(config, identity, options));\n } catch (e) {\n // The library raises its own InferenceError (a missing API key). It must\n // surface as a TracevalsError: `cli.ts`'s fail() maps only that to exit 2,\n // and letting a foreign error type through turns \"no API key configured\"\n // into an unhandled stack trace.\n throw new TracevalsError(errorMessage(e));\n }\n}\n\n/** Select, check, detect and construct: the provider a verb judges with. */\nexport async function makeJudgeProvider(\n config: TracevalsConfig,\n flags: ProviderFlags = {},\n ev: ProviderChoice = {},\n options: JudgeProviderOptions = {},\n): Promise<InferenceProvider> {\n return constructProvider(\n config,\n await resolveProviderIdentity(config, flags, ev),\n options,\n );\n}\n"],"mappings":"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","names":["selectProvider","providerSpecFor"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracevals/rules/mock.ts","../src/tracevals/commands/conformance.ts","../src/tracevals/rules/cache.ts","../src/tracevals/rules/prompt.ts","../src/tracevals/rules/requests-prompt.ts","../src/tracevals/rules/extract.ts"],"sourcesContent":["/**\n * A deterministic, schema-valid extraction for `--provider mock`.\n *\n * It reads the file the way the real prompt asks a model to, crudely: a bullet\n * that opens with an imperative verb is a rule, everything else is not. That\n * gives offline tests and the CI dogfood path rules they can predict from the\n * fixture alone.\n */\nimport type { InferenceProvider } from \"@hawkeyexl/inference\";\n\nconst IMPERATIVE =\n /^(?:run|use|never|always|do|don't|keep|write|read|prefer|add|avoid|ask|check|make|follow|commit|test|update|stop|ensure)\\b/i;\n\nfunction kebab(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .split(\"-\")\n .filter((w) => w !== \"\")\n .slice(0, 5)\n .join(\"-\");\n}\n\nexport function mockRulesResponse(content: string): {\n json: { rules: { id: string; text: string }[] };\n} {\n const rules: { id: string; text: string }[] = [];\n for (const line of content.split(/\\r?\\n/)) {\n const bullet = /^\\s*[-*]\\s+(.+)$/.exec(line);\n const text = bullet?.[1]?.trim();\n if (text === undefined || !IMPERATIVE.test(text)) continue;\n const id = kebab(text);\n if (id !== \"\") rules.push({ id, text });\n }\n return { json: { rules } };\n}\n\nconst ITEM = /^\\s*(?:[-*]|\\d+\\.)\\s+(?:\\[[ xX]\\]\\s+)?(.+)$/;\nconst SPEC_ITEM = /^(?:\\*\\*)?([A-Z]+-\\d+|T\\d+|\\d+(?:\\.\\d+)+)(?:\\*\\*)?:?\\s+(.+)$/;\n\n/**\n * The same crude reading for a source that says what the session was asked.\n * A bullet, a numbered prompt or a task checkbox is an item. One that opens\n * with a spec's own id (`FR-001`, `T014`, `1.2`) keeps that id, and any other\n * is a rule only when it opens with an imperative verb.\n */\nexport function mockRequestsResponse(content: string): {\n json: { rules: { id: string; text: string }[] };\n} {\n const rules: { id: string; text: string }[] = [];\n for (const line of content.split(/\\r?\\n/)) {\n const item = ITEM.exec(line)?.[1]?.trim();\n if (item === undefined) continue;\n const spec = SPEC_ITEM.exec(item);\n const specId = spec?.[1];\n const specText = spec?.[2]?.trim();\n if (specId !== undefined && specText !== undefined) {\n rules.push({ id: specId, text: specText });\n } else if (IMPERATIVE.test(item)) {\n const id = kebab(item);\n if (id !== \"\") rules.push({ id, text: item });\n }\n }\n return { json: { rules } };\n}\n\nconst PROHIBITION =/^(?:never|don't|do not|avoid)\\b/i;\n\n/**\n * A deterministic turn answer for `--provider mock`, read from the rule's\n * first code span as crudely as `mockRulesResponse` reads a file. A\n * prohibition is not followed when the turn shows its span, and followed\n * otherwise. Any other rule is followed when the turn shows its span. When it\n * does not, every score is 0, which the block bar sends to review. A rule with\n * no code span is followed. The reasoning says which it found.\n */\nexport function mockTurnScores(user: string): Record<string, string | number> {\n const marker = user.lastIndexOf(\"# The rule\\n\\n\");\n // The turn alone: what earlier turns did is not this turn's evidence.\n const turn = user.slice(Math.max(0, user.indexOf(\"# The turn\\n\\n\")), marker);\n const line = user.slice(marker).split(\"\\n\")[2] ?? \"\";\n const text = line.slice(line.indexOf(\": \") + 2);\n const span = /`([^`]+)`/.exec(text)?.[1];\n const answer = (reasoning: string, followed: number, notFollowed: number) => ({\n reasoning,\n \"not-applicable\": 0,\n followed,\n \"not-followed\": notFollowed,\n });\n if (span === undefined) return answer(\"The rule names nothing to look for.\", 100, 0);\n const shown = turn.includes(span);\n const reasoning = shown ? `The turn shows \\`${span}\\`.` : `The turn does not show \\`${span}\\`.`;\n if (PROHIBITION.test(text.trim())) return shown ? answer(reasoning, 0, 100) : answer(reasoning, 100, 0);\n return shown ? answer(reasoning, 100, 0) : answer(reasoning, 0, 0);\n}\n\n/** The turn judge under `--provider mock`: answers from `mockTurnScores`. */\nexport function mockTurnJudge(model: string, name = \"mock\"): InferenceProvider {\n return {\n provider: () => name,\n modelName: () => model,\n completeJSON: (req) => Promise.resolve({ json: mockTurnScores(req.user) }),\n };\n}\n","/**\n * What `prepare` and `check` share (proposal 0079): the two model roles,\n * extraction through the rules cache, and the local-model gates. Free of CLI\n * and IO plumbing, like every command core.\n */\nimport { resolve } from \"node:path\";\nimport type { InferenceProvider, ProviderName } from \"@hawkeyexl/inference\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport type { TracevalsConfig } from \"../core/config.js\";\nimport {\n assertProviderSelection,\n constructProvider,\n resolveSelectionIdentity,\n selectProvider,\n} from \"../judge/provider.js\";\nimport { RulesCache, rulesCacheKey } from \"../rules/cache.js\";\nimport type { HostSetting } from \"../rules/host.js\";\nimport { extractRules, promptFor, type Rule } from \"../rules/extract.js\";\nimport { GB, type LocalModels } from \"../rules/local.js\";\nimport { mockRequestsResponse, mockRulesResponse } from \"../rules/mock.js\";\nimport type { RuleSource } from \"../rules/sources.js\";\nimport { TracevalsError } from \"../types.js\";\n\nexport interface Identity {\n provider: ProviderName;\n model: string;\n}\n\n/**\n * Set on this process before any provider is built, so a judge it spawns\n * (`claude-cli`) runs its own hooks under gate 2 and never judges itself.\n */\nexport const JUDGE_ENV = \"MANNI_TRACEVALS_JUDGE\";\n\nexport function markJudgeProcess(): void {\n process.env[JUDGE_ENV] = \"1\";\n}\n\n/** Providers that never leave the machine, which `--offline` admits. */\nconst LOCAL_PROVIDERS: ReadonlySet<string> = new Set([\"llama-cpp\", \"mock\"]);\n\nexport function isNetworkProvider(provider: string): boolean {\n return !LOCAL_PROVIDERS.has(provider);\n}\n\n/** `--offline` met a role whose provider would leave the machine. */\nexport function offlineRefusal(role: string, identity: Identity): TracevalsError {\n return new TracevalsError(\n `--offline runs no network provider, and ${role} uses ${identity.provider}`,\n );\n}\n\n/** The first line of an error, as every message quoting one shows it. */\nexport function firstLine(err: unknown): string {\n return errorMessage(err).split(\"\\n\")[0] ?? \"\";\n}\n\n/** Defaults filled for a run by hand, where the section may be absent. */\nexport function conformanceOf(config: TracevalsConfig): NonNullable<TracevalsConfig[\"conformance\"]> {\n return (\n config.conformance ?? {\n hook: { provider: null, model: null, runs: 1 },\n include: [],\n exclude: [],\n plans: [],\n }\n );\n}\n\n/** The rules cache, beside the judge's, resolved as `run` resolves it. */\nexport function rulesCacheFor(\n config: TracevalsConfig,\n configDir: string,\n noCache: boolean,\n): RulesCache {\n return new RulesCache(resolve(configDir, config.judge.cacheDir, \"rules\"), !noCache);\n}\n\nexport interface Extraction {\n identity: Identity;\n cache: RulesCache;\n /** Whether a source still needs the model: not declared, not cached. */\n needs(source: RuleSource): boolean;\n /** A source's rules, declared or extracted. */\n rulesOf(source: RuleSource): Promise<{ rules: Rule[]; origin: \"declared\" | \"extracted\" }>;\n}\n\n/**\n * The out-of-loop model as extraction uses it: `tracevals.provider`/`model`,\n * then the family's `providers:`, then `auto`. No flag reaches it, so\n * `prepare`, the hook and `check` share one cache. jev is refused, because\n * extraction generates.\n *\n * The provider is built on the first uncached source, so a fully cached run\n * needs no API key. Under `mock` each source gets a scripted reading of its\n * own text.\n */\nexport async function extraction(\n config: TracevalsConfig,\n cache: RulesCache,\n injected?: InferenceProvider,\n host?: HostSetting,\n): Promise<Extraction> {\n let identity: Identity;\n if (injected !== undefined) {\n identity = { provider: injected.provider() as ProviderName, model: injected.modelName() };\n } else {\n const selection = selectProvider(config);\n assertProviderSelection(selection);\n identity = await resolveSelectionIdentity(config, selection);\n }\n let built: InferenceProvider | undefined = injected;\n const providerFor = (source: RuleSource): InferenceProvider => {\n // Under `mock` each source gets a scripted reading of its own text, so a\n // provider is built per source and never kept.\n if (built === undefined && identity.provider === \"mock\") {\n markJudgeProcess();\n const scripted =\n promptFor(source.format) === \"requests\"\n ? mockRequestsResponse(source.content)\n : mockRulesResponse(source.content);\n return constructProvider(config, identity, { mockResponses: [scripted] });\n }\n // Every other provider is built once, on the first uncached source.\n if (built === undefined) {\n markJudgeProcess();\n built = constructProvider(config, identity, host === undefined ? {} : { host });\n }\n return built;\n };\n const keyOf = (source: RuleSource): string =>\n rulesCacheKey({\n provider: identity.provider,\n model: identity.model,\n prompt: promptFor(source.format),\n temperature: config.judge.temperature,\n sha256: source.sha256,\n });\n return {\n identity,\n cache,\n needs: (source) =>\n source.declaredRules === undefined && cache.get(keyOf(source)) === undefined,\n rulesOf: async (source) => {\n if (source.declaredRules !== undefined) {\n return { rules: source.declaredRules, origin: \"declared\" };\n }\n const hit = cache.get(keyOf(source));\n if (hit !== undefined) return { rules: hit, origin: \"extracted\" };\n try {\n const extracted = await extractRules(\n {\n path: source.displayPath,\n format: source.format,\n content: source.content,\n sha256: source.sha256,\n },\n { provider: providerFor(source), cache, temperature: config.judge.temperature },\n );\n return { rules: extracted.rules, origin: \"extracted\" };\n } catch (err) {\n if (err instanceof TracevalsError) throw err;\n throw new TracevalsError(\n `could not extract rules from ${source.displayPath}: ${firstLine(err)}`,\n );\n }\n },\n };\n}\n\nexport type LocalGate = \"downloading\" | \"not-downloaded\" | \"memory\";\n\nexport interface GateSkip<G extends string = string> {\n gate: G;\n message: string;\n}\n\nconst wholeGb = (bytes: number): number => Math.round(bytes / GB);\n\n/**\n * Gates 5, 7 and 8 for one local model, in that order, each asked only when\n * listed. Nothing here loads or fetches a model: a runtime that is absent is\n * gate 7, and the memory probe is asked only once the runtime is there.\n *\n * The probe forks a worker and initializes the GPU to read free memory, which\n * costs most of a second. `memoryUnneeded` is asked first and, when it says so,\n * the probe is not run: memory only matters to a model about to be loaded.\n */\nexport async function localGate(\n local: LocalModels,\n model: string,\n gates: readonly LocalGate[],\n memoryUnneeded?: () => boolean | Promise<boolean>,\n): Promise<GateSkip<LocalGate> | undefined> {\n const state = await local.state(model);\n if (gates.includes(\"downloading\") && state === \"downloading\") {\n return { gate: \"downloading\", message: `tracevals skipped this turn: ${model} is still downloading.` };\n }\n if (gates.includes(\"not-downloaded\") && (state !== \"ready\" || !(await local.runtimePresent()))) {\n return {\n gate: \"not-downloaded\",\n message: `tracevals skipped this turn: ${model} is not downloaded yet. Run manni tracevals prepare to fetch it.`,\n };\n }\n if (gates.includes(\"memory\") && !(await memoryUnneeded?.())) {\n const fit = await local.fits(model);\n if (!fit.fits) {\n return {\n gate: \"memory\",\n message: `tracevals skipped this turn: ${model} needs about ${String(wholeGb(fit.needBytes))} GB and ${String(wholeGb(fit.freeBytes))} GB is free.`,\n };\n }\n }\n return undefined;\n}\n\n/** By hand a missing local model is an error, and nothing downloads. */\nexport async function assertDownloaded(local: LocalModels, model: string): Promise<void> {\n if ((await local.state(model)) === \"ready\" && (await local.runtimePresent())) return;\n throw new TracevalsError(`${model} is not downloaded; run manni tracevals prepare`);\n}\n","/**\n * Extracted-rules cache: content-addressed JSON holding the *gated* rules for\n * one rule-source file (proposal 0079, \"Extraction and its cache\").\n *\n * The key is the provider, the model, the prompt and its version, and the\n * sha256 of the whole file. The rules prompt and the requirements prompt read\n * one content differently, so each has entries of its own (proposal 0080).\n * The path is deliberately absent: identical content anywhere shares one\n * entry, so a vendored or copied rules file pays once.\n *\n * Reads go through the inference library's `JsonCache`. Writes do not: the\n * library writes in place, so a reader racing a writer could see half an\n * entry. A hook and a `check` run can overlap, so each entry is written to a\n * temporary file and renamed into place.\n */\nimport { mkdirSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { JsonCache, buildCacheKey } from \"@hawkeyexl/inference\";\nimport { warn } from \"../../shared/warn.js\";\nimport type { Rule } from \"./extract.js\";\nimport { RULES_PROMPT_VERSION } from \"./prompt.js\";\nimport { REQUIREMENTS_PROMPT_VERSION } from \"./requests-prompt.js\";\n\n/** Default location, under the tool's per-project cache directory. */\nexport const DEFAULT_RULES_CACHE_DIR = \".manni/tracevals/cache/rules\";\n\nexport interface RulesCacheKeyParts {\n provider: string;\n model: string;\n /** Which extraction prompt read the file. */\n prompt: \"rules\" | \"requests\";\n /** The extraction temperature, `judge.temperature`: another reading of one file. */\n temperature: number;\n /** sha256 of the whole source file. */\n sha256: string;\n}\n\nexport function rulesCacheKey(parts: RulesCacheKeyParts): string {\n return buildCacheKey([\n parts.provider,\n parts.model,\n // The rules prompt keeps the slot's old spelling, so rule files keep\n // their entries.\n parts.prompt === \"rules\"\n ? `rules-v${String(RULES_PROMPT_VERSION)}`\n : `requests-v${String(REQUIREMENTS_PROMPT_VERSION)}`,\n `t${String(parts.temperature)}`,\n parts.sha256,\n ]);\n}\n\nfunction isRule(value: unknown): value is Rule {\n if (typeof value !== \"object\" || value === null) return false;\n const r = value as Record<string, unknown>;\n return (\n typeof r.id === \"string\" &&\n typeof r.text === \"string\" &&\n (r.when === undefined ||\n (typeof r.when === \"object\" && r.when !== null && !Array.isArray(r.when)))\n );\n}\n\nexport class RulesCache {\n private readonly store: JsonCache<unknown>;\n private warned = false;\n\n constructor(\n private readonly dir: string = DEFAULT_RULES_CACHE_DIR,\n private readonly enabled: boolean = true,\n ) {\n this.store = new JsonCache<unknown>(dir, enabled, \"manni-tracevals\");\n }\n\n /** An entry that is not a list of rules, from an older shape, is a miss. */\n get(key: string): Rule[] | undefined {\n const value = this.store.get(key);\n if (!Array.isArray(value) || !value.every(isRule)) return undefined;\n return value;\n }\n\n set(key: string, rules: Rule[]): void {\n if (!this.enabled) return;\n const tmp = join(this.dir, `${key}.${process.pid}.${Date.now()}.tmp`);\n try {\n mkdirSync(this.dir, { recursive: true });\n writeFileSync(tmp, JSON.stringify(rules, null, 2));\n renameSync(tmp, join(this.dir, `${key}.json`));\n } catch (err) {\n rmSync(tmp, { force: true });\n if (!this.warned) {\n this.warned = true;\n warn(\n `could not write the rules cache at ${this.dir} (${err instanceof Error ? err.message : String(err)}). Continuing without caching.`,\n );\n }\n }\n }\n}\n","/**\n * Rule extraction prompt: asks the provider to read ONE rule-source file and\n * return only the directives a session transcript could show followed or\n * broken (proposal 0079, \"Only files that govern an agent\").\n *\n * The whole file goes in, uncapped. A cache keyed on slices would rarely hit,\n * and a partial read would let the agent off for sentences it never saw.\n */\nimport { Ajv2020 } from \"ajv/dist/2020.js\";\n\n/**\n * Part of the cache key: bump whenever the prompt or schema changes.\n *\n * A prompt edit that leaves this alone makes every cached extraction replay the\n * *old* prompt's output, silently, for as long as the cache lives.\n * `test/tracevals/unit/rules-prompt.test.ts` pins this to a digest of the\n * prompt surface so the pair has to move together.\n */\nexport const RULES_PROMPT_VERSION = 2;\n\n/** The `when` field and its conditions, which the requirements prompt shares. */\nexport const WHEN_GUIDE: readonly string[] = [\n \"- `when` (optional): a trigger saying which turns the rule concerns. Every\",\n \" listed condition must hold. The only conditions are:\",\n \" - `file-access`: a glob. The turn read, wrote or edited a matching file.\",\n \" - `tool-used`: a tool name. The turn called that tool.\",\n \" - `prompt-matches`: a regular expression. A prompt the user typed matches.\",\n \" - `turn-count-above`: a whole number. The session has more turns than that.\",\n \" - `command-matches`: a regular expression. A Bash command in the turn matches.\",\n \"\",\n \"Omit `when` unless the rule clearly concerns only certain files, tools or\",\n \"commands. A trigger that is too narrow hides violations, and a rule with no\",\n \"`when` is simply checked on every turn. When in doubt, leave it out.\",\n];\n\nexport const RULES_SYSTEM_PROMPT = [\n \"You extract rules from a file that governs an AI agent working in a repository.\",\n \"\",\n \"A rule is a directive addressed to the AI agent, which a recorded session\",\n \"transcript could show it following or breaking. The transcript holds the\",\n \"agent's prompts, its tool calls (with their inputs), the files it read or\",\n \"wrote, and its replies. Nothing else is observable.\",\n \"\",\n \"Return a rule only when the file tells the agent to do, or not to do,\",\n \"something. Return nothing for:\",\n \"- descriptions of how a system, tool or codebase behaves;\",\n \"- instructions written for end users or readers rather than the agent;\",\n \"- examples, sample output and code listings;\",\n \"- rules the file quotes from somewhere else, or reports as another party's.\",\n \"\",\n \"Keep a procedure's rules too, which a session shows across many turns:\",\n \"the order of steps, a gate that one step must pass before another, a route\",\n \"that a step's result chooses, a condition that calls for a step, a required\",\n \"step, and the step that comes last. Write each as its own rule.\",\n \"\",\n 'Drop a directive a transcript cannot show, such as \"prefer boring code\" or',\n '\"keep things simple\". If you cannot say what a violation would look like in',\n \"a transcript, it does not qualify.\",\n \"\",\n \"Each rule has:\",\n \"- `id`: a short kebab-case identifier, unique within this file.\",\n \"- `text`: one imperative sentence, faithful to the file. Do not strengthen,\",\n \" soften or merge directives, and do not invent ones the file lacks.\",\n ...WHEN_GUIDE,\n \"\",\n \"Return none at all when nothing qualifies.\",\n].join(\"\\n\");\n\nexport const RULES_SCHEMA = {\n type: \"object\",\n required: [\"rules\"],\n additionalProperties: false,\n properties: {\n rules: {\n type: \"array\",\n items: {\n type: \"object\",\n required: [\"id\", \"text\"],\n additionalProperties: false,\n properties: {\n id: { type: \"string\" },\n text: { type: \"string\", minLength: 1 },\n // Open on purpose: `extractRules` gates each `when` with `validateWhen`\n // and drops the one rule, where a schema miss would void the whole file.\n when: { type: \"object\" },\n },\n },\n },\n },\n} as const;\n\nconst ajv = new Ajv2020({ allErrors: true });\nconst validateRules = ajv.compile(\n RULES_SCHEMA as unknown as Record<string, unknown>,\n);\n\nexport function isValidRules(value: unknown): boolean {\n return validateRules(value);\n}\n\nexport interface RulesUserOptions {\n path: string;\n format: string;\n content: string;\n}\n\nexport function buildRulesUser(options: RulesUserOptions): string {\n return [\n \"# Rule source\",\n `path: ${options.path}`,\n `format: ${options.format}`,\n \"\",\n \"# File content\",\n \"\",\n options.content,\n ].join(\"\\n\");\n}\n","/**\n * Requirements extraction prompt: asks the provider to read ONE source that\n * says what the session was asked to build or keep, and return each item as a\n * rule in 0079's shape (proposal 0080, \"What the session was asked\").\n *\n * The sources are the typed prompts, an approved plan, and spec files. The\n * response schema and the `when` grammar are the rules prompt's, so a\n * requirement is judged like any other rule.\n */\nimport { WHEN_GUIDE } from \"./prompt.js\";\n\n/**\n * Part of the cache key: bump whenever the prompt changes.\n * `test/tracevals/unit/requests-prompt.test.ts` pins this to a digest of the\n * prompt surface so the pair has to move together.\n */\nexport const REQUIREMENTS_PROMPT_VERSION = 1;\n\n/** The source formats that say what the session was asked, which this prompt reads. */\nconst REQUEST_FORMATS: ReadonlySet<string> = new Set([\n \"prompt\",\n \"plan\",\n \"speckit-spec\",\n \"kiro-spec\",\n \"openspec-change\",\n \"plans\",\n]);\n\nexport function isRequestFormat(format: string): boolean {\n return REQUEST_FORMATS.has(format);\n}\n\nexport const REQUIREMENTS_SYSTEM_PROMPT = [\n \"You read what an AI agent working in a repository was asked to build or keep,\",\n \"and return each item as a rule.\",\n \"\",\n \"The source is one of three things: the prompts a person typed in the\",\n \"session, numbered in order; a plan the person approved; or a spec file,\",\n \"such as a feature spec, a design, a task list or a change proposal.\",\n \"\",\n \"A rule is something the work must deliver or keep, which a recorded session\",\n \"transcript could show met or broken. The transcript holds the agent's\",\n \"prompts, its tool calls (with their inputs), the files it read or wrote, and\",\n \"its replies. Nothing else is observable.\",\n \"\",\n \"Typed prompts are one sequence. Return the set that stands after the last\",\n \"prompt: a later prompt can add an item, change an earlier one, or drop it.\",\n \"A question with nothing to build yields nothing. Never return chat, such as\",\n \"greetings, thanks, or remarks about the work.\",\n \"\",\n \"A spec's items keep the spec's own ids, exactly as written, such as\",\n \"`FR-001`, `T014` or `1.2`. A task the file marks done is still a rule:\",\n \"ticking it says that task is done.\",\n \"\",\n \"Return nothing for background, rationale, examples, open questions, or\",\n \"items the source marks out of scope.\",\n \"\",\n \"Each rule has:\",\n \"- `id`: the source's own id for the item when it gives one, exactly as\",\n \" written. Otherwise a short kebab-case identifier. Unique within this source.\",\n \"- `text`: one imperative sentence, faithful to the source. Do not strengthen,\",\n \" soften or merge items, and do not invent ones the source lacks.\",\n ...WHEN_GUIDE,\n \"\",\n \"Return none at all when nothing qualifies.\",\n].join(\"\\n\");\n\nexport interface RequirementsUserOptions {\n path: string;\n format: string;\n content: string;\n}\n\nexport function buildRequirementsUser(options: RequirementsUserOptions): string {\n return [\n \"# Request source\",\n // Callers pass the display path (`prompt`, `plan`); a blank one names the format.\n `path: ${options.path !== \"\" ? options.path : options.format}`,\n `format: ${options.format}`,\n \"\",\n \"# Content\",\n \"\",\n options.content,\n ].join(\"\\n\");\n}\n","/**\n * Extract the rules one rule-source file declares for the agent, then gate\n * them (proposal 0079). The model proposes; the gate decides what survives, and\n * a rule it drops is reported with a reason rather than lost.\n *\n * A source that says what the session was asked, such as the typed prompts, a\n * plan or a spec, is read by the requirements prompt instead (proposal 0080).\n * Its gate keeps a spec's own ids as written, so `T014` and `1.2` survive.\n */\nimport {\n completeValidatedJSON,\n type InferenceProvider,\n} from \"@hawkeyexl/inference\";\nimport { validateWhen } from \"../graders/when.js\";\nimport { type RulesCache, rulesCacheKey } from \"./cache.js\";\nimport {\n RULES_SCHEMA,\n RULES_SYSTEM_PROMPT,\n buildRulesUser,\n isValidRules,\n} from \"./prompt.js\";\nimport {\n REQUIREMENTS_SYSTEM_PROMPT,\n buildRequirementsUser,\n isRequestFormat,\n} from \"./requests-prompt.js\";\n\nexport interface Rule {\n id: string;\n text: string;\n when?: Record<string, unknown>;\n}\n\nexport interface ExtractSource {\n path: string;\n format: string;\n content: string;\n /** sha256 of `content`; the cache key, so the path never enters it. */\n sha256: string;\n}\n\nexport interface ExtractDeps {\n provider: InferenceProvider;\n cache?: RulesCache;\n temperature?: number;\n}\n\nexport interface ExtractedRules {\n rules: Rule[];\n cached: boolean;\n dropped: { id?: string; reason: string }[];\n}\n\nconst KEBAB = /^[a-z0-9][a-z0-9-]*$/;\n/** A spec's own id, such as `FR-001`, `T014` or `1.2`, or a kebab-case one. */\nconst SPEC_ID = /^[A-Za-z0-9][A-Za-z0-9.-]*$/;\n\n/** Each extraction prompt, and the ids its gate accepts. */\nconst PROMPTS = {\n rules: {\n system: RULES_SYSTEM_PROMPT,\n user: buildRulesUser,\n id: KEBAB,\n idReason: \"id is not kebab-case\",\n },\n requests: {\n system: REQUIREMENTS_SYSTEM_PROMPT,\n user: buildRequirementsUser,\n id: SPEC_ID,\n idReason: \"id is neither a spec's own id nor kebab-case\",\n },\n} as const;\n\nexport type ExtractionPrompt = keyof typeof PROMPTS;\n\n/** The prompt a source of this format is read with. */\nexport function promptFor(format: string): ExtractionPrompt {\n return isRequestFormat(format) ? \"requests\" : \"rules\";\n}\n\n/** Gate the model's rules: valid id, text, unique id, grounded `when`. */\nexport function gateRules(\n proposed: Rule[],\n prompt: ExtractionPrompt = \"rules\",\n): Pick<ExtractedRules, \"rules\" | \"dropped\"> {\n const { id: idPattern, idReason } = PROMPTS[prompt];\n const rules: Rule[] = [];\n const dropped: ExtractedRules[\"dropped\"] = [];\n const seen = new Set<string>();\n for (const proposedRule of proposed) {\n // An empty `when` names no condition, which is what an absent one means.\n // Local models write it that way, so it is read as absent, not refused.\n const { when, ...bare } = proposedRule;\n const rule: Rule = when === undefined || Object.keys(when).length === 0 ? bare : proposedRule;\n if (!idPattern.test(rule.id)) {\n dropped.push({ id: rule.id, reason: idReason });\n } else if (rule.text.trim() === \"\") {\n dropped.push({ id: rule.id, reason: \"text is empty\" });\n } else if (seen.has(rule.id)) {\n dropped.push({ id: rule.id, reason: \"id repeats an earlier rule\" });\n } else {\n const invalid =\n rule.when === undefined ? undefined : validateWhen({ when: rule.when });\n if (invalid !== undefined) {\n dropped.push({ id: rule.id, reason: invalid });\n } else {\n seen.add(rule.id);\n rules.push(rule);\n }\n }\n }\n return { rules, dropped };\n}\n\n/**\n * Throws when the provider errors or returns a shape the schema rejects, so a\n * caller can tell \"this file yielded no rules\" (an empty list) from \"the model\n * never answered\".\n */\nexport async function extractRules(\n source: ExtractSource,\n deps: ExtractDeps,\n): Promise<ExtractedRules> {\n const { provider, cache } = deps;\n const prompt = promptFor(source.format);\n const key = rulesCacheKey({\n provider: provider.provider(),\n model: provider.modelName(),\n prompt,\n temperature: deps.temperature ?? 0,\n sha256: source.sha256,\n });\n\n const hit = cache?.get(key);\n if (hit !== undefined) return { rules: hit, cached: true, dropped: [] };\n\n const run = await completeValidatedJSON<{ rules: Rule[] }>({\n provider,\n system: PROMPTS[prompt].system,\n user: PROMPTS[prompt].user(source),\n schema: RULES_SCHEMA,\n ...(deps.temperature !== undefined ? { temperature: deps.temperature } : {}),\n });\n if (run.result === undefined || !isValidRules(run.result)) {\n throw new Error(\n run.error ?? \"provider returned rules that do not match the schema\",\n );\n }\n\n const gated = gateRules(run.result.rules, prompt);\n cache?.set(key, gated.rules);\n return { ...gated, cached: false };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAUA,IAAM,aACJ;AAEF,SAAS,MAAM,MAAsB;AACnC,SAAO,KACJ,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,MAAM,GAAG,EACT,OAAO,CAAC,MAAM,MAAM,EAAE,EACtB,MAAM,GAAG,CAAC,EACV,KAAK,GAAG;AACb;AAEO,SAAS,kBAAkB,SAEhC;AACA,QAAM,QAAwC,CAAC;AAC/C,aAAW,QAAQ,QAAQ,MAAM,OAAO,GAAG;AACzC,UAAM,SAAS,mBAAmB,KAAK,IAAI;AAC3C,UAAM,OAAO,SAAS,CAAC,GAAG,KAAK;AAC/B,QAAI,SAAS,UAAa,CAAC,WAAW,KAAK,IAAI,EAAG;AAClD,UAAM,KAAK,MAAM,IAAI;AACrB,QAAI,OAAO,GAAI,OAAM,KAAK,EAAE,IAAI,KAAK,CAAC;AAAA,EACxC;AACA,SAAO,EAAE,MAAM,EAAE,MAAM,EAAE;AAC3B;AAEA,IAAM,OAAO;AACb,IAAM,YAAY;AAQX,SAAS,qBAAqB,SAEnC;AACA,QAAM,QAAwC,CAAC;AAC/C,aAAW,QAAQ,QAAQ,MAAM,OAAO,GAAG;AACzC,UAAM,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK;AACxC,QAAI,SAAS,OAAW;AACxB,UAAM,OAAO,UAAU,KAAK,IAAI;AAChC,UAAM,SAAS,OAAO,CAAC;AACvB,UAAM,WAAW,OAAO,CAAC,GAAG,KAAK;AACjC,QAAI,WAAW,UAAa,aAAa,QAAW;AAClD,YAAM,KAAK,EAAE,IAAI,QAAQ,MAAM,SAAS,CAAC;AAAA,IAC3C,WAAW,WAAW,KAAK,IAAI,GAAG;AAChC,YAAM,KAAK,MAAM,IAAI;AACrB,UAAI,OAAO,GAAI,OAAM,KAAK,EAAE,IAAI,MAAM,KAAK,CAAC;AAAA,IAC9C;AAAA,EACF;AACA,SAAO,EAAE,MAAM,EAAE,MAAM,EAAE;AAC3B;AAEA,IAAM,cAAa;AAUZ,SAAS,eAAe,MAA+C;AAC5E,QAAM,SAAS,KAAK,YAAY,gBAAgB;AAEhD,QAAM,OAAO,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,QAAQ,gBAAgB,CAAC,GAAG,MAAM;AAC3E,QAAM,OAAO,KAAK,MAAM,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,KAAK;AAClD,QAAM,OAAO,KAAK,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC;AAC9C,QAAM,OAAO,YAAY,KAAK,IAAI,IAAI,CAAC;AACvC,QAAM,SAAS,CAACA,YAAmB,UAAkB,iBAAyB;AAAA,IAC5E,WAAAA;AAAA,IACA,kBAAkB;AAAA,IAClB;AAAA,IACA,gBAAgB;AAAA,EAClB;AACA,MAAI,SAAS,OAAW,QAAO,OAAO,uCAAuC,KAAK,CAAC;AACnF,QAAM,QAAQ,KAAK,SAAS,IAAI;AAChC,QAAM,YAAY,QAAQ,oBAAoB,IAAI,QAAQ,4BAA4B,IAAI;AAC1F,MAAI,YAAY,KAAK,KAAK,KAAK,CAAC,EAAG,QAAO,QAAQ,OAAO,WAAW,GAAG,GAAG,IAAI,OAAO,WAAW,KAAK,CAAC;AACtG,SAAO,QAAQ,OAAO,WAAW,KAAK,CAAC,IAAI,OAAO,WAAW,GAAG,CAAC;AACnE;AAGO,SAAS,cAAc,OAAe,OAAO,QAA2B;AAC7E,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,cAAc,CAAC,QAAQ,QAAQ,QAAQ,EAAE,MAAM,eAAe,IAAI,IAAI,EAAE,CAAC;AAAA,EAC3E;AACF;;;AClGA,SAAS,eAAe;;;ACUxB,SAAS,WAAW,YAAY,QAAQ,qBAAqB;AAC7D,SAAS,YAAY;AACrB,SAAS,WAAW,qBAAqB;;;ACTzC,SAAS,eAAe;AAUjB,IAAM,uBAAuB;AAG7B,IAAM,aAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AAAA,EACH;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAEJ,IAAM,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,UAAU,CAAC,OAAO;AAAA,EAClB,sBAAsB;AAAA,EACtB,YAAY;AAAA,IACV,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,QACL,MAAM;AAAA,QACN,UAAU,CAAC,MAAM,MAAM;AAAA,QACvB,sBAAsB;AAAA,QACtB,YAAY;AAAA,UACV,IAAI,EAAE,MAAM,SAAS;AAAA,UACrB,MAAM,EAAE,MAAM,UAAU,WAAW,EAAE;AAAA;AAAA;AAAA,UAGrC,MAAM,EAAE,MAAM,SAAS;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,MAAM,IAAI,QAAQ,EAAE,WAAW,KAAK,CAAC;AAC3C,IAAM,gBAAgB,IAAI;AAAA,EACxB;AACF;AAEO,SAAS,aAAa,OAAyB;AACpD,SAAO,cAAc,KAAK;AAC5B;AAQO,SAAS,eAAe,SAAmC;AAChE,SAAO;AAAA,IACL;AAAA,IACA,SAAS,QAAQ,IAAI;AAAA,IACrB,WAAW,QAAQ,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,EAAE,KAAK,IAAI;AACb;;;ACpGO,IAAM,8BAA8B;AAG3C,IAAM,kBAAuC,oBAAI,IAAI;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,gBAAgB,QAAyB;AACvD,SAAO,gBAAgB,IAAI,MAAM;AACnC;AAEO,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AAAA,EACH;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAQJ,SAAS,sBAAsB,SAA0C;AAC9E,SAAO;AAAA,IACL;AAAA;AAAA,IAEA,SAAS,QAAQ,SAAS,KAAK,QAAQ,OAAO,QAAQ,MAAM;AAAA,IAC5D,WAAW,QAAQ,MAAM;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV,EAAE,KAAK,IAAI;AACb;;;AF5DO,IAAM,0BAA0B;AAahC,SAAS,cAAc,OAAmC;AAC/D,SAAO,cAAc;AAAA,IACnB,MAAM;AAAA,IACN,MAAM;AAAA;AAAA;AAAA,IAGN,MAAM,WAAW,UACb,UAAU,OAAO,oBAAoB,CAAC,KACtC,aAAa,OAAO,2BAA2B,CAAC;AAAA,IACpD,IAAI,OAAO,MAAM,WAAW,CAAC;AAAA,IAC7B,MAAM;AAAA,EACR,CAAC;AACH;AAEA,SAAS,OAAO,OAA+B;AAC7C,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,OAAO,YAChB,OAAO,EAAE,SAAS,aACjB,EAAE,SAAS,UACT,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,QAAQ,CAAC,MAAM,QAAQ,EAAE,IAAI;AAE7E;AAEO,IAAM,aAAN,MAAiB;AAAA,EAItB,YACmB,MAAc,yBACd,UAAmB,MACpC;AAFiB;AACA;AAEjB,SAAK,QAAQ,IAAI,UAAmB,KAAK,SAAS,iBAAiB;AAAA,EACrE;AAAA,EAJmB;AAAA,EACA;AAAA,EALF;AAAA,EACT,SAAS;AAAA;AAAA,EAUjB,IAAI,KAAiC;AACnC,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,MAAM,MAAM,EAAG,QAAO;AAC1D,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,KAAa,OAAqB;AACpC,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,MAAM,KAAK,KAAK,KAAK,GAAG,GAAG,IAAI,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,MAAM;AACpE,QAAI;AACF,gBAAU,KAAK,KAAK,EAAE,WAAW,KAAK,CAAC;AACvC,oBAAc,KAAK,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AACjD,iBAAW,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,OAAO,CAAC;AAAA,IAC/C,SAAS,KAAK;AACZ,aAAO,KAAK,EAAE,OAAO,KAAK,CAAC;AAC3B,UAAI,CAAC,KAAK,QAAQ;AAChB,aAAK,SAAS;AACd;AAAA,UACE,sCAAsC,KAAK,GAAG,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACrG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AGxFA;AAAA,EACE;AAAA,OAEK;AAyCP,IAAM,QAAQ;AAEd,IAAM,UAAU;AAGhB,IAAM,UAAU;AAAA,EACd,OAAO;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,UAAU;AAAA,EACZ;AAAA,EACA,UAAU;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,UAAU;AAAA,EACZ;AACF;AAKO,SAAS,UAAU,QAAkC;AAC1D,SAAO,gBAAgB,MAAM,IAAI,aAAa;AAChD;AAGO,SAAS,UACd,UACA,SAA2B,SACgB;AAC3C,QAAM,EAAE,IAAI,WAAW,SAAS,IAAI,QAAQ,MAAM;AAClD,QAAM,QAAgB,CAAC;AACvB,QAAM,UAAqC,CAAC;AAC5C,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,gBAAgB,UAAU;AAGnC,UAAM,EAAE,MAAM,GAAG,KAAK,IAAI;AAC1B,UAAM,OAAa,SAAS,UAAa,OAAO,KAAK,IAAI,EAAE,WAAW,IAAI,OAAO;AACjF,QAAI,CAAC,UAAU,KAAK,KAAK,EAAE,GAAG;AAC5B,cAAQ,KAAK,EAAE,IAAI,KAAK,IAAI,QAAQ,SAAS,CAAC;AAAA,IAChD,WAAW,KAAK,KAAK,KAAK,MAAM,IAAI;AAClC,cAAQ,KAAK,EAAE,IAAI,KAAK,IAAI,QAAQ,gBAAgB,CAAC;AAAA,IACvD,WAAW,KAAK,IAAI,KAAK,EAAE,GAAG;AAC5B,cAAQ,KAAK,EAAE,IAAI,KAAK,IAAI,QAAQ,6BAA6B,CAAC;AAAA,IACpE,OAAO;AACL,YAAM,UACJ,KAAK,SAAS,SAAY,SAAY,aAAa,EAAE,MAAM,KAAK,KAAK,CAAC;AACxE,UAAI,YAAY,QAAW;AACzB,gBAAQ,KAAK,EAAE,IAAI,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAAA,MAC/C,OAAO;AACL,aAAK,IAAI,KAAK,EAAE;AAChB,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAOA,eAAsB,aACpB,QACA,MACyB;AACzB,QAAM,EAAE,UAAU,MAAM,IAAI;AAC5B,QAAM,SAAS,UAAU,OAAO,MAAM;AACtC,QAAM,MAAM,cAAc;AAAA,IACxB,UAAU,SAAS,SAAS;AAAA,IAC5B,OAAO,SAAS,UAAU;AAAA,IAC1B;AAAA,IACA,aAAa,KAAK,eAAe;AAAA,IACjC,QAAQ,OAAO;AAAA,EACjB,CAAC;AAED,QAAM,MAAM,OAAO,IAAI,GAAG;AAC1B,MAAI,QAAQ,OAAW,QAAO,EAAE,OAAO,KAAK,QAAQ,MAAM,SAAS,CAAC,EAAE;AAEtE,QAAM,MAAM,MAAM,sBAAyC;AAAA,IACzD;AAAA,IACA,QAAQ,QAAQ,MAAM,EAAE;AAAA,IACxB,MAAM,QAAQ,MAAM,EAAE,KAAK,MAAM;AAAA,IACjC,QAAQ;AAAA,IACR,GAAI,KAAK,gBAAgB,SAAY,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,EAC5E,CAAC;AACD,MAAI,IAAI,WAAW,UAAa,CAAC,aAAa,IAAI,MAAM,GAAG;AACzD,UAAM,IAAI;AAAA,MACR,IAAI,SAAS;AAAA,IACf;AAAA,EACF;AAEA,QAAM,QAAQ,UAAU,IAAI,OAAO,OAAO,MAAM;AAChD,SAAO,IAAI,KAAK,MAAM,KAAK;AAC3B,SAAO,EAAE,GAAG,OAAO,QAAQ,MAAM;AACnC;;;AJxHO,IAAM,YAAY;AAElB,SAAS,mBAAyB;AACvC,UAAQ,IAAI,SAAS,IAAI;AAC3B;AAGA,IAAM,kBAAuC,oBAAI,IAAI,CAAC,aAAa,MAAM,CAAC;AAEnE,SAAS,kBAAkB,UAA2B;AAC3D,SAAO,CAAC,gBAAgB,IAAI,QAAQ;AACtC;AAGO,SAAS,eAAe,MAAc,UAAoC;AAC/E,SAAO,IAAI;AAAA,IACT,2CAA2C,IAAI,SAAS,SAAS,QAAQ;AAAA,EAC3E;AACF;AAGO,SAAS,UAAU,KAAsB;AAC9C,SAAO,aAAa,GAAG,EAAE,MAAM,IAAI,EAAE,CAAC,KAAK;AAC7C;AAGO,SAAS,cAAc,QAAsE;AAClG,SACE,OAAO,eAAe;AAAA,IACpB,MAAM,EAAE,UAAU,MAAM,OAAO,MAAM,MAAM,EAAE;AAAA,IAC7C,SAAS,CAAC;AAAA,IACV,SAAS,CAAC;AAAA,IACV,OAAO,CAAC;AAAA,EACV;AAEJ;AAGO,SAAS,cACd,QACA,WACA,SACY;AACZ,SAAO,IAAI,WAAW,QAAQ,WAAW,OAAO,MAAM,UAAU,OAAO,GAAG,CAAC,OAAO;AACpF;AAqBA,eAAsB,WACpB,QACA,OACA,UACA,MACqB;AACrB,MAAI;AACJ,MAAI,aAAa,QAAW;AAC1B,eAAW,EAAE,UAAU,SAAS,SAAS,GAAmB,OAAO,SAAS,UAAU,EAAE;AAAA,EAC1F,OAAO;AACL,UAAM,YAAY,eAAe,MAAM;AACvC,4BAAwB,SAAS;AACjC,eAAW,MAAM,yBAAyB,QAAQ,SAAS;AAAA,EAC7D;AACA,MAAI,QAAuC;AAC3C,QAAM,cAAc,CAAC,WAA0C;AAG7D,QAAI,UAAU,UAAa,SAAS,aAAa,QAAQ;AACvD,uBAAiB;AACjB,YAAM,WACJ,UAAU,OAAO,MAAM,MAAM,aACzB,qBAAqB,OAAO,OAAO,IACnC,kBAAkB,OAAO,OAAO;AACtC,aAAO,kBAAkB,QAAQ,UAAU,EAAE,eAAe,CAAC,QAAQ,EAAE,CAAC;AAAA,IAC1E;AAEA,QAAI,UAAU,QAAW;AACvB,uBAAiB;AACjB,cAAQ,kBAAkB,QAAQ,UAAU,SAAS,SAAY,CAAC,IAAI,EAAE,KAAK,CAAC;AAAA,IAChF;AACA,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,CAAC,WACb,cAAc;AAAA,IACZ,UAAU,SAAS;AAAA,IACnB,OAAO,SAAS;AAAA,IAChB,QAAQ,UAAU,OAAO,MAAM;AAAA,IAC/B,aAAa,OAAO,MAAM;AAAA,IAC1B,QAAQ,OAAO;AAAA,EACjB,CAAC;AACH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,CAAC,WACN,OAAO,kBAAkB,UAAa,MAAM,IAAI,MAAM,MAAM,CAAC,MAAM;AAAA,IACrE,SAAS,OAAO,WAAW;AACzB,UAAI,OAAO,kBAAkB,QAAW;AACtC,eAAO,EAAE,OAAO,OAAO,eAAe,QAAQ,WAAW;AAAA,MAC3D;AACA,YAAM,MAAM,MAAM,IAAI,MAAM,MAAM,CAAC;AACnC,UAAI,QAAQ,OAAW,QAAO,EAAE,OAAO,KAAK,QAAQ,YAAY;AAChE,UAAI;AACF,cAAM,YAAY,MAAM;AAAA,UACtB;AAAA,YACE,MAAM,OAAO;AAAA,YACb,QAAQ,OAAO;AAAA,YACf,SAAS,OAAO;AAAA,YAChB,QAAQ,OAAO;AAAA,UACjB;AAAA,UACA,EAAE,UAAU,YAAY,MAAM,GAAG,OAAO,aAAa,OAAO,MAAM,YAAY;AAAA,QAChF;AACA,eAAO,EAAE,OAAO,UAAU,OAAO,QAAQ,YAAY;AAAA,MACvD,SAAS,KAAK;AACZ,YAAI,eAAe,eAAgB,OAAM;AACzC,cAAM,IAAI;AAAA,UACR,gCAAgC,OAAO,WAAW,KAAK,UAAU,GAAG,CAAC;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AASA,IAAM,UAAU,CAAC,UAA0B,KAAK,MAAM,QAAQ,EAAE;AAWhE,eAAsB,UACpB,OACA,OACA,OACA,gBAC0C;AAC1C,QAAM,QAAQ,MAAM,MAAM,MAAM,KAAK;AACrC,MAAI,MAAM,SAAS,aAAa,KAAK,UAAU,eAAe;AAC5D,WAAO,EAAE,MAAM,eAAe,SAAS,gCAAgC,KAAK,yBAAyB;AAAA,EACvG;AACA,MAAI,MAAM,SAAS,gBAAgB,MAAM,UAAU,WAAW,CAAE,MAAM,MAAM,eAAe,IAAK;AAC9F,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,gCAAgC,KAAK;AAAA,IAChD;AAAA,EACF;AACA,MAAI,MAAM,SAAS,QAAQ,KAAK,CAAE,MAAM,iBAAiB,GAAI;AAC3D,UAAM,MAAM,MAAM,MAAM,KAAK,KAAK;AAClC,QAAI,CAAC,IAAI,MAAM;AACb,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,gCAAgC,KAAK,gBAAgB,OAAO,QAAQ,IAAI,SAAS,CAAC,CAAC,WAAW,OAAO,QAAQ,IAAI,SAAS,CAAC,CAAC;AAAA,MACvI;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAsB,iBAAiB,OAAoB,OAA8B;AACvF,MAAK,MAAM,MAAM,MAAM,KAAK,MAAO,WAAY,MAAM,MAAM,eAAe,EAAI;AAC9E,QAAM,IAAI,eAAe,GAAG,KAAK,iDAAiD;AACpF;","names":["reasoning"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tracevals/rules/local.ts","../src/tracevals/reporters/conformance.ts"],"sourcesContent":["/**\n * What tracevals asks of a local model without loading it (proposal 0079,\n * gates 5, 8 and 9, and `prepare`). The inference library owns every answer;\n * this is the one seam, so a test can say \"downloading\" without a runtime.\n */\nimport {\n ensureModel,\n fits,\n modelState,\n nodeLlamaCppStatus,\n type EnsureModelResult,\n type FitsResult,\n type LlamaModelState,\n} from \"@hawkeyexl/inference\";\nimport type { ProviderConnections } from \"../../shared/providers.js\";\n\nexport interface LocalModels {\n /** Whether the llama.cpp binding is importable now, installing nothing. */\n runtimePresent(): Promise<boolean>;\n /** `ready`, `downloading` or `missing`, read without loading or fetching. */\n state(model: string): Promise<LlamaModelState>;\n /** The memory probe `auto` tiering uses. */\n fits(model: string): Promise<FitsResult>;\n /** Fetch the runtime and the weights, without loading either. */\n ensure(model: string): Promise<EnsureModelResult>;\n}\n\n/** The library's lifecycle calls, pointed at the family's models directory. */\nexport function libraryLocalModels(connections: ProviderConnections): LocalModels {\n const modelsDir = connections[\"llama-cpp\"]?.modelsDir;\n const options = modelsDir === undefined ? {} : { modelsDirectory: modelsDir };\n return {\n runtimePresent: async () => (await nodeLlamaCppStatus()).state === \"present\",\n state: (model) => modelState(model, options),\n fits: (model) => fits(model, options),\n ensure: (model) => ensureModel(model, options),\n };\n}\n\n/** Bytes in a gigabyte as the messages count them. */\nexport const GB = 1024 ** 3;\n","/**\n * Pretty output for `check`, `prepare` and `release` (proposal 0079). JSON is\n * each report as it stands, so only prose lives here. Colour is the caller's\n * decision, made once by `colorFor`.\n */\nimport { palette } from \"../../shared/color.js\";\nimport type { CheckReport } from \"../commands/check.js\";\nimport type { PrepareReport } from \"../commands/prepare.js\";\nimport type { ReleaseReport } from \"../commands/release.js\";\nimport { GB } from \"../rules/local.js\";\n\nconst count = (n: number, one: string, many: string): string =>\n `${String(n)} ${n === 1 ? one : many}`;\n\n/** Findings grouped under their source, then the closing line. */\nexport function renderCheck(report: CheckReport, opts: { color?: boolean } = {}): string {\n const pc = palette(opts.color === true);\n const lines: string[] = [];\n for (const source of report.sources) {\n const findings = report.findings.filter((f) => f.source === source.path);\n if (findings.length === 0) continue;\n lines.push(source.path);\n for (const f of findings) {\n const mark =\n f.outcome !== \"fail\" ? pc.yellow(\"?\") : f.severity === \"error\" ? pc.red(\"✖\") : pc.yellow(\"!\");\n lines.push(` ${mark} ${f.rule} ${f.text}`);\n lines.push(` ${pc.dim(`${f.observed} (${f.confidence.toFixed(2)})`)}`);\n }\n }\n lines.push(...sessionSoFar(report));\n for (const warning of report.warnings) lines.push(`${pc.yellow(\"!\")} ${warning}`);\n if (lines.length > 0) lines.push(\"\");\n lines.push(closing(report));\n return lines.join(\"\\n\");\n}\n\n/** The ledger's rules that were ever broken or sent to review, and a count of the rest. */\nfunction sessionSoFar(report: CheckReport): string[] {\n const rules = report.session?.rules ?? [];\n if (rules.length === 0) return [];\n const flagged = rules.filter((r) => r.broken > 0 || r.needsReview > 0);\n const lines = flagged.map((r) => {\n const counts = [\n [\"broken\", r.broken],\n [\"repaired\", r.repaired],\n [\"needs review\", r.needsReview],\n [\"followed\", r.followed],\n ] as const;\n const said = counts.filter(([, n]) => n > 0).map(([word, n]) => `${word} ${String(n)}`);\n return ` ${r.source}#${r.rule} ${said.join(\", \")}`;\n });\n const held = rules.length - flagged.length;\n if (held > 0) {\n lines.push(` ${count(held, \"rule\", \"rules\")} held every turn ${held === 1 ? \"it\" : \"they\"} applied to.`);\n }\n return [\"Session so far\", ...lines];\n}\n\nfunction closing(report: CheckReport): string {\n const head = `Last turn of ${report.sessionId.slice(0, 8)}:`;\n const { summary } = report;\n // \"sources\", because a typed prompt is not a file (proposal 0080).\n const scope = `${count(summary.rules, \"rule\", \"rules\")} from ${count(summary.sources, \"source\", \"sources\")}`;\n switch (report.skipped) {\n case \"empty-turn\":\n return `${head} nothing happened after the last prompt.`;\n case \"no-sources\":\n return `${head} no rule sources governed it.`;\n case \"not-applicable\":\n return `${head} ${scope}, none apply to this turn.`;\n case null: {\n const broken = summary.fail > 0 ? `${String(summary.fail)} broken` : \"None broken\";\n const review = summary.needsReview > 0 ? `, ${String(summary.needsReview)} needs review` : \"\";\n const reported = summary.reported > 0 ? `, ${String(summary.reported)} reported` : \"\";\n return `${head} ${scope}. ${broken}${review}${reported}.`;\n }\n }\n}\n\nexport const NOT_SET_UP = \"tracevals conformance is not set up; nothing to prepare.\";\n\nexport function renderPrepare(report: PrepareReport): string {\n const lines: string[] = [];\n const said = new Set<string>();\n for (const m of report.models) {\n if (m.state === \"hosted\" || said.has(m.model)) continue;\n said.add(m.model);\n const name = `${m.model} (${m.provider})`;\n lines.push(\n m.state === \"downloaded\"\n ? `${name} downloaded, ${((m.bytes ?? 0) / GB).toFixed(2)} GB.`\n : `${name} is ${m.state}.`,\n );\n }\n const ex = report.extraction;\n if (ex !== null) {\n const files = (n: number): string =>\n `${count(n, \"file\", \"files\")} that ${n === 1 ? \"applies\" : \"apply\"} to every session`;\n if (ex.extracted > 0) {\n lines.push(\n `Extracted ${count(ex.rules, \"rule\", \"rules\")} from ${files(ex.extracted)}.` +\n (ex.cached > 0 ? ` ${String(ex.cached)} more ${ex.cached === 1 ? \"was\" : \"were\"} cached.` : \"\"),\n );\n } else if (ex.cached > 0) {\n lines.push(`${files(ex.cached)} ${ex.cached === 1 ? \"is\" : \"are\"} cached. Nothing to extract.`);\n } else {\n lines.push(\"No file applies to every session. Nothing to extract.\");\n }\n }\n for (const warning of report.warnings) lines.push(warning);\n return lines.join(\"\\n\");\n}\n\nexport const NO_HOST = \"No model host is running.\";\n\nexport function renderRelease(report: ReleaseReport): string {\n if (!report.hostStopped && report.released.length === 0 && report.unloaded.length === 0) {\n return NO_HOST;\n }\n const unloaded = report.unloaded.length > 0 ? `Unloaded ${report.unloaded.join(\", \")}` : \"\";\n const stopped = report.hostStopped ? \"stopped the model host\" : \"\";\n const action = [unloaded, stopped].filter((s) => s !== \"\").join(\" and \");\n const held = count(report.released.length, \"session\", \"sessions\");\n return `${action === \"\" ? \"Released the lease\" : action}. ${held} held it.`;\n}\n"],"mappings":"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","names":[]}
|