@vibe-agent-toolkit/agent-skills 0.2.0-rc.7 → 0.2.0-rc.8

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 (208) hide show
  1. package/README.md +5 -5
  2. package/dist/builder.d.ts.map +1 -1
  3. package/dist/builder.js +7 -17
  4. package/dist/builder.js.map +1 -1
  5. package/dist/files-config.d.ts +2 -2
  6. package/dist/files-config.d.ts.map +1 -1
  7. package/dist/files-config.js +1 -7
  8. package/dist/files-config.js.map +1 -1
  9. package/dist/import.d.ts.map +1 -1
  10. package/dist/import.js +0 -4
  11. package/dist/import.js.map +1 -1
  12. package/dist/inventory/types.d.ts +8 -0
  13. package/dist/inventory/types.d.ts.map +1 -1
  14. package/dist/inventory/types.js.map +1 -1
  15. package/dist/plugin-distribution-layout.d.ts.map +1 -1
  16. package/dist/plugin-distribution-layout.js +0 -2
  17. package/dist/plugin-distribution-layout.js.map +1 -1
  18. package/dist/post-build-checks.d.ts.map +1 -1
  19. package/dist/post-build-checks.js +12 -11
  20. package/dist/post-build-checks.js.map +1 -1
  21. package/dist/schemas/installed-plugins-registry.d.ts.map +1 -1
  22. package/dist/schemas/installed-plugins-registry.js +7 -1
  23. package/dist/schemas/installed-plugins-registry.js.map +1 -1
  24. package/dist/skill-identity.d.ts +8 -3
  25. package/dist/skill-identity.d.ts.map +1 -1
  26. package/dist/skill-identity.js +13 -6
  27. package/dist/skill-identity.js.map +1 -1
  28. package/dist/skill-packager.d.ts +2 -1
  29. package/dist/skill-packager.d.ts.map +1 -1
  30. package/dist/skill-packager.js +47 -40
  31. package/dist/skill-packager.js.map +1 -1
  32. package/dist/skill-source/content-hash.d.ts.map +1 -1
  33. package/dist/skill-source/content-hash.js +21 -10
  34. package/dist/skill-source/content-hash.js.map +1 -1
  35. package/dist/skill-source/fetch-cache.d.ts.map +1 -1
  36. package/dist/skill-source/fetch-cache.js +0 -5
  37. package/dist/skill-source/fetch-cache.js.map +1 -1
  38. package/dist/skill-source/git-clone.d.ts.map +1 -1
  39. package/dist/skill-source/git-clone.js +0 -2
  40. package/dist/skill-source/git-clone.js.map +1 -1
  41. package/dist/skill-source/sources/url-source.d.ts.map +1 -1
  42. package/dist/skill-source/sources/url-source.js +0 -1
  43. package/dist/skill-source/sources/url-source.js.map +1 -1
  44. package/dist/skill-source/stage.d.ts.map +1 -1
  45. package/dist/skill-source/stage.js +0 -6
  46. package/dist/skill-source/stage.js.map +1 -1
  47. package/dist/skill-test/baseline-integrity.d.ts.map +1 -1
  48. package/dist/skill-test/baseline-integrity.js +8 -2
  49. package/dist/skill-test/baseline-integrity.js.map +1 -1
  50. package/dist/skill-test/build-hook.d.ts +3 -2
  51. package/dist/skill-test/build-hook.d.ts.map +1 -1
  52. package/dist/skill-test/build-hook.js +4 -4
  53. package/dist/skill-test/build-hook.js.map +1 -1
  54. package/dist/skill-test/declared-env.d.ts +5 -4
  55. package/dist/skill-test/declared-env.d.ts.map +1 -1
  56. package/dist/skill-test/declared-env.js +7 -9
  57. package/dist/skill-test/declared-env.js.map +1 -1
  58. package/dist/skill-test/eval-executor.d.ts +1 -1
  59. package/dist/skill-test/eval-executor.js +2 -2
  60. package/dist/skill-test/eval-executor.js.map +1 -1
  61. package/dist/skill-test/eval-fragment.d.ts +7 -5
  62. package/dist/skill-test/eval-fragment.d.ts.map +1 -1
  63. package/dist/skill-test/eval-fragment.js +13 -7
  64. package/dist/skill-test/eval-fragment.js.map +1 -1
  65. package/dist/skill-test/eval-grader.d.ts +56 -4
  66. package/dist/skill-test/eval-grader.d.ts.map +1 -1
  67. package/dist/skill-test/eval-grader.js +138 -73
  68. package/dist/skill-test/eval-grader.js.map +1 -1
  69. package/dist/skill-test/eval-inputs.d.ts +8 -7
  70. package/dist/skill-test/eval-inputs.d.ts.map +1 -1
  71. package/dist/skill-test/eval-inputs.js +9 -11
  72. package/dist/skill-test/eval-inputs.js.map +1 -1
  73. package/dist/skill-test/eval-lint.d.ts +4 -4
  74. package/dist/skill-test/eval-lint.js +5 -5
  75. package/dist/skill-test/eval-lint.js.map +1 -1
  76. package/dist/skill-test/eval-suite-isolation.d.ts.map +1 -1
  77. package/dist/skill-test/eval-suite-isolation.js +8 -5
  78. package/dist/skill-test/eval-suite-isolation.js.map +1 -1
  79. package/dist/skill-test/evals-template.d.ts +1 -1
  80. package/dist/skill-test/evals-template.d.ts.map +1 -1
  81. package/dist/skill-test/evals-template.js +1 -3
  82. package/dist/skill-test/evals-template.js.map +1 -1
  83. package/dist/skill-test/executor-prompt.d.ts +2 -2
  84. package/dist/skill-test/executor-prompt.js +2 -2
  85. package/dist/skill-test/failure-reason.d.ts +113 -0
  86. package/dist/skill-test/failure-reason.d.ts.map +1 -0
  87. package/dist/skill-test/failure-reason.js +124 -0
  88. package/dist/skill-test/failure-reason.js.map +1 -0
  89. package/dist/skill-test/fragment-merge.d.ts +2 -2
  90. package/dist/skill-test/fragment-merge.js +4 -4
  91. package/dist/skill-test/grader-prompt.d.ts +2 -2
  92. package/dist/skill-test/grader-prompt.d.ts.map +1 -1
  93. package/dist/skill-test/grader-prompt.js +12 -8
  94. package/dist/skill-test/grader-prompt.js.map +1 -1
  95. package/dist/skill-test/grading-adapter.d.ts +7 -3
  96. package/dist/skill-test/grading-adapter.d.ts.map +1 -1
  97. package/dist/skill-test/grading-adapter.js +10 -9
  98. package/dist/skill-test/grading-adapter.js.map +1 -1
  99. package/dist/skill-test/harness-location.d.ts +3 -2
  100. package/dist/skill-test/harness-location.d.ts.map +1 -1
  101. package/dist/skill-test/harness-location.js +5 -16
  102. package/dist/skill-test/harness-location.js.map +1 -1
  103. package/dist/skill-test/index.d.ts +1 -1
  104. package/dist/skill-test/index.d.ts.map +1 -1
  105. package/dist/skill-test/index.js +1 -1
  106. package/dist/skill-test/index.js.map +1 -1
  107. package/dist/skill-test/lock.d.ts +11 -10
  108. package/dist/skill-test/lock.d.ts.map +1 -1
  109. package/dist/skill-test/lock.js +13 -14
  110. package/dist/skill-test/lock.js.map +1 -1
  111. package/dist/skill-test/pipeline.d.ts +3 -1
  112. package/dist/skill-test/pipeline.d.ts.map +1 -1
  113. package/dist/skill-test/pipeline.js +5 -1
  114. package/dist/skill-test/pipeline.js.map +1 -1
  115. package/dist/skill-test/preflight.d.ts.map +1 -1
  116. package/dist/skill-test/preflight.js +0 -1
  117. package/dist/skill-test/preflight.js.map +1 -1
  118. package/dist/skill-test/prompt-invariants.d.ts +4 -2
  119. package/dist/skill-test/prompt-invariants.d.ts.map +1 -1
  120. package/dist/skill-test/prompt-invariants.js +5 -4
  121. package/dist/skill-test/prompt-invariants.js.map +1 -1
  122. package/dist/skill-test/run-harness.d.ts +160 -123
  123. package/dist/skill-test/run-harness.d.ts.map +1 -1
  124. package/dist/skill-test/run-harness.js +309 -173
  125. package/dist/skill-test/run-harness.js.map +1 -1
  126. package/dist/skill-test/staging.d.ts +12 -6
  127. package/dist/skill-test/staging.d.ts.map +1 -1
  128. package/dist/skill-test/staging.js +15 -12
  129. package/dist/skill-test/staging.js.map +1 -1
  130. package/dist/skill-test/tier-plan.d.ts +1 -1
  131. package/dist/skill-test/tier-plan.js +1 -1
  132. package/dist/skill-test/tool-eval-schema.js +2 -2
  133. package/dist/skill-test/vendor-manifest.d.ts +2 -1
  134. package/dist/skill-test/vendor-manifest.d.ts.map +1 -1
  135. package/dist/skill-test/vendor-manifest.js +10 -10
  136. package/dist/skill-test/vendor-manifest.js.map +1 -1
  137. package/dist/test-input.d.ts +2 -2
  138. package/dist/test-input.d.ts.map +1 -1
  139. package/dist/test-input.js +4 -5
  140. package/dist/test-input.js.map +1 -1
  141. package/dist/validators/agent-instruction-presence.d.ts.map +1 -1
  142. package/dist/validators/agent-instruction-presence.js +0 -1
  143. package/dist/validators/agent-instruction-presence.js.map +1 -1
  144. package/dist/validators/bundled-resource-link-detection.d.ts +5 -3
  145. package/dist/validators/bundled-resource-link-detection.d.ts.map +1 -1
  146. package/dist/validators/bundled-resource-link-detection.js +38 -38
  147. package/dist/validators/bundled-resource-link-detection.js.map +1 -1
  148. package/dist/validators/format-detection.d.ts +3 -0
  149. package/dist/validators/format-detection.d.ts.map +1 -1
  150. package/dist/validators/format-detection.js +41 -26
  151. package/dist/validators/format-detection.js.map +1 -1
  152. package/dist/validators/frontmatter-validation.js +1 -1
  153. package/dist/validators/frontmatter-validation.js.map +1 -1
  154. package/dist/validators/marketplace-validator.d.ts.map +1 -1
  155. package/dist/validators/marketplace-validator.js +0 -1
  156. package/dist/validators/marketplace-validator.js.map +1 -1
  157. package/dist/validators/mcp-tool-qualification.d.ts +1 -1
  158. package/dist/validators/mcp-tool-qualification.js +1 -1
  159. package/dist/validators/packaged-size-limit.d.ts.map +1 -1
  160. package/dist/validators/packaged-size-limit.js +0 -2
  161. package/dist/validators/packaged-size-limit.js.map +1 -1
  162. package/dist/validators/packaging-validator.d.ts +2 -2
  163. package/dist/validators/packaging-validator.d.ts.map +1 -1
  164. package/dist/validators/packaging-validator.js +8 -11
  165. package/dist/validators/packaging-validator.js.map +1 -1
  166. package/dist/validators/plugin-hosted-shape.d.ts +3 -1
  167. package/dist/validators/plugin-hosted-shape.d.ts.map +1 -1
  168. package/dist/validators/plugin-hosted-shape.js +5 -6
  169. package/dist/validators/plugin-hosted-shape.js.map +1 -1
  170. package/dist/validators/referenced-path-missing.d.ts.map +1 -1
  171. package/dist/validators/referenced-path-missing.js +0 -1
  172. package/dist/validators/referenced-path-missing.js.map +1 -1
  173. package/dist/validators/registry-validator.d.ts.map +1 -1
  174. package/dist/validators/registry-validator.js +0 -1
  175. package/dist/validators/registry-validator.js.map +1 -1
  176. package/dist/validators/rule-engine/index.d.ts +1 -1
  177. package/dist/validators/rule-engine/rule-context.d.ts +3 -3
  178. package/dist/validators/rule-engine/rule-context.js +1 -1
  179. package/dist/validators/rule-engine/rule-engine.d.ts +1 -1
  180. package/dist/validators/rule-engine/rule-engine.js +5 -5
  181. package/dist/validators/rule-engine/rule-engine.js.map +1 -1
  182. package/dist/validators/skill-validator.d.ts.map +1 -1
  183. package/dist/validators/skill-validator.js +41 -51
  184. package/dist/validators/skill-validator.js.map +1 -1
  185. package/dist/validators/source-only-codes.js +1 -1
  186. package/dist/validators/source-only-codes.js.map +1 -1
  187. package/dist/validators/types.d.ts +7 -1
  188. package/dist/validators/types.d.ts.map +1 -1
  189. package/dist/validators/unified-validator.d.ts.map +1 -1
  190. package/dist/validators/unified-validator.js +3 -4
  191. package/dist/validators/unified-validator.js.map +1 -1
  192. package/dist/validators/validation-rules.d.ts +3 -3
  193. package/dist/validators/validation-rules.d.ts.map +1 -1
  194. package/dist/validators/validation-rules.js +9 -38
  195. package/dist/validators/validation-rules.js.map +1 -1
  196. package/dist/validators/walker-to-issues.d.ts +2 -0
  197. package/dist/validators/walker-to-issues.d.ts.map +1 -1
  198. package/dist/validators/walker-to-issues.js +17 -12
  199. package/dist/validators/walker-to-issues.js.map +1 -1
  200. package/dist/walk-link-graph.d.ts +2 -0
  201. package/dist/walk-link-graph.d.ts.map +1 -1
  202. package/dist/walk-link-graph.js +20 -8
  203. package/dist/walk-link-graph.js.map +1 -1
  204. package/package.json +11 -19
  205. package/dist/skill-test/exit-codes.d.ts +0 -134
  206. package/dist/skill-test/exit-codes.d.ts.map +0 -1
  207. package/dist/skill-test/exit-codes.js +0 -224
  208. package/dist/skill-test/exit-codes.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-invariants.js","sourceRoot":"","sources":["../../src/skill-test/prompt-invariants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,6BAA6B,CAAC,MAAc,EAAE,KAAa;IACzE,OAAO;QACL,MAAM;QACN,EAAE;QACF,2EAA2E;QAC3E,6DAA6D,KAAK,EAAE;QACpE,+EAA+E;KAChF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"prompt-invariants.js","sourceRoot":"","sources":["../../src/skill-test/prompt-invariants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IACvC,MAAM,GAAG,WAAoB,CAAC;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,kBAAkB,EAAE,8BAA8B,OAAO,EAAE,CAAC,CAAC;IACrE,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,6BAA6B,CAAC,MAAc,EAAE,KAAa;IACzE,OAAO;QACL,MAAM;QACN,EAAE;QACF,2EAA2E;QAC3E,6DAA6D,KAAK,EAAE;QACpE,+EAA+E;KAChF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Implements the full harness sequence as a pure async function (no process.exit):
5
5
  * lock → assert safe workdir + harness root → stage → resolve staged-subject
6
- * eval path → bootstrap-check (scaffold template + exit 3 if absent)
6
+ * eval path → bootstrap-check (scaffold template + exit 2 with `Reason: bootstrap` if absent)
7
7
  * → preflight (return early exitCode 2 on failure) → ack enforcement
8
8
  * → dry-run short-circuit → build per-eval work items → run the vat-owned
9
9
  * executor→grader pipeline (bounded-parallel) → merge grader fragments →
@@ -11,16 +11,16 @@
11
11
  * → release lock → return result
12
12
  */
13
13
  import type { SkillSourceDescriptor } from '@vibe-agent-toolkit/resources';
14
+ import { ExitCode, type ExitCodeValue } from '@vibe-agent-toolkit/schema';
14
15
  import { type spawnHeadlessClaude, type ResolvedAuth } from '@vibe-agent-toolkit/utils/skill-test';
15
16
  import type { ResolveSkillSourceContext, SkillSource } from '../skill-source/types.js';
16
17
  import { type BaselineDelta } from './baseline-delta.js';
17
- import { type ArmEvalGrade, type BaselineControlArmFailure, type BaselineIntegrity, type DetectBaselineContaminationInput } from './baseline-integrity.js';
18
+ import { type ArmEvalGrade, type BaselineIntegrity, type DetectBaselineContaminationInput } from './baseline-integrity.js';
18
19
  import type { EvalFragment } from './eval-fragment.js';
19
20
  import { type ArmWorkspaceDirs, type EvalArm, type EvalEntry, type EvalSuite } from './eval-inputs.js';
20
- import { type SkillTestExitCodeValue } from './exit-codes.js';
21
+ import { type SkillTestFailureReason } from './failure-reason.js';
21
22
  import { type FrictionItem } from './friction-schema.js';
22
23
  import { type GradingVerdict } from './grading-adapter.js';
23
- import { RateLimitSignal } from './pipeline.js';
24
24
  import { type PreflightInput } from './preflight.js';
25
25
  import { type StageItem } from './staging.js';
26
26
  import { type SkippedEvalsSummary } from './tier-plan.js';
@@ -127,6 +127,11 @@ export interface RunHarnessOptions {
127
127
  * not the dist. Absent → derived from subject (legacy).
128
128
  */
129
129
  subjectScaffoldDir?: string;
130
+ /**
131
+ * True when the subject is an IN-PLACE skill (`publish: false`): no bundle exists,
132
+ * so it is staged from source and the run's friction report says so.
133
+ */
134
+ subjectInPlace: boolean;
130
135
  /**
131
136
  * True when run.ts actually rebuilt the subject (declared skill, no
132
137
  * --no-build/--dry-run). Recorded in provenance. Absent/false → staged as-is.
@@ -153,7 +158,7 @@ export interface RunHarnessOptions {
153
158
  * Declared executables the subject skill ships (name + kind + howInvoked),
154
159
  * populated by run.ts from the resolved subject's packaging config WHEN cleanly
155
160
  * reachable (a `buildable` ref carries `packagingConfig`; a plain path source
156
- * does not — issue #145 Phase T). Passed to the grader on the WITH arm ONLY as
161
+ * does not). Passed to the grader on the WITH arm ONLY as
157
162
  * a recognition aid alongside each eval's `toolExpectations`. Absent → the
158
163
  * grader still matches tools by the commands it sees in the transcript.
159
164
  *
@@ -171,7 +176,7 @@ export interface RunHarnessOptions {
171
176
  }>;
172
177
  /**
173
178
  * Opt-OUT of eval gating (for interactive use). By DEFAULT (false/absent) a
174
- * failing verdict returns exit EvalFailure (4) — fail-closed, so CI catches a
179
+ * failing verdict returns exit FINDINGS — fail-closed, so CI catches a
175
180
  * regression without an extra flag. When true, a failing verdict is downgraded
176
181
  * to Ok (0) and the pass/fail count lives only in the summary/grading.json.
177
182
  * Harness-broke codes (1/2/3) are unaffected either way.
@@ -180,7 +185,13 @@ export interface RunHarnessOptions {
180
185
  }
181
186
  export interface RunHarnessResult {
182
187
  harnessPath: string;
183
- exitCode: number;
188
+ exitCode: ExitCodeValue;
189
+ /**
190
+ * Present exactly when `exitCode` is `ERROR`: why the harness could not run.
191
+ * The CLI prints it as `Reason: …` on stderr. Absent on a completed run,
192
+ * whatever its verdict.
193
+ */
194
+ reason?: SkillTestFailureReason;
184
195
  summary: string;
185
196
  /**
186
197
  * Where the executor's per-eval working directories were materialized. Lives
@@ -226,22 +237,24 @@ export declare const SKILL_TEST_BUILTIN_CAPS: {
226
237
  };
227
238
  /**
228
239
  * Resolve the effective PER-EVAL wall-clock timeout (ms). Each executor and
229
- * grader spawn is an independent, bounded-parallel unit (issue #145), so the
240
+ * grader spawn is an independent, bounded-parallel unit, so the
230
241
  * budget is a flat per-spawn ceiling — NOT scaled by the suite size the way the
231
242
  * old single serial run's budget was. An explicit `--timeout` (seconds)
232
243
  * wins; otherwise the flat {@link DEFAULT_TIMEOUT_MS} default applies.
233
244
  */
234
- export declare function resolveTimeoutMs(opts: RunHarnessOptions): number;
245
+ declare function resolveTimeoutMs(opts: RunHarnessOptions): number;
235
246
  /**
236
247
  * Map an eval verdict to a process exit code. Default behavior (fail-closed): a
237
- * failing verdict escalates to EvalFailure (4) — distinct from the harness-broke
238
- * codes (1/2/3) so a CI consumer can `case $? in 0);; 4) tolerate;; *) hard fail;; esac`.
248
+ * failing verdict is `FINDINGS` — the harness ran to completion and what it
249
+ * examined did not pass, exactly as `vat skills validate` reports an
250
+ * error-severity finding — while a harness that could not run is `ERROR`, so a
251
+ * CI consumer can `case $? in 0);; 1) tolerate;; *) hard fail;; esac`.
239
252
  * When `tolerateEvalFailure` is set (interactive opt-out), a failing verdict is
240
- * downgraded to Ok (0) and the count lives only in the summary/grading.json.
253
+ * downgraded to `OK` and the count lives only in the summary/grading.json.
241
254
  */
242
- export declare function verdictExitCode(allPassed: boolean, tolerateEvalFailure: boolean): SkillTestExitCodeValue;
243
- export declare function resolveStallMs(opts: RunHarnessOptions): number | undefined;
244
- export declare function resolveKnobs(opts: RunHarnessOptions): {
255
+ export declare function verdictExitCode(allPassed: boolean, tolerateEvalFailure: boolean): typeof ExitCode.OK | typeof ExitCode.FINDINGS;
256
+ declare function resolveStallMs(opts: RunHarnessOptions): number | undefined;
257
+ declare function resolveKnobs(opts: RunHarnessOptions): {
245
258
  model?: string;
246
259
  maxTurns: number;
247
260
  maxBudgetUsd: number;
@@ -255,21 +268,21 @@ export declare function resolveKnobs(opts: RunHarnessOptions): {
255
268
  * sources (npm/url/vendored/workspace) have no local source tree to walk, so they
256
269
  * are always staged flat (returns undefined). undefined → flat staging.
257
270
  */
258
- export declare function detectItemPluginLayout(source: SkillSource, repoRoot: string): StageItem['pluginLayout'] | undefined;
259
- export declare function makeStageItem(name: string, source: SkillSource, repoRoot: string, role: 'subject' | undefined, optional?: true): StageItem;
271
+ declare function detectItemPluginLayout(source: SkillSource, repoRoot: string): StageItem['pluginLayout'] | undefined;
272
+ declare function makeStageItem(name: string, source: SkillSource, repoRoot: string, role: 'subject' | undefined, optional?: true): StageItem;
260
273
  /**
261
274
  * Build the full set of items `stageHarness` will stage: the subject, every
262
275
  * REQUIRED `--with` companion, and every OPTIONAL `--with-optional` companion.
263
276
  * Both `with` and `optional` STAGE the named companion and make it invocable —
264
- * they differ only in required-vs-optional resolution (issue #153; a `--with`
265
- * name that named no positional skill used to be silently dropped, never staged,
266
- * no manifest trace). Fail-closed on a DUPLICATE staged name (subject / `with` /
277
+ * they differ only in required-vs-optional resolution (a `--with` name that
278
+ * names no positional skill must never be silently dropped — unstaged, with no
279
+ * manifest trace). Fail-closed on a DUPLICATE staged name (subject / `with` /
267
280
  * `optional` all share one namespace): the first repeat throws
268
281
  * {@link DuplicateStagedSkillError} rather than silently letting a later item
269
282
  * clobber an earlier one under the same staged slot.
270
283
  */
271
- export declare function buildStageItems(opts: RunHarnessOptions, repoRoot: string): StageItem[];
272
- export declare function buildResolveCtx(harnessRoot: string, repoRoot: string): ResolveSkillSourceContext;
284
+ declare function buildStageItems(opts: RunHarnessOptions, repoRoot: string): StageItem[];
285
+ declare function buildResolveCtx(harnessRoot: string, repoRoot: string): ResolveSkillSourceContext;
273
286
  /**
274
287
  * Match a flag name as a whole token in `claude --help` output.
275
288
  *
@@ -278,13 +291,7 @@ export declare function buildResolveCtx(harnessRoot: string, repoRoot: string):
278
291
  * of each other (`--max-turns` / `--max-turns-per-eval` would collide). Neither
279
292
  * side of the token may be a letter or a dash.
280
293
  */
281
- export declare function helpTextDeclaresFlag(helpText: string, flag: string): boolean;
282
- /**
283
- * A flag name no `claude` will ever accept. It is probed alongside the real ones
284
- * as a NEGATIVE CONTROL: if the probe reports this as supported, the probe is
285
- * broken and its answer about every other flag is worthless.
286
- */
287
- export declare const FLAG_PROBE_SENTINEL = "--vat-probe-flag-that-cannot-exist";
294
+ declare function helpTextDeclaresFlag(helpText: string, flag: string): boolean;
288
295
  /**
289
296
  * Build a token-free flag-support probe from `claude --help`.
290
297
  *
@@ -305,8 +312,17 @@ export declare const FLAG_PROBE_SENTINEL = "--vat-probe-flag-that-cannot-exist";
305
312
  * outright — the probe reports EVERY flag unsupported rather than every flag
306
313
  * supported. A probe that cannot tell must fail closed and be seen; the defect it
307
314
  * replaces failed open and was invisible.
315
+ *
316
+ * `--help` runs on the FIRST flag query, not when the probe is built. Building
317
+ * it is part of assembling preflight's input, and a preflight that never asks
318
+ * (a stubbed one, or one that fails an earlier check) must not have already
319
+ * paid for a subprocess: with the spawn at build time every harness run cost
320
+ * one real `claude --help` — 75 ms where the CLI is installed, an instant
321
+ * ENOENT where it is not — which read as a 10× platform split in a test that
322
+ * had injected a fake spawn and stubbed preflight precisely so no process
323
+ * would start.
308
324
  */
309
- export declare function buildFlagParseProbe(runHelp?: () => string | null): (flag: string) => boolean;
325
+ declare function buildFlagParseProbe(runHelp?: () => string | null): (flag: string) => boolean;
310
326
  /**
311
327
  * ⚠️ KNOWN OPEN — `costEstimate` here is DEAD, in three independent ways, and none
312
328
  * of them is fixable from inside this function:
@@ -326,10 +342,10 @@ export declare function buildFlagParseProbe(runHelp?: () => string | null): (fla
326
342
  * reachable: a reachable estimate that says "1 evals × 2 config" is worse than a
327
343
  * silent one, because it is quotable.
328
344
  */
329
- export declare function buildPreflightInput(evalsPath: string, pluginDirs: string[], opts: RunHarnessOptions, knobs: {
345
+ declare function buildPreflightInput(evalsPath: string, pluginDirs: string[], opts: RunHarnessOptions, knobs: {
330
346
  maxBudgetUsd: number;
331
347
  }): PreflightInput;
332
- export declare function renderPreflightSummary(checks: {
348
+ declare function renderPreflightSummary(checks: {
333
349
  name: string;
334
350
  passed: boolean;
335
351
  message: string;
@@ -355,6 +371,18 @@ export declare function isAcknowledged(opts: Pick<RunHarnessOptions, 'dryRun' |
355
371
  * code can reach and rewrite after vat wrote it.
356
372
  */
357
373
  export declare function formatFrictionReport(items: readonly FrictionItem[]): string;
374
+ /**
375
+ * Read the run's friction.json (if present + valid) and echo a concise report to
376
+ * STDERR so users don't miss packaging-fidelity friction VAT merged from the grader
377
+ * fragments (it is otherwise only written to disk). Best-effort: a missing or empty
378
+ * report emits nothing. A report that is there but cannot be read or does not parse
379
+ * emits a one-line warning instead — this runs from the harness `finally`, so it
380
+ * must not throw, but vat is the sole writer of friction.json and a file it wrote
381
+ * that it cannot read back is worth a line. Never touches stdout (which stays
382
+ * machine-readable). Accepts `undefined` (a no-op) so the harness `finally` can
383
+ * call it unconditionally even when a throw preempted assignment of the path.
384
+ */
385
+ declare function emitFrictionReport(frictionPath: string | undefined): void;
358
386
  /**
359
387
  * Resolve the PERSISTENT location where a bootstrap scaffold should be written
360
388
  * so "fill it in and re-run" actually works for the user (the staged copy is
@@ -362,7 +390,7 @@ export declare function formatFrictionReport(items: readonly FrictionItem[]): st
362
390
  * that real source dir; otherwise we anchor under the repo root by skill name.
363
391
  */
364
392
  /** The subject skill's display name (trailing segment of the subject arg). */
365
- export declare function subjectSkillName(opts: RunHarnessOptions): string;
393
+ declare function subjectSkillName(opts: RunHarnessOptions): string;
366
394
  /**
367
395
  * Where this run READS its eval suite from, anchored at the subject's authored
368
396
  * source dir.
@@ -385,16 +413,7 @@ export declare function subjectSkillName(opts: RunHarnessOptions): string;
385
413
  * into `<skillDir>/<path>`, which does not exist — so the run did not fail, it
386
414
  * bootstrapped a starter template at the bogus location and graded that.
387
415
  */
388
- export declare function resolveScaffoldEvalsPath(opts: RunHarnessOptions, repoRoot: string, evalsRef: string | undefined): string;
389
- /**
390
- * The vat-only directory a subject's eval suite is relocated to when the resolved
391
- * artifact is the only place it exists (npm/url/vendored, or a source tree that
392
- * ships its own evals). Deliberately OUTSIDE the harness root — the harness root is
393
- * the executor's sandbox, and the suite is the answer key to the task the executor
394
- * is performing. Created 0700 and removed in the run's cleanup, exactly like
395
- * {@link resolveGraderOutDir}. Pure (derives a path only).
396
- */
397
- export declare function resolveEvalSuiteHoldDir(dirToken: string): string;
416
+ declare function resolveScaffoldEvalsPath(opts: RunHarnessOptions, repoRoot: string, evalsRef: string | undefined): string;
398
417
  /**
399
418
  * Locate the eval suite the run will read, WITHOUT it ever being reachable by the
400
419
  * executor. Precedence, and why:
@@ -405,12 +424,12 @@ export declare function resolveEvalSuiteHoldDir(dirToken: string): string;
405
424
  * 2. **The vat-only hold dir**, when staging harvested a suite that exists nowhere
406
425
  * else (a fetched artifact). Its layout mirrors an authored evals dir, so
407
426
  * `fixtures/` resolve relative to it unchanged.
408
- * 3. Neither → `undefined`, and the caller bootstraps a template (exit 3).
427
+ * 3. Neither → `undefined`, and the caller bootstraps a template (exit 2, `Reason: bootstrap`).
409
428
  *
410
429
  * Returns the suite's absolute path; its `dirname` is the base for each eval's
411
430
  * declared input `files`.
412
431
  */
413
- export declare function resolveEvalSuitePath(input: {
432
+ declare function resolveEvalSuitePath(input: {
414
433
  opts: RunHarnessOptions;
415
434
  repoRoot: string;
416
435
  /** Explicit `test.evals` / `--evals` value, or `undefined` for the convention. */
@@ -434,7 +453,7 @@ export declare function resolveEvalSuitePath(input: {
434
453
  * Named by an unpredictable token, like the other vat-only dirs, and removed by
435
454
  * the same cleanup. Pure (derives a path only).
436
455
  */
437
- export declare function resolveWorkspacesRoot(dirToken: string): string;
456
+ declare function resolveWorkspacesRoot(dirToken: string): string;
438
457
  /** Parse the staged eval suite and materialize each eval's input `files` into
439
458
  * `<workspacesRoot>/<arm>/<id>/`, once per arm this run will execute. Returns the
440
459
  * workspaces root, the parsed {@link EvalSuite} (so the eval loop has the entries
@@ -452,8 +471,8 @@ export declare function resolveWorkspacesRoot(dirToken: string): string;
452
471
  * 8 bytes is ample for "not guessable within a run that lasts minutes"; these are
453
472
  * blinding/anti-enumeration tokens, not secrets protecting data at rest.
454
473
  */
455
- export declare function mintArmWorkspaceDirs(baseline: boolean): ArmWorkspaceDirs;
456
- export declare function stageWorkspacesForRun(evalsPath: string, workspacesRoot: string, armDirs: ArmWorkspaceDirs): {
474
+ declare function mintArmWorkspaceDirs(baseline: boolean): ArmWorkspaceDirs;
475
+ declare function stageWorkspacesForRun(evalsPath: string, workspacesRoot: string, armDirs: ArmWorkspaceDirs): {
457
476
  workspacesRoot: string;
458
477
  declaredEvalCount: number;
459
478
  suite: EvalSuite;
@@ -555,12 +574,6 @@ export interface CleanupHarnessOptions {
555
574
  */
556
575
  created: boolean;
557
576
  }
558
- /**
559
- * The one child of the harness root that cleanup NEVER removes. Cleanup exists to
560
- * evict staged untrusted skill bytes and prompts from OS tmp; `results/` is the
561
- * opposite — it is the run's product, written solely by vat.
562
- */
563
- export declare const RETAINED_RESULTS_DIRNAME = "results";
564
577
  /**
565
578
  * Remove the harness directory's staged contents after a run so untrusted skill
566
579
  * bytes and prompts do not accumulate in OS tmp. No-op when the user asked to keep
@@ -588,7 +601,7 @@ export declare const RETAINED_RESULTS_DIRNAME = "results";
588
601
  * the run and cleanup is left in place rather than followed — `rmSync(recursive)`
589
602
  * could otherwise delete the symlink's target outside tmp.
590
603
  */
591
- export declare function cleanupHarness(harnessRoot: string, opts: CleanupHarnessOptions): void;
604
+ declare function cleanupHarness(harnessRoot: string, opts: CleanupHarnessOptions): void;
592
605
  /** One unit of executor→grader work: an eval + which arm (with/without skill). */
593
606
  export interface EvalWorkItem {
594
607
  entry: EvalEntry;
@@ -602,14 +615,14 @@ export interface EvalWorkItem {
602
615
  * (see {@link partitionFragmentsByArm}) and never drives tier gating. Pure +
603
616
  * unit-testable.
604
617
  */
605
- export declare function buildEvalWorkItems(evals: readonly EvalEntry[], baseline: boolean): EvalWorkItem[];
618
+ declare function buildEvalWorkItems(evals: readonly EvalEntry[], baseline: boolean): EvalWorkItem[];
606
619
  /**
607
620
  * Partition graded fragments into the WITH arm (the authoritative verdict +
608
621
  * grading.json) and the WITHOUT arm (baseline.json, informational only). A
609
622
  * fragment with no `arm` (or `arm: 'with'`) is a WITH-arm fragment. Pure +
610
623
  * unit-testable.
611
624
  */
612
- export declare function partitionFragmentsByArm(fragments: EvalFragment[]): {
625
+ declare function partitionFragmentsByArm(fragments: EvalFragment[]): {
613
626
  withArm: EvalFragment[];
614
627
  withoutArm: EvalFragment[];
615
628
  };
@@ -633,7 +646,7 @@ export declare function partitionFragmentsByArm(fragments: EvalFragment[]): {
633
646
  * container; that is tracked as a follow-up (see CHANGELOG "Security" notes) and
634
647
  * is the only thing that closes the residual race outright.
635
648
  */
636
- export declare function resolveGraderOutDir(dirToken: string): string;
649
+ declare function resolveGraderOutDir(dirToken: string): string;
637
650
  /**
638
651
  * The executor working directory for one eval ON ONE ARM: its staged input
639
652
  * workspace `<workspacesRoot>/<arm>/<id>`, ALWAYS — empty when the eval declares
@@ -655,7 +668,7 @@ export declare function resolveGraderOutDir(dirToken: string): string;
655
668
  * told the control arm it was the control, and `../with/e1` told it where to look.
656
669
  * See {@link mintArmWorkspaceDirs}. Pure + unit-testable.
657
670
  */
658
- export declare function resolvePerEvalWorkspaceDir(entry: EvalEntry, workspacesRoot: string, arm: EvalArm, armDirs: ArmWorkspaceDirs): string;
671
+ declare function resolvePerEvalWorkspaceDir(entry: EvalEntry, workspacesRoot: string, arm: EvalArm, armDirs: ArmWorkspaceDirs): string;
659
672
  /**
660
673
  * Best-effort removal of a vat-only tmp dir that lives OUTSIDE the harness root —
661
674
  * the grader fragment dir and the held eval suite. Never throws (it runs from
@@ -684,8 +697,12 @@ export declare function resolvePerEvalWorkspaceDir(entry: EvalEntry, workspacesR
684
697
  * could not be removed will break the NEXT run with a "busy" error, and an operator
685
698
  * who saw nothing here has no way to connect the two.
686
699
  */
687
- export declare function swallowCleanupFailure(step: () => void): void;
688
- export declare function removeVatOnlyDir(dir: string | undefined): void;
700
+ declare function swallowCleanupFailure(step: () => void): void;
701
+ /**
702
+ * Remove one vat-only temp dir. Same discipline as {@link cleanupHarness}: a failed
703
+ * removal is not a run failure, and it is reported rather than swallowed.
704
+ */
705
+ declare function removeVatOnlyDir(dir: string | undefined): void;
689
706
  /** Everything one executor→grader pipeline worker needs, built once per run. */
690
707
  interface EvalRunContext {
691
708
  subjectStagedDir: string;
@@ -745,24 +762,6 @@ interface EvalRunContext {
745
762
  */
746
763
  harnessRoot: string;
747
764
  }
748
- /**
749
- * The control arm ran out of rate-limit retries — record it and let the run live.
750
- *
751
- * The retryable case is handled correctly by {@link runEvalWorker} and must stay that
752
- * way; this is the EXHAUSTED case, which used to be indistinguishable from it. A
753
- * control executor rate-limited on every attempt threw after five retries, taking
754
- * down a run in which both treatment executors and both treatment graders had already
755
- * completed and been billed, leaving `results/` holding `provenance.json` and nothing
756
- * else — the exact failure {@link runEvalWorker} exists to prevent, reached by the one
757
- * error class it had to let through.
758
- *
759
- * The treatment arm still hard-fails: there is no treatment result to salvage, which
760
- * is the same asymmetry {@link EvalWorkOutcome} documents.
761
- *
762
- * Wired as the pipeline's `onRetriesExhausted`, and `--baseline` — which doubles the
763
- * spawn count — is the run most likely to need it.
764
- */
765
- export declare function rateLimitExhaustedOutcome(item: EvalWorkItem, error: RateLimitSignal): EvalWorkOutcome;
766
765
  /**
767
766
  * Strip the fields VAT attaches itself, before VAT attaches them.
768
767
  *
@@ -778,28 +777,7 @@ export declare function rateLimitExhaustedOutcome(item: EvalWorkItem, error: Rat
778
777
  * scanned properly, and an operator who learns to ignore that warning stops reading
779
778
  * the real ones.
780
779
  */
781
- export declare function withoutGraderContamination(fragment: EvalFragment): EvalFragment;
782
- /**
783
- * What one work item produced: a graded fragment, or — CONTROL ARM ONLY — a
784
- * recorded failure that the run carries on past.
785
- *
786
- * The asymmetry is the whole point and it is not a subjective call. A treatment-arm
787
- * failure leaves nothing to salvage: `grading.json` IS the treatment arm, so a run
788
- * that cannot produce it has produced nothing and may as well stop. A control-arm
789
- * failure destroys only the second half of a comparison whose first half is already
790
- * bought and paid for — and the artifact that reports that comparison already has a
791
- * way to say "I do not exist here" (`delta: null`). Failing the whole run on a
792
- * control-arm timeout threw away every treatment executor and grader spawn that had
793
- * already completed, wrote no `grading.json` at all, and left `results/` holding
794
- * only `provenance.json`.
795
- */
796
- type EvalWorkOutcome = {
797
- readonly fragment: EvalFragment;
798
- readonly controlFailure?: undefined;
799
- } | {
800
- readonly fragment?: undefined;
801
- readonly controlFailure: BaselineControlArmFailure;
802
- };
780
+ declare function withoutGraderContamination(fragment: EvalFragment): EvalFragment;
803
781
  /**
804
782
  * Lift the run's content needles off the STAGED SKILL.md.
805
783
  *
@@ -821,13 +799,14 @@ type EvalWorkOutcome = {
821
799
  * Fixtures are read from the STAGED workspace rather than the suite directory, for
822
800
  * the same reason the SKILL.md is: that is byte-for-byte what the arm was handed.
823
801
  *
824
- * Returns `[]` when the file cannot be read. A missing SKILL.md is not this
802
+ * Returns `[]` when there is no staged SKILL.md. A missing SKILL.md is not this
825
803
  * function's error to raise (staging has already validated the subject), and an
826
- * unarmed signal is reported as unarmed rather than claimed as clean. An
827
- * unreadable FIXTURE is skipped for the same reason, and errs the safe way: a
828
- * fixture we could not exclude can only make the signal noisier, never blinder.
804
+ * unarmed signal is reported as unarmed rather than claimed as clean. A SKILL.md
805
+ * that is THERE but refused is a different thing — `[]` would silently disarm the
806
+ * contamination signal for the whole run — so a refusal propagates. The same split
807
+ * applies to fixtures: see {@link collectFixtureText}.
829
808
  */
830
- export declare function resolveSkillContentNeedles(subjectStagedDir: string, evals: readonly EvalEntry[],
809
+ declare function resolveSkillContentNeedles(subjectStagedDir: string, evals: readonly EvalEntry[],
831
810
  /**
832
811
  * Where the staged fixtures live, as the two inputs an arm root is DERIVED from
833
812
  * rather than as the pre-joined path itself — see {@link armWorkspaceRoot}. Taking
@@ -886,13 +865,13 @@ export type ContaminationCtx = Pick<EvalRunContext, 'armDirs' | 'workspacesRoot'
886
865
  * not to run. That is the same shape as the dropped `armCwd` that anchored the whole
887
866
  * walk one directory too high, also green.
888
867
  */
889
- export declare function buildContaminationInput(transcript: string, ctx: ContaminationCtx, evalId: string): DetectBaselineContaminationInput;
868
+ declare function buildContaminationInput(transcript: string, ctx: ContaminationCtx, evalId: string): DetectBaselineContaminationInput;
890
869
  /**
891
870
  * The same input built for the "which detectors are ARMED?" question, which is asked
892
871
  * once per run with no transcript and no eval — so it can honestly supply neither,
893
872
  * and `armCwd` is correctly absent rather than accidentally dropped.
894
873
  */
895
- export declare function buildContaminationSignalsInput(ctx: ContaminationCtx): DetectBaselineContaminationInput;
874
+ declare function buildContaminationSignalsInput(ctx: ContaminationCtx): DetectBaselineContaminationInput;
896
875
  /** The results/ artifacts vat is the SOLE writer of, resolved for one run. */
897
876
  export interface ArtifactPaths {
898
877
  gradingOut: string;
@@ -903,7 +882,7 @@ export interface ArtifactPaths {
903
882
  /** Resolve the run's grading/friction/baseline/tool-eval artifact paths under
904
883
  * `resultsDir`. Single source of truth for the filenames (used by the
905
884
  * pre-pipeline stale wipe AND the post-merge writer). */
906
- export declare function resolveArtifactPaths(resultsDir: string): ArtifactPaths;
885
+ declare function resolveArtifactPaths(resultsDir: string): ArtifactPaths;
907
886
  /**
908
887
  * Remove any PRIOR run's artifacts before this run writes its own. The harness
909
888
  * root is deterministic per skill-set and reused across runs (`--keep`/`--out`, or
@@ -913,7 +892,7 @@ export declare function resolveArtifactPaths(resultsDir: string): ArtifactPaths;
913
892
  * run's. Wiping all three up front closes that cross-run leak. Best-effort
914
893
  * (`force: true`) — a missing file is fine.
915
894
  */
916
- export declare function wipeStaleArtifacts(paths: ArtifactPaths): void;
895
+ declare function wipeStaleArtifacts(paths: ArtifactPaths): void;
917
896
  /**
918
897
  * Where a results artifact goes when it fails the fail-closed gate.
919
898
  *
@@ -924,7 +903,7 @@ export declare function wipeStaleArtifacts(paths: ArtifactPaths): void;
924
903
  * a maintainer needs in order to see which refine tripped, and a name ending in
925
904
  * `.rejected` cannot be mistaken for the artifact a reader came for.
926
905
  */
927
- export declare function rejectedArtifactPath(path: string): string;
906
+ declare function rejectedArtifactPath(path: string): string;
928
907
  /**
929
908
  * Merge the run's grader fragments and WRITE the run artifacts (vat is the SOLE
930
909
  * writer): grading.json from the WITH-arm fragments, friction.json from ALL
@@ -952,7 +931,7 @@ export declare function rejectedArtifactPath(path: string): string;
952
931
  * everything it declared, so the two fields were numerically identical in all of
953
932
  * them and the ONE thing this function exists to keep distinct was unpinned.
954
933
  */
955
- export declare function gradedCounts(fragments: EvalFragment[]): ArmEvalGrade[];
934
+ declare function gradedCounts(fragments: EvalFragment[]): ArmEvalGrade[];
956
935
  /**
957
936
  * The stderr report for a `--baseline` run: the delta line, then the ⚠️ banner when
958
937
  * the run is unusable. Pure — the caller decides WHEN it goes out, which is the
@@ -992,24 +971,24 @@ export declare function gradedCounts(fragments: EvalFragment[]): ArmEvalGrade[];
992
971
  * on a run where they can be. A contaminated delta is also diagnostic in its own
993
972
  * right: it collapses toward zero, which is corroboration, not noise.
994
973
  */
995
- export declare function formatBaselineReport(delta: BaselineDelta, integrity: BaselineIntegrity): string;
974
+ declare function formatBaselineReport(delta: BaselineDelta, integrity: BaselineIntegrity): string;
996
975
  /**
997
- * The COMPOSITE run verdict (issue #145 Phase T): the run passes only when BOTH
976
+ * The COMPOSITE run verdict: the run passes only when BOTH
998
977
  * the prose-expectation grading passed AND every tool-expectation verdict passed.
999
978
  * Tool verdicts live in tool-eval.json (a SEPARATE channel — C2); this combines
1000
979
  * the two at the exit-code layer WITHOUT mixing the channels' data. When no eval
1001
980
  * declared `toolExpectations`, `toolEval.evals` is empty and this equals
1002
981
  * `outputAllPassed`. Pure + unit-testable.
1003
982
  */
1004
- export declare function computeCompositeVerdict(outputAllPassed: boolean, toolEval: ToolEvalReport): boolean;
983
+ declare function computeCompositeVerdict(outputAllPassed: boolean, toolEval: ToolEvalReport): boolean;
1005
984
  /**
1006
985
  * The run's final pass/fail after cost-tiered fail-fast: the {@link
1007
986
  * computeCompositeVerdict} of the tiers that RAN, AND no tiers were skipped. A
1008
987
  * fail-fast run that gated higher tiers is NEVER a pass (skipped ≠ passed) — this
1009
- * forces `false` so the exit code is EvalFailure (4), never downgraded to 0 by the
988
+ * forces `false` so the exit code is FINDINGS, never downgraded to 0 by the
1010
989
  * composite path alone. Pure + unit-testable.
1011
990
  */
1012
- export declare function resolveCompositeAllPassed(outputAllPassed: boolean, toolEval: ToolEvalReport, skipped: SkippedEvalsSummary | undefined): boolean;
991
+ declare function resolveCompositeAllPassed(outputAllPassed: boolean, toolEval: ToolEvalReport, skipped: SkippedEvalsSummary | undefined): boolean;
1013
992
  /**
1014
993
  * Running total of spend across every executor+grader session in a run (adopter
1015
994
  * follow-up). `sessions` counts only sessions that REPORTED a `total_cost_usd`, so
@@ -1022,13 +1001,13 @@ export interface RunCostSummary {
1022
1001
  sessions: number;
1023
1002
  }
1024
1003
  /** Fold one session's `total_cost_usd` into the accumulator; a non-number (mock spawn / missing result) is ignored. */
1025
- export declare function recordSessionCost(acc: RunCostSummary, totalCostUsd: number | undefined): void;
1004
+ declare function recordSessionCost(acc: RunCostSummary, totalCostUsd: number | undefined): void;
1026
1005
  /**
1027
1006
  * The ` | ≈$0.42 across 6 sessions` spend suffix for the summary line, or `''`
1028
1007
  * when no session reported a cost (e.g. every spawn was a test mock) so the suffix
1029
1008
  * never adds noise to a run with no cost signal. Pure + unit-testable.
1030
1009
  */
1031
- export declare function formatRunCostSuffix(cost: RunCostSummary | undefined): string;
1010
+ declare function formatRunCostSuffix(cost: RunCostSummary | undefined): string;
1032
1011
  /**
1033
1012
  * The run's human summary line, computed from the COMPOSITE verdict so an
1034
1013
  * output-pass with a failing tool verdict still reads FAIL. The prose-expectation
@@ -1036,7 +1015,7 @@ export declare function formatRunCostSuffix(cost: RunCostSummary | undefined): s
1036
1015
  * verdict failed, a `(N tool)` suffix names how many — so a composite FAIL whose
1037
1016
  * OUTPUT counts look all-green (e.g. `FAIL 3/3 (1 tool)`) is self-explaining. Pure.
1038
1017
  */
1039
- export declare function buildRunSummary(verdict: GradingVerdict, toolEval: ToolEvalReport, compositeAllPassed: boolean): string;
1018
+ declare function buildRunSummary(verdict: GradingVerdict, toolEval: ToolEvalReport, compositeAllPassed: boolean): string;
1040
1019
  /**
1041
1020
  * The run summary line, appending the fail-fast SKIPPED note when the tier gate
1042
1021
  * stopped higher tiers. Legibility is required — the skipped tiers are named on
@@ -1044,7 +1023,7 @@ export declare function buildRunSummary(verdict: GradingVerdict, toolEval: ToolE
1044
1023
  * tiers ALWAYS reads FAIL (skipped ≠ passed forces `compositeAllPassed` false at
1045
1024
  * the call site), so the base line is already FAIL when the note is present.
1046
1025
  */
1047
- export declare function buildRunSummaryWithSkips(verdict: GradingVerdict, toolEval: ToolEvalReport, compositeAllPassed: boolean, skipped: SkippedEvalsSummary | undefined, cost?: RunCostSummary): string;
1026
+ declare function buildRunSummaryWithSkips(verdict: GradingVerdict, toolEval: ToolEvalReport, compositeAllPassed: boolean, skipped: SkippedEvalsSummary | undefined, cost?: RunCostSummary): string;
1048
1027
  /**
1049
1028
  * Post-merge D2 gate over the vat-written results artifacts (vat is SOLE writer):
1050
1029
  * grading.json, friction.json, tool-eval.json — and, on a baseline run, baseline.json
@@ -1065,7 +1044,7 @@ export declare function buildRunSummaryWithSkips(verdict: GradingVerdict, toolEv
1065
1044
  * baseline and wrote nothing), which is exactly what a fail-CLOSED gate must not do.
1066
1045
  * A non-baseline run writes no baseline.json at all and is not asked about one.
1067
1046
  */
1068
- export declare function assertVatWroteArtifacts(paths: ArtifactPaths, baselineRun: boolean): void;
1047
+ declare function assertVatWroteArtifacts(paths: ArtifactPaths, baselineRun: boolean): void;
1069
1048
  /**
1070
1049
  * Domain orchestrator for `vat skill test run`. Pure of process.exit — all
1071
1050
  * exit-code decisions live in the caller (run.ts).
@@ -1082,10 +1061,68 @@ export declare function assertVatWroteArtifacts(paths: ArtifactPaths, baselineRu
1082
1061
  * `harnessCreated` is true only for the derived-under-OS-tmp case; an explicit
1083
1062
  * `--out` or `--workdir` is a location the user owns and is never auto-removed.
1084
1063
  */
1085
- export declare function resolveHarnessLocation(opts: Pick<RunHarnessOptions, 'out' | 'workdir' | 'subject'>): {
1064
+ declare function resolveHarnessLocation(opts: Pick<RunHarnessOptions, 'out' | 'workdir' | 'subject'>): {
1086
1065
  harnessRoot: string;
1087
1066
  harnessCreated: boolean;
1088
1067
  };
1089
1068
  export declare function runSkillTestHarness(opts: RunHarnessOptions): Promise<RunHarnessResult>;
1069
+ /**
1070
+ * The test-facing seam — every helper the unit tests reach that is NOT part of
1071
+ * this module's API.
1072
+ *
1073
+ * These used to be forty-four separate `export`s, indistinguishable at the export
1074
+ * keyword from the seven names the skill-test barrel actually publishes, so
1075
+ * "is this API?" was a question for a JSDoc rather than a grep. Now it is a
1076
+ * grep: a name here is reachable by a test and by nothing else. Nothing under
1077
+ * `src/` imports `__internal` and no barrel re-exports it — a dev-tools test
1078
+ * holds both lines. Types stay exported on their own: an object cannot carry
1079
+ * them, and a type is not a call site.
1080
+ */
1081
+ export declare const __internal: {
1082
+ readonly assertVatWroteArtifacts: typeof assertVatWroteArtifacts;
1083
+ readonly buildContaminationInput: typeof buildContaminationInput;
1084
+ readonly buildContaminationSignalsInput: typeof buildContaminationSignalsInput;
1085
+ readonly buildEvalWorkItems: typeof buildEvalWorkItems;
1086
+ readonly buildFlagParseProbe: typeof buildFlagParseProbe;
1087
+ readonly buildPreflightInput: typeof buildPreflightInput;
1088
+ readonly buildResolveCtx: typeof buildResolveCtx;
1089
+ readonly buildRunSummary: typeof buildRunSummary;
1090
+ readonly buildRunSummaryWithSkips: typeof buildRunSummaryWithSkips;
1091
+ readonly computeCompositeVerdict: typeof computeCompositeVerdict;
1092
+ readonly detectItemPluginLayout: typeof detectItemPluginLayout;
1093
+ readonly emitFrictionReport: typeof emitFrictionReport;
1094
+ readonly FLAG_PROBE_SENTINEL: "--vat-probe-flag-that-cannot-exist";
1095
+ readonly formatBaselineReport: typeof formatBaselineReport;
1096
+ readonly formatRunCostSuffix: typeof formatRunCostSuffix;
1097
+ readonly gradedCounts: typeof gradedCounts;
1098
+ readonly helpTextDeclaresFlag: typeof helpTextDeclaresFlag;
1099
+ readonly makeStageItem: typeof makeStageItem;
1100
+ readonly mintArmWorkspaceDirs: typeof mintArmWorkspaceDirs;
1101
+ readonly partitionFragmentsByArm: typeof partitionFragmentsByArm;
1102
+ readonly recordSessionCost: typeof recordSessionCost;
1103
+ readonly rejectedArtifactPath: typeof rejectedArtifactPath;
1104
+ readonly removeVatOnlyDir: typeof removeVatOnlyDir;
1105
+ readonly renderPreflightSummary: typeof renderPreflightSummary;
1106
+ readonly resolveArtifactPaths: typeof resolveArtifactPaths;
1107
+ readonly resolveCompositeAllPassed: typeof resolveCompositeAllPassed;
1108
+ readonly resolveHarnessLocation: typeof resolveHarnessLocation;
1109
+ readonly resolveKnobs: typeof resolveKnobs;
1110
+ readonly resolvePerEvalWorkspaceDir: typeof resolvePerEvalWorkspaceDir;
1111
+ readonly resolveScaffoldEvalsPath: typeof resolveScaffoldEvalsPath;
1112
+ readonly resolveSkillContentNeedles: typeof resolveSkillContentNeedles;
1113
+ readonly resolveStallMs: typeof resolveStallMs;
1114
+ readonly resolveTimeoutMs: typeof resolveTimeoutMs;
1115
+ readonly resolveWorkspacesRoot: typeof resolveWorkspacesRoot;
1116
+ readonly RETAINED_RESULTS_DIRNAME: "results";
1117
+ readonly stageWorkspacesForRun: typeof stageWorkspacesForRun;
1118
+ readonly subjectSkillName: typeof subjectSkillName;
1119
+ readonly swallowCleanupFailure: typeof swallowCleanupFailure;
1120
+ readonly wipeStaleArtifacts: typeof wipeStaleArtifacts;
1121
+ readonly withoutGraderContamination: typeof withoutGraderContamination;
1122
+ readonly cleanupHarness: typeof cleanupHarness;
1123
+ readonly buildStageItems: typeof buildStageItems;
1124
+ readonly resolveGraderOutDir: typeof resolveGraderOutDir;
1125
+ readonly resolveEvalSuitePath: typeof resolveEvalSuitePath;
1126
+ };
1090
1127
  export {};
1091
1128
  //# sourceMappingURL=run-harness.d.ts.map