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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,50 @@
1
+ import { spawnHeadlessClaude, type ParsedTranscript, type SpawnResult } from '@vibe-agent-toolkit/utils';
2
+ export interface RunExecutorInput {
3
+ evalId: string;
4
+ task: string;
5
+ subjectStagedDir: string;
6
+ /** `<workspacesRoot>/<id>` when the eval declares input `files`. */
7
+ workspaceDir?: string;
8
+ pluginDirs: string[];
9
+ env: NodeJS.ProcessEnv;
10
+ model?: string;
11
+ maxTurns: number;
12
+ maxBudgetUsd: number;
13
+ timeoutMs: number;
14
+ stallMs?: number;
15
+ /** Injectable seam for tests; defaults to the real {@link spawnHeadlessClaude}. */
16
+ spawn?: typeof spawnHeadlessClaude;
17
+ /** Called with each stdout chunk as it streams (for progress echo). */
18
+ onProgress?: (chunk: string) => void;
19
+ }
20
+ export interface ExecutorOutcome {
21
+ /** Full captured stdout (stream-json), held IN MEMORY only — never written to disk. */
22
+ transcript: string;
23
+ parsed: ParsedTranscript;
24
+ spawnResult: SpawnResult;
25
+ /** true = the executor exited non-zero WITHIN budget — a valid eval failure, not a harness break. */
26
+ cleanFailure: boolean;
27
+ }
28
+ /**
29
+ * Run ONE eval's executor: a blind `claude -p` spawn that performs `task`
30
+ * against the staged subject (issue #145). The executor's entire stream-json
31
+ * stdout is accumulated in memory (never written to a skill-writable disk
32
+ * path — the "stop discarding stdout" fix) and echoed to `onProgress` chunk
33
+ * by chunk for visibility.
34
+ *
35
+ * Encodes the R1 exit bifurcation at the executor boundary:
36
+ * - A spawn error (the promise rejects), or our own watchdog firing
37
+ * (`timedOut`/`stalled`), is HARNESS breakage → thrown as
38
+ * {@link InternalHarnessError} (exit 1).
39
+ * - A mid-stream rate-limit that cuts the run off before it completes (status
40
+ * !== 0) is NOT a harness failure but also not gradeable → thrown as
41
+ * {@link RateLimitSignal} so the caller's pool can back off and retry this
42
+ * eval. A rate-limit event that the run still completed past (status 0) is
43
+ * kept and returned normally.
44
+ * - Anything else — including a clean non-zero exit within budget — is a
45
+ * valid eval OUTCOME, not a harness break: returned with `cleanFailure`
46
+ * reflecting whether the executor exited non-zero. Never laundered into a
47
+ * thrown error; the grader decides whether the transcript passes.
48
+ */
49
+ export declare function runExecutorForEval(input: RunExecutorInput): Promise<ExecutorOutcome>;
50
+ //# sourceMappingURL=eval-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-executor.d.ts","sourceRoot":"","sources":["../../src/skill-test/eval-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AAMnC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,KAAK,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACnC,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,qGAAqG;IACrG,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAsE1F"}
@@ -0,0 +1,85 @@
1
+ import { parseStreamJsonTranscript, spawnHeadlessClaude, } from '@vibe-agent-toolkit/utils';
2
+ import { assertExecutorPromptInvariants, buildExecutorPrompt } from './executor-prompt.js';
3
+ import { InternalHarnessError } from './exit-codes.js';
4
+ import { RateLimitSignal } from './pipeline.js';
5
+ /**
6
+ * Run ONE eval's executor: a blind `claude -p` spawn that performs `task`
7
+ * against the staged subject (issue #145). The executor's entire stream-json
8
+ * stdout is accumulated in memory (never written to a skill-writable disk
9
+ * path — the "stop discarding stdout" fix) and echoed to `onProgress` chunk
10
+ * by chunk for visibility.
11
+ *
12
+ * Encodes the R1 exit bifurcation at the executor boundary:
13
+ * - A spawn error (the promise rejects), or our own watchdog firing
14
+ * (`timedOut`/`stalled`), is HARNESS breakage → thrown as
15
+ * {@link InternalHarnessError} (exit 1).
16
+ * - A mid-stream rate-limit that cuts the run off before it completes (status
17
+ * !== 0) is NOT a harness failure but also not gradeable → thrown as
18
+ * {@link RateLimitSignal} so the caller's pool can back off and retry this
19
+ * eval. A rate-limit event that the run still completed past (status 0) is
20
+ * kept and returned normally.
21
+ * - Anything else — including a clean non-zero exit within budget — is a
22
+ * valid eval OUTCOME, not a harness break: returned with `cleanFailure`
23
+ * reflecting whether the executor exited non-zero. Never laundered into a
24
+ * thrown error; the grader decides whether the transcript passes.
25
+ */
26
+ export async function runExecutorForEval(input) {
27
+ const workDir = input.workspaceDir ?? input.subjectStagedDir;
28
+ const prompt = buildExecutorPrompt({
29
+ task: input.task,
30
+ subjectPath: input.subjectStagedDir,
31
+ ...(input.workspaceDir === undefined ? {} : { workspaceDir: input.workspaceDir }),
32
+ });
33
+ // Defense-in-depth (parity with run-harness's build→assert→use pattern):
34
+ // re-verify the built prompt didn't accidentally blind-break the executor
35
+ // before spawning. Only OUR scaffolding is policed — the adopter task is
36
+ // excluded, so a legit task containing denylist words does not trip this.
37
+ assertExecutorPromptInvariants(prompt, input.task);
38
+ const spawn = input.spawn ?? spawnHeadlessClaude;
39
+ let transcript = '';
40
+ const onStdout = (chunk) => {
41
+ transcript += chunk;
42
+ input.onProgress?.(chunk);
43
+ };
44
+ let spawnResult;
45
+ try {
46
+ spawnResult = await spawn({
47
+ prompt,
48
+ pluginDirs: input.pluginDirs,
49
+ sandboxDir: workDir,
50
+ cwd: workDir,
51
+ env: input.env,
52
+ timeoutMs: input.timeoutMs,
53
+ onStdout,
54
+ maxTurns: input.maxTurns,
55
+ maxBudgetUsd: input.maxBudgetUsd,
56
+ ...(input.model === undefined ? {} : { model: input.model }),
57
+ ...(input.stallMs === undefined ? {} : { stallMs: input.stallMs }),
58
+ });
59
+ }
60
+ catch (err) {
61
+ throw new InternalHarnessError(`Executor spawn failed for eval "${input.evalId}": ${err instanceof Error ? err.message : String(err)}`);
62
+ }
63
+ // Watchdog kills (our own harness code, not the executor) are harness
64
+ // breakage regardless of what the executor produced before being killed.
65
+ if (spawnResult.stalled) {
66
+ throw new InternalHarnessError(`Executor stalled for eval "${input.evalId}" (no output for ${input.stallMs ?? 0}ms).`);
67
+ }
68
+ if (spawnResult.timedOut) {
69
+ throw new InternalHarnessError(`Executor timed out for eval "${input.evalId}" (limit ${input.timeoutMs}ms).`);
70
+ }
71
+ const parsed = parseStreamJsonTranscript(transcript);
72
+ // A rate-limit that cut the run off before completion (non-zero status) is
73
+ // not gradeable — signal the pool to back off and retry. A rate-limit event
74
+ // the run otherwise completed past (status 0) is kept as-is.
75
+ if (parsed.rateLimited && spawnResult.status !== 0) {
76
+ throw new RateLimitSignal(`Executor rate-limited for eval "${input.evalId}".`);
77
+ }
78
+ return {
79
+ transcript,
80
+ parsed,
81
+ spawnResult,
82
+ cleanFailure: spawnResult.status !== 0,
83
+ };
84
+ }
85
+ //# sourceMappingURL=eval-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-executor.js","sourceRoot":"","sources":["../../src/skill-test/eval-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,278 @@
1
+ import { z } from 'zod';
2
+ /** One graded expectation inside a per-eval grader fragment. */
3
+ export declare const EvalFragmentExpectationSchema: z.ZodObject<{
4
+ text: z.ZodString;
5
+ passed: z.ZodBoolean;
6
+ evidence: z.ZodOptional<z.ZodString>;
7
+ }, "strict", z.ZodTypeAny, {
8
+ passed: boolean;
9
+ text: string;
10
+ evidence?: string | undefined;
11
+ }, {
12
+ passed: boolean;
13
+ text: string;
14
+ evidence?: string | undefined;
15
+ }>;
16
+ export type EvalFragmentExpectation = z.infer<typeof EvalFragmentExpectationSchema>;
17
+ /**
18
+ * Strict shape of a single grader subagent's output (issue #145 Task 4). One
19
+ * GRADER spawn grades ONE eval's expectations from that eval's captured
20
+ * transcript and writes exactly one fragment matching this schema; vat reads
21
+ * every eval's fragment back and merges them into the run's aggregate grading
22
+ * result (skill-creator's flat `grading.json` shape — see grading-adapter.ts).
23
+ *
24
+ * `.strict()`: this is vat's OWN output artifact contract, not external data
25
+ * we're auditing (see CLAUDE.md Postel's Law) — an unrecognized field is a
26
+ * grader bug we want surfaced immediately, not silently dropped.
27
+ *
28
+ * `arm` distinguishes a WITH/WITHOUT baseline run's fragment; absent means the
29
+ * default 'with' (skill present) arm.
30
+ *
31
+ * `tool` (issue #145 Phase T) carries this eval's tool-expectation verdict —
32
+ * a SEPARATE channel from `expectations[]` and from `friction` (see
33
+ * tool-eval-schema.ts). It is {@link ToolVerdictBodySchema}, i.e. a
34
+ * {@link import('./tool-eval-schema.js').ToolVerdict} WITHOUT `evalId`: the
35
+ * fragment already carries `evalId` at its top level, so the merge step
36
+ * (`mergeFragmentsToToolEval` in fragment-merge.ts) re-attaches it from the
37
+ * fragment when assembling vat's `tool-eval.json`.
38
+ */
39
+ export declare const EvalFragmentSchema: z.ZodObject<{
40
+ runNonce: z.ZodString;
41
+ evalId: z.ZodString;
42
+ arm: z.ZodOptional<z.ZodEnum<["with", "without"]>>;
43
+ expectations: z.ZodArray<z.ZodObject<{
44
+ text: z.ZodString;
45
+ passed: z.ZodBoolean;
46
+ evidence: z.ZodOptional<z.ZodString>;
47
+ }, "strict", z.ZodTypeAny, {
48
+ passed: boolean;
49
+ text: string;
50
+ evidence?: string | undefined;
51
+ }, {
52
+ passed: boolean;
53
+ text: string;
54
+ evidence?: string | undefined;
55
+ }>, "many">;
56
+ friction: z.ZodOptional<z.ZodArray<z.ZodObject<{
57
+ severity: z.ZodEnum<["high", "medium", "low"]>;
58
+ category: z.ZodEnum<["path-assumption", "undeclared-dependency", "ambient-propping", "doc-engine-drift", "missing-bundled-file", "tool-expectation"]>;
59
+ message: z.ZodString;
60
+ subjectFile: z.ZodOptional<z.ZodString>;
61
+ evidence: z.ZodOptional<z.ZodString>;
62
+ }, "strict", z.ZodTypeAny, {
63
+ message: string;
64
+ severity: "high" | "medium" | "low";
65
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
66
+ evidence?: string | undefined;
67
+ subjectFile?: string | undefined;
68
+ }, {
69
+ message: string;
70
+ severity: "high" | "medium" | "low";
71
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
72
+ evidence?: string | undefined;
73
+ subjectFile?: string | undefined;
74
+ }>, "many">>;
75
+ tool: z.ZodOptional<z.ZodObject<{
76
+ mustRun: z.ZodOptional<z.ZodArray<z.ZodObject<{
77
+ name: z.ZodString;
78
+ ran: z.ZodBoolean;
79
+ evidence: z.ZodOptional<z.ZodString>;
80
+ }, "strict", z.ZodTypeAny, {
81
+ name: string;
82
+ ran: boolean;
83
+ evidence?: string | undefined;
84
+ }, {
85
+ name: string;
86
+ ran: boolean;
87
+ evidence?: string | undefined;
88
+ }>, "many">>;
89
+ mustNotRun: z.ZodOptional<z.ZodArray<z.ZodObject<{
90
+ name: z.ZodString;
91
+ ran: z.ZodBoolean;
92
+ evidence: z.ZodOptional<z.ZodString>;
93
+ }, "strict", z.ZodTypeAny, {
94
+ name: string;
95
+ ran: boolean;
96
+ evidence?: string | undefined;
97
+ }, {
98
+ name: string;
99
+ ran: boolean;
100
+ evidence?: string | undefined;
101
+ }>, "many">>;
102
+ mustSucceed: z.ZodOptional<z.ZodArray<z.ZodObject<{
103
+ name: z.ZodString;
104
+ succeeded: z.ZodBoolean;
105
+ evidence: z.ZodOptional<z.ZodString>;
106
+ }, "strict", z.ZodTypeAny, {
107
+ name: string;
108
+ succeeded: boolean;
109
+ evidence?: string | undefined;
110
+ }, {
111
+ name: string;
112
+ succeeded: boolean;
113
+ evidence?: string | undefined;
114
+ }>, "many">>;
115
+ sequence: z.ZodOptional<z.ZodArray<z.ZodObject<{
116
+ steps: z.ZodArray<z.ZodString, "many">;
117
+ satisfied: z.ZodBoolean;
118
+ evidence: z.ZodOptional<z.ZodString>;
119
+ }, "strict", z.ZodTypeAny, {
120
+ steps: string[];
121
+ satisfied: boolean;
122
+ evidence?: string | undefined;
123
+ }, {
124
+ steps: string[];
125
+ satisfied: boolean;
126
+ evidence?: string | undefined;
127
+ }>, "many">>;
128
+ passed: z.ZodBoolean;
129
+ }, "strict", z.ZodTypeAny, {
130
+ passed: boolean;
131
+ mustRun?: {
132
+ name: string;
133
+ ran: boolean;
134
+ evidence?: string | undefined;
135
+ }[] | undefined;
136
+ mustNotRun?: {
137
+ name: string;
138
+ ran: boolean;
139
+ evidence?: string | undefined;
140
+ }[] | undefined;
141
+ mustSucceed?: {
142
+ name: string;
143
+ succeeded: boolean;
144
+ evidence?: string | undefined;
145
+ }[] | undefined;
146
+ sequence?: {
147
+ steps: string[];
148
+ satisfied: boolean;
149
+ evidence?: string | undefined;
150
+ }[] | undefined;
151
+ }, {
152
+ passed: boolean;
153
+ mustRun?: {
154
+ name: string;
155
+ ran: boolean;
156
+ evidence?: string | undefined;
157
+ }[] | undefined;
158
+ mustNotRun?: {
159
+ name: string;
160
+ ran: boolean;
161
+ evidence?: string | undefined;
162
+ }[] | undefined;
163
+ mustSucceed?: {
164
+ name: string;
165
+ succeeded: boolean;
166
+ evidence?: string | undefined;
167
+ }[] | undefined;
168
+ sequence?: {
169
+ steps: string[];
170
+ satisfied: boolean;
171
+ evidence?: string | undefined;
172
+ }[] | undefined;
173
+ }>>;
174
+ }, "strict", z.ZodTypeAny, {
175
+ expectations: {
176
+ passed: boolean;
177
+ text: string;
178
+ evidence?: string | undefined;
179
+ }[];
180
+ evalId: string;
181
+ runNonce: string;
182
+ arm?: "with" | "without" | undefined;
183
+ friction?: {
184
+ message: string;
185
+ severity: "high" | "medium" | "low";
186
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
187
+ evidence?: string | undefined;
188
+ subjectFile?: string | undefined;
189
+ }[] | undefined;
190
+ tool?: {
191
+ passed: boolean;
192
+ mustRun?: {
193
+ name: string;
194
+ ran: boolean;
195
+ evidence?: string | undefined;
196
+ }[] | undefined;
197
+ mustNotRun?: {
198
+ name: string;
199
+ ran: boolean;
200
+ evidence?: string | undefined;
201
+ }[] | undefined;
202
+ mustSucceed?: {
203
+ name: string;
204
+ succeeded: boolean;
205
+ evidence?: string | undefined;
206
+ }[] | undefined;
207
+ sequence?: {
208
+ steps: string[];
209
+ satisfied: boolean;
210
+ evidence?: string | undefined;
211
+ }[] | undefined;
212
+ } | undefined;
213
+ }, {
214
+ expectations: {
215
+ passed: boolean;
216
+ text: string;
217
+ evidence?: string | undefined;
218
+ }[];
219
+ evalId: string;
220
+ runNonce: string;
221
+ arm?: "with" | "without" | undefined;
222
+ friction?: {
223
+ message: string;
224
+ severity: "high" | "medium" | "low";
225
+ category: "path-assumption" | "undeclared-dependency" | "ambient-propping" | "doc-engine-drift" | "missing-bundled-file" | "tool-expectation";
226
+ evidence?: string | undefined;
227
+ subjectFile?: string | undefined;
228
+ }[] | undefined;
229
+ tool?: {
230
+ passed: boolean;
231
+ mustRun?: {
232
+ name: string;
233
+ ran: boolean;
234
+ evidence?: string | undefined;
235
+ }[] | undefined;
236
+ mustNotRun?: {
237
+ name: string;
238
+ ran: boolean;
239
+ evidence?: string | undefined;
240
+ }[] | undefined;
241
+ mustSucceed?: {
242
+ name: string;
243
+ succeeded: boolean;
244
+ evidence?: string | undefined;
245
+ }[] | undefined;
246
+ sequence?: {
247
+ steps: string[];
248
+ satisfied: boolean;
249
+ evidence?: string | undefined;
250
+ }[] | undefined;
251
+ } | undefined;
252
+ }>;
253
+ export type EvalFragment = z.infer<typeof EvalFragmentSchema>;
254
+ /**
255
+ * Thrown when a single grader subagent's fragment output does not match
256
+ * {@link EvalFragmentSchema}. Deliberately distinct from `GradingSkewError`
257
+ * (grading-adapter.ts): that error's message is specific to the AGGREGATE
258
+ * `grading.json` shape (skill-creator's flat report) and is wrong when the
259
+ * thing that failed to parse is one grader's per-eval fragment — a fragment
260
+ * shape bug is a GRADER bug, not an aggregate-assembly bug, and the message
261
+ * should point at the offending eval, not at "Re-sync the vendored
262
+ * skill-creator".
263
+ */
264
+ export declare class EvalFragmentError extends Error {
265
+ constructor(message: string);
266
+ }
267
+ /**
268
+ * Parse + validate one grader's fragment output. Throws {@link EvalFragmentError}
269
+ * — never {@link GradingSkewError} — because this is a per-eval fragment, not
270
+ * the assembled aggregate `grading.json`.
271
+ *
272
+ * The verdict channels are strict. The auxiliary `friction` field is sanitized
273
+ * leniently first (see {@link sanitizeFrictionField}); when items are dropped,
274
+ * `onWarn` (if given) is called so the operator sees that friction was partial —
275
+ * grading itself is never affected.
276
+ */
277
+ export declare function parseEvalFragment(raw: unknown, onWarn?: (message: string) => void): EvalFragment;
278
+ //# sourceMappingURL=eval-fragment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-fragment.d.ts","sourceRoot":"","sources":["../../src/skill-test/eval-fragment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,gEAAgE;AAChE,eAAO,MAAM,6BAA6B;;;;;;;;;;;;EAI/B,CAAC;AAEZ,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAOpB,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;;;;;;GASG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AA+CD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,YAAY,CAkBhG"}
@@ -0,0 +1,128 @@
1
+ import { z } from 'zod';
2
+ import { FrictionItemSchema } from './friction-schema.js';
3
+ import { ToolVerdictBodySchema } from './tool-eval-schema.js';
4
+ /** One graded expectation inside a per-eval grader fragment. */
5
+ export const EvalFragmentExpectationSchema = z.object({
6
+ text: z.string(),
7
+ passed: z.boolean(),
8
+ evidence: z.string().optional(),
9
+ }).strict();
10
+ /**
11
+ * Strict shape of a single grader subagent's output (issue #145 Task 4). One
12
+ * GRADER spawn grades ONE eval's expectations from that eval's captured
13
+ * transcript and writes exactly one fragment matching this schema; vat reads
14
+ * every eval's fragment back and merges them into the run's aggregate grading
15
+ * result (skill-creator's flat `grading.json` shape — see grading-adapter.ts).
16
+ *
17
+ * `.strict()`: this is vat's OWN output artifact contract, not external data
18
+ * we're auditing (see CLAUDE.md Postel's Law) — an unrecognized field is a
19
+ * grader bug we want surfaced immediately, not silently dropped.
20
+ *
21
+ * `arm` distinguishes a WITH/WITHOUT baseline run's fragment; absent means the
22
+ * default 'with' (skill present) arm.
23
+ *
24
+ * `tool` (issue #145 Phase T) carries this eval's tool-expectation verdict —
25
+ * a SEPARATE channel from `expectations[]` and from `friction` (see
26
+ * tool-eval-schema.ts). It is {@link ToolVerdictBodySchema}, i.e. a
27
+ * {@link import('./tool-eval-schema.js').ToolVerdict} WITHOUT `evalId`: the
28
+ * fragment already carries `evalId` at its top level, so the merge step
29
+ * (`mergeFragmentsToToolEval` in fragment-merge.ts) re-attaches it from the
30
+ * fragment when assembling vat's `tool-eval.json`.
31
+ */
32
+ export const EvalFragmentSchema = z.object({
33
+ runNonce: z.string().min(1),
34
+ evalId: z.string().min(1),
35
+ arm: z.enum(['with', 'without']).optional(),
36
+ expectations: z.array(EvalFragmentExpectationSchema).min(1),
37
+ friction: z.array(FrictionItemSchema).optional(),
38
+ tool: ToolVerdictBodySchema.optional(),
39
+ }).strict();
40
+ /**
41
+ * Thrown when a single grader subagent's fragment output does not match
42
+ * {@link EvalFragmentSchema}. Deliberately distinct from `GradingSkewError`
43
+ * (grading-adapter.ts): that error's message is specific to the AGGREGATE
44
+ * `grading.json` shape (skill-creator's flat report) and is wrong when the
45
+ * thing that failed to parse is one grader's per-eval fragment — a fragment
46
+ * shape bug is a GRADER bug, not an aggregate-assembly bug, and the message
47
+ * should point at the offending eval, not at "Re-sync the vendored
48
+ * skill-creator".
49
+ */
50
+ export class EvalFragmentError extends Error {
51
+ constructor(message) {
52
+ super(message);
53
+ this.name = 'EvalFragmentError';
54
+ }
55
+ }
56
+ /** Best-effort extraction of `evalId` from raw input for error messages, tolerating any shape. */
57
+ function extractRawEvalId(raw) {
58
+ if (typeof raw === 'object' && raw !== null && 'evalId' in raw) {
59
+ const value = raw['evalId'];
60
+ if (typeof value === 'string' && value.length > 0)
61
+ return `"${value}"`;
62
+ }
63
+ return '(unknown)';
64
+ }
65
+ /**
66
+ * Sanitize ONLY the (non-verdict-bearing) `friction` field before the strict
67
+ * fragment parse. Friction is auxiliary advisory data, not a verdict channel —
68
+ * so a grader that wobbles on the friction shape (e.g. emits bare strings, the
69
+ * common failure mode — PR #147) must NOT be allowed to discard the
70
+ * verdict-bearing grading for the whole run. We drop friction items that don't
71
+ * match {@link FrictionItemSchema} (and a `friction` that isn't an array at
72
+ * all), then hand the rest to the STRICT fragment parse — so the verdict
73
+ * channels (`runNonce`/`evalId`/`expectations`/`tool`) stay fully fail-closed
74
+ * and an unknown field elsewhere still surfaces as a grader bug.
75
+ *
76
+ * Returns the possibly-rewritten raw value and how many friction items were
77
+ * dropped (0 when friction is absent or already well-shaped — the input is then
78
+ * returned untouched).
79
+ */
80
+ function sanitizeFrictionField(raw) {
81
+ if (typeof raw !== 'object' || raw === null || !('friction' in raw)) {
82
+ return { value: raw, dropped: 0 };
83
+ }
84
+ const obj = raw;
85
+ const friction = obj['friction'];
86
+ if (friction === undefined)
87
+ return { value: raw, dropped: 0 };
88
+ if (!Array.isArray(friction)) {
89
+ // A non-array `friction` (e.g. a bare string) is unusable auxiliary noise —
90
+ // drop the whole field rather than fail the run over it.
91
+ const rest = {};
92
+ for (const [key, val] of Object.entries(obj)) {
93
+ if (key !== 'friction')
94
+ rest[key] = val;
95
+ }
96
+ return { value: rest, dropped: 1 };
97
+ }
98
+ const kept = friction.filter((item) => FrictionItemSchema.safeParse(item).success);
99
+ if (kept.length === friction.length)
100
+ return { value: raw, dropped: 0 };
101
+ return { value: { ...obj, friction: kept }, dropped: friction.length - kept.length };
102
+ }
103
+ /**
104
+ * Parse + validate one grader's fragment output. Throws {@link EvalFragmentError}
105
+ * — never {@link GradingSkewError} — because this is a per-eval fragment, not
106
+ * the assembled aggregate `grading.json`.
107
+ *
108
+ * The verdict channels are strict. The auxiliary `friction` field is sanitized
109
+ * leniently first (see {@link sanitizeFrictionField}); when items are dropped,
110
+ * `onWarn` (if given) is called so the operator sees that friction was partial —
111
+ * grading itself is never affected.
112
+ */
113
+ export function parseEvalFragment(raw, onWarn) {
114
+ const { value, dropped } = sanitizeFrictionField(raw);
115
+ if (dropped > 0) {
116
+ onWarn?.(`grader fragment for eval ${extractRawEvalId(raw)} had ${dropped} malformed friction item(s) — ` +
117
+ `dropped them (friction is advisory; grading is unaffected).`);
118
+ }
119
+ const result = EvalFragmentSchema.safeParse(value);
120
+ if (!result.success) {
121
+ const firstIssue = result.error.issues[0];
122
+ const path = firstIssue?.path.join('.') ?? '(root)';
123
+ const evalId = extractRawEvalId(raw);
124
+ throw new EvalFragmentError(`grader fragment for eval ${evalId} has an invalid shape: invalid field at "${path}" (${firstIssue?.message ?? 'unknown'})`);
125
+ }
126
+ return result.data;
127
+ }
128
+ //# sourceMappingURL=eval-fragment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-fragment.js","sourceRoot":"","sources":["../../src/skill-test/eval-fragment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { spawnHeadlessClaude } from '@vibe-agent-toolkit/utils';
2
+ import { type EvalFragment } from './eval-fragment.js';
3
+ import type { ToolExpectations } from './eval-inputs.js';
4
+ export interface RunGraderInput {
5
+ evalId: string;
6
+ /** The FULL captured transcript (stream-json) for this eval's executor run. */
7
+ transcript: string;
8
+ expectations: string[];
9
+ expectedOutput?: string;
10
+ /** Path to the vendored skill-creator grader rubric (references/grader.md). */
11
+ rubricPath: string;
12
+ /**
13
+ * The eval's declared tool expectations (issue #145 Phase T). Optional — when
14
+ * absent, `buildGraderPrompt` emits no tool-verdict instruction and the
15
+ * returned fragment omits `tool`. See `grader-prompt.ts`'s
16
+ * `BuildGraderPromptOptions.toolExpectations`.
17
+ */
18
+ toolExpectations?: ToolExpectations;
19
+ /** Name → invocation hint for declared executables, a recognition aid alongside `toolExpectations`. */
20
+ declaredExecutables?: Array<{
21
+ name: string;
22
+ howInvoked: string;
23
+ kind: string;
24
+ }>;
25
+ /**
26
+ * VAT-ONLY directory the grader fragment is written to — deliberately
27
+ * OUTSIDE the skill-writable sandbox (never the executor's staged/workspace
28
+ * dir) so untrusted skill code from Task 7's executor run cannot forge or
29
+ * delete the fragment this run relies on.
30
+ */
31
+ graderOutDir: string;
32
+ graderModel: string;
33
+ /** Per-run integrity nonce the grader must echo back in the fragment. */
34
+ nonce: string;
35
+ maxTurns: number;
36
+ maxBudgetUsd: number;
37
+ timeoutMs: number;
38
+ stallMs?: number;
39
+ /** Grader auth env — no skill secrets are needed beyond auth. */
40
+ env: NodeJS.ProcessEnv;
41
+ /** Injectable seam for tests; defaults to the real {@link spawnHeadlessClaude}. */
42
+ spawn?: typeof spawnHeadlessClaude;
43
+ /** Called with each stdout chunk as it streams (for progress echo). */
44
+ onProgress?: (chunk: string) => void;
45
+ /**
46
+ * Reports this grader session's `total_cost_usd` (parsed from its stream-json
47
+ * transcript's terminal result; `undefined` when the transcript carried none,
48
+ * e.g. a mock spawn). Called once after a successful grader spawn so the run can
49
+ * aggregate total spend across all executor+grader sessions (adopter follow-up).
50
+ */
51
+ costSink?: (totalCostUsd: number | undefined) => void;
52
+ }
53
+ export declare function runGraderForEval(input: RunGraderInput): Promise<EvalFragment>;
54
+ //# sourceMappingURL=eval-grader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-grader.d.ts","sourceRoot":"","sources":["../../src/skill-test/eval-grader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsD,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEpH,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAMzD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uGAAuG;IACvG,mBAAmB,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,mFAAmF;IACnF,KAAK,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACnC,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;CACvD;AAsCD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAoGnF"}