@vibe-agent-toolkit/agent-skills 0.1.40-rc.2 → 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 (89) hide show
  1. package/dist/builder.js +11 -11
  2. package/dist/skill-test/eval-executor.d.ts +50 -0
  3. package/dist/skill-test/eval-executor.d.ts.map +1 -0
  4. package/dist/skill-test/eval-executor.js +85 -0
  5. package/dist/skill-test/eval-executor.js.map +1 -0
  6. package/dist/skill-test/eval-fragment.d.ts +278 -0
  7. package/dist/skill-test/eval-fragment.d.ts.map +1 -0
  8. package/dist/skill-test/eval-fragment.js +128 -0
  9. package/dist/skill-test/eval-fragment.js.map +1 -0
  10. package/dist/skill-test/eval-grader.d.ts +54 -0
  11. package/dist/skill-test/eval-grader.d.ts.map +1 -0
  12. package/dist/skill-test/eval-grader.js +184 -0
  13. package/dist/skill-test/eval-grader.js.map +1 -0
  14. package/dist/skill-test/eval-inputs.d.ts +355 -0
  15. package/dist/skill-test/eval-inputs.d.ts.map +1 -1
  16. package/dist/skill-test/eval-inputs.js +36 -8
  17. package/dist/skill-test/eval-inputs.js.map +1 -1
  18. package/dist/skill-test/eval-lint.d.ts +51 -0
  19. package/dist/skill-test/eval-lint.d.ts.map +1 -0
  20. package/dist/skill-test/eval-lint.js +157 -0
  21. package/dist/skill-test/eval-lint.js.map +1 -0
  22. package/dist/skill-test/evals-template.d.ts.map +1 -1
  23. package/dist/skill-test/evals-template.js +7 -0
  24. package/dist/skill-test/evals-template.js.map +1 -1
  25. package/dist/skill-test/executor-prompt.d.ts +41 -0
  26. package/dist/skill-test/executor-prompt.d.ts.map +1 -0
  27. package/dist/skill-test/executor-prompt.js +63 -0
  28. package/dist/skill-test/executor-prompt.js.map +1 -0
  29. package/dist/skill-test/exit-codes.d.ts +22 -13
  30. package/dist/skill-test/exit-codes.d.ts.map +1 -1
  31. package/dist/skill-test/exit-codes.js +26 -15
  32. package/dist/skill-test/exit-codes.js.map +1 -1
  33. package/dist/skill-test/fragment-merge.d.ts +46 -0
  34. package/dist/skill-test/fragment-merge.d.ts.map +1 -0
  35. package/dist/skill-test/fragment-merge.js +77 -0
  36. package/dist/skill-test/fragment-merge.js.map +1 -0
  37. package/dist/skill-test/friction-schema.d.ts +10 -10
  38. package/dist/skill-test/friction-schema.d.ts.map +1 -1
  39. package/dist/skill-test/friction-schema.js +6 -1
  40. package/dist/skill-test/friction-schema.js.map +1 -1
  41. package/dist/skill-test/grader-model.d.ts +6 -0
  42. package/dist/skill-test/grader-model.d.ts.map +1 -0
  43. package/dist/skill-test/grader-model.js +6 -0
  44. package/dist/skill-test/grader-model.js.map +1 -0
  45. package/dist/skill-test/grader-prompt.d.ts +74 -0
  46. package/dist/skill-test/grader-prompt.d.ts.map +1 -0
  47. package/dist/skill-test/grader-prompt.js +173 -0
  48. package/dist/skill-test/grader-prompt.js.map +1 -0
  49. package/dist/skill-test/grading-adapter.d.ts +5 -11
  50. package/dist/skill-test/grading-adapter.d.ts.map +1 -1
  51. package/dist/skill-test/grading-adapter.js +9 -22
  52. package/dist/skill-test/grading-adapter.js.map +1 -1
  53. package/dist/skill-test/grading-schema.d.ts +18 -15
  54. package/dist/skill-test/grading-schema.d.ts.map +1 -1
  55. package/dist/skill-test/grading-schema.js +6 -5
  56. package/dist/skill-test/grading-schema.js.map +1 -1
  57. package/dist/skill-test/index.d.ts +13 -3
  58. package/dist/skill-test/index.d.ts.map +1 -1
  59. package/dist/skill-test/index.js +13 -3
  60. package/dist/skill-test/index.js.map +1 -1
  61. package/dist/skill-test/pipeline.d.ts +29 -0
  62. package/dist/skill-test/pipeline.d.ts.map +1 -0
  63. package/dist/skill-test/pipeline.js +77 -0
  64. package/dist/skill-test/pipeline.js.map +1 -0
  65. package/dist/skill-test/prompt-invariants.d.ts +27 -0
  66. package/dist/skill-test/prompt-invariants.d.ts.map +1 -0
  67. package/dist/skill-test/prompt-invariants.js +38 -0
  68. package/dist/skill-test/prompt-invariants.js.map +1 -0
  69. package/dist/skill-test/run-harness.d.ts +209 -30
  70. package/dist/skill-test/run-harness.d.ts.map +1 -1
  71. package/dist/skill-test/run-harness.js +585 -135
  72. package/dist/skill-test/run-harness.js.map +1 -1
  73. package/dist/skill-test/tier-plan.d.ts +89 -0
  74. package/dist/skill-test/tier-plan.d.ts.map +1 -0
  75. package/dist/skill-test/tier-plan.js +96 -0
  76. package/dist/skill-test/tier-plan.js.map +1 -0
  77. package/dist/skill-test/tool-eval-schema.d.ts +412 -0
  78. package/dist/skill-test/tool-eval-schema.d.ts.map +1 -0
  79. package/dist/skill-test/tool-eval-schema.js +83 -0
  80. package/dist/skill-test/tool-eval-schema.js.map +1 -0
  81. package/dist/validators/packaging-validator.d.ts +8 -1
  82. package/dist/validators/packaging-validator.d.ts.map +1 -1
  83. package/dist/validators/packaging-validator.js.map +1 -1
  84. package/package.json +8 -7
  85. package/schemas/friction-report.json +2 -1
  86. package/dist/skill-test/experimenter-prompt.d.ts +0 -42
  87. package/dist/skill-test/experimenter-prompt.d.ts.map +0 -1
  88. package/dist/skill-test/experimenter-prompt.js +0 -104
  89. package/dist/skill-test/experimenter-prompt.js.map +0 -1
package/dist/builder.js CHANGED
@@ -128,7 +128,7 @@ metadata:
128
128
  spec:
129
129
  llm:
130
130
  provider: anthropic
131
- model: claude-sonnet-4-20250514
131
+ model: claude-sonnet-5
132
132
 
133
133
  prompts:
134
134
  system:
@@ -183,7 +183,7 @@ metadata:
183
183
  spec:
184
184
  llm: # LLM configuration (required)
185
185
  provider: anthropic # anthropic, openai, google
186
- model: claude-sonnet-4-20250514
186
+ model: claude-sonnet-5
187
187
  temperature: 0.7 # 0.0-2.0 (default varies by provider)
188
188
  maxTokens: 16000 # optional
189
189
  topP: 0.9 # optional nucleus sampling
@@ -234,7 +234,7 @@ metadata:
234
234
  spec:
235
235
  llm:
236
236
  provider: anthropic
237
- model: claude-sonnet-4-20250514
237
+ model: claude-sonnet-5
238
238
  prompts:
239
239
  system:
240
240
  $ref: ./prompts/system.md
@@ -262,12 +262,12 @@ spec:
262
262
 
263
263
  llm:
264
264
  provider: anthropic
265
- model: claude-sonnet-4-20250514
265
+ model: claude-sonnet-5
266
266
  temperature: 0.3
267
267
  maxTokens: 16000
268
268
  alternatives:
269
269
  - provider: anthropic
270
- model: claude-opus-4-20250514
270
+ model: claude-opus-4-8
271
271
  - provider: openai
272
272
  model: gpt-4o
273
273
 
@@ -333,10 +333,10 @@ Specify fallback models for cost optimization or availability:
333
333
  spec:
334
334
  llm:
335
335
  provider: anthropic
336
- model: claude-sonnet-4-20250514
336
+ model: claude-sonnet-5
337
337
  alternatives:
338
338
  - provider: anthropic
339
- model: claude-3-5-haiku-20241022 # Faster/cheaper fallback
339
+ model: claude-haiku-4-5 # Faster/cheaper fallback
340
340
  - provider: openai
341
341
  model: gpt-4o # Cross-provider fallback
342
342
  \`\`\`
@@ -432,17 +432,17 @@ spec:
432
432
  \`\`\`yaml
433
433
  spec:
434
434
  llm:
435
- model: claude-sonnet # BAD: which version?
435
+ model: claude-sonnet # BAD: which family member?
436
436
  \`\`\`
437
437
 
438
- **Why**: Model versions change capabilities and pricing. Be specific.
438
+ **Why**: A bare family name is ambiguous. Pin a specific, current model alias so capabilities and pricing are well-defined.
439
439
 
440
- ✅ **Do**: Use full version identifiers
440
+ ✅ **Do**: Use a specific model alias
441
441
 
442
442
  \`\`\`yaml
443
443
  spec:
444
444
  llm:
445
- model: claude-sonnet-4-20250514 # Explicit version
445
+ model: claude-sonnet-5 # Specific current alias
446
446
  \`\`\`
447
447
 
448
448
  ### ❌ Don't: Duplicate Information
@@ -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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"}