@vibe-agent-toolkit/agent-skills 0.1.39-rc.9 → 0.1.39

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 (95) hide show
  1. package/dist/files-config.d.ts +61 -0
  2. package/dist/files-config.d.ts.map +1 -1
  3. package/dist/files-config.js +262 -6
  4. package/dist/files-config.js.map +1 -1
  5. package/dist/index.d.ts +4 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/plugin-distribution-layout.d.ts +70 -0
  10. package/dist/plugin-distribution-layout.d.ts.map +1 -0
  11. package/dist/plugin-distribution-layout.js +97 -0
  12. package/dist/plugin-distribution-layout.js.map +1 -0
  13. package/dist/skill-packager.d.ts +43 -1
  14. package/dist/skill-packager.d.ts.map +1 -1
  15. package/dist/skill-packager.js +131 -53
  16. package/dist/skill-packager.js.map +1 -1
  17. package/dist/skill-source/git-clone.d.ts +2 -2
  18. package/dist/skill-source/git-clone.d.ts.map +1 -1
  19. package/dist/skill-source/git-clone.js +33 -10
  20. package/dist/skill-source/git-clone.js.map +1 -1
  21. package/dist/skill-source/sources/url-source.d.ts.map +1 -1
  22. package/dist/skill-source/sources/url-source.js +23 -8
  23. package/dist/skill-source/sources/url-source.js.map +1 -1
  24. package/dist/skill-source/sources/workspace-source.d.ts.map +1 -1
  25. package/dist/skill-source/sources/workspace-source.js +16 -8
  26. package/dist/skill-source/sources/workspace-source.js.map +1 -1
  27. package/dist/skill-source/stage.js +6 -2
  28. package/dist/skill-source/stage.js.map +1 -1
  29. package/dist/skill-test/configure-writer.d.ts +19 -11
  30. package/dist/skill-test/configure-writer.d.ts.map +1 -1
  31. package/dist/skill-test/configure-writer.js +23 -15
  32. package/dist/skill-test/configure-writer.js.map +1 -1
  33. package/dist/skill-test/declared-env.d.ts +72 -0
  34. package/dist/skill-test/declared-env.d.ts.map +1 -0
  35. package/dist/skill-test/declared-env.js +85 -0
  36. package/dist/skill-test/declared-env.js.map +1 -0
  37. package/dist/skill-test/eval-inputs.d.ts +159 -0
  38. package/dist/skill-test/eval-inputs.d.ts.map +1 -0
  39. package/dist/skill-test/eval-inputs.js +158 -0
  40. package/dist/skill-test/eval-inputs.js.map +1 -0
  41. package/dist/skill-test/evals-template.d.ts.map +1 -1
  42. package/dist/skill-test/evals-template.js +27 -10
  43. package/dist/skill-test/evals-template.js.map +1 -1
  44. package/dist/skill-test/exit-codes.d.ts +43 -5
  45. package/dist/skill-test/exit-codes.d.ts.map +1 -1
  46. package/dist/skill-test/exit-codes.js +60 -9
  47. package/dist/skill-test/exit-codes.js.map +1 -1
  48. package/dist/skill-test/experimenter-prompt.d.ts +22 -0
  49. package/dist/skill-test/experimenter-prompt.d.ts.map +1 -1
  50. package/dist/skill-test/experimenter-prompt.js +38 -2
  51. package/dist/skill-test/experimenter-prompt.js.map +1 -1
  52. package/dist/skill-test/grading-adapter.d.ts +42 -0
  53. package/dist/skill-test/grading-adapter.d.ts.map +1 -1
  54. package/dist/skill-test/grading-adapter.js +63 -1
  55. package/dist/skill-test/grading-adapter.js.map +1 -1
  56. package/dist/skill-test/grading-schema.d.ts +73 -5
  57. package/dist/skill-test/grading-schema.d.ts.map +1 -1
  58. package/dist/skill-test/grading-schema.js +20 -5
  59. package/dist/skill-test/grading-schema.js.map +1 -1
  60. package/dist/skill-test/harness-location.d.ts +22 -4
  61. package/dist/skill-test/harness-location.d.ts.map +1 -1
  62. package/dist/skill-test/harness-location.js +83 -18
  63. package/dist/skill-test/harness-location.js.map +1 -1
  64. package/dist/skill-test/index.d.ts +7 -4
  65. package/dist/skill-test/index.d.ts.map +1 -1
  66. package/dist/skill-test/index.js +7 -4
  67. package/dist/skill-test/index.js.map +1 -1
  68. package/dist/skill-test/lock.d.ts +23 -0
  69. package/dist/skill-test/lock.d.ts.map +1 -1
  70. package/dist/skill-test/lock.js +34 -0
  71. package/dist/skill-test/lock.js.map +1 -1
  72. package/dist/skill-test/preflight.d.ts.map +1 -1
  73. package/dist/skill-test/preflight.js +1 -2
  74. package/dist/skill-test/preflight.js.map +1 -1
  75. package/dist/skill-test/run-harness.d.ts +193 -19
  76. package/dist/skill-test/run-harness.d.ts.map +1 -1
  77. package/dist/skill-test/run-harness.js +366 -76
  78. package/dist/skill-test/run-harness.js.map +1 -1
  79. package/dist/skill-test/staging.d.ts.map +1 -1
  80. package/dist/skill-test/staging.js +31 -15
  81. package/dist/skill-test/staging.js.map +1 -1
  82. package/dist/skill-test/vendor-manifest.d.ts +3 -3
  83. package/dist/skill-test/vendor-manifest.d.ts.map +1 -1
  84. package/dist/skill-test/vendor-manifest.js +13 -3
  85. package/dist/skill-test/vendor-manifest.js.map +1 -1
  86. package/dist/validators/packaging-validator.d.ts.map +1 -1
  87. package/dist/validators/packaging-validator.js +134 -1
  88. package/dist/validators/packaging-validator.js.map +1 -1
  89. package/dist/validators/skill-validator.d.ts.map +1 -1
  90. package/dist/validators/skill-validator.js +18 -14
  91. package/dist/validators/skill-validator.js.map +1 -1
  92. package/dist/walk-link-graph.d.ts.map +1 -1
  93. package/dist/walk-link-graph.js +26 -1
  94. package/dist/walk-link-graph.js.map +1 -1
  95. package/package.json +6 -5
@@ -0,0 +1,159 @@
1
+ import { z } from 'zod';
2
+ /** Raised for any eval-input problem (bad JSON, schema failure, missing input file). Maps to exit 2. */
3
+ export declare class EvalInputError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ export declare const EvalEntrySchema: z.ZodEffects<z.ZodObject<{
7
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
8
+ prompt: z.ZodString;
9
+ expected_output: z.ZodOptional<z.ZodString>;
10
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
11
+ expectations: z.ZodArray<z.ZodString, "many">;
12
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
13
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
14
+ prompt: z.ZodString;
15
+ expected_output: z.ZodOptional<z.ZodString>;
16
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
17
+ expectations: z.ZodArray<z.ZodString, "many">;
18
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
19
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
20
+ prompt: z.ZodString;
21
+ expected_output: z.ZodOptional<z.ZodString>;
22
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
23
+ expectations: z.ZodArray<z.ZodString, "many">;
24
+ }, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
25
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
26
+ prompt: z.ZodString;
27
+ expected_output: z.ZodOptional<z.ZodString>;
28
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
29
+ expectations: z.ZodArray<z.ZodString, "many">;
30
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
31
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
32
+ prompt: z.ZodString;
33
+ expected_output: z.ZodOptional<z.ZodString>;
34
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
35
+ expectations: z.ZodArray<z.ZodString, "many">;
36
+ }, z.ZodTypeAny, "passthrough">>;
37
+ export declare const EvalSuiteSchema: z.ZodObject<{
38
+ _comment: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
39
+ skill_name: z.ZodString;
40
+ evals: z.ZodArray<z.ZodEffects<z.ZodObject<{
41
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
42
+ prompt: z.ZodString;
43
+ expected_output: z.ZodOptional<z.ZodString>;
44
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
45
+ expectations: z.ZodArray<z.ZodString, "many">;
46
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
47
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
48
+ prompt: z.ZodString;
49
+ expected_output: z.ZodOptional<z.ZodString>;
50
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
51
+ expectations: z.ZodArray<z.ZodString, "many">;
52
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
53
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
54
+ prompt: z.ZodString;
55
+ expected_output: z.ZodOptional<z.ZodString>;
56
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
57
+ expectations: z.ZodArray<z.ZodString, "many">;
58
+ }, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
59
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
60
+ prompt: z.ZodString;
61
+ expected_output: z.ZodOptional<z.ZodString>;
62
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
63
+ expectations: z.ZodArray<z.ZodString, "many">;
64
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
65
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
66
+ prompt: z.ZodString;
67
+ expected_output: z.ZodOptional<z.ZodString>;
68
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
69
+ expectations: z.ZodArray<z.ZodString, "many">;
70
+ }, z.ZodTypeAny, "passthrough">>, "many">;
71
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
72
+ _comment: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
73
+ skill_name: z.ZodString;
74
+ evals: z.ZodArray<z.ZodEffects<z.ZodObject<{
75
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
76
+ prompt: z.ZodString;
77
+ expected_output: z.ZodOptional<z.ZodString>;
78
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
79
+ expectations: z.ZodArray<z.ZodString, "many">;
80
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
81
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
82
+ prompt: z.ZodString;
83
+ expected_output: z.ZodOptional<z.ZodString>;
84
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
85
+ expectations: z.ZodArray<z.ZodString, "many">;
86
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
87
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
88
+ prompt: z.ZodString;
89
+ expected_output: z.ZodOptional<z.ZodString>;
90
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
91
+ expectations: z.ZodArray<z.ZodString, "many">;
92
+ }, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
93
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
94
+ prompt: z.ZodString;
95
+ expected_output: z.ZodOptional<z.ZodString>;
96
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
97
+ expectations: z.ZodArray<z.ZodString, "many">;
98
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
99
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
100
+ prompt: z.ZodString;
101
+ expected_output: z.ZodOptional<z.ZodString>;
102
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
103
+ expectations: z.ZodArray<z.ZodString, "many">;
104
+ }, z.ZodTypeAny, "passthrough">>, "many">;
105
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
106
+ _comment: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
107
+ skill_name: z.ZodString;
108
+ evals: z.ZodArray<z.ZodEffects<z.ZodObject<{
109
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
110
+ prompt: z.ZodString;
111
+ expected_output: z.ZodOptional<z.ZodString>;
112
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
113
+ expectations: z.ZodArray<z.ZodString, "many">;
114
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
115
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
116
+ prompt: z.ZodString;
117
+ expected_output: z.ZodOptional<z.ZodString>;
118
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
119
+ expectations: z.ZodArray<z.ZodString, "many">;
120
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
121
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
122
+ prompt: z.ZodString;
123
+ expected_output: z.ZodOptional<z.ZodString>;
124
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
125
+ expectations: z.ZodArray<z.ZodString, "many">;
126
+ }, z.ZodTypeAny, "passthrough">>, z.objectOutputType<{
127
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
128
+ prompt: z.ZodString;
129
+ expected_output: z.ZodOptional<z.ZodString>;
130
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
131
+ expectations: z.ZodArray<z.ZodString, "many">;
132
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
133
+ id: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
134
+ prompt: z.ZodString;
135
+ expected_output: z.ZodOptional<z.ZodString>;
136
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
137
+ expectations: z.ZodArray<z.ZodString, "many">;
138
+ }, z.ZodTypeAny, "passthrough">>, "many">;
139
+ }, z.ZodTypeAny, "passthrough">>;
140
+ export type EvalEntry = z.infer<typeof EvalEntrySchema>;
141
+ export type EvalSuite = z.infer<typeof EvalSuiteSchema>;
142
+ /** Parse + validate a skill-test eval suite. Throws {@link EvalInputError} on any problem. */
143
+ export declare function parseEvalSuite(jsonText: string): EvalSuite;
144
+ export interface StageEvalWorkspacesInput {
145
+ /** Parsed suite (Task 1). */
146
+ suite: EvalSuite;
147
+ /** Directory containing evals.json — the base for each eval's relative `files`. */
148
+ evalsDir: string;
149
+ /** `<harnessRoot>/workspaces` — per-eval dirs are created beneath it. */
150
+ workspacesRoot: string;
151
+ }
152
+ /**
153
+ * Materialize each eval's declared input `files` into `<workspacesRoot>/<id>/<relpath>`,
154
+ * preserving relative structure. Evals without `files` are skipped. Throws
155
+ * {@link EvalInputError} if a listed file does not exist (the eval cannot run without it).
156
+ * Returns `workspacesRoot`.
157
+ */
158
+ export declare function stageEvalWorkspaces(input: StageEvalWorkspacesInput): string;
159
+ //# sourceMappingURL=eval-inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-inputs.d.ts","sourceRoot":"","sources":["../../src/skill-test/eval-inputs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wGAAwG;AACxG,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AA4CD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAmCxB,CAAC;AAEL,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAMZ,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAmB1D;AAED,MAAM,WAAW,wBAAwB;IACvC,6BAA6B;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,mFAAmF;IACnF,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,MAAM,CAkC3E"}
@@ -0,0 +1,158 @@
1
+ import { cpSync, existsSync } from 'node:fs';
2
+ import { mkdirSyncReal, safePath } from '@vibe-agent-toolkit/utils';
3
+ import { z } from 'zod';
4
+ /** Raised for any eval-input problem (bad JSON, schema failure, missing input file). Maps to exit 2. */
5
+ export class EvalInputError extends Error {
6
+ constructor(message) {
7
+ super(message);
8
+ this.name = 'EvalInputError';
9
+ }
10
+ }
11
+ /**
12
+ * String eval ids name a per-eval working directory ({@link stageEvalWorkspaces}),
13
+ * so they must be safe path segments on every platform. Letters, digits, hyphen,
14
+ * and underscore only — this rejects `/`, `\`, `:`, spaces, `..`, and other
15
+ * filesystem-illegal characters that would otherwise fail (or behave
16
+ * inconsistently) on Windows. Descriptive adopter ids like `dollar-quote-recovery`
17
+ * pass unchanged; `year:extraction` is rejected at parse with a clear message
18
+ * instead of failing later as an opaque copy/escape error.
19
+ */
20
+ const EVAL_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
21
+ /** Fields VAT recognizes per eval. Unknown fields are allowed (passthrough); a
22
+ * near-miss of one of these is flagged as a likely typo (see superRefine). */
23
+ const RECOGNIZED_EVAL_FIELDS = ['id', 'prompt', 'expected_output', 'files', 'expectations'];
24
+ /**
25
+ * True when `key` is exactly one edit (insert/delete/substitute one char) from
26
+ * `target`. Used only to catch typos of recognized fields — deliberately a tiny
27
+ * single-edit check, not a general edit-distance routine, so it stays cheap and
28
+ * never fires on legitimately distinct adopter keys (`name`, `category`, `notes`).
29
+ */
30
+ function isSingleEditAway(key, target) {
31
+ if (key === target)
32
+ return false;
33
+ const lk = key.length;
34
+ const lt = target.length;
35
+ if (Math.abs(lk - lt) > 1)
36
+ return false;
37
+ let i = 0;
38
+ while (i < lk && i < lt && key[i] === target[i])
39
+ i++;
40
+ if (lk === lt)
41
+ return key.slice(i + 1) === target.slice(i + 1); // substitution
42
+ if (lk > lt)
43
+ return key.slice(i + 1) === target.slice(i); // deletion from key
44
+ return key.slice(i) === target.slice(i + 1); // insertion into key
45
+ }
46
+ // evals.json is adopter-authored input that VAT *reads* — so per the project's
47
+ // Postel's Law (read the outside world liberally), we validate only the fields
48
+ // VAT actually consumes and pass everything else through untouched. `id` accepts
49
+ // a string OR an int: skill-creator's methodology encourages *descriptive* eval
50
+ // identifiers, and real adopter suites (e.g. dxa) use descriptive string ids plus
51
+ // adopter-owned metadata like `category` / top-level `_category_note`. The
52
+ // load-bearing fields stay required, so a typo in a REQUIRED field is caught by
53
+ // its absence; a near-miss typo of the OPTIONAL `files` field (which would
54
+ // otherwise be silently swallowed by passthrough) is caught by the superRefine.
55
+ export const EvalEntrySchema = z
56
+ .object({
57
+ id: z.union([
58
+ z.number().int(),
59
+ z
60
+ .string()
61
+ .min(1)
62
+ .regex(EVAL_ID_PATTERN, 'string eval id must contain only letters, digits, hyphen, or underscore (it names a working directory)'),
63
+ ]),
64
+ prompt: z.string().min(1),
65
+ // Optional: a human-readable success description. The pass/fail verdict is
66
+ // always decided per `expectations` entry, so this is not load-bearing and
67
+ // (per Postel's Law) is not required — real adopter suites (e.g. dxa-consumption)
68
+ // grade with `expectations` alone. When present, the experimenter prompt feeds it
69
+ // to the grader as prose CONTEXT informing judgment (see experimenter-prompt.ts).
70
+ expected_output: z.string().min(1).optional(),
71
+ files: z.array(z.string().min(1)).optional(),
72
+ expectations: z.array(z.string().min(1)).min(1),
73
+ })
74
+ .passthrough()
75
+ .superRefine((entry, ctx) => {
76
+ for (const key of Object.keys(entry)) {
77
+ if (RECOGNIZED_EVAL_FIELDS.includes(key))
78
+ continue;
79
+ const near = RECOGNIZED_EVAL_FIELDS.find((field) => isSingleEditAway(key.toLowerCase(), field));
80
+ if (near !== undefined) {
81
+ ctx.addIssue({
82
+ code: z.ZodIssueCode.custom,
83
+ message: `unknown eval field "${key}" — did you mean "${near}"? (other custom fields are allowed and ignored)`,
84
+ path: [key],
85
+ });
86
+ }
87
+ }
88
+ });
89
+ export const EvalSuiteSchema = z
90
+ .object({
91
+ _comment: z.array(z.string()).optional(),
92
+ skill_name: z.string().min(1),
93
+ evals: z.array(EvalEntrySchema).min(1),
94
+ })
95
+ .passthrough();
96
+ /** Parse + validate a skill-test eval suite. Throws {@link EvalInputError} on any problem. */
97
+ export function parseEvalSuite(jsonText) {
98
+ let raw;
99
+ try {
100
+ raw = JSON.parse(jsonText);
101
+ }
102
+ catch (e) {
103
+ throw new EvalInputError(`evals.json is not valid JSON: ${e.message}`);
104
+ }
105
+ const result = EvalSuiteSchema.safeParse(raw);
106
+ if (!result.success) {
107
+ throw new EvalInputError(`evals.json failed schema validation: ${result.error.message}`);
108
+ }
109
+ // Compare ids as strings: each id names a working directory via String(id),
110
+ // so a numeric `1` and a string `"1"` would collide on disk even though they
111
+ // are distinct JS values. Dedup on the stringified form to catch that.
112
+ const ids = result.data.evals.map((e) => String(e.id));
113
+ if (new Set(ids).size !== ids.length) {
114
+ throw new EvalInputError('eval ids must be unique within a suite (ids are compared as strings, so 1 and "1" collide)');
115
+ }
116
+ return result.data;
117
+ }
118
+ /**
119
+ * Materialize each eval's declared input `files` into `<workspacesRoot>/<id>/<relpath>`,
120
+ * preserving relative structure. Evals without `files` are skipped. Throws
121
+ * {@link EvalInputError} if a listed file does not exist (the eval cannot run without it).
122
+ * Returns `workspacesRoot`.
123
+ */
124
+ export function stageEvalWorkspaces(input) {
125
+ for (const entry of input.suite.evals) {
126
+ if (entry.files === undefined || entry.files.length === 0)
127
+ continue;
128
+ const evalWorkspace = safePath.joinUnderRoot(input.workspacesRoot, String(entry.id));
129
+ for (const rel of entry.files) {
130
+ // Containment first: a `rel` that escapes evalsDir or the workspace is a
131
+ // genuine "escapes the eval directory" problem and is reported as such.
132
+ let src;
133
+ let dest;
134
+ try {
135
+ src = safePath.joinUnderRoot(input.evalsDir, rel);
136
+ dest = safePath.joinUnderRoot(evalWorkspace, rel);
137
+ }
138
+ catch (err) {
139
+ throw new EvalInputError(`eval ${entry.id} declares input file "${rel}" that escapes the eval directory: ${err.message}`);
140
+ }
141
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- src is contained under evalsDir via joinUnderRoot; suite is developer-authored
142
+ if (!existsSync(src)) {
143
+ throw new EvalInputError(`eval ${entry.id} declares input file "${rel}" but it is absent at ${src}`);
144
+ }
145
+ // Copy failures (permissions, illegal filename on the host, disk) are
146
+ // reported accurately rather than mislabeled as a containment escape.
147
+ try {
148
+ mkdirSyncReal(safePath.join(dest, '..'), { recursive: true });
149
+ cpSync(src, dest, { recursive: true });
150
+ }
151
+ catch (err) {
152
+ throw new EvalInputError(`eval ${entry.id} failed to stage input file "${rel}" into the workspace: ${err.message}`);
153
+ }
154
+ }
155
+ }
156
+ return input.workspacesRoot;
157
+ }
158
+ //# sourceMappingURL=eval-inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-inputs.js","sourceRoot":"","sources":["../../src/skill-test/eval-inputs.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,CA0B5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAM/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,CAsC5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAW/E"}
@@ -12,7 +12,7 @@
12
12
  * Both are stripped by the user as they fill in real evals; the harness does not
13
13
  * read `_comment`.
14
14
  */
15
- import { writeFileSync } from 'node:fs';
15
+ import { existsSync, writeFileSync } from 'node:fs';
16
16
  import { mkdirSyncReal, safePath } from '@vibe-agent-toolkit/utils';
17
17
  /** Build the annotated evals.json template text for a given skill name. */
18
18
  export function buildEvalsTemplate(skillName) {
@@ -21,21 +21,33 @@ export function buildEvalsTemplate(skillName) {
21
21
  'This is a starter evals.json scaffolded by `vat skill test`.',
22
22
  'Replace the placeholder eval below with one entry per behavior you want to verify.',
23
23
  'Fields per eval:',
24
- ' id — unique integer identifier',
25
- ' prompt — the task prompt handed to the executor (it is NOT told it is being tested)',
26
- ' expected_output human-readable description of what success looks like',
27
- ' files — OPTIONAL list of input file paths relative to the skill root',
28
- ' expectations list of verifiable statements the grader checks against the output',
29
- 'Delete this _comment field once you have filled in real evals, then re-run.',
24
+ ' id — unique identifier: an integer (1) or a short descriptive',
25
+ ' string ("year-extraction"). Descriptive ids read better in results.',
26
+ ' A string id names a working directory, so use only letters,',
27
+ ' digits, hyphen, or underscore (no spaces, slashes, or colons).',
28
+ ' prompt the task, written the way a REAL user would phrase it. The executor',
29
+ ' is NOT told it is being tested, so do not mention testing/evals here.',
30
+ ' expected_output — OPTIONAL human-readable description of what a correct result looks like',
31
+ ' files — OPTIONAL input files (paths relative to THIS evals.json dir),',
32
+ ' staged into a per-eval working directory the executor operates on',
33
+ ' expectations — verifiable statements the grader checks. Make them DISCRIMINATING:',
34
+ ' a wrong or hallucinated output should FAIL them (presence != correctness).',
35
+ ' Include negative assertions too, e.g. "does NOT claim every row reconciles".',
36
+ ' category — OPTIONAL label you choose to group evals (e.g. "recognition",',
37
+ ' "guidance", "recovery"). VAT ignores it; it is for your own organization.',
38
+ 'Aim for at least 3 evals covering real scenarios. Delete this _comment field once filled in, then re-run.',
30
39
  ],
31
40
  skill_name: skillName,
32
41
  evals: [
33
42
  {
34
43
  id: 1,
35
- prompt: 'TODO: describe the task a user would ask this skill to perform.',
44
+ category: 'TODO: optional grouping label, or remove this field',
45
+ prompt: 'TODO: a realistic task a user would actually ask this skill to perform.',
36
46
  expected_output: 'TODO: describe what a correct result looks like.',
47
+ files: [],
37
48
  expectations: [
38
- 'TODO: a verifiable statement about the output, e.g. "The output includes X".',
49
+ 'TODO: a verifiable statement a correct output satisfies, e.g. "The output reports a total of 29500".',
50
+ 'TODO: a negative assertion a wrong output would trip, e.g. "The output does NOT claim the file is empty".',
39
51
  ],
40
52
  },
41
53
  ],
@@ -49,8 +61,13 @@ export function buildEvalsTemplate(skillName) {
49
61
  export function writeEvalsTemplate(evalsPath, skillName) {
50
62
  const parent = safePath.join(evalsPath, '..');
51
63
  mkdirSyncReal(parent, { recursive: true });
64
+ // Defensive: never clobber an authored eval suite. Callers only reach here when
65
+ // the suite is absent, but guard so a stray call can never destroy real evals.
52
66
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- our own resolved scaffold path
53
- writeFileSync(evalsPath, buildEvalsTemplate(skillName), 'utf8');
67
+ if (!existsSync(evalsPath)) {
68
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- our own resolved scaffold path
69
+ writeFileSync(evalsPath, buildEvalsTemplate(skillName), 'utf8');
70
+ }
54
71
  return evalsPath;
55
72
  }
56
73
  //# sourceMappingURL=evals-template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evals-template.js","sourceRoot":"","sources":["../../src/skill-test/evals-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,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,+CAA+C;YAC/C,gGAAgG;YAChG,2EAA2E;YAC3E,kFAAkF;YAClF,wFAAwF;YACxF,6EAA6E;SAC9E;QACD,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE;YACL;gBACE,EAAE,EAAE,CAAC;gBACL,MAAM,EAAE,iEAAiE;gBACzE,eAAe,EAAE,kDAAkD;gBACnE,YAAY,EAAE;oBACZ,8EAA8E;iBAC/E;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,qGAAqG;IACrG,aAAa,CAAC,SAAS,EAAE,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;IAChE,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,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"}
@@ -4,17 +4,48 @@ export declare const SkillTestExitCode: {
4
4
  readonly Internal: 1;
5
5
  readonly Preflight: 2;
6
6
  readonly Bootstrap: 3;
7
+ /**
8
+ * At least one eval FAILED and the caller opted into eval-gating via
9
+ * `--fail-on-eval-failure`. Distinct from the harness-broke codes (1/2):
10
+ * the harness ran to completion and produced a valid grading.json — the
11
+ * skill's expectations simply did not all pass. Returned DIRECTLY by the
12
+ * harness verdict (see verdictExitCode in run-harness.ts), not via
13
+ * mapErrorToExitCode, because it is an outcome, not a thrown error.
14
+ */
15
+ readonly EvalFailure: 4;
7
16
  };
8
17
  export type SkillTestExitCodeValue = (typeof SkillTestExitCode)[keyof typeof SkillTestExitCode];
9
18
  /**
10
19
  * A required input is absent in a way vat can scaffold (missing evals.json).
11
- * Exit 3, NOT a failure. `expectedPath` is the real, persistent location where
12
- * the harness wrote the annotated starter template for the user to fill in.
20
+ * Exit 3, NOT a failure. `expectedPath` is the persistent location of the
21
+ * annotated starter template.
22
+ *
23
+ * In a real run the harness has already written that template, and the message
24
+ * says so. Under `--dry-run` nothing is written — a dry run must never touch the
25
+ * filesystem — so the message instead describes what a real run *would* scaffold
26
+ * and where, while surfacing the same exit-3 "bootstrap needed" signal.
13
27
  */
14
28
  export declare class BootstrapNeededError extends Error {
15
29
  readonly expectedPath: string;
16
30
  readonly exitCode: 3;
17
- constructor(expectedPath: string);
31
+ constructor(expectedPath: string, opts?: {
32
+ dryRun?: boolean;
33
+ });
34
+ }
35
+ /** Thrown when building a declared skill (pool packageSkill or plugin build) fails. Exit 2 (preflight class). */
36
+ export declare class SkillBuildError extends Error {
37
+ readonly exitCode: 2;
38
+ constructor(message: string);
39
+ }
40
+ /**
41
+ * The §12 security acknowledgment is required but absent, thrown BEFORE any
42
+ * build/pre-stage command (which executes untrusted repo code) runs for a
43
+ * buildable subject. Exit 2 (preflight class). Mirrors the harness Step-6 ack
44
+ * message wording so the two enforcement points read identically.
45
+ */
46
+ export declare class SecurityAckError extends Error {
47
+ readonly exitCode: 2;
48
+ constructor();
18
49
  }
19
50
  /** Internal harness failure (incl. experimenter exiting without valid grading.json). Exit 1. */
20
51
  export declare class InternalHarnessError extends Error {
@@ -26,8 +57,15 @@ export declare class InternalHarnessError extends Error {
26
57
  * `exitCode` (Bootstrap/Auth/HarnessLocation/Internal) are authoritative;
27
58
  * a PromptInvariantError is a user-correctable preflight problem (a supplied
28
59
  * prompt override is missing a required safety instruction) → 2; a BuildHookError
29
- * is a pre-stage build failure → 2; GradingSkewError is a parse failure → 1;
30
- * everything unknown1.
60
+ * is a pre-stage build failure → 2; a SkillBuildError is a declared-skill build
61
+ * failure 2; a SecurityAckError is a missing security ack before a build 2;
62
+ * an UnknownEnvTokenError is a bad ${token} in a
63
+ * declared env value → 2; GradingSkewError (parse failure) and GradingNonceError
64
+ * (forged/mismatched grading nonce) are both → 1; everything unknown → 1.
65
+ *
66
+ * Note: SkillTestExitCode.EvalFailure (4) is NOT produced here — it is an
67
+ * outcome of a completed run (an eval failed under `--fail-on-eval-failure`),
68
+ * not a thrown error, so the harness returns it directly (see verdictExitCode).
31
69
  */
32
70
  export declare function mapErrorToExitCode(err: unknown): number;
33
71
  //# sourceMappingURL=exit-codes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../../src/skill-test/exit-codes.ts"],"names":[],"mappings":"AAOA,kDAAkD;AAClD,eAAO,MAAM,iBAAiB;;;;;CAKpB,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAEhG;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAEjB,YAAY,EAAE,MAAM;IADhD,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACH,YAAY,EAAE,MAAM;CAIjD;AAED,gGAAgG;AAChG,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACnB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAYvD"}
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;;;;;;;OAOG;;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;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAqBvD"}
@@ -1,7 +1,8 @@
1
1
  import { AuthPreflightError } from '@vibe-agent-toolkit/utils';
2
2
  import { BuildHookError } from './build-hook.js';
3
+ import { UnknownEnvTokenError } from './declared-env.js';
3
4
  import { PromptInvariantError } from './experimenter-prompt.js';
4
- import { GradingSkewError } from './grading-adapter.js';
5
+ import { GradingNonceError, GradingSkewError } from './grading-adapter.js';
5
6
  import { HarnessLocationError } from './harness-location.js';
6
7
  /** Exit codes for `vat skill test` (spec §6d). */
7
8
  export const SkillTestExitCode = {
@@ -9,21 +10,58 @@ export const SkillTestExitCode = {
9
10
  Internal: 1,
10
11
  Preflight: 2,
11
12
  Bootstrap: 3,
13
+ /**
14
+ * At least one eval FAILED and the caller opted into eval-gating via
15
+ * `--fail-on-eval-failure`. Distinct from the harness-broke codes (1/2):
16
+ * the harness ran to completion and produced a valid grading.json — the
17
+ * skill's expectations simply did not all pass. Returned DIRECTLY by the
18
+ * harness verdict (see verdictExitCode in run-harness.ts), not via
19
+ * mapErrorToExitCode, because it is an outcome, not a thrown error.
20
+ */
21
+ EvalFailure: 4,
12
22
  };
13
23
  /**
14
24
  * A required input is absent in a way vat can scaffold (missing evals.json).
15
- * Exit 3, NOT a failure. `expectedPath` is the real, persistent location where
16
- * the harness wrote the annotated starter template for the user to fill in.
25
+ * Exit 3, NOT a failure. `expectedPath` is the persistent location of the
26
+ * annotated starter template.
27
+ *
28
+ * In a real run the harness has already written that template, and the message
29
+ * says so. Under `--dry-run` nothing is written — a dry run must never touch the
30
+ * filesystem — so the message instead describes what a real run *would* scaffold
31
+ * and where, while surfacing the same exit-3 "bootstrap needed" signal.
17
32
  */
18
33
  export class BootstrapNeededError extends Error {
19
34
  expectedPath;
20
35
  exitCode = 3;
21
- constructor(expectedPath) {
22
- super(`Wrote an evals.json template at ${expectedPath} — fill it in and re-run.`);
36
+ constructor(expectedPath, opts) {
37
+ super(opts?.dryRun === true
38
+ ? `[dry-run] No evals.json found. A real run would scaffold an annotated template at ${expectedPath} — fill it in and re-run. (dry-run: nothing was written.)`
39
+ : `Wrote an evals.json template at ${expectedPath} — fill it in and re-run.`);
23
40
  this.expectedPath = expectedPath;
24
41
  this.name = 'BootstrapNeededError';
25
42
  }
26
43
  }
44
+ /** Thrown when building a declared skill (pool packageSkill or plugin build) fails. Exit 2 (preflight class). */
45
+ export class SkillBuildError extends Error {
46
+ exitCode = 2;
47
+ constructor(message) {
48
+ super(message);
49
+ this.name = 'SkillBuildError';
50
+ }
51
+ }
52
+ /**
53
+ * The §12 security acknowledgment is required but absent, thrown BEFORE any
54
+ * build/pre-stage command (which executes untrusted repo code) runs for a
55
+ * buildable subject. Exit 2 (preflight class). Mirrors the harness Step-6 ack
56
+ * message wording so the two enforcement points read identically.
57
+ */
58
+ export class SecurityAckError extends Error {
59
+ exitCode = 2;
60
+ constructor() {
61
+ super('Security acknowledgment required. Pass --i-understand-this-runs-skill-code to proceed.');
62
+ this.name = 'SecurityAckError';
63
+ }
64
+ }
27
65
  /** Internal harness failure (incl. experimenter exiting without valid grading.json). Exit 1. */
28
66
  export class InternalHarnessError extends Error {
29
67
  exitCode = 1;
@@ -37,8 +75,15 @@ export class InternalHarnessError extends Error {
37
75
  * `exitCode` (Bootstrap/Auth/HarnessLocation/Internal) are authoritative;
38
76
  * a PromptInvariantError is a user-correctable preflight problem (a supplied
39
77
  * prompt override is missing a required safety instruction) → 2; a BuildHookError
40
- * is a pre-stage build failure → 2; GradingSkewError is a parse failure → 1;
41
- * everything unknown1.
78
+ * is a pre-stage build failure → 2; a SkillBuildError is a declared-skill build
79
+ * failure 2; a SecurityAckError is a missing security ack before a build 2;
80
+ * an UnknownEnvTokenError is a bad ${token} in a
81
+ * declared env value → 2; GradingSkewError (parse failure) and GradingNonceError
82
+ * (forged/mismatched grading nonce) are both → 1; everything unknown → 1.
83
+ *
84
+ * Note: SkillTestExitCode.EvalFailure (4) is NOT produced here — it is an
85
+ * outcome of a completed run (an eval failed under `--fail-on-eval-failure`),
86
+ * not a thrown error, so the harness returns it directly (see verdictExitCode).
42
87
  */
43
88
  export function mapErrorToExitCode(err) {
44
89
  if (err instanceof BootstrapNeededError)
@@ -46,11 +91,17 @@ export function mapErrorToExitCode(err) {
46
91
  if (err instanceof AuthPreflightError ||
47
92
  err instanceof BuildHookError ||
48
93
  err instanceof HarnessLocationError ||
49
- err instanceof PromptInvariantError) {
94
+ err instanceof PromptInvariantError ||
95
+ err instanceof SecurityAckError ||
96
+ err instanceof SkillBuildError ||
97
+ err instanceof UnknownEnvTokenError) {
50
98
  return SkillTestExitCode.Preflight;
51
99
  }
52
- if (err instanceof GradingSkewError || err instanceof InternalHarnessError)
100
+ if (err instanceof GradingNonceError ||
101
+ err instanceof GradingSkewError ||
102
+ err instanceof InternalHarnessError) {
53
103
  return SkillTestExitCode.Internal;
104
+ }
54
105
  return SkillTestExitCode.Internal;
55
106
  }
56
107
  //# sourceMappingURL=exit-codes.js.map
@@ -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,0BAA0B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,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;CACJ,CAAC;AAIX;;;;GAIG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAEjB;IADnB,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAA4B,YAAoB;QAC9C,KAAK,CAAC,mCAAmC,YAAY,2BAA2B,CAAC,CAAC;QADxD,iBAAY,GAAZ,YAAY,CAAQ;QAE9C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,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;;;;;;;GAOG;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,EACnC,CAAC;QACD,OAAO,iBAAiB,CAAC,SAAS,CAAC;IACrC,CAAC;IACD,IAAI,GAAG,YAAY,gBAAgB,IAAI,GAAG,YAAY,oBAAoB;QAAE,OAAO,iBAAiB,CAAC,QAAQ,CAAC;IAC9G,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,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;;;;;;;OAOG;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;;;;;;;;;;;;;;GAcG;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"}