@vibe-agent-toolkit/agent-skills 0.1.40 → 0.1.41-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/skill-test/eval-executor.d.ts +50 -0
  2. package/dist/skill-test/eval-executor.d.ts.map +1 -0
  3. package/dist/skill-test/eval-executor.js +85 -0
  4. package/dist/skill-test/eval-executor.js.map +1 -0
  5. package/dist/skill-test/eval-fragment.d.ts +278 -0
  6. package/dist/skill-test/eval-fragment.d.ts.map +1 -0
  7. package/dist/skill-test/eval-fragment.js +128 -0
  8. package/dist/skill-test/eval-fragment.js.map +1 -0
  9. package/dist/skill-test/eval-grader.d.ts +54 -0
  10. package/dist/skill-test/eval-grader.d.ts.map +1 -0
  11. package/dist/skill-test/eval-grader.js +184 -0
  12. package/dist/skill-test/eval-grader.js.map +1 -0
  13. package/dist/skill-test/eval-inputs.d.ts +355 -0
  14. package/dist/skill-test/eval-inputs.d.ts.map +1 -1
  15. package/dist/skill-test/eval-inputs.js +36 -8
  16. package/dist/skill-test/eval-inputs.js.map +1 -1
  17. package/dist/skill-test/eval-lint.d.ts +51 -0
  18. package/dist/skill-test/eval-lint.d.ts.map +1 -0
  19. package/dist/skill-test/eval-lint.js +157 -0
  20. package/dist/skill-test/eval-lint.js.map +1 -0
  21. package/dist/skill-test/evals-template.d.ts.map +1 -1
  22. package/dist/skill-test/evals-template.js +7 -0
  23. package/dist/skill-test/evals-template.js.map +1 -1
  24. package/dist/skill-test/executor-prompt.d.ts +41 -0
  25. package/dist/skill-test/executor-prompt.d.ts.map +1 -0
  26. package/dist/skill-test/executor-prompt.js +63 -0
  27. package/dist/skill-test/executor-prompt.js.map +1 -0
  28. package/dist/skill-test/exit-codes.d.ts +8 -5
  29. package/dist/skill-test/exit-codes.d.ts.map +1 -1
  30. package/dist/skill-test/exit-codes.js +12 -7
  31. package/dist/skill-test/exit-codes.js.map +1 -1
  32. package/dist/skill-test/fragment-merge.d.ts +46 -0
  33. package/dist/skill-test/fragment-merge.d.ts.map +1 -0
  34. package/dist/skill-test/fragment-merge.js +77 -0
  35. package/dist/skill-test/fragment-merge.js.map +1 -0
  36. package/dist/skill-test/friction-schema.d.ts +10 -10
  37. package/dist/skill-test/friction-schema.d.ts.map +1 -1
  38. package/dist/skill-test/friction-schema.js +6 -1
  39. package/dist/skill-test/friction-schema.js.map +1 -1
  40. package/dist/skill-test/grader-model.d.ts +6 -0
  41. package/dist/skill-test/grader-model.d.ts.map +1 -0
  42. package/dist/skill-test/grader-model.js +6 -0
  43. package/dist/skill-test/grader-model.js.map +1 -0
  44. package/dist/skill-test/grader-prompt.d.ts +74 -0
  45. package/dist/skill-test/grader-prompt.d.ts.map +1 -0
  46. package/dist/skill-test/grader-prompt.js +173 -0
  47. package/dist/skill-test/grader-prompt.js.map +1 -0
  48. package/dist/skill-test/grading-adapter.d.ts +5 -11
  49. package/dist/skill-test/grading-adapter.d.ts.map +1 -1
  50. package/dist/skill-test/grading-adapter.js +9 -22
  51. package/dist/skill-test/grading-adapter.js.map +1 -1
  52. package/dist/skill-test/grading-schema.d.ts +18 -15
  53. package/dist/skill-test/grading-schema.d.ts.map +1 -1
  54. package/dist/skill-test/grading-schema.js +6 -5
  55. package/dist/skill-test/grading-schema.js.map +1 -1
  56. package/dist/skill-test/index.d.ts +13 -3
  57. package/dist/skill-test/index.d.ts.map +1 -1
  58. package/dist/skill-test/index.js +13 -3
  59. package/dist/skill-test/index.js.map +1 -1
  60. package/dist/skill-test/pipeline.d.ts +29 -0
  61. package/dist/skill-test/pipeline.d.ts.map +1 -0
  62. package/dist/skill-test/pipeline.js +77 -0
  63. package/dist/skill-test/pipeline.js.map +1 -0
  64. package/dist/skill-test/prompt-invariants.d.ts +27 -0
  65. package/dist/skill-test/prompt-invariants.d.ts.map +1 -0
  66. package/dist/skill-test/prompt-invariants.js +38 -0
  67. package/dist/skill-test/prompt-invariants.js.map +1 -0
  68. package/dist/skill-test/run-harness.d.ts +187 -55
  69. package/dist/skill-test/run-harness.d.ts.map +1 -1
  70. package/dist/skill-test/run-harness.js +539 -189
  71. package/dist/skill-test/run-harness.js.map +1 -1
  72. package/dist/skill-test/tier-plan.d.ts +89 -0
  73. package/dist/skill-test/tier-plan.d.ts.map +1 -0
  74. package/dist/skill-test/tier-plan.js +96 -0
  75. package/dist/skill-test/tier-plan.js.map +1 -0
  76. package/dist/skill-test/tool-eval-schema.d.ts +412 -0
  77. package/dist/skill-test/tool-eval-schema.d.ts.map +1 -0
  78. package/dist/skill-test/tool-eval-schema.js +83 -0
  79. package/dist/skill-test/tool-eval-schema.js.map +1 -0
  80. package/dist/validators/packaging-validator.d.ts +8 -1
  81. package/dist/validators/packaging-validator.d.ts.map +1 -1
  82. package/dist/validators/packaging-validator.js.map +1 -1
  83. package/package.json +5 -5
  84. package/schemas/friction-report.json +2 -1
  85. package/dist/skill-test/experimenter-prompt.d.ts +0 -42
  86. package/dist/skill-test/experimenter-prompt.d.ts.map +0 -1
  87. package/dist/skill-test/experimenter-prompt.js +0 -104
  88. package/dist/skill-test/experimenter-prompt.js.map +0 -1
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Advisory (never-fatal) lint over an eval suite's `expectations` prose (issue #145
3
+ * follow-up). An adopter reported that WEAK expectations — pure "mentions X" /
4
+ * "includes Y" presence checks with no discriminating or negative counterpart —
5
+ * pass even for a hallucinated or right-for-the-wrong-reason answer, giving false
6
+ * confidence in a green run. This module flags that pattern so authors can
7
+ * strengthen the eval; it never blocks a run or changes an exit code.
8
+ *
9
+ * Deliberately conservative: this is a heuristic over free-text prose, not a
10
+ * grammar. When in doubt, do NOT warn — a false "your eval is weak" nag is worse
11
+ * than a missed one, since the grader (an LLM judging the transcript) is the real
12
+ * backstop for eval quality.
13
+ */
14
+ import { isSingleEditAway } from './eval-inputs.js';
15
+ // An expectation "looks like" a pure presence/mention check when it uses one of
16
+ // these verbs — the vocabulary authors reach for when asserting "X shows up
17
+ // somewhere in the output" without saying what a WRONG output would look like.
18
+ const PRESENCE_ONLY_PATTERN = /\b(mentions?|includes?|contains?|references?|present|appears?|states?)\b/i;
19
+ // Any of these cues make an expectation discriminating, regardless of whether it
20
+ // also uses a presence verb above: negation ("not"/"never"/"without"/"must not"),
21
+ // an explicit alternative ("instead of"/"rather than"), a precision bound
22
+ // ("only"/"exactly"), or a named failure mode ("wrong"/"incorrect"/"fails"/
23
+ // "error"). ONE such cue on an expectation is enough to exempt it from the
24
+ // presence-only bucket — a single negative check already rules out a hallucinated
25
+ // or wrong-for-the-right-reason answer for that expectation.
26
+ const DISCRIMINATING_PATTERN = /\b(not|never|without|must not|should not|instead of|rather than|wrong|incorrect|only|exactly|fails?|error)\b/i;
27
+ /** True when a single expectation string is a presence-only check (matches the presence vocabulary and carries no discriminating cue). */
28
+ function isPresenceOnlyExpectation(expectation) {
29
+ return PRESENCE_ONLY_PATTERN.test(expectation) && !DISCRIMINATING_PATTERN.test(expectation);
30
+ }
31
+ /**
32
+ * Lint a parsed eval suite's `expectations` for the weak-presence-only pattern.
33
+ * Flags an eval only when ALL of these hold (conservative — minimize false
34
+ * positives):
35
+ * (a) it has at least one expectation;
36
+ * (b) EVERY expectation string is presence-only (see {@link isPresenceOnlyExpectation});
37
+ * (c) the eval declares no `toolExpectations` — a `mustRun`/`mustNotRun`/`sequence`
38
+ * assertion is itself discriminating (it can fail a transcript that never
39
+ * invoked the right tool), so its presence already covers the concern this
40
+ * lint exists to catch.
41
+ *
42
+ * Pure and side-effect free — callers decide how/where to surface the warnings
43
+ * (this never throws and never affects exit code).
44
+ */
45
+ export function lintEvalExpectations(evals) {
46
+ const warnings = [];
47
+ for (const entry of evals) {
48
+ if (entry.expectations.length === 0)
49
+ continue;
50
+ if (entry.toolExpectations !== undefined)
51
+ continue;
52
+ if (!entry.expectations.every(isPresenceOnlyExpectation))
53
+ continue;
54
+ const evalId = String(entry.id);
55
+ warnings.push({
56
+ evalId,
57
+ message: `eval "${evalId}": all expectations are presence-only ("mentions/includes …") with no discriminating ` +
58
+ 'or negative check — a hallucinated or wrong-for-the-right-reason answer may still pass. Add a negative ' +
59
+ 'expectation or a toolExpectations assertion.',
60
+ });
61
+ }
62
+ return warnings;
63
+ }
64
+ // ---------------------------------------------------------------------------
65
+ // Undeclared-executable lint (issue #145 adopter follow-up)
66
+ // ---------------------------------------------------------------------------
67
+ // A trailing script/binary extension we strip before comparing an executable
68
+ // name to a declared one, so `dxa.py`/`./dxa`/`dxa` all normalize to `dxa` (the
69
+ // grader already recognizes those launch forms — see deriveDeclaredExecutableNames,
70
+ // which strips the extension from a declared name too). Matches only well-known
71
+ // script suffixes so a name that legitimately ENDS in one of these words is left
72
+ // alone.
73
+ const SCRIPT_EXTENSION = /\.(?:py|js|mjs|cjs|ts|sh|rb|go|pl|php)$/i;
74
+ /** Normalize an executable name for comparison: trim, drop a leading `./` and a trailing script extension, lowercase. */
75
+ function normalizeExecutableName(name) {
76
+ return name.trim().replace(/^\.\//, '').replace(SCRIPT_EXTENSION, '').toLowerCase();
77
+ }
78
+ /** Every executable named across an eval's `toolExpectations` arrays (mustRun/mustNotRun/mustSucceed/sequence). */
79
+ function collectToolExpectationExecutables(entry) {
80
+ const te = entry.toolExpectations;
81
+ if (te === undefined)
82
+ return [];
83
+ return [...(te.mustRun ?? []), ...(te.mustNotRun ?? []), ...(te.mustSucceed ?? []), ...(te.sequence ?? [])];
84
+ }
85
+ /**
86
+ * True when `decorated` is `stem` plus a SEPARATOR-delimited suffix — i.e. `stem`
87
+ * is a ≥3-char prefix of `decorated` and the next char is a non-alphanumeric
88
+ * separator (`-`, `_`, `.`, space). Catches a declared `dxa` typo'd as `dxa-py`
89
+ * (a `-py` decoration) while NOT firing on a genuinely different word that merely
90
+ * shares a prefix (`git` vs `github` — the boundary char `h` is alphanumeric).
91
+ */
92
+ function isDecoratedStem(decorated, stem) {
93
+ if (stem.length < 3 || decorated.length <= stem.length || !decorated.startsWith(stem))
94
+ return false;
95
+ return /[^a-z0-9]/.test(decorated.charAt(stem.length));
96
+ }
97
+ /**
98
+ * The declared executable a referenced `name` is PROBABLY a typo of, or undefined
99
+ * when it matches a declared name exactly (recognized — no warning) or is not
100
+ * close to any declared name (a legit reference to a built-in/system tool like
101
+ * `Bash`/`git` — also no warning, staying conservative like {@link lintEvalExpectations}).
102
+ * "Close" = a single-edit typo of, or a separator-decorated form of, a declared name.
103
+ */
104
+ function probableDeclaredTypoTarget(name, declared) {
105
+ const normalized = normalizeExecutableName(name);
106
+ if (declared.some((d) => d.normalized === normalized))
107
+ return undefined; // exact / recognized launch form
108
+ for (const d of declared) {
109
+ if (isSingleEditAway(normalized, d.normalized))
110
+ return d.original;
111
+ if (isDecoratedStem(normalized, d.normalized) || isDecoratedStem(d.normalized, normalized))
112
+ return d.original;
113
+ }
114
+ return undefined;
115
+ }
116
+ /**
117
+ * Advisory (never-fatal) lint: flag a `toolExpectations` entry that names an
118
+ * executable which looks like a TYPO of one of the skill's `declaredExecutables`
119
+ * (issue #145 adopter follow-up). A name that never matches a real tool is a quiet
120
+ * footgun — `mustRun`/`mustSucceed`/`sequence` then fail for the wrong reason, and
121
+ * `mustNotRun` passes vacuously (the tool "never ran" only because the name is
122
+ * wrong). This is zero-token static plumbing, run before any spend.
123
+ *
124
+ * Conservative, like {@link lintEvalExpectations}: it only fires when there is a
125
+ * SPECIFIC declared name the reference is probably a typo of (so it can suggest
126
+ * "did you mean X?"). A reference that matches a declared name exactly, or that is
127
+ * not close to any declared name (a deliberate built-in/system tool reference), is
128
+ * never flagged. When the skill declares no executables there is nothing to compare
129
+ * against, so it returns no warnings. Pure + side-effect free.
130
+ */
131
+ export function lintToolExpectationExecutables(evals, declaredExecutableNames) {
132
+ const warnings = [];
133
+ const declared = declaredExecutableNames.map((original) => ({ original, normalized: normalizeExecutableName(original) }));
134
+ if (declared.length === 0)
135
+ return warnings;
136
+ const declaredList = declared.map((d) => d.original).join(', ');
137
+ for (const entry of evals) {
138
+ const evalId = String(entry.id);
139
+ const seen = new Set();
140
+ for (const name of collectToolExpectationExecutables(entry)) {
141
+ if (seen.has(name))
142
+ continue;
143
+ seen.add(name);
144
+ const target = probableDeclaredTypoTarget(name, declared);
145
+ if (target === undefined)
146
+ continue;
147
+ warnings.push({
148
+ evalId,
149
+ message: `eval "${evalId}": toolExpectation references executable "${name}", which no declared executable matches — ` +
150
+ `did you mean "${target}"? A name that never matches a real tool makes mustRun/mustSucceed/sequence fail ` +
151
+ `for the wrong reason (or mustNotRun pass vacuously). Declared executables: ${declaredList}.`,
152
+ });
153
+ }
154
+ }
155
+ return warnings;
156
+ }
157
+ //# sourceMappingURL=eval-lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-lint.js","sourceRoot":"","sources":["../../src/skill-test/eval-lint.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"evals-template.d.ts","sourceRoot":"","sources":["../../src/skill-test/evals-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAsC5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAW/E"}
1
+ {"version":3,"file":"evals-template.d.ts","sourceRoot":"","sources":["../../src/skill-test/evals-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA6C5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAW/E"}
@@ -35,6 +35,13 @@ export function buildEvalsTemplate(skillName) {
35
35
  ' Include negative assertions too, e.g. "does NOT claim every row reconciles".',
36
36
  ' category — OPTIONAL label you choose to group evals (e.g. "recognition",',
37
37
  ' "guidance", "recovery"). VAT ignores it; it is for your own organization.',
38
+ ' tier — OPTIONAL non-negative integer cost/foundational tier, ascending',
39
+ ' (0 = cheapest/first). Used for fail-fast gating: cheaper tiers run',
40
+ ' first and can short-circuit later, more expensive tiers. Default: 0.',
41
+ ' toolExpectations — OPTIONAL { mustRun, mustNotRun, sequence }, each an array of',
42
+ ' executable tool NAMES. The grader checks these against what the',
43
+ ' executor actually ran in the transcript (mustRun: all present;',
44
+ ' mustNotRun: none present; sequence: appear in this relative order).',
38
45
  'Aim for at least 3 evals covering real scenarios. Delete this _comment field once filled in, then re-run.',
39
46
  ],
40
47
  skill_name: skillName,
@@ -1 +1 @@
1
- {"version":3,"file":"evals-template.js","sourceRoot":"","sources":["../../src/skill-test/evals-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAEpE,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,QAAQ,GAAG;QACf,QAAQ,EAAE;YACR,8DAA8D;YAC9D,oFAAoF;YACpF,kBAAkB;YAClB,8EAA8E;YAC9E,yFAAyF;YACzF,iFAAiF;YACjF,oFAAoF;YACpF,yFAAyF;YACzF,2FAA2F;YAC3F,6FAA6F;YAC7F,mFAAmF;YACnF,uFAAuF;YACvF,wFAAwF;YACxF,gGAAgG;YAChG,kGAAkG;YAClG,mFAAmF;YACnF,+FAA+F;YAC/F,2GAA2G;SAC5G;QACD,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE;YACL;gBACE,EAAE,EAAE,CAAC;gBACL,QAAQ,EAAE,qDAAqD;gBAC/D,MAAM,EAAE,yEAAyE;gBACjF,eAAe,EAAE,kDAAkD;gBACnE,KAAK,EAAE,EAAE;gBACT,YAAY,EAAE;oBACZ,sGAAsG;oBACtG,2GAA2G;iBAC5G;aACF;SACF;KACF,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,SAAiB;IACrE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9C,aAAa,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,gFAAgF;IAChF,+EAA+E;IAC/E,qGAAqG;IACrG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,qGAAqG;QACrG,aAAa,CAAC,SAAS,EAAE,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"evals-template.js","sourceRoot":"","sources":["../../src/skill-test/evals-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAEpE,2EAA2E;AAC3E,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,QAAQ,GAAG;QACf,QAAQ,EAAE;YACR,8DAA8D;YAC9D,oFAAoF;YACpF,kBAAkB;YAClB,8EAA8E;YAC9E,yFAAyF;YACzF,iFAAiF;YACjF,oFAAoF;YACpF,yFAAyF;YACzF,2FAA2F;YAC3F,6FAA6F;YAC7F,mFAAmF;YACnF,uFAAuF;YACvF,wFAAwF;YACxF,gGAAgG;YAChG,kGAAkG;YAClG,mFAAmF;YACnF,+FAA+F;YAC/F,qFAAqF;YACrF,wFAAwF;YACxF,0FAA0F;YAC1F,mFAAmF;YACnF,qFAAqF;YACrF,oFAAoF;YACpF,yFAAyF;YACzF,2GAA2G;SAC5G;QACD,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE;YACL;gBACE,EAAE,EAAE,CAAC;gBACL,QAAQ,EAAE,qDAAqD;gBAC/D,MAAM,EAAE,yEAAyE;gBACjF,eAAe,EAAE,kDAAkD;gBACnE,KAAK,EAAE,EAAE;gBACT,YAAY,EAAE;oBACZ,sGAAsG;oBACtG,2GAA2G;iBAC5G;aACF;SACF;KACF,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,SAAiB;IACrE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9C,aAAa,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,gFAAgF;IAChF,+EAA+E;IAC/E,qGAAqG;IACrG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,qGAAqG;QACrG,aAAa,CAAC,SAAS,EAAE,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,41 @@
1
+ export interface BuildExecutorPromptOptions {
2
+ /** The eval's `prompt` field, verbatim — the task the executor must perform. */
3
+ task: string;
4
+ /** Path to the staged subject (skill/plugin under test). */
5
+ subjectPath: string;
6
+ /** `<workspacesRoot>/<id>` when the eval declares input `files` — the project the executor should operate on. */
7
+ workspaceDir?: string;
8
+ }
9
+ /**
10
+ * Build the prompt handed to the blind executor subagent (issue #145 —
11
+ * transcript-grounded eval rewrite). The executor is a real worker, not a
12
+ * participant in an eval: it receives the task and its working context ONLY,
13
+ * phrased exactly as a genuine user request. It must NEVER be told (directly
14
+ * or by implication) that it is being tested, evaluated, or graded — that
15
+ * knowledge would change its behavior and invalidate the eval.
16
+ *
17
+ * `subjectPath` is where the skill/plugin under test is staged (context the
18
+ * executor's environment provides); `workspaceDir`, when the eval declares
19
+ * input `files`, is the project the executor is actually meant to operate on.
20
+ *
21
+ * Pure function: same inputs always produce the same prompt.
22
+ */
23
+ export declare function buildExecutorPrompt(opts: BuildExecutorPromptOptions): string;
24
+ /**
25
+ * Invariants for the executor prompt. Two guarantees:
26
+ *
27
+ * 1. **Task-present**: `task` must be non-empty and appear verbatim in
28
+ * `prompt` — the executor is a real worker, so the adopter's task text
29
+ * must actually reach it.
30
+ * 2. **No blinding-breaker in OUR scaffolding**: the denylist
31
+ * ({@link BLINDING_BREAKERS}) is scanned ONLY against the prompt's
32
+ * scaffolding — the prompt with the adopter's `task` text removed. The
33
+ * adopter's task is arbitrary and may legitimately contain words like
34
+ * "grading" or "you are being evaluated" (e.g. an essay-grading skill);
35
+ * policing it would be a false positive. The invariant's real job is to
36
+ * catch OUR builder accidentally telling the executor it is under test.
37
+ *
38
+ * Throws `PromptInvariantError` on violation.
39
+ */
40
+ export declare function assertExecutorPromptInvariants(prompt: string, task: string): void;
41
+ //# sourceMappingURL=executor-prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor-prompt.d.ts","sourceRoot":"","sources":["../../src/skill-test/executor-prompt.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,0BAA0B;IACzC,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,iHAAiH;IACjH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,0BAA0B,GAAG,MAAM,CAM5E;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAiBjF"}
@@ -0,0 +1,63 @@
1
+ import { PromptInvariantError } from './prompt-invariants.js';
2
+ /**
3
+ * Build the prompt handed to the blind executor subagent (issue #145 —
4
+ * transcript-grounded eval rewrite). The executor is a real worker, not a
5
+ * participant in an eval: it receives the task and its working context ONLY,
6
+ * phrased exactly as a genuine user request. It must NEVER be told (directly
7
+ * or by implication) that it is being tested, evaluated, or graded — that
8
+ * knowledge would change its behavior and invalidate the eval.
9
+ *
10
+ * `subjectPath` is where the skill/plugin under test is staged (context the
11
+ * executor's environment provides); `workspaceDir`, when the eval declares
12
+ * input `files`, is the project the executor is actually meant to operate on.
13
+ *
14
+ * Pure function: same inputs always produce the same prompt.
15
+ */
16
+ export function buildExecutorPrompt(opts) {
17
+ const lines = [opts.task, '', `The relevant files are located at ${opts.subjectPath}.`];
18
+ if (opts.workspaceDir !== undefined) {
19
+ lines.push(`Your working directory is ${opts.workspaceDir} — the project to operate on.`);
20
+ }
21
+ return lines.join('\n');
22
+ }
23
+ /**
24
+ * Phrases that, if present in an executor prompt, would break the blind
25
+ * setup by revealing to the executor that it is participating in an eval.
26
+ * Kept intentionally tight: this is a denylist of known blinding-breakers,
27
+ * not a general "sounds suspicious" heuristic, so it stays predictable for
28
+ * prompt authors overriding the default.
29
+ */
30
+ const BLINDING_BREAKERS = ['being tested', 'this is an eval', 'you are being evaluated', 'grading'];
31
+ /**
32
+ * Invariants for the executor prompt. Two guarantees:
33
+ *
34
+ * 1. **Task-present**: `task` must be non-empty and appear verbatim in
35
+ * `prompt` — the executor is a real worker, so the adopter's task text
36
+ * must actually reach it.
37
+ * 2. **No blinding-breaker in OUR scaffolding**: the denylist
38
+ * ({@link BLINDING_BREAKERS}) is scanned ONLY against the prompt's
39
+ * scaffolding — the prompt with the adopter's `task` text removed. The
40
+ * adopter's task is arbitrary and may legitimately contain words like
41
+ * "grading" or "you are being evaluated" (e.g. an essay-grading skill);
42
+ * policing it would be a false positive. The invariant's real job is to
43
+ * catch OUR builder accidentally telling the executor it is under test.
44
+ *
45
+ * Throws `PromptInvariantError` on violation.
46
+ */
47
+ export function assertExecutorPromptInvariants(prompt, task) {
48
+ if (task.trim() === '') {
49
+ throw new PromptInvariantError('must include the task text (task is empty)');
50
+ }
51
+ if (!prompt.includes(task)) {
52
+ throw new PromptInvariantError('must include the task text (task not present in prompt)');
53
+ }
54
+ // Exclude the adopter task from the scan: only OUR scaffolding is policed.
55
+ // A space join avoids fusing the surrounding words across the excised task.
56
+ const scaffolding = prompt.split(task).join(' ').toLowerCase();
57
+ for (const breaker of BLINDING_BREAKERS) {
58
+ if (scaffolding.includes(breaker)) {
59
+ throw new PromptInvariantError(`must not reveal to the executor that it is being tested/evaluated/graded (found "${breaker}")`);
60
+ }
61
+ }
62
+ }
63
+ //# sourceMappingURL=executor-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor-prompt.js","sourceRoot":"","sources":["../../src/skill-test/executor-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAW9D;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAgC;IAClE,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,qCAAqC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;IACxF,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,6BAA6B,IAAI,CAAC,YAAY,+BAA+B,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,iBAAiB,GAAG,CAAC,cAAc,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,SAAS,CAAC,CAAC;AAEpG;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,8BAA8B,CAAC,MAAc,EAAE,IAAY;IACzE,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACvB,MAAM,IAAI,oBAAoB,CAAC,4CAA4C,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,oBAAoB,CAAC,yDAAyD,CAAC,CAAC;IAC5F,CAAC;IACD,2EAA2E;IAC3E,4EAA4E;IAC5E,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACxC,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,oBAAoB,CAC5B,oFAAoF,OAAO,IAAI,CAChG,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -52,7 +52,7 @@ export declare class SecurityAckError extends Error {
52
52
  readonly exitCode: 2;
53
53
  constructor();
54
54
  }
55
- /** Internal harness failure (incl. experimenter exiting without valid grading.json). Exit 1. */
55
+ /** Internal harness failure (an executor/grader spawn error, watchdog timeout/stall, or a missing grader fragment). Exit 1. */
56
56
  export declare class InternalHarnessError extends Error {
57
57
  readonly exitCode: 1;
58
58
  constructor(message: string);
@@ -60,13 +60,16 @@ export declare class InternalHarnessError extends Error {
60
60
  /**
61
61
  * Map any thrown error to the process exit code. Errors that carry their own
62
62
  * `exitCode` (Bootstrap/Auth/HarnessLocation/Internal) are authoritative;
63
- * a PromptInvariantError is a user-correctable preflight problem (a supplied
64
- * prompt override is missing a required safety instruction) 2; a BuildHookError
63
+ * a PromptInvariantError is a defense-in-depth failure over VAT's OWN generated
64
+ * executor/grader prompts (a required safety directive missing from a prompt VAT
65
+ * built) — surfaced as a user-visible preflight-class problem → 2; a BuildHookError
65
66
  * is a pre-stage build failure → 2; a SkillBuildError is a declared-skill build
66
67
  * failure → 2; a SecurityAckError is a missing security ack before a build → 2;
67
68
  * an UnknownEnvTokenError is a bad ${token} in a
68
- * declared env value → 2; GradingSkewError (parse failure) and GradingNonceError
69
- * (forged/mismatched grading nonce) are both → 1; everything unknown → 1.
69
+ * declared env value → 2; GradingSkewError (aggregate grading.json shape skew),
70
+ * EvalFragmentError (per-eval grader fragment parse failure), and
71
+ * GradingNonceError (forged/mismatched per-fragment grader nonce) are all → 1;
72
+ * everything unknown → 1.
70
73
  *
71
74
  * Note: SkillTestExitCode.EvalFailure (4) is NOT produced here — it is an
72
75
  * outcome of a completed run (an eval failed, the fail-closed default unless
@@ -1 +1 @@
1
- {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../../src/skill-test/exit-codes.ts"],"names":[],"mappings":"AAQA,kDAAkD;AAClD,eAAO,MAAM,iBAAiB;;;;;IAK5B;;;;;;;;;;;;OAYG;;CAEK,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAEhG;;;;;;;;;GASG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAEjB,YAAY,EAAE,MAAM;IADhD,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACH,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE;CAQ9E;AAED,iHAAiH;AACjH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACnB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;;CAKhC;AAED,gGAAgG;AAChG,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACnB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAqBvD"}
1
+ {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../../src/skill-test/exit-codes.ts"],"names":[],"mappings":"AASA,kDAAkD;AAClD,eAAO,MAAM,iBAAiB;;;;;IAK5B;;;;;;;;;;;;OAYG;;CAEK,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAEhG;;;;;;;;;GASG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAEjB,YAAY,EAAE,MAAM;IADhD,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACH,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE;CAQ9E;AAED,iHAAiH;AACjH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACnB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;;CAKhC;AAED,+HAA+H;AAC/H,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACnB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAsBvD"}
@@ -1,9 +1,10 @@
1
1
  import { AuthPreflightError } from '@vibe-agent-toolkit/utils';
2
2
  import { BuildHookError } from './build-hook.js';
3
3
  import { UnknownEnvTokenError } from './declared-env.js';
4
- import { PromptInvariantError } from './experimenter-prompt.js';
4
+ import { EvalFragmentError } from './eval-fragment.js';
5
5
  import { GradingNonceError, GradingSkewError } from './grading-adapter.js';
6
6
  import { HarnessLocationError } from './harness-location.js';
7
+ import { PromptInvariantError } from './prompt-invariants.js';
7
8
  /** Exit codes for `vat skill test` (spec §6d). */
8
9
  export const SkillTestExitCode = {
9
10
  Ok: 0,
@@ -67,7 +68,7 @@ export class SecurityAckError extends Error {
67
68
  this.name = 'SecurityAckError';
68
69
  }
69
70
  }
70
- /** Internal harness failure (incl. experimenter exiting without valid grading.json). Exit 1. */
71
+ /** Internal harness failure (an executor/grader spawn error, watchdog timeout/stall, or a missing grader fragment). Exit 1. */
71
72
  export class InternalHarnessError extends Error {
72
73
  exitCode = 1;
73
74
  constructor(message) {
@@ -78,13 +79,16 @@ export class InternalHarnessError extends Error {
78
79
  /**
79
80
  * Map any thrown error to the process exit code. Errors that carry their own
80
81
  * `exitCode` (Bootstrap/Auth/HarnessLocation/Internal) are authoritative;
81
- * a PromptInvariantError is a user-correctable preflight problem (a supplied
82
- * prompt override is missing a required safety instruction) 2; a BuildHookError
82
+ * a PromptInvariantError is a defense-in-depth failure over VAT's OWN generated
83
+ * executor/grader prompts (a required safety directive missing from a prompt VAT
84
+ * built) — surfaced as a user-visible preflight-class problem → 2; a BuildHookError
83
85
  * is a pre-stage build failure → 2; a SkillBuildError is a declared-skill build
84
86
  * failure → 2; a SecurityAckError is a missing security ack before a build → 2;
85
87
  * an UnknownEnvTokenError is a bad ${token} in a
86
- * declared env value → 2; GradingSkewError (parse failure) and GradingNonceError
87
- * (forged/mismatched grading nonce) are both → 1; everything unknown → 1.
88
+ * declared env value → 2; GradingSkewError (aggregate grading.json shape skew),
89
+ * EvalFragmentError (per-eval grader fragment parse failure), and
90
+ * GradingNonceError (forged/mismatched per-fragment grader nonce) are all → 1;
91
+ * everything unknown → 1.
88
92
  *
89
93
  * Note: SkillTestExitCode.EvalFailure (4) is NOT produced here — it is an
90
94
  * outcome of a completed run (an eval failed, the fail-closed default unless
@@ -103,7 +107,8 @@ export function mapErrorToExitCode(err) {
103
107
  err instanceof UnknownEnvTokenError) {
104
108
  return SkillTestExitCode.Preflight;
105
109
  }
106
- if (err instanceof GradingNonceError ||
110
+ if (err instanceof EvalFragmentError ||
111
+ err instanceof GradingNonceError ||
107
112
  err instanceof GradingSkewError ||
108
113
  err instanceof InternalHarnessError) {
109
114
  return SkillTestExitCode.Internal;
@@ -1 +1 @@
1
- {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/skill-test/exit-codes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,kDAAkD;AAClD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,EAAE,EAAE,CAAC;IACL,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ;;;;;;;;;;;;OAYG;IACH,WAAW,EAAE,CAAC;CACN,CAAC;AAIX;;;;;;;;;GASG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAEjB;IADnB,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAA4B,YAAoB,EAAE,IAA2B;QAC3E,KAAK,CACH,IAAI,EAAE,MAAM,KAAK,IAAI;YACnB,CAAC,CAAC,qFAAqF,YAAY,2DAA2D;YAC9J,CAAC,CAAC,mCAAmC,YAAY,2BAA2B,CAC/E,CAAC;QALwB,iBAAY,GAAZ,YAAY,CAAQ;QAM9C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,iHAAiH;AACjH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,QAAQ,GAAG,CAAU,CAAC;IAC/B;QACE,KAAK,CAAC,wFAAwF,CAAC,CAAC;QAChG,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,gGAAgG;AAChG,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,GAAG,YAAY,oBAAoB;QAAE,OAAO,iBAAiB,CAAC,SAAS,CAAC;IAC5E,IACE,GAAG,YAAY,kBAAkB;QACjC,GAAG,YAAY,cAAc;QAC7B,GAAG,YAAY,oBAAoB;QACnC,GAAG,YAAY,oBAAoB;QACnC,GAAG,YAAY,gBAAgB;QAC/B,GAAG,YAAY,eAAe;QAC9B,GAAG,YAAY,oBAAoB,EACnC,CAAC;QACD,OAAO,iBAAiB,CAAC,SAAS,CAAC;IACrC,CAAC;IACD,IACE,GAAG,YAAY,iBAAiB;QAChC,GAAG,YAAY,gBAAgB;QAC/B,GAAG,YAAY,oBAAoB,EACnC,CAAC;QACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;IACpC,CAAC;IACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/skill-test/exit-codes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,kDAAkD;AAClD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,EAAE,EAAE,CAAC;IACL,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ;;;;;;;;;;;;OAYG;IACH,WAAW,EAAE,CAAC;CACN,CAAC;AAIX;;;;;;;;;GASG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAEjB;IADnB,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAA4B,YAAoB,EAAE,IAA2B;QAC3E,KAAK,CACH,IAAI,EAAE,MAAM,KAAK,IAAI;YACnB,CAAC,CAAC,qFAAqF,YAAY,2DAA2D;YAC9J,CAAC,CAAC,mCAAmC,YAAY,2BAA2B,CAC/E,CAAC;QALwB,iBAAY,GAAZ,YAAY,CAAQ;QAM9C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,iHAAiH;AACjH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,QAAQ,GAAG,CAAU,CAAC;IAC/B;QACE,KAAK,CAAC,wFAAwF,CAAC,CAAC;QAChG,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,+HAA+H;AAC/H,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,GAAG,YAAY,oBAAoB;QAAE,OAAO,iBAAiB,CAAC,SAAS,CAAC;IAC5E,IACE,GAAG,YAAY,kBAAkB;QACjC,GAAG,YAAY,cAAc;QAC7B,GAAG,YAAY,oBAAoB;QACnC,GAAG,YAAY,oBAAoB;QACnC,GAAG,YAAY,gBAAgB;QAC/B,GAAG,YAAY,eAAe;QAC9B,GAAG,YAAY,oBAAoB,EACnC,CAAC;QACD,OAAO,iBAAiB,CAAC,SAAS,CAAC;IACrC,CAAC;IACD,IACE,GAAG,YAAY,iBAAiB;QAChC,GAAG,YAAY,iBAAiB;QAChC,GAAG,YAAY,gBAAgB;QAC/B,GAAG,YAAY,oBAAoB,EACnC,CAAC;QACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;IACpC,CAAC;IACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC;AACpC,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { EvalFragment } from './eval-fragment.js';
2
+ import { type FrictionReport } from './friction-schema.js';
3
+ import { type NormalizedGrading } from './grading-adapter.js';
4
+ import { type ToolEvalReport } from './tool-eval-schema.js';
5
+ /**
6
+ * Assemble the run's aggregate grading result (skill-creator's flat
7
+ * `grading.json` shape) from every eval's per-eval grader fragment (issue #145
8
+ * Task 4/5). vat is the SOLE writer of the aggregate; this is that assembly
9
+ * step — the result feeds {@link import('./grading-adapter.js').reconcileGrading}
10
+ * unchanged.
11
+ *
12
+ * Every fragment must carry the SAME `runNonce` the harness stamped for this
13
+ * run — a mismatch means a fragment was not produced for this run (forged,
14
+ * stale, or left behind by untrusted skill code in the shared sandbox) and is
15
+ * rejected via {@link GradingNonceError}, never silently dropped.
16
+ *
17
+ * Zero fragments in → zero expectations out. This is deliberate: the existing
18
+ * "graded nothing" guard in `reconcileGrading` already throws
19
+ * `GradingSkewError` on an empty `expectations[]`, so that case is NOT
20
+ * special-cased here.
21
+ */
22
+ export declare function mergeFragmentsToGrading(fragments: EvalFragment[], runNonce: string): NormalizedGrading;
23
+ /**
24
+ * Assemble the run's aggregate friction report from every eval's fragment
25
+ * (vat-owned; see friction-schema.ts). Concatenates each fragment's
26
+ * `friction` items (fragments without any are treated as empty), de-dups
27
+ * byte-identical items, then validates the result against
28
+ * {@link FrictionReportSchema} — vat's own output contract, strict, no
29
+ * passthrough.
30
+ */
31
+ export declare function mergeFragmentsToFriction(fragments: EvalFragment[]): FrictionReport;
32
+ /**
33
+ * Assemble vat's `tool-eval.json` from every eval's fragment (issue #145
34
+ * Phase T; see tool-eval-schema.ts). A SEPARATE channel from `grading.json`
35
+ * and from friction (C2) — tool verdicts judge declared `toolExpectations`
36
+ * against the transcript, not prose expectations or packaging friction.
37
+ *
38
+ * Fragments carry only the `tool` BODY (no `evalId` — see
39
+ * {@link import('./tool-eval-schema.js').ToolVerdictBodySchema}); this merge
40
+ * re-attaches each fragment's own `evalId` to produce a full
41
+ * {@link import('./tool-eval-schema.js').ToolVerdict}. Fragments with no
42
+ * `tool` body are OMITTED — not every eval declares `toolExpectations`, so
43
+ * "no tool block" is a legitimate, non-error case, not a zero-filled verdict.
44
+ */
45
+ export declare function mergeFragmentsToToolEval(fragments: EvalFragment[]): ToolEvalReport;
46
+ //# sourceMappingURL=fragment-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fragment-merge.d.ts","sourceRoot":"","sources":["../../src/skill-test/fragment-merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAElF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAoBtG;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,cAAc,CAYlF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,cAAc,CAMlF"}
@@ -0,0 +1,77 @@
1
+ import { FrictionReportSchema } from './friction-schema.js';
2
+ import { GradingNonceError } from './grading-adapter.js';
3
+ import { ToolEvalReportSchema } from './tool-eval-schema.js';
4
+ /**
5
+ * Assemble the run's aggregate grading result (skill-creator's flat
6
+ * `grading.json` shape) from every eval's per-eval grader fragment (issue #145
7
+ * Task 4/5). vat is the SOLE writer of the aggregate; this is that assembly
8
+ * step — the result feeds {@link import('./grading-adapter.js').reconcileGrading}
9
+ * unchanged.
10
+ *
11
+ * Every fragment must carry the SAME `runNonce` the harness stamped for this
12
+ * run — a mismatch means a fragment was not produced for this run (forged,
13
+ * stale, or left behind by untrusted skill code in the shared sandbox) and is
14
+ * rejected via {@link GradingNonceError}, never silently dropped.
15
+ *
16
+ * Zero fragments in → zero expectations out. This is deliberate: the existing
17
+ * "graded nothing" guard in `reconcileGrading` already throws
18
+ * `GradingSkewError` on an empty `expectations[]`, so that case is NOT
19
+ * special-cased here.
20
+ */
21
+ export function mergeFragmentsToGrading(fragments, runNonce) {
22
+ const expectations = [];
23
+ for (const fragment of fragments) {
24
+ if (fragment.runNonce !== runNonce) {
25
+ throw new GradingNonceError(`fragment for eval "${fragment.evalId}" carries runNonce "${fragment.runNonce}", expected "${runNonce}"`);
26
+ }
27
+ for (const expectation of fragment.expectations) {
28
+ expectations.push({
29
+ text: expectation.text,
30
+ passed: expectation.passed,
31
+ ...(expectation.evidence === undefined ? {} : { evidence: expectation.evidence }),
32
+ });
33
+ }
34
+ }
35
+ const passed = expectations.filter(e => e.passed).length;
36
+ return { summary: { passed, total: expectations.length }, expectations, runNonce };
37
+ }
38
+ /**
39
+ * Assemble the run's aggregate friction report from every eval's fragment
40
+ * (vat-owned; see friction-schema.ts). Concatenates each fragment's
41
+ * `friction` items (fragments without any are treated as empty), de-dups
42
+ * byte-identical items, then validates the result against
43
+ * {@link FrictionReportSchema} — vat's own output contract, strict, no
44
+ * passthrough.
45
+ */
46
+ export function mergeFragmentsToFriction(fragments) {
47
+ const allItems = fragments.flatMap(fragment => fragment.friction ?? []);
48
+ const seen = new Set();
49
+ const deduped = allItems.filter(item => {
50
+ const key = JSON.stringify(item);
51
+ if (seen.has(key))
52
+ return false;
53
+ seen.add(key);
54
+ return true;
55
+ });
56
+ return FrictionReportSchema.parse({ items: deduped });
57
+ }
58
+ /**
59
+ * Assemble vat's `tool-eval.json` from every eval's fragment (issue #145
60
+ * Phase T; see tool-eval-schema.ts). A SEPARATE channel from `grading.json`
61
+ * and from friction (C2) — tool verdicts judge declared `toolExpectations`
62
+ * against the transcript, not prose expectations or packaging friction.
63
+ *
64
+ * Fragments carry only the `tool` BODY (no `evalId` — see
65
+ * {@link import('./tool-eval-schema.js').ToolVerdictBodySchema}); this merge
66
+ * re-attaches each fragment's own `evalId` to produce a full
67
+ * {@link import('./tool-eval-schema.js').ToolVerdict}. Fragments with no
68
+ * `tool` body are OMITTED — not every eval declares `toolExpectations`, so
69
+ * "no tool block" is a legitimate, non-error case, not a zero-filled verdict.
70
+ */
71
+ export function mergeFragmentsToToolEval(fragments) {
72
+ const evals = fragments
73
+ .filter((fragment) => fragment.tool !== undefined)
74
+ .map(fragment => ({ evalId: fragment.evalId, ...fragment.tool }));
75
+ return ToolEvalReportSchema.parse({ evals });
76
+ }
77
+ //# sourceMappingURL=fragment-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fragment-merge.js","sourceRoot":"","sources":["../../src/skill-test/fragment-merge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAuB,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAA0B,MAAM,sBAAsB,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAuB,MAAM,uBAAuB,CAAC;AAElF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAyB,EAAE,QAAgB;IACjF,MAAM,YAAY,GAAsC,EAAE,CAAC;IAE3D,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,IAAI,iBAAiB,CACzB,sBAAsB,QAAQ,CAAC,MAAM,uBAAuB,QAAQ,CAAC,QAAQ,gBAAgB,QAAQ,GAAG,CACzG,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;YAChD,YAAY,CAAC,IAAI,CAAC;gBAChB,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,GAAG,CAAC,WAAW,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC;aAClF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IACzD,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AACrF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,SAAyB;IAChE,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAExE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,oBAAoB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CAAC,SAAyB;IAChE,MAAM,KAAK,GAAG,SAAS;SACpB,MAAM,CAAC,CAAC,QAAQ,EAA0E,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC;SACzH,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAEpE,OAAO,oBAAoB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC/C,CAAC"}
@@ -3,25 +3,25 @@ import { z } from 'zod';
3
3
  export declare const FrictionSeveritySchema: z.ZodEnum<["high", "medium", "low"]>;
4
4
  /**
5
5
  * Closed set of packaging-fidelity friction categories (spec §18). vat owns
6
- * this enum; the experimenter must emit one of these.
6
+ * this enum; the grader must emit one of these.
7
7
  */
8
- export declare const FrictionCategorySchema: z.ZodEnum<["path-assumption", "undeclared-dependency", "ambient-propping", "doc-engine-drift", "missing-bundled-file"]>;
8
+ export declare const FrictionCategorySchema: z.ZodEnum<["path-assumption", "undeclared-dependency", "ambient-propping", "doc-engine-drift", "missing-bundled-file", "tool-expectation"]>;
9
9
  export declare const FrictionItemSchema: z.ZodObject<{
10
10
  severity: z.ZodEnum<["high", "medium", "low"]>;
11
- category: z.ZodEnum<["path-assumption", "undeclared-dependency", "ambient-propping", "doc-engine-drift", "missing-bundled-file"]>;
11
+ category: z.ZodEnum<["path-assumption", "undeclared-dependency", "ambient-propping", "doc-engine-drift", "missing-bundled-file", "tool-expectation"]>;
12
12
  message: z.ZodString;
13
13
  subjectFile: z.ZodOptional<z.ZodString>;
14
14
  evidence: z.ZodOptional<z.ZodString>;
15
15
  }, "strict", z.ZodTypeAny, {
16
16
  message: string;
17
17
  severity: "high" | "medium" | "low";
18
- category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file";
18
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
19
19
  evidence?: string | undefined;
20
20
  subjectFile?: string | undefined;
21
21
  }, {
22
22
  message: string;
23
23
  severity: "high" | "medium" | "low";
24
- category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file";
24
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
25
25
  evidence?: string | undefined;
26
26
  subjectFile?: string | undefined;
27
27
  }>;
@@ -30,20 +30,20 @@ export type FrictionItem = z.infer<typeof FrictionItemSchema>;
30
30
  export declare const FrictionReportSchema: z.ZodObject<{
31
31
  items: z.ZodArray<z.ZodObject<{
32
32
  severity: z.ZodEnum<["high", "medium", "low"]>;
33
- category: z.ZodEnum<["path-assumption", "undeclared-dependency", "ambient-propping", "doc-engine-drift", "missing-bundled-file"]>;
33
+ category: z.ZodEnum<["path-assumption", "undeclared-dependency", "ambient-propping", "doc-engine-drift", "missing-bundled-file", "tool-expectation"]>;
34
34
  message: z.ZodString;
35
35
  subjectFile: z.ZodOptional<z.ZodString>;
36
36
  evidence: z.ZodOptional<z.ZodString>;
37
37
  }, "strict", z.ZodTypeAny, {
38
38
  message: string;
39
39
  severity: "high" | "medium" | "low";
40
- category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file";
40
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
41
41
  evidence?: string | undefined;
42
42
  subjectFile?: string | undefined;
43
43
  }, {
44
44
  message: string;
45
45
  severity: "high" | "medium" | "low";
46
- category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file";
46
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
47
47
  evidence?: string | undefined;
48
48
  subjectFile?: string | undefined;
49
49
  }>, "many">;
@@ -51,7 +51,7 @@ export declare const FrictionReportSchema: z.ZodObject<{
51
51
  items: {
52
52
  message: string;
53
53
  severity: "high" | "medium" | "low";
54
- category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file";
54
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
55
55
  evidence?: string | undefined;
56
56
  subjectFile?: string | undefined;
57
57
  }[];
@@ -59,7 +59,7 @@ export declare const FrictionReportSchema: z.ZodObject<{
59
59
  items: {
60
60
  message: string;
61
61
  severity: "high" | "medium" | "low";
62
- category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file";
62
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
63
63
  evidence?: string | undefined;
64
64
  subjectFile?: string | undefined;
65
65
  }[];