@vibe-agent-toolkit/cli 0.1.42 → 0.2.0-rc.10

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 (504) hide show
  1. package/README.md +4 -5
  2. package/dist/bin/vat +95 -28
  3. package/dist/bin/vat.js +95 -28
  4. package/dist/bin/vat.js.map +1 -1
  5. package/dist/bin.js +137 -76
  6. package/dist/bin.js.map +1 -1
  7. package/dist/command-loaders.d.ts +44 -0
  8. package/dist/command-loaders.d.ts.map +1 -0
  9. package/dist/command-loaders.js +60 -0
  10. package/dist/command-loaders.js.map +1 -0
  11. package/dist/commands/agent/build.d.ts.map +1 -1
  12. package/dist/commands/agent/build.js +2 -1
  13. package/dist/commands/agent/build.js.map +1 -1
  14. package/dist/commands/agent/import.d.ts.map +1 -1
  15. package/dist/commands/agent/import.js +3 -2
  16. package/dist/commands/agent/import.js.map +1 -1
  17. package/dist/commands/agent/index.js +1 -1
  18. package/dist/commands/agent/install-path.d.ts +36 -0
  19. package/dist/commands/agent/install-path.d.ts.map +1 -0
  20. package/dist/commands/agent/install-path.js +44 -0
  21. package/dist/commands/agent/install-path.js.map +1 -0
  22. package/dist/commands/agent/install.d.ts.map +1 -1
  23. package/dist/commands/agent/install.js +66 -13
  24. package/dist/commands/agent/install.js.map +1 -1
  25. package/dist/commands/agent/installed.d.ts.map +1 -1
  26. package/dist/commands/agent/installed.js +22 -12
  27. package/dist/commands/agent/installed.js.map +1 -1
  28. package/dist/commands/agent/list.d.ts.map +1 -1
  29. package/dist/commands/agent/list.js +2 -1
  30. package/dist/commands/agent/list.js.map +1 -1
  31. package/dist/commands/agent/run.d.ts.map +1 -1
  32. package/dist/commands/agent/run.js +2 -1
  33. package/dist/commands/agent/run.js.map +1 -1
  34. package/dist/commands/agent/uninstall.d.ts.map +1 -1
  35. package/dist/commands/agent/uninstall.js +13 -6
  36. package/dist/commands/agent/uninstall.js.map +1 -1
  37. package/dist/commands/agent/validate.d.ts.map +1 -1
  38. package/dist/commands/agent/validate.js +3 -2
  39. package/dist/commands/agent/validate.js.map +1 -1
  40. package/dist/commands/ard/emit.d.ts +153 -0
  41. package/dist/commands/ard/emit.d.ts.map +1 -0
  42. package/dist/commands/ard/emit.js +276 -0
  43. package/dist/commands/ard/emit.js.map +1 -0
  44. package/dist/commands/ard/index.d.ts +12 -0
  45. package/dist/commands/ard/index.d.ts.map +1 -0
  46. package/dist/commands/ard/index.js +80 -0
  47. package/dist/commands/ard/index.js.map +1 -0
  48. package/dist/commands/ard/surfaces.d.ts +56 -0
  49. package/dist/commands/ard/surfaces.d.ts.map +1 -0
  50. package/dist/commands/ard/surfaces.js +150 -0
  51. package/dist/commands/ard/surfaces.js.map +1 -0
  52. package/dist/commands/audit/distributed-tree.d.ts +60 -2
  53. package/dist/commands/audit/distributed-tree.d.ts.map +1 -1
  54. package/dist/commands/audit/distributed-tree.js +73 -1
  55. package/dist/commands/audit/distributed-tree.js.map +1 -1
  56. package/dist/commands/audit/git-url-clone.d.ts +1 -1
  57. package/dist/commands/audit/git-url-clone.d.ts.map +1 -1
  58. package/dist/commands/audit/git-url-clone.js.map +1 -1
  59. package/dist/commands/audit/hierarchical-output.d.ts +1 -1
  60. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
  61. package/dist/commands/audit/hierarchical-output.js +1 -1
  62. package/dist/commands/audit/hierarchical-output.js.map +1 -1
  63. package/dist/commands/audit/provenance.d.ts.map +1 -1
  64. package/dist/commands/audit/provenance.js +4 -3
  65. package/dist/commands/audit/provenance.js.map +1 -1
  66. package/dist/commands/audit/scan-population.d.ts +158 -0
  67. package/dist/commands/audit/scan-population.d.ts.map +1 -0
  68. package/dist/commands/audit/scan-population.js +292 -0
  69. package/dist/commands/audit/scan-population.js.map +1 -0
  70. package/dist/commands/audit-settings.d.ts.map +1 -1
  71. package/dist/commands/audit-settings.js +6 -5
  72. package/dist/commands/audit-settings.js.map +1 -1
  73. package/dist/commands/audit.d.ts +98 -8
  74. package/dist/commands/audit.d.ts.map +1 -1
  75. package/dist/commands/audit.js +1133 -395
  76. package/dist/commands/audit.js.map +1 -1
  77. package/dist/commands/build.d.ts +1 -1
  78. package/dist/commands/build.d.ts.map +1 -1
  79. package/dist/commands/build.js +40 -36
  80. package/dist/commands/build.js.map +1 -1
  81. package/dist/commands/cache/cache-control.d.ts +82 -0
  82. package/dist/commands/cache/cache-control.d.ts.map +1 -0
  83. package/dist/commands/cache/cache-control.js +86 -0
  84. package/dist/commands/cache/cache-control.js.map +1 -0
  85. package/dist/commands/cache/clear.d.ts +105 -0
  86. package/dist/commands/cache/clear.d.ts.map +1 -0
  87. package/dist/commands/cache/clear.js +248 -0
  88. package/dist/commands/cache/clear.js.map +1 -0
  89. package/dist/commands/cache/index.d.ts +18 -0
  90. package/dist/commands/cache/index.d.ts.map +1 -0
  91. package/dist/commands/cache/index.js +94 -0
  92. package/dist/commands/cache/index.js.map +1 -0
  93. package/dist/commands/claude/claude-config.d.ts.map +1 -1
  94. package/dist/commands/claude/claude-config.js +6 -0
  95. package/dist/commands/claude/claude-config.js.map +1 -1
  96. package/dist/commands/claude/context.d.ts +340 -0
  97. package/dist/commands/claude/context.d.ts.map +1 -0
  98. package/dist/commands/claude/context.js +1080 -0
  99. package/dist/commands/claude/context.js.map +1 -0
  100. package/dist/commands/claude/index.d.ts +14 -0
  101. package/dist/commands/claude/index.d.ts.map +1 -1
  102. package/dist/commands/claude/index.js +22 -2
  103. package/dist/commands/claude/index.js.map +1 -1
  104. package/dist/commands/claude/marketplace/changelog-utils.d.ts +1 -1
  105. package/dist/commands/claude/marketplace/changelog-utils.d.ts.map +1 -1
  106. package/dist/commands/claude/marketplace/changelog-utils.js +1 -2
  107. package/dist/commands/claude/marketplace/changelog-utils.js.map +1 -1
  108. package/dist/commands/claude/marketplace/git-publish.d.ts.map +1 -1
  109. package/dist/commands/claude/marketplace/git-publish.js +40 -31
  110. package/dist/commands/claude/marketplace/git-publish.js.map +1 -1
  111. package/dist/commands/claude/marketplace/license-utils.d.ts.map +1 -1
  112. package/dist/commands/claude/marketplace/license-utils.js +0 -1
  113. package/dist/commands/claude/marketplace/license-utils.js.map +1 -1
  114. package/dist/commands/claude/marketplace/publish-tree.d.ts.map +1 -1
  115. package/dist/commands/claude/marketplace/publish-tree.js +0 -6
  116. package/dist/commands/claude/marketplace/publish-tree.js.map +1 -1
  117. package/dist/commands/claude/marketplace/publish.d.ts.map +1 -1
  118. package/dist/commands/claude/marketplace/publish.js +2 -1
  119. package/dist/commands/claude/marketplace/publish.js.map +1 -1
  120. package/dist/commands/claude/marketplace/validate.d.ts +73 -22
  121. package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
  122. package/dist/commands/claude/marketplace/validate.js +407 -72
  123. package/dist/commands/claude/marketplace/validate.js.map +1 -1
  124. package/dist/commands/claude/org/api-keys.d.ts +0 -3
  125. package/dist/commands/claude/org/api-keys.d.ts.map +1 -1
  126. package/dist/commands/claude/org/api-keys.js +2 -1
  127. package/dist/commands/claude/org/api-keys.js.map +1 -1
  128. package/dist/commands/claude/org/helpers.d.ts +54 -1
  129. package/dist/commands/claude/org/helpers.d.ts.map +1 -1
  130. package/dist/commands/claude/org/helpers.js +42 -7
  131. package/dist/commands/claude/org/helpers.js.map +1 -1
  132. package/dist/commands/claude/org/index.d.ts.map +1 -1
  133. package/dist/commands/claude/org/index.js +24 -16
  134. package/dist/commands/claude/org/index.js.map +1 -1
  135. package/dist/commands/claude/org/invites.d.ts +0 -3
  136. package/dist/commands/claude/org/invites.d.ts.map +1 -1
  137. package/dist/commands/claude/org/invites.js +3 -2
  138. package/dist/commands/claude/org/invites.js.map +1 -1
  139. package/dist/commands/claude/org/skills.d.ts +527 -0
  140. package/dist/commands/claude/org/skills.d.ts.map +1 -1
  141. package/dist/commands/claude/org/skills.js +1414 -108
  142. package/dist/commands/claude/org/skills.js.map +1 -1
  143. package/dist/commands/claude/org/users.d.ts +0 -3
  144. package/dist/commands/claude/org/users.d.ts.map +1 -1
  145. package/dist/commands/claude/org/users.js +6 -3
  146. package/dist/commands/claude/org/users.js.map +1 -1
  147. package/dist/commands/claude/org/workspaces.d.ts +0 -3
  148. package/dist/commands/claude/org/workspaces.d.ts.map +1 -1
  149. package/dist/commands/claude/org/workspaces.js +11 -7
  150. package/dist/commands/claude/org/workspaces.js.map +1 -1
  151. package/dist/commands/claude/plugin/build.d.ts +41 -3
  152. package/dist/commands/claude/plugin/build.d.ts.map +1 -1
  153. package/dist/commands/claude/plugin/build.js +147 -80
  154. package/dist/commands/claude/plugin/build.js.map +1 -1
  155. package/dist/commands/claude/plugin/helpers.d.ts.map +1 -1
  156. package/dist/commands/claude/plugin/helpers.js +2 -7
  157. package/dist/commands/claude/plugin/helpers.js.map +1 -1
  158. package/dist/commands/claude/plugin/install.d.ts +12 -0
  159. package/dist/commands/claude/plugin/install.d.ts.map +1 -1
  160. package/dist/commands/claude/plugin/install.js +93 -62
  161. package/dist/commands/claude/plugin/install.js.map +1 -1
  162. package/dist/commands/claude/plugin/list.d.ts.map +1 -1
  163. package/dist/commands/claude/plugin/list.js +3 -2
  164. package/dist/commands/claude/plugin/list.js.map +1 -1
  165. package/dist/commands/claude/plugin/marketplace-json.d.ts +24 -9
  166. package/dist/commands/claude/plugin/marketplace-json.d.ts.map +1 -1
  167. package/dist/commands/claude/plugin/marketplace-json.js +10 -9
  168. package/dist/commands/claude/plugin/marketplace-json.js.map +1 -1
  169. package/dist/commands/claude/plugin/plugin-changelog.d.ts.map +1 -1
  170. package/dist/commands/claude/plugin/plugin-changelog.js +0 -2
  171. package/dist/commands/claude/plugin/plugin-changelog.js.map +1 -1
  172. package/dist/commands/claude/plugin/plugin-files.d.ts.map +1 -1
  173. package/dist/commands/claude/plugin/plugin-files.js +3 -6
  174. package/dist/commands/claude/plugin/plugin-files.js.map +1 -1
  175. package/dist/commands/claude/plugin/plugin-validators.d.ts.map +1 -1
  176. package/dist/commands/claude/plugin/plugin-validators.js +3 -6
  177. package/dist/commands/claude/plugin/plugin-validators.js.map +1 -1
  178. package/dist/commands/claude/plugin/tree-copy.d.ts +73 -0
  179. package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
  180. package/dist/commands/claude/plugin/tree-copy.js +221 -14
  181. package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
  182. package/dist/commands/claude/plugin/uninstall.d.ts.map +1 -1
  183. package/dist/commands/claude/plugin/uninstall.js +4 -4
  184. package/dist/commands/claude/plugin/uninstall.js.map +1 -1
  185. package/dist/commands/consistency-check.d.ts +17 -15
  186. package/dist/commands/consistency-check.d.ts.map +1 -1
  187. package/dist/commands/consistency-check.js +152 -106
  188. package/dist/commands/consistency-check.js.map +1 -1
  189. package/dist/commands/corpus/index.d.ts.map +1 -1
  190. package/dist/commands/corpus/index.js +3 -0
  191. package/dist/commands/corpus/index.js.map +1 -1
  192. package/dist/commands/corpus/report.d.ts +1 -2
  193. package/dist/commands/corpus/report.d.ts.map +1 -1
  194. package/dist/commands/corpus/report.js +1 -3
  195. package/dist/commands/corpus/report.js.map +1 -1
  196. package/dist/commands/corpus/runner.d.ts +58 -1
  197. package/dist/commands/corpus/runner.d.ts.map +1 -1
  198. package/dist/commands/corpus/runner.js +95 -41
  199. package/dist/commands/corpus/runner.js.map +1 -1
  200. package/dist/commands/corpus/scan.d.ts.map +1 -1
  201. package/dist/commands/corpus/scan.js +20 -12
  202. package/dist/commands/corpus/scan.js.map +1 -1
  203. package/dist/commands/corpus/seed.d.ts +4 -4
  204. package/dist/commands/corpus/seed.d.ts.map +1 -1
  205. package/dist/commands/corpus/seed.js +1 -3
  206. package/dist/commands/corpus/seed.js.map +1 -1
  207. package/dist/commands/doctor.d.ts +50 -0
  208. package/dist/commands/doctor.d.ts.map +1 -1
  209. package/dist/commands/doctor.js +245 -52
  210. package/dist/commands/doctor.js.map +1 -1
  211. package/dist/commands/inventory.d.ts +13 -1
  212. package/dist/commands/inventory.d.ts.map +1 -1
  213. package/dist/commands/inventory.js +128 -17
  214. package/dist/commands/inventory.js.map +1 -1
  215. package/dist/commands/mcp/collections.d.ts +1 -1
  216. package/dist/commands/mcp/collections.d.ts.map +1 -1
  217. package/dist/commands/mcp/list-collections.d.ts.map +1 -1
  218. package/dist/commands/mcp/list-collections.js +2 -1
  219. package/dist/commands/mcp/list-collections.js.map +1 -1
  220. package/dist/commands/mcp/serve.d.ts.map +1 -1
  221. package/dist/commands/mcp/serve.js +3 -2
  222. package/dist/commands/mcp/serve.js.map +1 -1
  223. package/dist/commands/okf/index.d.ts +11 -0
  224. package/dist/commands/okf/index.d.ts.map +1 -0
  225. package/dist/commands/okf/index.js +114 -0
  226. package/dist/commands/okf/index.js.map +1 -0
  227. package/dist/commands/okf/validate.d.ts +191 -0
  228. package/dist/commands/okf/validate.d.ts.map +1 -0
  229. package/dist/commands/okf/validate.js +190 -0
  230. package/dist/commands/okf/validate.js.map +1 -0
  231. package/dist/commands/phase-utils.d.ts +182 -114
  232. package/dist/commands/phase-utils.d.ts.map +1 -1
  233. package/dist/commands/phase-utils.js +154 -163
  234. package/dist/commands/phase-utils.js.map +1 -1
  235. package/dist/commands/positional-args.d.ts.map +1 -1
  236. package/dist/commands/positional-args.js +3 -2
  237. package/dist/commands/positional-args.js.map +1 -1
  238. package/dist/commands/rag/clear-command.d.ts.map +1 -1
  239. package/dist/commands/rag/clear-command.js +2 -1
  240. package/dist/commands/rag/clear-command.js.map +1 -1
  241. package/dist/commands/rag/index-command.d.ts +64 -0
  242. package/dist/commands/rag/index-command.d.ts.map +1 -1
  243. package/dist/commands/rag/index-command.js +72 -6
  244. package/dist/commands/rag/index-command.js.map +1 -1
  245. package/dist/commands/rag/index.d.ts.map +1 -1
  246. package/dist/commands/rag/index.js +23 -10
  247. package/dist/commands/rag/index.js.map +1 -1
  248. package/dist/commands/rag/query-command.d.ts.map +1 -1
  249. package/dist/commands/rag/query-command.js +2 -1
  250. package/dist/commands/rag/query-command.js.map +1 -1
  251. package/dist/commands/rag/stats-command.d.ts.map +1 -1
  252. package/dist/commands/rag/stats-command.js +2 -1
  253. package/dist/commands/rag/stats-command.js.map +1 -1
  254. package/dist/commands/resources/builtin-help.d.ts +27 -0
  255. package/dist/commands/resources/builtin-help.d.ts.map +1 -0
  256. package/dist/commands/resources/builtin-help.js +46 -0
  257. package/dist/commands/resources/builtin-help.js.map +1 -0
  258. package/dist/commands/resources/check-progress.d.ts +154 -0
  259. package/dist/commands/resources/check-progress.d.ts.map +1 -0
  260. package/dist/commands/resources/check-progress.js +222 -0
  261. package/dist/commands/resources/check-progress.js.map +1 -0
  262. package/dist/commands/resources/check-supervisor.d.ts +465 -0
  263. package/dist/commands/resources/check-supervisor.d.ts.map +1 -0
  264. package/dist/commands/resources/check-supervisor.js +573 -0
  265. package/dist/commands/resources/check-supervisor.js.map +1 -0
  266. package/dist/commands/resources/check.d.ts +593 -0
  267. package/dist/commands/resources/check.d.ts.map +1 -0
  268. package/dist/commands/resources/check.js +1365 -0
  269. package/dist/commands/resources/check.js.map +1 -0
  270. package/dist/commands/resources/index.d.ts.map +1 -1
  271. package/dist/commands/resources/index.js +425 -6
  272. package/dist/commands/resources/index.js.map +1 -1
  273. package/dist/commands/resources/query.d.ts +106 -0
  274. package/dist/commands/resources/query.d.ts.map +1 -0
  275. package/dist/commands/resources/query.js +177 -0
  276. package/dist/commands/resources/query.js.map +1 -0
  277. package/dist/commands/resources/scan.d.ts +24 -0
  278. package/dist/commands/resources/scan.d.ts.map +1 -1
  279. package/dist/commands/resources/scan.js +17 -8
  280. package/dist/commands/resources/scan.js.map +1 -1
  281. package/dist/commands/resources/validate.d.ts +57 -4
  282. package/dist/commands/resources/validate.d.ts.map +1 -1
  283. package/dist/commands/resources/validate.js +224 -56
  284. package/dist/commands/resources/validate.js.map +1 -1
  285. package/dist/commands/skill/review-checklist.d.ts +3 -2
  286. package/dist/commands/skill/review-checklist.d.ts.map +1 -1
  287. package/dist/commands/skill/review-checklist.js +40 -2
  288. package/dist/commands/skill/review-checklist.js.map +1 -1
  289. package/dist/commands/skill/review.d.ts +247 -0
  290. package/dist/commands/skill/review.d.ts.map +1 -1
  291. package/dist/commands/skill/review.js +99 -62
  292. package/dist/commands/skill/review.js.map +1 -1
  293. package/dist/commands/skill/test/configure.d.ts +56 -0
  294. package/dist/commands/skill/test/configure.d.ts.map +1 -1
  295. package/dist/commands/skill/test/configure.js +75 -16
  296. package/dist/commands/skill/test/configure.js.map +1 -1
  297. package/dist/commands/skill/test/run.d.ts +63 -10
  298. package/dist/commands/skill/test/run.d.ts.map +1 -1
  299. package/dist/commands/skill/test/run.js +258 -77
  300. package/dist/commands/skill/test/run.js.map +1 -1
  301. package/dist/commands/skills/build.d.ts +94 -4
  302. package/dist/commands/skills/build.d.ts.map +1 -1
  303. package/dist/commands/skills/build.js +325 -97
  304. package/dist/commands/skills/build.js.map +1 -1
  305. package/dist/commands/skills/install.d.ts +2 -1
  306. package/dist/commands/skills/install.d.ts.map +1 -1
  307. package/dist/commands/skills/install.js +20 -31
  308. package/dist/commands/skills/install.js.map +1 -1
  309. package/dist/commands/skills/list.d.ts +2 -1
  310. package/dist/commands/skills/list.d.ts.map +1 -1
  311. package/dist/commands/skills/list.js +44 -26
  312. package/dist/commands/skills/list.js.map +1 -1
  313. package/dist/commands/skills/package.d.ts +24 -3
  314. package/dist/commands/skills/package.d.ts.map +1 -1
  315. package/dist/commands/skills/package.js +42 -17
  316. package/dist/commands/skills/package.js.map +1 -1
  317. package/dist/commands/skills/scope-guard.d.ts.map +1 -1
  318. package/dist/commands/skills/scope-guard.js +3 -5
  319. package/dist/commands/skills/scope-guard.js.map +1 -1
  320. package/dist/commands/skills/shared.d.ts.map +1 -1
  321. package/dist/commands/skills/shared.js +2 -4
  322. package/dist/commands/skills/shared.js.map +1 -1
  323. package/dist/commands/skills/skill-discovery.d.ts +47 -6
  324. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  325. package/dist/commands/skills/skill-discovery.js +66 -16
  326. package/dist/commands/skills/skill-discovery.js.map +1 -1
  327. package/dist/commands/skills/source-resolvers.d.ts +15 -0
  328. package/dist/commands/skills/source-resolvers.d.ts.map +1 -1
  329. package/dist/commands/skills/source-resolvers.js +25 -4
  330. package/dist/commands/skills/source-resolvers.js.map +1 -1
  331. package/dist/commands/skills/validate-command.d.ts.map +1 -1
  332. package/dist/commands/skills/validate-command.js +11 -3
  333. package/dist/commands/skills/validate-command.js.map +1 -1
  334. package/dist/commands/skills/validate.d.ts +140 -4
  335. package/dist/commands/skills/validate.d.ts.map +1 -1
  336. package/dist/commands/skills/validate.js +224 -67
  337. package/dist/commands/skills/validate.js.map +1 -1
  338. package/dist/commands/validate.d.ts +1 -1
  339. package/dist/commands/validate.d.ts.map +1 -1
  340. package/dist/commands/validate.js +63 -27
  341. package/dist/commands/validate.js.map +1 -1
  342. package/dist/commands/verify.d.ts +119 -15
  343. package/dist/commands/verify.d.ts.map +1 -1
  344. package/dist/commands/verify.js +357 -142
  345. package/dist/commands/verify.js.map +1 -1
  346. package/dist/index.d.ts +0 -1
  347. package/dist/index.d.ts.map +1 -1
  348. package/dist/index.js +5 -1
  349. package/dist/index.js.map +1 -1
  350. package/dist/report-schemas.d.ts +45 -0
  351. package/dist/report-schemas.d.ts.map +1 -0
  352. package/dist/report-schemas.js +100 -0
  353. package/dist/report-schemas.js.map +1 -0
  354. package/dist/skill-resolution/classify.js +2 -2
  355. package/dist/skill-resolution/classify.js.map +1 -1
  356. package/dist/skill-resolution/packaging-config.d.ts +49 -5
  357. package/dist/skill-resolution/packaging-config.d.ts.map +1 -1
  358. package/dist/skill-resolution/packaging-config.js +59 -19
  359. package/dist/skill-resolution/packaging-config.js.map +1 -1
  360. package/dist/skill-resolution/resolve-skill-reference.d.ts.map +1 -1
  361. package/dist/skill-resolution/resolve-skill-reference.js +55 -57
  362. package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
  363. package/dist/utils/agent-discovery.d.ts.map +1 -1
  364. package/dist/utils/agent-discovery.js +22 -11
  365. package/dist/utils/agent-discovery.js.map +1 -1
  366. package/dist/utils/agent-runner.d.ts.map +1 -1
  367. package/dist/utils/agent-runner.js +7 -4
  368. package/dist/utils/agent-runner.js.map +1 -1
  369. package/dist/utils/claude-context-lens.d.ts +34 -0
  370. package/dist/utils/claude-context-lens.d.ts.map +1 -0
  371. package/dist/utils/claude-context-lens.js +39 -0
  372. package/dist/utils/claude-context-lens.js.map +1 -0
  373. package/dist/utils/command-error.d.ts +144 -7
  374. package/dist/utils/command-error.d.ts.map +1 -1
  375. package/dist/utils/command-error.js +179 -16
  376. package/dist/utils/command-error.js.map +1 -1
  377. package/dist/utils/config-loader.d.ts +2 -1
  378. package/dist/utils/config-loader.d.ts.map +1 -1
  379. package/dist/utils/config-loader.js +40 -14
  380. package/dist/utils/config-loader.js.map +1 -1
  381. package/dist/utils/corpus-target.d.ts +26 -0
  382. package/dist/utils/corpus-target.d.ts.map +1 -0
  383. package/dist/utils/corpus-target.js +35 -0
  384. package/dist/utils/corpus-target.js.map +1 -0
  385. package/dist/utils/edge-lens-evaluation.d.ts +83 -0
  386. package/dist/utils/edge-lens-evaluation.d.ts.map +1 -0
  387. package/dist/utils/edge-lens-evaluation.js +110 -0
  388. package/dist/utils/edge-lens-evaluation.js.map +1 -0
  389. package/dist/utils/help-loader.d.ts.map +1 -1
  390. package/dist/utils/help-loader.js +0 -1
  391. package/dist/utils/help-loader.js.map +1 -1
  392. package/dist/utils/issue-anchor.d.ts +2 -2
  393. package/dist/utils/issue-anchor.d.ts.map +1 -1
  394. package/dist/utils/issue-anchor.js +1 -1
  395. package/dist/utils/issue-rendering.d.ts +3 -3
  396. package/dist/utils/issue-rendering.d.ts.map +1 -1
  397. package/dist/utils/issue-rendering.js +3 -3
  398. package/dist/utils/issue-rendering.js.map +1 -1
  399. package/dist/utils/issue-severity.d.ts +12 -5
  400. package/dist/utils/issue-severity.d.ts.map +1 -1
  401. package/dist/utils/issue-severity.js +1 -1
  402. package/dist/utils/issue-severity.js.map +1 -1
  403. package/dist/utils/optional-backend.d.ts +78 -0
  404. package/dist/utils/optional-backend.d.ts.map +1 -0
  405. package/dist/utils/optional-backend.js +117 -0
  406. package/dist/utils/optional-backend.js.map +1 -0
  407. package/dist/utils/output.d.ts +26 -0
  408. package/dist/utils/output.d.ts.map +1 -1
  409. package/dist/utils/output.js +35 -0
  410. package/dist/utils/output.js.map +1 -1
  411. package/dist/utils/package-json.d.ts +24 -0
  412. package/dist/utils/package-json.d.ts.map +1 -0
  413. package/dist/utils/package-json.js +49 -0
  414. package/dist/utils/package-json.js.map +1 -0
  415. package/dist/utils/population-wiring.d.ts +100 -0
  416. package/dist/utils/population-wiring.d.ts.map +1 -0
  417. package/dist/utils/population-wiring.js +98 -0
  418. package/dist/utils/population-wiring.js.map +1 -0
  419. package/dist/utils/project-root-policy.d.ts +20 -0
  420. package/dist/utils/project-root-policy.d.ts.map +1 -1
  421. package/dist/utils/project-root-policy.js +30 -0
  422. package/dist/utils/project-root-policy.js.map +1 -1
  423. package/dist/utils/projection-lenses.d.ts +98 -0
  424. package/dist/utils/projection-lenses.d.ts.map +1 -0
  425. package/dist/utils/projection-lenses.js +203 -0
  426. package/dist/utils/projection-lenses.js.map +1 -0
  427. package/dist/utils/projection-query.d.ts +324 -0
  428. package/dist/utils/projection-query.d.ts.map +1 -0
  429. package/dist/utils/projection-query.js +357 -0
  430. package/dist/utils/projection-query.js.map +1 -0
  431. package/dist/utils/projection-store.d.ts +335 -0
  432. package/dist/utils/projection-store.d.ts.map +1 -0
  433. package/dist/utils/projection-store.js +522 -0
  434. package/dist/utils/projection-store.js.map +1 -0
  435. package/dist/utils/relation-limits.d.ts +50 -0
  436. package/dist/utils/relation-limits.d.ts.map +1 -0
  437. package/dist/utils/relation-limits.js +50 -0
  438. package/dist/utils/relation-limits.js.map +1 -0
  439. package/dist/utils/repeatable-option.d.ts +37 -0
  440. package/dist/utils/repeatable-option.d.ts.map +1 -0
  441. package/dist/utils/repeatable-option.js +39 -0
  442. package/dist/utils/repeatable-option.js.map +1 -0
  443. package/dist/utils/resource-loader.d.ts +132 -2
  444. package/dist/utils/resource-loader.d.ts.map +1 -1
  445. package/dist/utils/resource-loader.js +288 -27
  446. package/dist/utils/resource-loader.js.map +1 -1
  447. package/dist/utils/root-argv.d.ts +53 -0
  448. package/dist/utils/root-argv.d.ts.map +1 -0
  449. package/dist/utils/root-argv.js +215 -0
  450. package/dist/utils/root-argv.js.map +1 -0
  451. package/dist/utils/run-integrity.d.ts +95 -0
  452. package/dist/utils/run-integrity.d.ts.map +1 -0
  453. package/dist/utils/run-integrity.js +102 -0
  454. package/dist/utils/run-integrity.js.map +1 -0
  455. package/dist/utils/skill-discovery.d.ts.map +1 -1
  456. package/dist/utils/skill-discovery.js +2 -1
  457. package/dist/utils/skill-discovery.js.map +1 -1
  458. package/dist/utils/skill-packaging-config.d.ts +63 -1
  459. package/dist/utils/skill-packaging-config.d.ts.map +1 -1
  460. package/dist/utils/skill-packaging-config.js +56 -1
  461. package/dist/utils/skill-packaging-config.js.map +1 -1
  462. package/dist/utils/sqlite-experimental-warning.d.ts +69 -0
  463. package/dist/utils/sqlite-experimental-warning.d.ts.map +1 -0
  464. package/dist/utils/sqlite-experimental-warning.js +144 -0
  465. package/dist/utils/sqlite-experimental-warning.js.map +1 -0
  466. package/dist/utils/url-redact.d.ts.map +1 -1
  467. package/dist/utils/url-redact.js +4 -6
  468. package/dist/utils/url-redact.js.map +1 -1
  469. package/dist/utils/user-context-scanner.d.ts +8 -0
  470. package/dist/utils/user-context-scanner.d.ts.map +1 -1
  471. package/dist/utils/user-context-scanner.js +4 -2
  472. package/dist/utils/user-context-scanner.js.map +1 -1
  473. package/dist/utils/validate-help-files.d.ts.map +1 -1
  474. package/dist/utils/validate-help-files.js +12 -6
  475. package/dist/utils/validate-help-files.js.map +1 -1
  476. package/dist/utils/vat-bin-path.d.ts +36 -0
  477. package/dist/utils/vat-bin-path.d.ts.map +1 -0
  478. package/dist/utils/vat-bin-path.js +48 -0
  479. package/dist/utils/vat-bin-path.js.map +1 -0
  480. package/dist/utils/verdict-helpers.d.ts +1 -1
  481. package/dist/utils/verdict-helpers.d.ts.map +1 -1
  482. package/dist/utils/verdict-helpers.js +1 -1
  483. package/dist/utils/verdict-helpers.js.map +1 -1
  484. package/dist/version.d.ts.map +1 -1
  485. package/dist/version.js +1 -3
  486. package/dist/version.js.map +1 -1
  487. package/docs/agent.md +2 -2
  488. package/docs/audit.md +141 -37
  489. package/docs/doctor.md +7 -6
  490. package/docs/index.md +40 -12
  491. package/docs/mcp.md +2 -2
  492. package/docs/rag.md +3 -2
  493. package/docs/resources.md +13 -3
  494. package/docs/skill-test.md +10 -9
  495. package/docs/skills.md +53 -69
  496. package/package.json +38 -27
  497. package/schemas/ard-emit.json +149 -0
  498. package/schemas/okf-validate.json +170 -0
  499. package/schemas/resources-check.json +229 -0
  500. package/schemas/skill-review.json +230 -0
  501. package/dist/commands/resources/command-helpers.d.ts +0 -5
  502. package/dist/commands/resources/command-helpers.d.ts.map +0 -1
  503. package/dist/commands/resources/command-helpers.js +0 -6
  504. package/dist/commands/resources/command-helpers.js.map +0 -1
@@ -7,17 +7,21 @@
7
7
  */
8
8
  import { existsSync } from 'node:fs';
9
9
  import { basename, dirname, extname } from 'node:path';
10
- import { BootstrapNeededError, buildStaleDistWarningLines, DuplicateStagedSkillError, isAcknowledged, mapErrorToExitCode, packageSkill, packagingConfigToPackageOptions, runPreStageBuild, runSkillTestHarness, SecurityAckError, SKILL_TEST_BUILTIN_CAPS, SkillBuildError, SkillTestExitCode, } from '@vibe-agent-toolkit/agent-skills';
11
- import { findProjectRoot, resolveAssetReference, safePath, toForwardSlash } from '@vibe-agent-toolkit/utils';
10
+ import { BootstrapNeededError, buildStaleDistWarningLines, DuplicateStagedSkillError, isAcknowledged, conventionalSuiteProbe, packageSkill, packagingConfigToPackageOptions, runPreStageBuild, runSkillTestHarness, SecurityAckError, SKILL_TEST_BUILTIN_CAPS, SkillBuildError, skillTestFailureReason, } from '@vibe-agent-toolkit/agent-skills';
11
+ import { ExitCode } from '@vibe-agent-toolkit/schema';
12
+ import { findProjectRoot, prefixMessageOnce, resolveAssetReference, safePath, toForwardSlashAnyPlatform } from '@vibe-agent-toolkit/utils';
13
+ import { DirectoryListingRefusedError } from '@vibe-agent-toolkit/utils/crawl';
12
14
  import { Command } from 'commander';
13
15
  import { parseSourceSpec } from '../../../skill-resolution/classify.js';
14
16
  import { findDeclaredSkillForPath, findDeclaredSkillForSourceDir, resolveProjectDeclaredEvalSuites, resolveSkillReference, } from '../../../skill-resolution/index.js';
15
17
  import { ConfigLoadError, loadConfig, loadConfigCached } from '../../../utils/config-loader.js';
18
+ import { collectRepeated } from '../../../utils/repeatable-option.js';
19
+ import { isSkillPublished } from '../../../utils/skill-packaging-config.js';
16
20
  import { runClaudePluginBuild } from '../../claude/plugin/build.js';
17
21
  import { assertValidAuth, assertValidRequireAuth } from './auth-flags.js';
18
22
  /** Extract the trailing path segment (cross-platform) from a path-like string. */
19
23
  function lastPathSegment(p) {
20
- return basename(toForwardSlash(p));
24
+ return basename(toForwardSlashAnyPlatform(p));
21
25
  }
22
26
  // ---------------------------------------------------------------------------
23
27
  // Security warning (§12)
@@ -82,20 +86,28 @@ function coerceKnobs(options) {
82
86
  }
83
87
  /**
84
88
  * Map a resolved skill's packaging-config `executables` (SkillExecutableEntry[]) to
85
- * the grader's recognition-aid shape (issue #145 Phase T): each entry's stable NAME
89
+ * the grader's recognition-aid shape: each entry's stable NAME
86
90
  * is its `path` basename with the extension stripped (`scripts/csvsum.py` → `csvsum`),
87
- * carried alongside its `howInvoked` + `kind`. Returns undefined for absent/empty
88
- * input so the harness omits the aid entirely (the grader still matches tools by the
89
- * commands in the transcript). Pure + unit-testable.
91
+ * carried alongside its `howInvoked`, `kind` and the declared `path` itself. Returns
92
+ * undefined for absent/empty input so the harness omits the aid entirely (the grader
93
+ * still matches tools by the commands in the transcript). Pure + unit-testable.
94
+ *
95
+ * ⛔ THE `path` USED TO BE READ AND DISCARDED. It is the ONLY thing that separates
96
+ * an ambient copy of the skill — which is a copy, so it reproduces
97
+ * `…/scripts/csvsum.py` under whatever root it sits at — from the control arm's own
98
+ * scratch file of the same name. Forward-slashed at the derivation rather than at the
99
+ * consumer, because every needle and every resolved reach inside the detector is
100
+ * `/`-normalized and a `\` would silently match nothing.
90
101
  */
91
102
  export function deriveDeclaredExecutableNames(executables) {
92
103
  if (executables === undefined || executables.length === 0)
93
104
  return undefined;
94
105
  return executables.map((e) => {
95
- const base = basename(toForwardSlash(e.path));
106
+ const path = toForwardSlashAnyPlatform(e.path);
107
+ const base = basename(path);
96
108
  const ext = extname(base);
97
109
  const name = ext === '' ? base : base.slice(0, -ext.length);
98
- return { name, howInvoked: e.howInvoked, kind: e.kind };
110
+ return { name, howInvoked: e.howInvoked, kind: e.kind, path };
99
111
  });
100
112
  }
101
113
  /**
@@ -126,7 +138,7 @@ export function parseWithFlags(pairs) {
126
138
  for (const pair of pairs) {
127
139
  const [name, spec] = parseWithPair(pair);
128
140
  // Fail closed on a repeated companion name rather than silently overwriting
129
- // (last-wins would drop a companion the user asked for — the #153 no-op class).
141
+ // (last-wins would drop a companion the user asked for — a silent no-op).
130
142
  if (Object.hasOwn(record, name))
131
143
  throw new DuplicateStagedSkillError(name);
132
144
  record[name] = spec;
@@ -153,8 +165,8 @@ export function descriptorsToRecord(list) {
153
165
  for (const d of list) {
154
166
  const name = descriptorName(d);
155
167
  // Two config descriptors deriving the same name (e.g. two `path:` entries with
156
- // the same basename) would silently overwrite — the exact silent-drop #153
157
- // targets, one layer above buildStageItems. Fail closed here instead.
168
+ // the same basename) would silently overwrite — the exact silent drop
169
+ // buildStageItems refuses, one layer above it. Fail closed here instead.
158
170
  if (Object.hasOwn(record, name))
159
171
  throw new DuplicateStagedSkillError(name);
160
172
  record[name] = d;
@@ -233,7 +245,7 @@ function resolveRepoRoot() {
233
245
  * {@link loadTestConfig}, which reads the PER-SKILL `skills.config.<skill>.test`
234
246
  * block: graderModel/concurrency are global judge/pipeline settings that apply
235
247
  * across every skill's test run, not something a single skill's config should
236
- * override (issue #145).
248
+ * override.
237
249
  *
238
250
  * Undefined when there's no project root or no `test:` node. A broken config
239
251
  * throws {@link ConfigLoadError}, propagated the same way as loadTestConfig's
@@ -272,7 +284,7 @@ function applyScalarMerges(opts, options, config) {
272
284
  const authRequirement = options.requireAuth ?? config?.requireAuth;
273
285
  if (authRequirement !== undefined)
274
286
  opts.requireAuth = authRequirement;
275
- const baseline = options.baseline ?? config?.baseline;
287
+ const baseline = resolveBaseline(options.baseline, config?.baseline);
276
288
  if (baseline !== undefined)
277
289
  opts.baseline = baseline;
278
290
  const model = options.model ?? config?.model;
@@ -287,6 +299,36 @@ function applyScalarMerges(opts, options, config) {
287
299
  if (evalsRef !== undefined)
288
300
  opts.evalsSubpath = evalsRef;
289
301
  }
302
+ /**
303
+ * Resolve `--baseline` with flag > config precedence, ANNOUNCING a config-sourced
304
+ * enable on stderr.
305
+ *
306
+ * Same threat model as {@link resolveCappedKnob} next door — a value from a
307
+ * COMMITTED config rides along in an untrusted subject repo — applied to the one
308
+ * cost knob that has no cap to clamp. `baseline` is the LARGEST cost multiplier in
309
+ * this command: it runs every eval TWICE (skill declared vs withheld), and each arm
310
+ * is an executor spawn AND a grader spawn, so `skills.config.<skill>.test.baseline:
311
+ * true` roughly doubles the spend of every `vat skill test run` an operator types.
312
+ * `--max-budget-usd` is a PER-SPAWN cap, so the worst-case ceiling doubles with it.
313
+ *
314
+ * A boolean cannot be clamped to a ceiling, so it is announced instead, and
315
+ * `--no-baseline` exists so the operator can turn it back off for THIS run without
316
+ * hand-editing someone else's YAML. Precedence runs both directions: an explicit
317
+ * flag wins whether it says true or false (hence the `undefined` check rather than
318
+ * `??`-style falsiness, which would let a config `true` override `--no-baseline`).
319
+ *
320
+ * Only an ENABLE is announced. A config `false` costs nothing and needs no note.
321
+ */
322
+ export function resolveBaseline(flagValue, configValue) {
323
+ if (flagValue !== undefined)
324
+ return flagValue;
325
+ if (configValue !== true)
326
+ return configValue;
327
+ process.stderr.write("Note: baseline is ON from this project's committed config ('skills.config.<skill>.test.baseline'), " +
328
+ 'not from a flag; it runs every eval TWICE (an executor AND a grader spawn per arm), roughly doubling ' +
329
+ 'the spawns and the spend. Pass --no-baseline to turn it off for this run.\n');
330
+ return true;
331
+ }
290
332
  /**
291
333
  * Resolve one cost/runtime knob with flag > config > default precedence AND a
292
334
  * built-in safety cap, enforcing an asymmetry between the two sources:
@@ -401,15 +443,16 @@ function applyGraderMerges(opts, options, knobs, globalTest) {
401
443
  * precedence. CLI flags win; config (`skills.config.<skill>.test`) fills gaps;
402
444
  * built-in defaults (inside the domain) are the final fallback.
403
445
  */
404
- function buildHarnessOpts(subject, options, knobs, config, globalTest) {
446
+ function buildHarnessOpts(subject, options, knobs, config, globalTest, resolvedSubject) {
405
447
  const repoRoot = resolveRepoRoot();
406
- const opts = { subject, repoRoot };
448
+ const opts = { subject, repoRoot, subjectInPlace: resolvedSubject.inPlace };
407
449
  applyFlagOnlyOptions(opts, options);
408
450
  applyScalarMerges(opts, options, config);
409
451
  applyKnobMerges(opts, knobs, config);
410
452
  applyDepMerges(opts, options, config);
411
453
  applyEnvMerges(opts, options, config);
412
454
  applyGraderMerges(opts, options, knobs, globalTest);
455
+ applyResolvedSubject(opts, resolvedSubject);
413
456
  return opts;
414
457
  }
415
458
  /**
@@ -432,7 +475,7 @@ function sourceScaffoldFields(source, declaredSkill, cwd) {
432
475
  * Project-aware subject resolution for `vat skill test run`. Resolves the subject
433
476
  * reference; for a declared skill, builds it (real entry points) and returns the
434
477
  * dist dir to stage; everything else is staged as-is. Throws SkillBuildError
435
- * (exit 2) for name-miss / not-found / --no-build-without-dist / build failure.
478
+ * (reason `preflight`) for name-miss / not-found / --no-build-without-dist / build failure.
436
479
  *
437
480
  * `memo` is the per-run build memo (see {@link BuildMemo}) — pass the SAME map used
438
481
  * for companion resolution so a skill that is both subject and companion builds once.
@@ -449,6 +492,7 @@ export async function resolveSubjectForTest(ref, cwd, flags, memo, buildCommand)
449
492
  return {
450
493
  subjectSource: resolved.source,
451
494
  rebuilt: false,
495
+ inPlace: false,
452
496
  wouldBuild: false,
453
497
  ...sourceScaffoldFields(resolved.source, resolved.declaredSkill, cwd),
454
498
  };
@@ -466,6 +510,16 @@ export async function resolveSubjectForTest(ref, cwd, flags, memo, buildCommand)
466
510
  }
467
511
  }
468
512
  }
513
+ /**
514
+ * An IN-PLACE declared skill: a POOL skill whose merged config says `publish: false`.
515
+ * `vat build` never bundles it (see `isSkillPublished`), so a test must not invent the
516
+ * bundle either — it stages the authored directory, which is what is used in place. A
517
+ * plugin-local skill is never in-place: `publish` scopes the pool only, and it ships
518
+ * with its plugin whatever the flag says.
519
+ */
520
+ function isInPlaceSkill(ref) {
521
+ return ref.distribution.kind === 'pool' && !isSkillPublished(ref.packagingConfig);
522
+ }
469
523
  /**
470
524
  * --no-build / --dry-run branch of {@link buildDeclaredSkill}: never builds. Stage
471
525
  * the existing dist if present; for a dry-run with no dist yet, fall back to the
@@ -473,7 +527,6 @@ export async function resolveSubjectForTest(ref, cwd, flags, memo, buildCommand)
473
527
  * when --no-build is set but no dist exists.
474
528
  */
475
529
  function resolveExistingDistOrThrow(ref, flags) {
476
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- expectedDistDir derived from project config
477
530
  if (existsSync(ref.expectedDistDir)) {
478
531
  if (flags.noBuild) {
479
532
  process.stderr.write(`Using existing dist (NOT rebuilt): ${ref.expectedDistDir}\n`);
@@ -513,7 +566,7 @@ export function buildMemoKey(ref) {
513
566
  * writes nothing (or writes an empty shell with no `SKILL.md`) would otherwise hand
514
567
  * back a path a required companion then fails opaquely at staging, or an OPTIONAL
515
568
  * one silently skips — the exact non-functional-companion-with-no-diagnostic
516
- * symptom of issue #158. Two distinct checks, two distinct messages, so the error
569
+ * symptom adopters reported. Two distinct checks, two distinct messages, so the error
517
570
  * tells the author which failure mode they hit:
518
571
  * 1. `expectedDistDir` itself is missing — "no output at all".
519
572
  * 2. `expectedDistDir` exists but has no `SKILL.md` — an empty/incomplete shell.
@@ -523,13 +576,11 @@ export function buildMemoKey(ref) {
523
576
  * and is always checked.
524
577
  */
525
578
  function verifyBuiltDist(ref) {
526
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- expectedDistDir derived from project config
527
579
  if (!existsSync(ref.expectedDistDir)) {
528
580
  throw new SkillBuildError(`Skill build for '${ref.name}' reported success but produced no output at ${ref.expectedDistDir}. ` +
529
581
  `Check the skill's packaging config (\`vat build\` should create this directory).`);
530
582
  }
531
583
  const skillMdPath = safePath.join(ref.expectedDistDir, 'SKILL.md');
532
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- skillMdPath derived from project config
533
584
  if (!existsSync(skillMdPath)) {
534
585
  throw new SkillBuildError(`Skill build for '${ref.name}' reported success but produced no SKILL.md at ${ref.expectedDistDir}. ` +
535
586
  `Check the skill's packaging config (\`vat build\` should create this file).`);
@@ -580,7 +631,20 @@ async function runDeclaredSkillBuild(ref) {
580
631
  // excludes every skill's test input. Getting this wrong would hand the executor
581
632
  // under test another skill's answer key — the exact signal the harness exists to
582
633
  // protect. Memoized per config root, so a multi-skill run discovers once.
583
- await packageSkill(ref.sourcePath, packagingConfigToPackageOptions(ref.packagingConfig, { skillPath: ref.sourcePath, outputPath: ref.expectedDistDir }, await resolveProjectDeclaredEvalSuites(ref.sourcePath)));
634
+ await packageSkill(ref.sourcePath, packagingConfigToPackageOptions(ref.packagingConfig, { skillPath: ref.sourcePath, outputPath: ref.expectedDistDir },
635
+ // `'refuse'`: staging a dist around a directory discovery could not
636
+ // list may hand the executor another skill's answer key. The throw is
637
+ // wrapped as `SkillBuildError` by the caller, message intact.
638
+ await resolveProjectDeclaredEvalSuites(ref.sourcePath, 'refuse'),
639
+ // Per CALL, deliberately, and this is parity rather than a regression: the
640
+ // probe was built inside `resolveTestInputDirs` on every path before it was
641
+ // threaded, so this lane pays exactly what it paid before. It is also the
642
+ // wrong lane to optimize — `runDeclaredSkillBuild` runs per buildable ref for
643
+ // a test run's handful of skills, not over a whole project, and there is no
644
+ // run-scoped seam threaded this far down to hang one on. The lane that made
645
+ // the O(S²) matter (`vat resources validate`, measured at 10,815 probes over
646
+ // 103 paths) hoists its probe; see the comment there.
647
+ conventionalSuiteProbe()));
584
648
  return;
585
649
  }
586
650
  await runClaudePluginBuild(ref.configRoot, { marketplace: ref.distribution.marketplaceName });
@@ -590,7 +654,7 @@ async function runDeclaredSkillBuild(ref) {
590
654
  * the existing dist under --no-build/--dry-run. Shared by SUBJECT resolution
591
655
  * ({@link resolveBuildableSubject}) and `--with`/`--with-optional` COMPANION
592
656
  * resolution ({@link resolveCompanionSpec}) so a companion that maps to a declared
593
- * skill gets the exact same build treatment as the subject (issue #158) — its
657
+ * skill gets the exact same build treatment as the subject — its
594
658
  * `files:` injection runs before staging, instead of a raw, possibly
595
659
  * build-artifact-incomplete, source-tree copy.
596
660
  *
@@ -619,8 +683,11 @@ async function buildDeclaredSkill(ref, flags, memo, buildCommand) {
619
683
  // dry run stays the one mode that is safe to point at an untrusted clone. That
620
684
  // preview falls back to an existing dist and says so (stale warning) — the honest
621
685
  // trade, since accuracy requires consent to execute the repo's own build.
686
+ // An in-place skill has no dist to reuse or build: its authored directory IS what
687
+ // ships (in place), under every flag combination.
688
+ const inPlaceResult = { distDir: dirname(ref.sourcePath), rebuilt: false };
622
689
  if (flags.noBuild || (flags.dryRun && !flags.explicitAck)) {
623
- return resolveExistingDistOrThrow(ref, flags);
690
+ return isInPlaceSkill(ref) ? inPlaceResult : resolveExistingDistOrThrow(ref, flags);
624
691
  }
625
692
  // SECURITY (§12): reaching here means a real build WOULD run — runPreStageBuild
626
693
  // executes an ARBITRARY shell command from the repo's committed `test.build`, and
@@ -630,6 +697,12 @@ async function buildDeclaredSkill(ref, flags, memo, buildCommand) {
630
697
  if (!flags.acknowledged) {
631
698
  throw new SecurityAckError();
632
699
  }
700
+ // The `test.build` hook still runs for an in-place skill — it prepares what the
701
+ // test needs (the declared contract: once, before staging) — but nothing is bundled.
702
+ if (isInPlaceSkill(ref)) {
703
+ runPreStageBuildOnce(buildCommand, ref.configRoot, memo);
704
+ return inPlaceResult;
705
+ }
633
706
  const key = buildMemoKey(ref);
634
707
  // Memo HIT: this operation already ran in THIS process — skip the rebuild, but
635
708
  // still verify this ref's own dist (the hit may be a marketplace sibling's).
@@ -660,10 +733,22 @@ async function buildDeclaredSkill(ref, flags, memo, buildCommand) {
660
733
  async function resolveBuildableSubject(ref, flags, memo, buildCommand) {
661
734
  const scaffoldDir = dirname(ref.sourcePath);
662
735
  const build = await buildDeclaredSkill(ref, flags, memo, buildCommand);
736
+ if (isInPlaceSkill(ref)) {
737
+ // Staged as-is from source, but still the declared skill: its `test:` config applies.
738
+ return {
739
+ subjectSource: { path: build.distDir },
740
+ subjectScaffoldDir: scaffoldDir,
741
+ rebuilt: false,
742
+ inPlace: true,
743
+ wouldBuild: false,
744
+ linkedToDeclaredSkill: true,
745
+ };
746
+ }
663
747
  return {
664
748
  subjectSource: { path: build.distDir },
665
749
  subjectScaffoldDir: scaffoldDir,
666
750
  rebuilt: build.rebuilt,
751
+ inPlace: false,
667
752
  wouldBuild: true,
668
753
  ...(build.dryRunStagedExistingDist === undefined
669
754
  ? {}
@@ -713,11 +798,12 @@ function isSurvivableCompanionFailure(err, declared, optional, flags) {
713
798
  * with several companions leaves the user unable to tell which flag to fix.
714
799
  *
715
800
  * The message is prefixed IN PLACE so the error's CLASS (and therefore its
716
- * `exitCode` / {@link mapErrorToExitCode} mapping) is unchanged — no new error class,
717
- * no re-wrapping. Prefixing is skipped when the message is ALREADY prefixed (starts
718
- * with `companion '`) — this makes the function idempotent against repeat rethrows of
719
- * the SAME error object, structurally, rather than relying on a hand-maintained
720
- * argument that no caught error class is ever cached/reused across companions.
801
+ * `reason` / {@link skillTestFailureReason} mapping) is unchanged — no new error class,
802
+ * no re-wrapping. Prefixing happens ONCE per error object (`prefixMessageOnce`
803
+ * remembers the object, never re-reads the message) — this makes the function
804
+ * idempotent against repeat rethrows of the SAME error object, structurally, rather
805
+ * than relying on a hand-maintained argument that no caught error class is ever
806
+ * cached/reused across companions.
721
807
  * {@link ConfigLoadError} instances ARE cached and re-thrown per config root by
722
808
  * `loadConfigCached`, so mutating one in place would otherwise corrupt the cache; the
723
809
  * already-prefixed check covers this case too (in practice `ConfigLoadError` is
@@ -728,18 +814,16 @@ function isSurvivableCompanionFailure(err, declared, optional, flags) {
728
814
  * Debug output that prints `.stack` can disagree with the prefixed text on stderr.
729
815
  */
730
816
  function rethrowNamingCompanion(err, alias, declaredName) {
731
- if (err instanceof Error && !err.message.startsWith("companion '")) {
732
- err.message = `companion '${alias}' (declared skill '${declaredName}'): ${err.message}`;
733
- }
817
+ prefixMessageOnce(err, `companion '${alias}' (declared skill '${declaredName}'): `);
734
818
  throw err;
735
819
  }
736
820
  /**
737
- * Companion analog of {@link resolveBuildableSubject} (issue #158): resolve every
821
+ * Companion analog of {@link resolveBuildableSubject}: resolve every
738
822
  * `--with`/`--with-optional` companion whose spec is a `{ path }` pointing at a
739
823
  * declared skill's SOURCE directory to that skill's BUILT dist, via the exact same
740
824
  * {@link buildDeclaredSkill} the subject uses. Anything else — workspace:/npm:/
741
- * url:/vendored specs, or a path outside this project's config — is "a different
742
- * story" (per the issue's own framing): left untouched, staged as today.
825
+ * url:/vendored specs, or a path outside this project's config — is a different
826
+ * story: left untouched, staged as today.
743
827
  *
744
828
  * The `test.build` hook used is the COMPANION's own — read from the config that
745
829
  * governs IT ({@link declaredSkillTestConfig}), not the subject's. The subject's hook
@@ -821,7 +905,7 @@ function warnIfPathTargetBypassesConfig(subject) {
821
905
  /**
822
906
  * Validate usage-level flags (auth values, numeric knobs) and load the subject's
823
907
  * persisted test config. Runs before the async harness work, so a bad flag exits
824
- * with a clean message + preflight code (2) instead of surfacing as an unhandled
908
+ * with a clean message + `Reason: preflight` instead of surfacing as an unhandled
825
909
  * promise rejection (raw stack trace, exit 1).
826
910
  */
827
911
  async function preflightKnobsAndConfig(subject, options, cwd) {
@@ -836,21 +920,49 @@ async function preflightKnobsAndConfig(subject, options, cwd) {
836
920
  }
837
921
  catch (err) {
838
922
  process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
839
- process.exit(SkillTestExitCode.Preflight);
923
+ exitWithReason('preflight');
840
924
  }
841
925
  }
842
926
  /**
843
- * Exit code for an error escaping EITHER phase of {@link runSkillTestRun}.
927
+ * End the run on `ERROR`, saying WHY on stderr.
928
+ *
929
+ * The reason used to be three exit codes (1 internal, 2 preflight, 3
930
+ * bootstrap). Under the one exit-code contract every verb shares, every way the
931
+ * harness could not run is `ERROR`, and the `Reason:` line is where a CI
932
+ * author reads "harness broke" apart from "my environment is wrong".
933
+ */
934
+ function exitWithReason(reason) {
935
+ process.stderr.write(`Reason: ${reason}\n`);
936
+ process.exit(ExitCode.ERROR);
937
+ }
938
+ /**
939
+ * End the run on the harness's own verdict: the `Summary:` line on stdout (the
940
+ * one channel kept machine-readable), the `Reason:` line on stderr when the
941
+ * harness could not run, and the exit code the harness decided.
942
+ */
943
+ function exitWithResult(result) {
944
+ process.stdout.write(`Summary: ${result.summary}\n`);
945
+ if (result.reason !== undefined)
946
+ process.stderr.write(`Reason: ${result.reason}\n`);
947
+ process.exit(result.exitCode);
948
+ }
949
+ /**
950
+ * The reason for an error escaping EITHER phase of {@link runSkillTestRun}.
844
951
  *
845
952
  * A broken governing config ({@link ConfigLoadError}) is a user-fixable PREFLIGHT
846
- * problem (exit 2), not an internal harness failure — {@link mapErrorToExitCode} has
847
- * no case for it and falls through to Internal (1). ONE helper shared by BOTH catch
953
+ * problem, not an internal harness failure — {@link skillTestFailureReason} has
954
+ * no case for it and falls through to `internal`. ONE helper shared by BOTH catch
848
955
  * blocks so the SUBJECT arm and the COMPANION arm can never drift: a companion's
849
956
  * governing config root can differ from the subject's, so a broken config is
850
- * reachable from either arm and must report the same code from both.
957
+ * reachable from either arm and must report the same reason from both.
851
958
  */
852
- function exitCodeForRunError(err) {
853
- return err instanceof ConfigLoadError ? SkillTestExitCode.Preflight : mapErrorToExitCode(err);
959
+ function reasonForRunError(err) {
960
+ // A directory the governing `skills.include` reaches and the crawl cannot list
961
+ // is the same class: discovery refuses it by name, and the remedy is `chmod` or
962
+ // a narrower include pattern — the operator's, not the harness's.
963
+ return err instanceof ConfigLoadError || err instanceof DirectoryListingRefusedError
964
+ ? 'preflight'
965
+ : skillTestFailureReason(err);
854
966
  }
855
967
  /**
856
968
  * Copy the resolved-subject fields onto the harness options. Optional fields are
@@ -892,7 +1004,7 @@ export async function runSkillTestRun(subject, options) {
892
1004
  dryRun: options.dryRun === true,
893
1005
  acknowledgedRunsSkillCode: options.iUnderstandThisRunsSkillCode === true,
894
1006
  });
895
- // Shared by subject AND companion resolution (issue #158) so a --with/--with-optional
1007
+ // Shared by subject AND companion resolution so a --with/--with-optional
896
1008
  // companion that maps to a declared skill gets the exact same build GATING (no-build/
897
1009
  // dry-run/security-ack) as the subject. The `test.build` hook is deliberately NOT in
898
1010
  // here: it is per-skill (see BuildFlags), so the subject's own command is passed only
@@ -913,20 +1025,19 @@ export async function runSkillTestRun(subject, options) {
913
1025
  }
914
1026
  catch (err) {
915
1027
  // A broken governing config surfacing during subject resolution is a preflight
916
- // problem the user must fix (exit 2), not an internal harness failure (exit 1).
917
- const exitCode = exitCodeForRunError(err);
1028
+ // problem the user must fix, not an internal harness failure.
918
1029
  process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
919
- process.exit(exitCode);
1030
+ // 🪤 `return` after a `never`: under test `process.exit` is a spy that RETURNS.
1031
+ exitWithReason(reasonForRunError(err));
920
1032
  return;
921
1033
  }
922
1034
  warnIfPathTargetBypassesConfig(resolvedSubject);
923
1035
  try {
924
1036
  // buildHarnessOpts assembles the companion records (--with/--with-optional and
925
1037
  // config with:/optional:) and can throw DuplicateStagedSkillError on a repeated
926
- // name — inside the try so it maps to exit 2 like every other preflight error.
927
- const harnessOpts = buildHarnessOpts(subject, options, knobs, config, globalTest);
928
- applyResolvedSubject(harnessOpts, resolvedSubject);
929
- // Companion build resolution (issue #158): a --with/--with-optional companion
1038
+ // name — inside the try so it reads as preflight like every other preflight error.
1039
+ const harnessOpts = buildHarnessOpts(subject, options, knobs, config, globalTest, resolvedSubject);
1040
+ // Companion build resolution: a --with/--with-optional companion
930
1041
  // whose source is a path into a declared skill gets built (its `files:`
931
1042
  // injection runs) exactly like the subject, instead of a raw source-tree copy.
932
1043
  const repoRoot = resolveRepoRoot();
@@ -937,25 +1048,56 @@ export async function runSkillTestRun(subject, options) {
937
1048
  if (withOptional !== undefined)
938
1049
  harnessOpts.withOptional = withOptional;
939
1050
  const result = await runSkillTestHarness(harnessOpts);
940
- process.stderr.write(`Harness: ${result.harnessPath}\n`);
941
- process.stdout.write(`Summary: ${result.summary}\n`);
942
- process.exit(result.exitCode);
1051
+ // Same rule as the `Workspaces:` line below — "a populated value is a promise
1052
+ // that the path is still there" — applied to the sibling it was written next to
1053
+ // and not applied to. Harness cleanup runs inside the harness's own `finally`,
1054
+ // BEFORE this result reaches the CLI: a run that returns before Step 7 creates
1055
+ // `results/` (the §12 security-ack refusal, and the preflight-failure branch
1056
+ // reachable from a `--require-auth` mismatch) leaves the harness root with no
1057
+ // `results/` child, and cleanup removes the ROOT outright. Printing the path
1058
+ // anyway hands the operator a directory that no longer exists.
1059
+ //
1060
+ // Asked of the PATH rather than re-derived from --keep/--out/--workdir on
1061
+ // purpose: the retention rule has ONE author (cleanupHarness), and a second copy
1062
+ // of its predicate here would drift from it. The filesystem cannot.
1063
+ if (existsSync(result.harnessPath)) {
1064
+ process.stderr.write(`Harness: ${result.harnessPath}\n`);
1065
+ }
1066
+ // The artifacts this command's help text tells the operator to read
1067
+ // (grading.json / friction.json / baseline.json). Reported separately from the
1068
+ // harness path because on a default run — no --out, no --workdir, no --keep —
1069
+ // results/ is the ONLY thing left under it: everything else is staged untrusted
1070
+ // bytes that cleanup evicts. Pointing at the harness root alone made the
1071
+ // operator guess which of its children still existed.
1072
+ if (result.resultsPath !== undefined) {
1073
+ process.stderr.write(`Results: ${result.resultsPath}\n`);
1074
+ }
1075
+ // The executor's working directories live OUTSIDE the harness root under an
1076
+ // unguessable token, so the harness path no longer leads an operator to them.
1077
+ // Under --keep they survive holding everything the evals produced; unreported,
1078
+ // they would be an orphan the operator cannot find to inspect or reap. On every
1079
+ // other run cleanup deletes them, and the harness answers with no
1080
+ // `workspacesPath` at all — the retention rule has ONE author, over there, so
1081
+ // this stays a plain presence check and never a second copy of it.
1082
+ if (result.workspacesPath !== undefined) {
1083
+ process.stderr.write(`Workspaces: ${result.workspacesPath}\n`);
1084
+ }
1085
+ exitWithResult(result);
943
1086
  return;
944
1087
  }
945
1088
  catch (err) {
946
- // Same rule as the subject arm above (see {@link exitCodeForRunError}): companion
1089
+ // Same rule as the subject arm above (see {@link reasonForRunError}): companion
947
1090
  // resolution can surface a ConfigLoadError from a DIFFERENT config root than the
948
- // subject's, and that must exit 2 (preflight), not 1 (internal).
949
- const exitCode = exitCodeForRunError(err);
950
- // BootstrapNeededError (exit 3) is the happy "wrote a template, fill it in
951
- // and re-run" path — surface its message plainly, not as a hard `Error:`.
1091
+ // subject's, and that must read as preflight, not internal.
1092
+ // BootstrapNeededError is the happy "wrote a template, fill it in and
1093
+ // re-run" path — surface its message plainly, not as a hard `Error:`.
952
1094
  if (err instanceof BootstrapNeededError) {
953
1095
  process.stderr.write(`${err.message}\n`);
954
1096
  }
955
1097
  else {
956
1098
  process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
957
1099
  }
958
- process.exit(exitCode);
1100
+ exitWithReason(reasonForRunError(err));
959
1101
  return;
960
1102
  }
961
1103
  }
@@ -967,11 +1109,15 @@ export function createSkillTestRunCommand() {
967
1109
  command
968
1110
  .description('Execute a packaged skill\'s eval suite in a headless, context-isolated Claude session (runs the skill\'s code; not an OS sandbox)')
969
1111
  .argument('<skill>', 'The skill to test')
970
- .option('--with <pair...>', 'Stage a REQUIRED companion skill the subject can invoke, as name=<src> (repeatable). <src> is workspace:<pkg> | npm:<spec> | url:<u> | path:<dir> | vendored (e.g. helper=npm:@scope/s@1.2.3). A path:<dir> that maps to a declared skill is BUILT like the subject (files: build artifacts included), not tree-copied as raw source. The run fails if a source cannot be resolved or its build fails.')
971
- .option('--with-optional <pair...>', 'Stage an OPTIONAL companion skill, as name=<src> (same syntax, repeatable). Staged from its raw (unbuilt) source with a warning if its source cannot be resolved, or if a non-destructive build fails; the run continues.')
972
- .option('--env <pair...>', 'Inject an env var into the executor spawn as KEY=VALUE (repeatable). Values support ${fixturesDir}, ${stagedSkillDir}, ${harnessRoot}, ${resultsDir}. ${fixturesDir} is per-eval and requires that eval to declare input `files`. CLI overrides config for the same key.')
973
- .option('--pass-env <key...>', 'Forward a host env var by NAME to the executor spawn if present (repeatable). Protected names (PATH, auth, model) are ignored.')
974
- .option('--refresh', 'Force a full re-stage (ignore existing staged content)')
1112
+ // All four are repeatable single-value options, NOT variadic. A variadic
1113
+ // option consumes every token up to the next flag, so it ate the `<skill>`
1114
+ // positional and the run died reporting the subject missing. See
1115
+ // collectRepeated. Their help text always said "(repeatable)"; now it is true.
1116
+ .option('--with <pair>', 'Stage a REQUIRED companion skill the subject can invoke, as name=<src> (repeatable). <src> is workspace:<pkg> | npm:<spec> | url:<u> | path:<dir> | vendored (e.g. helper=npm:@scope/s@1.2.3). A path:<dir> that maps to a declared skill is BUILT like the subject (files: build artifacts included), not tree-copied as raw source. The run fails if a source cannot be resolved or its build fails.', collectRepeated)
1117
+ .option('--with-optional <pair>', 'Stage an OPTIONAL companion skill, as name=<src> (same syntax, repeatable). Staged from its raw (unbuilt) source with a warning if its source cannot be resolved, or if a non-destructive build fails; the run continues.', collectRepeated)
1118
+ .option('--env <pair>', 'Inject an env var into the executor spawn as KEY=VALUE (repeatable). Values support ${fixturesDir}, ${stagedSkillDir}, ${harnessRoot}, ${resultsDir}. ${fixturesDir} is per-eval and requires that eval to declare input `files`. CLI overrides config for the same key.', collectRepeated)
1119
+ .option('--pass-env <key>', 'Forward a host env var by NAME to the executor spawn if present (repeatable). Protected names (PATH, auth, model) are ignored.', collectRepeated)
1120
+ .option('--refresh', 'No-op today, accepted for forward compatibility: staging already does a full re-stage on every run, so there is no retained staged content for this flag to ignore. Nothing reads it — passing it changes nothing.')
975
1121
  .option('--no-build', 'Skip building declared skills (subject and any --with/--with-optional companion); stage existing dist instead. Errors if absent for the subject or a REQUIRED companion; an OPTIONAL companion falls back to raw source with a warning.')
976
1122
  .option('--workdir <dir>', 'Override the harness working directory')
977
1123
  .option('--out <dir>', 'Override the harness output directory')
@@ -979,15 +1125,19 @@ export function createSkillTestRunCommand() {
979
1125
  .option('--dry-run', 'Build and stage exactly as a real run would, then stop without spawning Claude (no tokens spent). Combine with --no-build to skip the build too.')
980
1126
  .option('--auth <mode>', 'Auth mechanism: inherit | subscription | api-key | auto')
981
1127
  .option('--require-auth <mech>', 'Require a specific auth mechanism: subscription | api-key')
982
- .option('--baseline', 'Enable A/B baseline run (with/without skill)')
983
- .option('--allow-eval-failure', 'Opt out of the fail-closed default: exit 0 even when an eval fails (for interactive use). By DEFAULT a failing eval exits 4, distinct from the harness-broke codes (1/2/3) so CI can gate on it.')
1128
+ // `--baseline` MUST be declared before `--no-baseline`: Commander only leaves the
1129
+ // value undefined-when-untyped if a positive option already exists, and that
1130
+ // tri-state is what lets a flag beat config in BOTH directions (see resolveBaseline).
1131
+ .option('--baseline', "A/B the skill's INSTRUCTIONS (declared vs withheld) and report the lift on stderr. Runs every eval TWICE, so it roughly DOUBLES the spawns and the spend (--max-budget-usd is per-spawn). Both arms share a filesystem — not a capability control; see baselineDelta and baselineIntegrity in baseline.json")
1132
+ .option('--no-baseline', 'Force the baseline A/B OFF for this run, overriding a committed `test.baseline: true` in the project config (which is announced on stderr when it applies).')
1133
+ .option('--allow-eval-failure', 'Opt out of the fail-closed default: exit 0 even when an eval fails (for interactive use). By DEFAULT a failing eval exits 1, distinct from the harness-could-not-run exit 2 (with a Reason: line) so CI can gate on it.')
984
1134
  .option('--allow-unverified-skill-source', 'Skip the vendored manifest integrity check')
985
1135
  .option('--i-understand-this-runs-skill-code', 'Acknowledge this command executes skill code (required)')
986
1136
  .option('--model <id>', "Model ID passed VERBATIM to `claude --model <id>` for the model UNDER TEST (the executor). VAT does no mapping/validation (e.g. opus, sonnet, claude-opus-4-8). Omit to use claude's own default model. Independent of --grader-model.")
987
1137
  .option('--grader-model <id>', 'Model for the fixed grader/judge, passed VERBATIM to `claude --model` (default claude-sonnet-5). GLOBAL (top-level `test:` config), independent of --model (the model UNDER TEST).')
988
1138
  .option('--evals <path>', "Eval suite to grade against: a path to an evals.json (resolved against the CURRENT DIRECTORY, so it may point outside the skill's tree) or an npm bare specifier honoring that package's exports map. Overrides `test.evals`, which is resolved against the skill source instead. Use this to test a skill you did not author — a correctly packaged skill ships no evals, because the suite is the answer key.")
989
1139
  .option('--max-turns <n>', 'Per-spawn cap on executor/grader turns (positive integer)')
990
- .option('--max-budget-usd <n>', 'Hard USD budget cap (positive number)')
1140
+ .option('--max-budget-usd <n>', 'Per-spawn USD budget cap, applied to EACH executor and grader spawn (positive number). Not a whole-run ceiling: a --baseline run has twice the spawns, so twice the worst-case spend.')
991
1141
  .option('--timeout <s>', 'Wall-clock timeout in seconds (positive integer)')
992
1142
  .option('--stall <s>', 'Stall-watchdog in seconds (positive integer)')
993
1143
  .option('--concurrency <n>', 'Max evals graded in parallel (positive integer; default 4)')
@@ -1004,11 +1154,41 @@ Description:
1004
1154
  transcript against the skill's expectations. VAT merges the grader results and
1005
1155
  writes grading.json.
1006
1156
 
1157
+ A declared skill is built before staging -- except an IN-PLACE one (merged
1158
+ config publish: false), which 'vat build' never bundles: it is staged from its
1159
+ source directory, and friction.json says links leaving that directory are absent.
1160
+
1007
1161
  IMPORTANT: This command EXECUTES the skill's code with your user account's
1008
1162
  full privileges (filesystem, network, shell) and a reachable auth credential.
1009
1163
  Only run skills you trust. You MUST pass --i-understand-this-runs-skill-code
1010
1164
  to acknowledge this and proceed.
1011
1165
 
1166
+ Artifacts:
1167
+ grading.json (the verdict), friction.json, tool-eval.json, provenance.json,
1168
+ and -- with --baseline -- baseline.json are written to a results/ directory
1169
+ whose path is echoed to stderr ("Results: <path>"). On a DEFAULT run (no --out,
1170
+ --workdir or --keep) that directory SURVIVES and the staged skill bytes around
1171
+ it are removed.
1172
+
1173
+ --out or --workdir spares only the harness ROOT: it is a location you own, so
1174
+ vat never deletes it, and the staged (untrusted) skill bytes inside it stay
1175
+ until you delete them yourself. It is NOT a blanket "keep everything". Three
1176
+ vat-owned directories live OUTSIDE that root -- the grader's output dir, the
1177
+ held eval suite, and the per-eval executor WORKSPACES (every eval's working
1178
+ directory and everything the evals wrote) -- and they are reaped on a rule that
1179
+ ignores --out and --workdir entirely. --keep is the only flag that retains the
1180
+ workspaces; without it they are gone before this command prints, which is why
1181
+ the "Workspaces: <path>" line appears only under --keep. Pass --keep when you
1182
+ intend to inspect what the evals produced.
1183
+
1184
+ A --baseline run also echoes its lift to stderr ("Baseline delta: +2 (with
1185
+ skill: 3/3, without skill: 1/3)."), and stamps the same numbers into
1186
+ baseline.json as baselineDelta, run-level and per eval. A delta of 0 means the
1187
+ skill lifted nothing; a delta of null means the two arms were graded against a
1188
+ different number of expectations and cannot be subtracted at all -- see
1189
+ baselineIntegrity.skew for which evals, and prefer null over a number that
1190
+ would read as "100% without the skill".
1191
+
1012
1192
  Model:
1013
1193
  --model <id> selects the model UNDER TEST (the executor spawn): passed
1014
1194
  straight through as \`claude --model <id>\` (verbatim -- VAT does not map or
@@ -1027,23 +1207,24 @@ Model:
1027
1207
 
1028
1208
  Exit Codes:
1029
1209
  0 - Harness ran to completion and every eval passed (or --allow-eval-failure suppressed a failing verdict)
1030
- 1 - Internal error (grader fragment absent/invalid, summary/expectations skew, executor/grader crash, stall/timeout)
1031
- 2 - Preflight failed (missing binary, auth error, eval inputs absent, unsafe workdir, ack missing, broken project config, a required skill -- subject or --with companion -- failed to build, --no-build with no existing dist for one of them, or an OPTIONAL --with-optional companion hitting a non-survivable failure: a destructive plugin-local build failure, missing security ack, or broken config)
1032
- 3 - Bootstrap needed: evals.json was absent, so VAT wrote a starter template next to the skill source. Fill it in and re-run.
1033
- 4 - An eval FAILED (the harness completed and produced a valid grading.json; expectations did not all pass). This is the fail-closed DEFAULT -- suppress with --allow-eval-failure.
1210
+ 1 - An eval FAILED (the harness completed and produced a valid grading.json; expectations did not all pass). This is the fail-closed DEFAULT -- suppress with --allow-eval-failure.
1211
+ 2 - The harness could not run. A 'Reason: <reason>' line on stderr says why:
1212
+ internal - the harness broke (grader fragment absent or off-schema, summary/expectations skew, executor/grader crash, stall/timeout)
1213
+ preflight - the environment or inputs need fixing (missing binary, auth error, eval inputs absent, unsafe workdir, ack missing, broken project config, a required skill -- subject or --with companion -- failed to build, --no-build with no existing dist for one of them, or an OPTIONAL --with-optional companion hitting a non-survivable failure: a destructive plugin-local build failure, missing security ack, or broken config)
1214
+ bootstrap - evals.json was absent, so VAT wrote a starter template next to the skill source. Fill it in and re-run.
1034
1215
 
1035
- The taxonomy is designed so a CI consumer can tolerate eval failures while
1036
- failing closed on every other (harness-broke) outcome:
1216
+ The same three-way contract as every other vat command, so a CI consumer
1217
+ can tolerate eval failures while failing closed on a harness that broke:
1037
1218
 
1038
1219
  vat skill test run my-skill --i-understand-this-runs-skill-code
1039
1220
  case $? in
1040
1221
  0) ;; # all evals passed
1041
- 4) ;; # evals failed but the harness is healthy -- tolerate/warn
1042
- *) exit 1 ;; # 1/2/3/unknown -- harness broke, fail the build
1222
+ 1) ;; # evals failed but the harness is healthy -- tolerate/warn
1223
+ *) exit 1 ;; # harness could not run -- fail the build; read Reason:
1043
1224
  esac
1044
1225
 
1045
1226
  Which specific evals failed lives in grading.json, never in the exit code.
1046
- For interactive iteration, --allow-eval-failure downgrades 4 to 0.
1227
+ For interactive iteration, --allow-eval-failure downgrades 1 to 0.
1047
1228
 
1048
1229
  Example:
1049
1230
  $ vat skill test run my-skill --i-understand-this-runs-skill-code