@webpresso/agent-kit 3.1.28 → 3.2.0

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.

Potentially problematic release.


This version of @webpresso/agent-kit might be problematic. Click here for more details.

Files changed (329) hide show
  1. package/README.md +53 -15
  2. package/bin/_run.js +179 -19
  3. package/catalog/AGENTS.md.tpl +6 -6
  4. package/catalog/agent/agents/implementer.md +45 -0
  5. package/catalog/agent/rules/ci-cost-local-first.md +139 -0
  6. package/catalog/agent/rules/ci-test-perf.md +5 -1
  7. package/catalog/agent/rules/cmd-execution.md +9 -0
  8. package/catalog/agent/rules/parallel-orchestration-quota.md +100 -0
  9. package/catalog/agent/rules/pre-implementation.md +30 -2
  10. package/catalog/agent/rules/supported-agent-clis.md +9 -0
  11. package/catalog/agent/rules/test-scan-perf.md +80 -0
  12. package/catalog/agent/rules/typescript-version.md +50 -0
  13. package/catalog/agent/rules/workflow-skills-routing.md +4 -2
  14. package/catalog/agent/skills/codex/SKILL.md +25 -1
  15. package/catalog/agent/skills/fix/SKILL.md +3 -0
  16. package/catalog/agent/skills/verify/SKILL.md +22 -2
  17. package/catalog/docs/templates/blueprint.md +1 -1
  18. package/dist/esm/audit/agents.js +1 -0
  19. package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +12 -0
  20. package/dist/esm/audit/blueprint-lifecycle-sql.js +23 -2
  21. package/dist/esm/audit/blueprint-pr-coverage.js +72 -7
  22. package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
  23. package/dist/esm/audit/ci-guardrails-wiring.js +90 -0
  24. package/dist/esm/audit/ci-test-perf.js +30 -0
  25. package/dist/esm/audit/command-surface.js +4 -2
  26. package/dist/esm/audit/host-substitution-risk.d.ts +2 -0
  27. package/dist/esm/audit/host-substitution-risk.js +256 -0
  28. package/dist/esm/audit/registry.d.ts +4 -4
  29. package/dist/esm/audit/registry.js +11 -1
  30. package/dist/esm/audit/roadmap-links.js +6 -0
  31. package/dist/esm/audit/test-scan-perf.d.ts +18 -0
  32. package/dist/esm/audit/test-scan-perf.js +275 -0
  33. package/dist/esm/audit/toolchain-isolation.js +1 -2
  34. package/dist/esm/audit/typescript-version.d.ts +2 -0
  35. package/dist/esm/audit/typescript-version.js +123 -0
  36. package/dist/esm/blueprint/core/parser.js +43 -1
  37. package/dist/esm/blueprint/core/validation/criteria.d.ts +14 -0
  38. package/dist/esm/blueprint/core/validation/criteria.js +41 -2
  39. package/dist/esm/blueprint/core/validation/state.js +25 -14
  40. package/dist/esm/blueprint/db/migrations/run.js +4 -2
  41. package/dist/esm/blueprint/lifecycle/audit.d.ts +20 -0
  42. package/dist/esm/blueprint/lifecycle/audit.js +65 -10
  43. package/dist/esm/blueprint/lifecycle/canonicalize.d.ts +6 -0
  44. package/dist/esm/blueprint/lifecycle/canonicalize.js +135 -0
  45. package/dist/esm/blueprint/lifecycle/engine.d.ts +9 -0
  46. package/dist/esm/blueprint/lifecycle/engine.js +53 -6
  47. package/dist/esm/blueprint/lifecycle/local.d.ts +2 -1
  48. package/dist/esm/blueprint/lifecycle/local.js +19 -3
  49. package/dist/esm/blueprint/lifecycle/review-provenance.d.ts +6 -0
  50. package/dist/esm/blueprint/lifecycle/review-provenance.js +118 -12
  51. package/dist/esm/blueprint/markdown/helpers.js +6 -2
  52. package/dist/esm/blueprint/service/BlueprintCreationService.d.ts +1 -0
  53. package/dist/esm/blueprint/service/BlueprintCreationService.js +53 -4
  54. package/dist/esm/blueprint/service/blueprint-tech-debt-links.js +16 -2
  55. package/dist/esm/blueprint/trust/command-runner.d.ts +26 -0
  56. package/dist/esm/blueprint/trust/command-runner.js +148 -0
  57. package/dist/esm/blueprint/trust/gates.d.ts +7 -0
  58. package/dist/esm/blueprint/trust/gates.js +20 -0
  59. package/dist/esm/blueprint/trust/promotion.d.ts +8 -0
  60. package/dist/esm/blueprint/trust/promotion.js +62 -112
  61. package/dist/esm/blueprint/trust/scaffold.d.ts +19 -0
  62. package/dist/esm/blueprint/trust/scaffold.js +64 -0
  63. package/dist/esm/blueprint/trust/validator.d.ts +1 -0
  64. package/dist/esm/blueprint/trust/validator.js +7 -1
  65. package/dist/esm/blueprint/utils/archive.js +27 -5
  66. package/dist/esm/blueprint/utils/document-paths.d.ts +18 -0
  67. package/dist/esm/blueprint/utils/document-paths.js +45 -12
  68. package/dist/esm/build/cli-mcp-parity.js +10 -0
  69. package/dist/esm/ci/act-replay.js +110 -7
  70. package/dist/esm/ci/act-runner.d.ts +4 -0
  71. package/dist/esm/ci/act-runner.js +85 -26
  72. package/dist/esm/ci/act-worktree-git.d.ts +11 -0
  73. package/dist/esm/ci/act-worktree-git.js +219 -0
  74. package/dist/esm/cli/bundle/commands/blueprint.d.ts +1 -0
  75. package/dist/esm/cli/bundle/commands/blueprint.js +1 -0
  76. package/dist/esm/cli/cli.d.ts +1 -1
  77. package/dist/esm/cli/cli.js +34 -0
  78. package/dist/esm/cli/commands/agent-launch.d.ts +6 -1
  79. package/dist/esm/cli/commands/agent-launch.js +82 -4
  80. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  81. package/dist/esm/cli/commands/audit-core.js +8 -1
  82. package/dist/esm/cli/commands/audit.js +20 -5
  83. package/dist/esm/cli/commands/blueprint/execution.js +18 -6
  84. package/dist/esm/cli/commands/blueprint/mutations.js +83 -47
  85. package/dist/esm/cli/commands/blueprint/router-dispatch.d.ts +2 -1
  86. package/dist/esm/cli/commands/blueprint/router-dispatch.js +20 -1
  87. package/dist/esm/cli/commands/blueprint/router-output.d.ts +21 -0
  88. package/dist/esm/cli/commands/blueprint/router-output.js +48 -17
  89. package/dist/esm/cli/commands/blueprint/router.d.ts +7 -0
  90. package/dist/esm/cli/commands/blueprint/router.js +40 -3
  91. package/dist/esm/cli/commands/ci-preflight.d.ts +13 -2
  92. package/dist/esm/cli/commands/ci-preflight.js +6 -3
  93. package/dist/esm/cli/commands/ci.d.ts +8 -1
  94. package/dist/esm/cli/commands/ci.js +80 -21
  95. package/dist/esm/cli/commands/compile.js +5 -31
  96. package/dist/esm/cli/commands/dash/delivery-status.d.ts +1 -0
  97. package/dist/esm/cli/commands/dash/delivery-status.js +11 -4
  98. package/dist/esm/cli/commands/dash/keymap.js +1 -0
  99. package/dist/esm/cli/commands/dash/launch-preferences.d.ts +15 -0
  100. package/dist/esm/cli/commands/dash/launch-preferences.js +46 -17
  101. package/dist/esm/cli/commands/dash/plan-once-label.d.ts +7 -0
  102. package/dist/esm/cli/commands/dash/plan-once-label.js +5 -0
  103. package/dist/esm/cli/commands/dash/plan-once-membership.d.ts +67 -0
  104. package/dist/esm/cli/commands/dash/plan-once-membership.js +151 -0
  105. package/dist/esm/cli/commands/dash/plan-once-merge.d.ts +143 -0
  106. package/dist/esm/cli/commands/dash/plan-once-merge.js +238 -0
  107. package/dist/esm/cli/commands/dash/plan-once.d.ts +22 -2
  108. package/dist/esm/cli/commands/dash/plan-once.js +41 -4
  109. package/dist/esm/cli/commands/dash/tui/attention-hud.d.ts +9 -0
  110. package/dist/esm/cli/commands/dash/tui/attention-hud.js +9 -0
  111. package/dist/esm/cli/commands/dash/tui/chat-bridge.d.ts +41 -0
  112. package/dist/esm/cli/commands/dash/tui/chat-bridge.js +73 -0
  113. package/dist/esm/cli/commands/dash/tui/chat-mode.d.ts +47 -0
  114. package/dist/esm/cli/commands/dash/tui/chat-mode.js +98 -0
  115. package/dist/esm/cli/commands/dash/tui/frame.d.ts +3 -0
  116. package/dist/esm/cli/commands/dash/tui/frame.js +3 -1
  117. package/dist/esm/cli/commands/dash/tui/palette.d.ts +1 -1
  118. package/dist/esm/cli/commands/dash/tui/palette.js +14 -0
  119. package/dist/esm/cli/commands/dash/tui/runtime.js +239 -4
  120. package/dist/esm/cli/commands/dash/tui/state.d.ts +41 -0
  121. package/dist/esm/cli/commands/dash/tui/state.js +257 -4
  122. package/dist/esm/cli/commands/doctor.js +5 -0
  123. package/dist/esm/cli/commands/format.js +0 -2
  124. package/dist/esm/cli/commands/hook.d.ts +5 -0
  125. package/dist/esm/cli/commands/hook.js +15 -9
  126. package/dist/esm/cli/commands/init/config.d.ts +0 -1
  127. package/dist/esm/cli/commands/init/config.js +3 -6
  128. package/dist/esm/cli/commands/init/convergence-apply.d.ts +24 -0
  129. package/dist/esm/cli/commands/init/convergence-apply.js +221 -0
  130. package/dist/esm/cli/commands/init/convergence-state.d.ts +13 -0
  131. package/dist/esm/cli/commands/init/convergence-state.js +54 -0
  132. package/dist/esm/cli/commands/init/convergence.d.ts +23 -0
  133. package/dist/esm/cli/commands/init/convergence.js +57 -0
  134. package/dist/esm/cli/commands/init/git-convergence.d.ts +19 -0
  135. package/dist/esm/cli/commands/init/git-convergence.js +168 -0
  136. package/dist/esm/cli/commands/init/gitignore-patcher.js +2 -0
  137. package/dist/esm/cli/commands/init/grok-privacy-smoke.d.ts +52 -0
  138. package/dist/esm/cli/commands/init/grok-privacy-smoke.js +91 -0
  139. package/dist/esm/cli/commands/init/host-native-proof.d.ts +18 -0
  140. package/dist/esm/cli/commands/init/host-native-proof.js +88 -0
  141. package/dist/esm/cli/commands/init/host-visibility.d.ts +2 -2
  142. package/dist/esm/cli/commands/init/host-visibility.js +94 -5
  143. package/dist/esm/cli/commands/init/index.d.ts +1 -0
  144. package/dist/esm/cli/commands/init/index.js +326 -173
  145. package/dist/esm/cli/commands/init/mcp-spec.d.ts +57 -0
  146. package/dist/esm/cli/commands/init/mcp-spec.js +273 -0
  147. package/dist/esm/cli/commands/init/merge.d.ts +1 -0
  148. package/dist/esm/cli/commands/init/merge.js +30 -1
  149. package/dist/esm/cli/commands/init/plugin-cache-prune.d.ts +0 -3
  150. package/dist/esm/cli/commands/init/plugin-cache-prune.js +0 -1
  151. package/dist/esm/cli/commands/init/scaffold-agents-md.d.ts +1 -1
  152. package/dist/esm/cli/commands/init/scaffold-agents-md.js +9 -3
  153. package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +11 -0
  154. package/dist/esm/cli/commands/init/scaffold-base-kit.js +56 -1
  155. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/claude.d.ts +5 -6
  156. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/claude.js +6 -13
  157. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.d.ts +14 -8
  158. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.js +41 -24
  159. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +2 -0
  160. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +51 -23
  161. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/ir.d.ts +0 -2
  162. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/ir.js +0 -2
  163. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/merge.d.ts +6 -3
  164. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/merge.js +39 -26
  165. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +12 -31
  166. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +297 -173
  167. package/dist/esm/cli/commands/init/scaffolders/file-transaction.d.ts +7 -0
  168. package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +58 -0
  169. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.d.ts +38 -0
  170. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.js +73 -0
  171. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.d.ts +21 -0
  172. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.js +559 -63
  173. package/dist/esm/cli/commands/init/untracked-collision.d.ts +14 -0
  174. package/dist/esm/cli/commands/init/untracked-collision.js +42 -0
  175. package/dist/esm/cli/commands/logs.d.ts +15 -0
  176. package/dist/esm/cli/commands/logs.js +192 -3
  177. package/dist/esm/cli/commands/opencode-rotate.d.ts +49 -0
  178. package/dist/esm/cli/commands/opencode-rotate.js +135 -0
  179. package/dist/esm/cli/commands/public-readiness.d.ts +11 -0
  180. package/dist/esm/cli/commands/public-readiness.js +42 -0
  181. package/dist/esm/cli/commands/quality-log-store.d.ts +1 -0
  182. package/dist/esm/cli/commands/quality-log-store.js +187 -51
  183. package/dist/esm/cli/commands/review.d.ts +35 -3
  184. package/dist/esm/cli/commands/review.js +734 -217
  185. package/dist/esm/cli/commands/run-wait.d.ts +2 -0
  186. package/dist/esm/cli/commands/run-wait.js +122 -0
  187. package/dist/esm/cli/commands/secrets.d.ts +1 -0
  188. package/dist/esm/cli/commands/secrets.js +4 -1
  189. package/dist/esm/cli/commands/setup-help.js +1 -1
  190. package/dist/esm/cli/commands/setup-repair-help.js +1 -1
  191. package/dist/esm/cli/commands/worktree/router-dispatch.js +13 -8
  192. package/dist/esm/cli/direct-provider-launch.js +31 -3
  193. package/dist/esm/cli/optional-tool-freshness.d.ts +27 -0
  194. package/dist/esm/cli/optional-tool-freshness.js +219 -9
  195. package/dist/esm/daemon/domains/git-actions.d.ts +29 -0
  196. package/dist/esm/daemon/domains/git-actions.js +136 -0
  197. package/dist/esm/daemon/domains/run-registry-interop.d.ts +16 -0
  198. package/dist/esm/daemon/domains/run-registry-interop.js +45 -0
  199. package/dist/esm/daemon/domains/sessions-search.d.ts +11 -0
  200. package/dist/esm/daemon/domains/sessions-search.js +29 -0
  201. package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +5 -0
  202. package/dist/esm/daemon/handlers/blueprints-handlers.js +36 -0
  203. package/dist/esm/daemon/handlers/deploy-handlers.d.ts +6 -0
  204. package/dist/esm/daemon/handlers/deploy-handlers.js +5 -0
  205. package/dist/esm/daemon/handlers/fleet-handlers.d.ts +15 -0
  206. package/dist/esm/daemon/handlers/fleet-handlers.js +91 -0
  207. package/dist/esm/daemon/handlers/git-handlers.d.ts +6 -0
  208. package/dist/esm/daemon/handlers/git-handlers.js +27 -0
  209. package/dist/esm/daemon/handlers/product.d.ts +7 -0
  210. package/dist/esm/daemon/handlers/product.js +10 -119
  211. package/dist/esm/daemon/handlers/sessions-handlers.d.ts +12 -0
  212. package/dist/esm/daemon/handlers/sessions-handlers.js +31 -0
  213. package/dist/esm/daemon/handlers/shared.d.ts +5 -0
  214. package/dist/esm/daemon/handlers/shared.js +16 -0
  215. package/dist/esm/daemon/methods.d.ts +8 -1
  216. package/dist/esm/daemon/methods.js +7 -0
  217. package/dist/esm/daemon/protocol/contract.d.ts +43 -0
  218. package/dist/esm/daemon/protocol/contract.js +26 -0
  219. package/dist/esm/daemon/protocol/index.d.ts +1 -1
  220. package/dist/esm/daemon/protocol/index.js +1 -1
  221. package/dist/esm/hooks/__conformance__/matrix.d.ts +6 -0
  222. package/dist/esm/hooks/__conformance__/matrix.js +137 -0
  223. package/dist/esm/hooks/conformance/batch.js +5 -0
  224. package/dist/esm/hooks/doctor.d.ts +15 -0
  225. package/dist/esm/hooks/doctor.js +79 -8
  226. package/dist/esm/hooks/permission-request/index.js +9 -3
  227. package/dist/esm/hooks/permission-request/policy.d.ts +9 -0
  228. package/dist/esm/hooks/permission-request/policy.js +13 -0
  229. package/dist/esm/hooks/pretool-guard/dev-routing.d.ts +9 -0
  230. package/dist/esm/hooks/pretool-guard/dev-routing.js +41 -5
  231. package/dist/esm/hooks/pretool-guard/logger.d.ts +7 -0
  232. package/dist/esm/hooks/pretool-guard/logger.js +16 -0
  233. package/dist/esm/hooks/pretool-guard/runner.d.ts +6 -0
  234. package/dist/esm/hooks/pretool-guard/runner.js +68 -16
  235. package/dist/esm/hooks/pretool-guard/validators/blueprint.js +30 -10
  236. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +58 -4
  237. package/dist/esm/hooks/pretool-guard/validators/index.d.ts +7 -0
  238. package/dist/esm/hooks/pretool-guard/validators/index.js +21 -0
  239. package/dist/esm/hooks/pretool-guard/validators/mcp-redirect.d.ts +0 -1
  240. package/dist/esm/hooks/pretool-guard/validators/mcp-redirect.js +8 -5
  241. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +19 -0
  242. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +25 -8
  243. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.d.ts +9 -7
  244. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.js +126 -14
  245. package/dist/esm/hooks/shared/guard-outcome.d.ts +149 -0
  246. package/dist/esm/hooks/shared/guard-outcome.js +215 -0
  247. package/dist/esm/hooks/shared/hook-bootstrap.d.ts +26 -0
  248. package/dist/esm/hooks/shared/hook-bootstrap.js +64 -1
  249. package/dist/esm/hooks/shared/types.d.ts +8 -5
  250. package/dist/esm/hooks/shared/types.js +23 -8
  251. package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
  252. package/dist/esm/hooks/stop/qa-changed-files.js +74 -0
  253. package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
  254. package/dist/esm/mcp/blueprint/handlers/document-mutations.js +78 -4
  255. package/dist/esm/mcp/blueprint/handlers/review-log.js +8 -1
  256. package/dist/esm/mcp/blueprint/handlers/task-advance.js +113 -54
  257. package/dist/esm/mcp/blueprint/handlers/task-verify.js +39 -19
  258. package/dist/esm/mcp/blueprint/registration.js +3 -2
  259. package/dist/esm/mcp/server.d.ts +1 -0
  260. package/dist/esm/mcp/server.js +27 -0
  261. package/dist/esm/mcp/tools/_names.d.ts +1 -1
  262. package/dist/esm/mcp/tools/_names.js +5 -0
  263. package/dist/esm/mcp/tools/_registry.js +10 -0
  264. package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
  265. package/dist/esm/mcp/tools/_shared/result.js +44 -1
  266. package/dist/esm/mcp/tools/audit.d.ts +5 -1
  267. package/dist/esm/mcp/tools/audit.js +40 -0
  268. package/dist/esm/mcp/tools/audits.d.ts +4 -0
  269. package/dist/esm/mcp/tools/ci-act.js +9 -11
  270. package/dist/esm/mcp/tools/ci-preflight.d.ts +50 -0
  271. package/dist/esm/mcp/tools/ci-preflight.js +183 -0
  272. package/dist/esm/mcp/tools/pr-upsert.js +39 -1
  273. package/dist/esm/mcp/tools/review-run.d.ts +28 -0
  274. package/dist/esm/mcp/tools/review-run.js +216 -0
  275. package/dist/esm/mcp/tools/run-wait.d.ts +86 -0
  276. package/dist/esm/mcp/tools/run-wait.js +593 -0
  277. package/dist/esm/mcp/tools/session-id.d.ts +3 -0
  278. package/dist/esm/mcp/tools/session-id.js +45 -0
  279. package/dist/esm/mcp/tools/session-info.d.ts +3 -0
  280. package/dist/esm/mcp/tools/session-info.js +49 -0
  281. package/dist/esm/output-transforms/audit.d.ts +23 -0
  282. package/dist/esm/output-transforms/audit.js +47 -0
  283. package/dist/esm/output-transforms/index.js +2 -0
  284. package/dist/esm/paths/state-root.js +3 -0
  285. package/dist/esm/review/authority.js +30 -7
  286. package/dist/esm/review/availability.d.ts +22 -0
  287. package/dist/esm/review/availability.js +123 -23
  288. package/dist/esm/review/delivery-verifier.d.ts +27 -0
  289. package/dist/esm/review/delivery-verifier.js +115 -0
  290. package/dist/esm/review/events.d.ts +3 -2
  291. package/dist/esm/review/events.js +23 -3
  292. package/dist/esm/review/execution/adapters.js +26 -9
  293. package/dist/esm/review/execution/output-policy.d.ts +2 -0
  294. package/dist/esm/review/execution/output-policy.js +12 -0
  295. package/dist/esm/review/execution/review-checkout.js +87 -6
  296. package/dist/esm/review/execution/supervisor.js +5 -0
  297. package/dist/esm/review/execution/types.d.ts +8 -0
  298. package/dist/esm/review/opencode-account.d.ts +24 -0
  299. package/dist/esm/review/opencode-account.js +68 -0
  300. package/dist/esm/review/opencode-auth.d.ts +33 -0
  301. package/dist/esm/review/opencode-auth.js +79 -0
  302. package/dist/esm/review/subject.d.ts +27 -0
  303. package/dist/esm/review/subject.js +179 -32
  304. package/dist/esm/runtime/executor.d.ts +1 -0
  305. package/dist/esm/runtime/executor.js +2 -1
  306. package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
  307. package/dist/esm/runtime/opencode-account-materializer.js +33 -0
  308. package/dist/esm/secret-gate/runner.d.ts +1 -0
  309. package/dist/esm/secret-gate/runner.js +4 -1
  310. package/dist/esm/status/snapshot.js +30 -19
  311. package/dist/esm/test/duration-sequencer.d.ts +20 -0
  312. package/dist/esm/test/duration-sequencer.js +54 -0
  313. package/dist/esm/test/shard-durations.json +922 -0
  314. package/dist/esm/test/worker-budget.d.ts +6 -0
  315. package/dist/esm/test/worker-budget.js +59 -1
  316. package/dist/esm/test-helpers/global-setup.d.ts +1 -1
  317. package/dist/esm/test-helpers/global-setup.js +68 -24
  318. package/dist/esm/ultragoal/service.d.ts +7 -0
  319. package/dist/esm/ultragoal/service.js +42 -2
  320. package/dist/esm/utils/write-json-file.js +3 -1
  321. package/dist/esm/worktrees/codex-project-trust.d.ts +15 -0
  322. package/dist/esm/worktrees/codex-project-trust.js +56 -0
  323. package/dist/esm/worktrees/current.d.ts +1 -0
  324. package/dist/esm/worktrees/current.js +1 -0
  325. package/dist/esm/worktrees/project-agent-surfaces.d.ts +1 -0
  326. package/dist/esm/worktrees/project-agent-surfaces.js +2 -1
  327. package/dist/esm/worktrees/registry.d.ts +8 -0
  328. package/dist/esm/worktrees/registry.js +18 -3
  329. package/package.json +18 -15
@@ -0,0 +1,100 @@
1
+ ---
2
+ type: rule
3
+ slug: parallel-orchestration-quota
4
+ title: Parallel orchestration and quota discipline
5
+ status: active
6
+ scope: repo
7
+ applies_to: [agents]
8
+ related:
9
+ - ci-cost-local-first
10
+ - cmd-execution
11
+ - pre-implementation
12
+ - engineering-principles
13
+ - supported-agent-clis
14
+ created: "2026-07-24"
15
+ last_reviewed: "2026-07-24"
16
+ paths:
17
+ - "blueprints/**"
18
+ - "catalog/agent/**"
19
+ ---
20
+
21
+ # Parallel orchestration and quota discipline
22
+
23
+ How to execute multi-blueprint work: one orchestrator, many cheap executors,
24
+ lowest defensible token/quota/CI cost. This is the **default** execution model
25
+ for programs of more than ~3 blueprints — not an opt-in mode.
26
+
27
+ Companion rules (do not restate them here): `ci-cost-local-first.md` for runner
28
+ policy, `cmd-execution.md` for the scoped-command surface,
29
+ `pre-implementation.md` for the blueprint gate, `engineering-principles.md` for
30
+ scope filters, `supported-agent-clis.md` for host tiers.
31
+
32
+ ## Orchestrator / executor split
33
+
34
+ The session that owns the program is an **orchestrator**: it plans, sequences,
35
+ dispatches, reviews, and lands. It does not implement. Implementation is
36
+ delegated to **executor subagents**, one per blueprint, each confined to that
37
+ blueprint's owner worktree.
38
+
39
+ - Spawn a **fresh executor per task** inside a multi-task blueprint. Long
40
+ single-session runs drift; a fresh executor per task keeps a consolidated
41
+ blueprint cheap to run correctly.
42
+ - Executors never touch the primary checkout or another blueprint's worktree.
43
+ - The orchestrator runs from its own controller worktree cut from
44
+ `origin/main`, never from the primary checkout.
45
+
46
+ ## Model tier by intrinsic difficulty
47
+
48
+ Pick the **cheapest model that can do the job**, judged by the hardest task in
49
+ the blueprint — never by aggregate diff size or file count.
50
+
51
+ | Complexity | Executor |
52
+ | --------------------------------------------------- | -------------------------------------------- |
53
+ | L / XL, design-heavy, security- or protocol-bearing | premium reasoning tier |
54
+ | M | mid tier, high effort |
55
+ | S / XS, mechanical | mid tier, medium effort — or small/fast tier |
56
+
57
+ A blueprint bundling many mechanically-trivial edits stays a cheap-tier job. If
58
+ a blueprint would need a premium tier only because of one hard task, that task
59
+ is mis-homed: move it to a blueprint whose tier it matches.
60
+
61
+ **Exception: design, UI, and frontend work always gets the premium tier**,
62
+ whatever its sized complexity — components, panels, layout, styling, UX flows,
63
+ design systems, and the frontend half of any feature. Mechanical work degrades
64
+ gracefully at a cheaper tier: it is either correct or it fails a test. Interface
65
+ work does not. A technically-correct but badly-judged UI passes every check and
66
+ still has to be redone, so the cheaper tier is not actually cheaper. Backend and
67
+ mechanical work keeps the cheapest-capable rule above.
68
+
69
+ ## Quota awareness across hosts
70
+
71
+ Provider subscriptions are the budget. Treat weekly quota as a shared,
72
+ exhaustible resource across every host (see `supported-agent-clis.md`).
73
+
74
+ - Route each job — implementation and review alike — to the host whose
75
+ subscription can absorb it, not reflexively to the strongest one.
76
+ - On a provider usage-limit error, **rotate provider and resume** rather than
77
+ waiting or retrying the same host. Review gates are resumable by gate id.
78
+ - Never spend a premium tier on work a cheap tier finishes identically.
79
+
80
+ ## Review and CI cost
81
+
82
+ Blueprint count is the dominant cost driver: one executable blueprint is one
83
+ PR, one external review, and one full CI matrix run.
84
+
85
+ - **Consolidate coherent work.** One blueprint = one reviewable contract in one
86
+ subsystem. Never straddle a dependency cut, mix intrinsic-difficulty tiers, or
87
+ merge unrelated subsystems just to reduce count.
88
+ - **Route each review gate to the cheapest adequate provider.** Reserve premium
89
+ reviewers for premium-tier blueprints.
90
+ - **Prefer work that needs no gate at all.** Markdown-only PRs are exempt from
91
+ blueprint PR coverage; pure git hygiene (branch/worktree pruning) needs no PR.
92
+ - Verify locally before pushing, and rebase onto fresh `origin/main` before
93
+ landing so cached CI layers are reused.
94
+
95
+ ## Parallelism
96
+
97
+ Run 3–4 blueprints concurrently. Widen only when the extra lanes touch disjoint
98
+ files; serialize where they contend. When several features would edit one hot
99
+ file, land a **behavior-preserving split first** so each feature owns its own
100
+ file — that split pays for itself across the whole program.
@@ -7,7 +7,7 @@ scope: repo
7
7
  applies_to: [agents, humans]
8
8
  related: []
9
9
  created: "2026-05-06"
10
- last_reviewed: "2026-05-06"
10
+ last_reviewed: "2026-07-23"
11
11
  ---
12
12
 
13
13
  # Pre-Implementation Rules
@@ -157,6 +157,10 @@ as finished.
157
157
  A blueprint is a **folder** (`blueprints/<status>/<slug>/_overview.md`) and may
158
158
  not be promoted from `draft/` to `planned/` until it has **1 provenance-backed
159
159
  approval from Claude/Codex/Grok or an OpenCode-Go model** on the current content.
160
+ Legacy flat blueprints (`blueprints/<status>/<slug>.md`) remain readable and
161
+ lifecycle-valid, but they have no sibling review authority; run
162
+ `wp blueprint canonicalize <slug>` before recording review ledgers, artifacts,
163
+ Ultragoal events, or approval frontmatter.
160
164
 
161
165
  - **Gate input = committed in-folder review authority.** The preferred path is a
162
166
  content-addressed v2 `review-events.jsonl` event produced by `wp review gate`.
@@ -203,6 +207,19 @@ approval from Claude/Codex/Grok or an OpenCode-Go model** on the current content
203
207
  `approvals:` frontmatter with first-hand knowledge that reviewer actually
204
208
  produced that verdict — there is intentionally no MCP-reachable shortcut
205
209
  around that.
210
+ - **`wp review override <slug> --reason "…" --confirm` is the gated CLI escape
211
+ hatch for a genuinely un-convergeable gate** — a strong reviewer legitimately
212
+ rejected the subject but its sole remaining blocker is physically
213
+ un-remediable (e.g. a platform residual the code cannot fix). It records a
214
+ `maintainer-override` approval that satisfies the promotion gate DISTINCTLY
215
+ (never counted as a strong or OpenCode-Go approval). It is not a way to skip
216
+ review: it REFUSES unless a formal Claude/Codex/Grok/OpenCode-Go gate has
217
+ already rejected the exact current subject, and it requires an explicit reason
218
+ plus `--confirm`. `maintainer-override` is not in the `wp review log` /
219
+ `wp_blueprint_review_log` reviewer enum, so this command is the only writer —
220
+ there is no MCP-reachable or frontmatter shortcut to mint it. Reserve it for
221
+ the residual that no code change can close; a normal blocker is fixed and
222
+ re-reviewed, not overridden.
206
223
  - **Retry interrupted or structurally failed gates with the same immutable
207
224
  target** by running `wp review gate ... --resume <gate-id>`. Aborted,
208
225
  timed-out, incomplete, and protocol/transport failures append a new attempt
@@ -210,6 +227,16 @@ approval from Claude/Codex/Grok or an OpenCode-Go model** on the current content
210
227
  killed writer is never overwritten. A complete content rejection is terminal
211
228
  for that unchanged target, while active provider limits/unavailability remain
212
229
  suppressed until their recorded retry window permits another attempt.
230
+ - **Completed rejections have a two-subject circuit breaker.** Plan review
231
+ lineage uses the canonical `wp-blueprint-v1` subject, so lifecycle/trust
232
+ bookkeeping commits reuse the prior rejection and do not invoke another
233
+ reviewer. One semantically changed remediation subject may receive the final
234
+ formal review; its prompt includes the prior rejection artifact and requires
235
+ all remaining blockers together. After two distinct semantic subjects are
236
+ rejected, `wp review gate` returns `scope-exhausted` before provider
237
+ invocation. Stop automated retries and obtain an explicit human scope
238
+ decision before creating a successor blueprint. Plan and delivery purposes
239
+ have separate budgets; delivery retains its existing whole-tree subject.
213
240
  - **`provider-event-too-large` means one captured provider JSON event exceeded
214
241
  the bounded event limit; it is not a reviewer verdict.** Keep the bound in
215
242
  place, retry the same gate id, and switch provider/model when possible because
@@ -264,7 +291,8 @@ Doing it post-merge is also impossible without a second PR: you cannot push the
264
291
  **Local pre-push check (catches the CI failure before it costs minutes):** the
265
292
  local lifecycle audit gives a false pass here because the owner worktree resolves
266
293
  on your machine. So do not rely on it alone — before opening or updating the PR,
267
- confirm no changed blueprint is still under `blueprints/in-progress/`:
294
+ run `wp ci-preflight` for ordinary quality gates and confirm no changed blueprint
295
+ is still under `blueprints/in-progress/`:
268
296
 
269
297
  ```bash
270
298
  git diff --name-only origin/main...HEAD | grep -q '^blueprints/in-progress/' \
@@ -56,6 +56,15 @@ This is a product control-plane surface, not a silent Tier-1 promotion:
56
56
  - Missing binary/auth degrades with an explicit UI reason (never silent omit).
57
57
  - Benchmarks/plugins that require Tier-1 guarantees MUST still treat Grok as
58
58
  outside Tier 1 until a separate tier promotion lands.
59
+ - `wp setup` also delivers the native project surfaces for Grok: the
60
+ `.grok/config.toml` `[mcp_servers.webpresso]` entry and trust-gated
61
+ `.grok/hooks/webpresso.json` managed hooks (run `/hooks-trust` once in Grok).
62
+ Grok reads `AGENTS.md`/`CLAUDE.md` natively, so no instruction projection is
63
+ needed.
64
+ - After trusting the project hooks, operators verify native discovery with
65
+ `grok inspect --json`, `grok mcp list --json`, and
66
+ `grok mcp doctor --json`. Grok remains a trial host until its protected
67
+ privacy/native-proof job passes for the release SHA.
59
68
 
60
69
  ## Tier 3 — not supported
61
70
 
@@ -0,0 +1,80 @@
1
+ ---
2
+ type: rule
3
+ slug: test-scan-perf
4
+ title: Test scan performance (no full-repo FS walks)
5
+ status: active
6
+ scope: repo
7
+ applies_to: [agents]
8
+ related:
9
+ - testing-philosophy
10
+ - ci-test-perf
11
+ created: "2026-07-20"
12
+ last_reviewed: "2026-07-20"
13
+ paths:
14
+ - "**/*.{test,spec}.{ts,tsx,js,jsx}"
15
+ - "src/audit/test-scan-perf.ts"
16
+ ---
17
+
18
+ # Test scan performance
19
+
20
+ Unit and contract tests must not walk the whole repository with
21
+ `readdirSync` / `statSync` / `readFileSync` and paper over the cost with a
22
+ 30s+ per-test timeout.
23
+
24
+ ## Forbidden pattern
25
+
26
+ ```ts
27
+ const repoRoot = findRepoRoot();
28
+ const walk = (dir: string) => {
29
+ for (const entry of readdirSync(dir)) {
30
+ const full = join(dir, entry);
31
+ if (statSync(full).isDirectory()) {
32
+ walk(full);
33
+ continue;
34
+ }
35
+ const text = readFileSync(full, "utf8");
36
+ // ...
37
+ }
38
+ };
39
+ walk(repoRoot);
40
+
41
+ it("scan", () => {
42
+ /* ... */
43
+ }, 30_000); // band-aid
44
+ ```
45
+
46
+ ## Preferred
47
+
48
+ ```ts
49
+ // Tracked files only — seconds, not tens of seconds.
50
+ const stdout = execFileSync(
51
+ "git",
52
+ ["-C", root, "grep", "-l", "-I", "-E", "RETIRED_SPECIFIER_A|RETIRED_SPECIFIER_B"],
53
+ { encoding: "utf8" },
54
+ );
55
+ ```
56
+
57
+ Or walk a **bounded** fixture / package tree (not `findRepoRoot()` / `process.cwd()`).
58
+
59
+ ## Guardrail
60
+
61
+ | Surface | Contract |
62
+ | ---------- | ---------------------------------- |
63
+ | Audit | `wp audit test-scan-perf` |
64
+ | Guardrails | included in `wp audit guardrails` |
65
+ | Scope | affected-safe (changed test files) |
66
+
67
+ ### Opt-out
68
+
69
+ ```ts
70
+ // test-scan-perf-allow — one-off inventory with justification
71
+ walk(repoRoot);
72
+
73
+ // or once per file:
74
+ // test-scan-perf-allow-file — full inventory intentionally walks the tree
75
+ ```
76
+
77
+ ## Related
78
+
79
+ - Implementation: `src/audit/test-scan-perf.ts`
80
+ - CI workers/cache: `ci-test-perf` (workflow-level, separate concern)
@@ -0,0 +1,50 @@
1
+ ---
2
+ type: rule
3
+ slug: typescript-version
4
+ title: TypeScript 7 required at consumers
5
+ status: active
6
+ scope: repo
7
+ applies_to: [agents]
8
+ related:
9
+ - package-conventions
10
+ - ci-test-perf
11
+ created: "2026-07-24"
12
+ last_reviewed: "2026-07-24"
13
+ paths:
14
+ - "pnpm-workspace.yaml"
15
+ - "**/package.json"
16
+ ---
17
+
18
+ # TypeScript 7 required at consumers
19
+
20
+ The Webpresso toolchain runs on **TypeScript 7** — the native (Go) compiler that
21
+ `tsc` resolves to since the 7.0 GA. Consumer repos must stay on the 7 major so
22
+ their typecheck, build, and shipped `.d.ts` match the compiler agent-kit ships
23
+ and tests against.
24
+
25
+ ## What is enforced
26
+
27
+ `wp audit typescript-version` (bundled in `wp audit guardrails`, so it runs in
28
+ every consumer CI that calls guardrails, and updates automatically on the next
29
+ `wp` / agent-kit bump — no CI edits) fails when the `typescript` compiler
30
+ dependency is pinned below major 7, in either:
31
+
32
+ - the `catalog.typescript` pin in `pnpm-workspace.yaml`, or
33
+ - a direct `typescript` dependency/devDependency in any `package.json`
34
+ (`catalog:` / `workspace:` references are skipped — they resolve through the
35
+ catalog, which is checked directly).
36
+
37
+ ## `@typescript/typescript6` is allowed — it is not legacy
38
+
39
+ TypeScript 7's **programmatic** compiler API is not stable until 7.1, so tooling
40
+ that calls the compiler API (e.g. `wp typecheck`) bridges through
41
+ `@typescript/typescript6`, the Microsoft-published TS6 compiler-API
42
+ compatibility package. That is a distinct dependency from the `typescript`
43
+ compiler and is **never** flagged by this audit. Keep `typescript` on `^7` and
44
+ `@typescript/typescript6` on `^6` — do not downgrade the `typescript` compiler.
45
+
46
+ ## Temporary exception
47
+
48
+ A consumer mid-migration may add a `typescript-version-allow` comment in
49
+ `pnpm-workspace.yaml` (or the manifest) to suppress the check. Treat it as
50
+ temporary and remove it once the repo is on TypeScript 7.
@@ -74,8 +74,10 @@ Map routing intent like this:
74
74
  - debugging and regressions → `investigate` then `fix`
75
75
  - bounded cleanup after behavior is green → `ai-deslop`
76
76
  - multi-task / parallel execute → `ultragoal` + `/pll` (ready-queue, worktrees)
77
- - local completeness → `/verify`; merge-ready outside voice `/verify --merge-ready`
78
- (exactly one sequential outside reviewer unless user sets N)
77
+ - local completeness → `/verify` then `wp ci-preflight` before push; merge-ready
78
+ outside voice → `/verify --merge-ready` (exactly one sequential outside
79
+ reviewer unless user sets N). Do not use remote CI as the first debugger
80
+ (`ci-cost-local-first`).
79
81
 
80
82
  Use the full `wp_*` MCP surface for tests, lint, typecheck, audits, session memory,
81
83
  ultragoal, worktrees, PRs, and quality gates — not shell reimplementations. Use
@@ -8,13 +8,37 @@ license: MIT
8
8
 
9
9
  Use this skill from Claude or another non-Codex host when the user wants Codex to independently review a diff, challenge a plan, or answer a repo question. Keep Codex read-only by default and treat its answer as external advice until independently verified.
10
10
 
11
+ ## Primary path: the `wp_review_run` MCP tool
12
+
13
+ When the webpresso MCP server is available, call `wp_review_run` directly instead of any bash block below — it is the same `wp review run` typed runtime, called in-process, with two ergonomic wins: it takes a `prompt` string (no `--prompt-file` bookkeeping) and it runs the probe stage and the review stage in **one call** by default (the review stage is skipped automatically if the probe fails, so you never waste a full review invocation on a cold/broken provider).
14
+
15
+ ```jsonc
16
+ // wp_review_run MCP tool call
17
+ {
18
+ "prompt": "<diff summary + what to look for>",
19
+ "provider": "codex",
20
+ // model, effort, artifactRoot, idleSeconds are all optional and default
21
+ // the same way the `wp review run` CLI does. Omit `stage` for automatic
22
+ // probe-then-review; pass stage: "probe" or stage: "review" only for
23
+ // manual single-stage control.
24
+ }
25
+ ```
26
+
27
+ **Provider fallback lives in this one call.** If your primary provider (e.g. Codex) is unavailable — out of credits, auth expired — switch the `provider` parameter to another supported value (`claude`, `opencode`, `grok`) in the SAME `wp_review_run` call. Never shell into a different provider's CLI directly; that bypasses artifact capture under `.webpresso/reviews`, availability tracking, and the probe-then-review handshake this tool exists to provide. The pretool guard hook actively blocks shelling straight into a provider CLI's review-launching subcommand and redirects here.
28
+
29
+ The bash blocks in this skill (below) are the **MCP-unavailable fallback only** — use them when the webpresso MCP server itself is not reachable in the current host, not as a provider-fallback mechanism.
30
+
11
31
  ## Single-shot budget (anti-stampede)
12
32
 
13
33
  - Default: **one** review invocation per request.
14
34
  - Do **not** fan out parallel multi-host review matrices unless the user set `review_budget`/`N` > 1.
15
- - Prefer `wp review run` / `wp review gate` over spawn/wait agent loops for review.
35
+ - Prefer `wp_review_run` (MCP) or `wp review run` / `wp review gate` (CLI fallback) over spawn/wait agent loops for review.
16
36
  - Keep prompts bounded; no whole-repo paste.
17
37
 
38
+ ## MCP-unavailable fallback (raw CLI)
39
+
40
+ Everything from here down is the manual `wp review run` CLI path documented for hosts or sessions where the webpresso MCP server is not reachable. Prefer `wp_review_run` above whenever MCP is available.
41
+
18
42
  ## Auth check
19
43
 
20
44
  ```bash
@@ -122,12 +122,15 @@ Run the narrowest checks that prove the repaired behavior on the real repo surfa
122
122
  - `wp_test` / targeted tests for the repaired path
123
123
  - `wp_lint` / `wp_typecheck` for changed surfaces
124
124
  - `wp_qa` only when the blast radius needs the bookend
125
+ - Before push: `wp ci-preflight` (local pre-push owner). Do not use remote CI
126
+ re-runs as the primary fix loop (`ci-cost-local-first`).
125
127
 
126
128
  Rules:
127
129
 
128
130
  - Prefer MCP `wp_*` over raw host Bash.
129
131
  - Reuse fresh logs / session-memory indexed output; do not re-run long commands just to re-read.
130
132
  - Read the exit code and summary before making a claim.
133
+ - Never `git push --no-verify` to land an unproven fix.
131
134
 
132
135
  Escalate to `/verify <target>` (local) or `/verify <target> --merge-ready` when any of these are true:
133
136
 
@@ -109,6 +109,9 @@ workflow:
109
109
  1. Identify target type (file / package / blueprint slug / all).
110
110
  2. Map each claim you plan to make to the exact command or log that proves it.
111
111
  3. If the target is a blueprint slug, run the repo's blueprint show/audit surface and record the acceptance boxes that still need proof.
112
+ 4. **CI cost / local-first:** treat remote CI as confirmation, not the first
113
+ debugger. Load `ci-cost-local-first` expectations: no hook skips, no
114
+ blind `gh run rerun`, Ubicloud for private non-release jobs.
112
115
 
113
116
  ## Phase 1 — Governance gates
114
117
 
@@ -130,12 +133,27 @@ Run the narrowest checks that prove the touched behavior:
130
133
  - `wp_test` / targeted tests
131
134
  - `wp_qa`, `wp_e2e`, build / package checks only when the change requires them
132
135
 
136
+ **Before push or PR open/update**, run the pre-push owner end-to-end:
137
+
138
+ ```bash
139
+ wp ci-preflight
140
+ ```
141
+
142
+ That is fail-fast branch-scoped format → guardrails → typecheck → lint →
143
+ test. Agent-kit itself enforces it from `.husky/pre-push`; consumer repos may
144
+ keep pre-push checks user-owned, so run the command explicitly before pushing.
145
+ Do **not** claim push-ready if preflight failed. Do **not** bypass hooks to ship
146
+ red work.
147
+
133
148
  Rules:
134
149
 
135
150
  - Prefer MCP `wp_*` over raw underlying tools.
136
151
  - Reuse fresh logs / session-memory indexed output if the runner auto-saves them.
137
152
  - Never claim broader correctness than the commands actually proved.
138
153
  - If the repo documents a "full QA" bookend, reserve `wp_qa` / `--full` for the final broad pass rather than every iteration.
154
+ - If CI is already red: read the failed job log, reproduce with the matching
155
+ local `wp` command, fix, re-run `wp ci-preflight`, then push **one**
156
+ corrective commit — do not burn another full matrix “to check.”
139
157
 
140
158
  ## Phase 3 — Cross-surface impact scan
141
159
 
@@ -217,8 +235,10 @@ Reviewer preference (pick **one** path):
217
235
 
218
236
  Approval evidence requirements:
219
237
 
220
- - Blueprint lifecycle: `wp review gate <blueprint-slug> --target HEAD --json` first.
221
- Use `wp review log` / `wp review read` for inspection.
238
+ - Blueprint lifecycle: `wp review gate <blueprint-slug> --purpose delivery --target HEAD --json`
239
+ first. Delivery gates automatically run declared Promotion Gates from the
240
+ Trust Dossier before outside-review provider probes. Use `wp review log` /
241
+ `wp review read` for inspection.
222
242
  - Each reviewer must return clear `APPROVED`/`BLOCKED` with enough evidence.
223
243
  - Record as PR comments when a PR exists (model/tool, verdict, reviewed commit).
224
244
  - Unavailable reviewer → try next preferred; if still short, report gap and
@@ -22,7 +22,7 @@ approvals: [] # Legacy approval mirror; authority may also come from v2 review-e
22
22
  - Draft slug: `{{slug}}`
23
23
  - Output path: `{{output_path}}`
24
24
  - Generated command: `wp blueprint new "{{description}}" --complexity {{complexity}}`
25
- - Default shape: folder (`blueprints/<status>/<slug>/_overview.md`, with sibling `reviews.md` for approvals); flat `blueprints/<status>/<slug>.md` is legacy-valid
25
+ - Default shape: folder (`blueprints/<status>/<slug>/_overview.md`, with sibling `reviews.md` for approvals); flat `blueprints/<status>/<slug>.md` stays readable but cannot hold review evidence, ledgers, or approvals — run `wp blueprint canonicalize <slug>` first
26
26
  - Validation scope: parser compliance before write
27
27
 
28
28
  ## Architecture Overview
@@ -13,6 +13,7 @@ const REQUIRED_SUBAGENTS = [
13
13
  "security-auditor.md",
14
14
  "doc-writer.md",
15
15
  "explorer.md",
16
+ "implementer.md",
16
17
  ];
17
18
  const EXPLORER_CONTRACT_MARKERS = [
18
19
  "3–5 tool calls",
@@ -35,4 +35,16 @@ export interface BlueprintLifecycleAuditOptions {
35
35
  */
36
36
  readonly affectedFiles?: readonly string[];
37
37
  }
38
+ /**
39
+ * Decide the file scope for the per-file `runBlueprintAudit` pass. In
40
+ * changed-only mode with a resolved changed scope, audit only the changed
41
+ * blueprint files (bounded, pre-commit-fast); otherwise audit the whole corpus
42
+ * (`all: true`, the CI-grade pass). Extracted + exported so the scoping contract
43
+ * is unit-testable without standing up the full corpus.
44
+ */
45
+ export declare function resolveRunBlueprintAuditScope(changedOnly: boolean, changedFiles: ReadonlySet<string> | null): {
46
+ readonly stagedFiles: string[];
47
+ } | {
48
+ readonly all: true;
49
+ };
38
50
  export declare function auditBlueprintLifecycleSql(cwd?: string, options?: BlueprintLifecycleAuditOptions): Promise<RepoAuditResult>;
@@ -357,17 +357,20 @@ function listTrackedBlueprintPaths(cwd) {
357
357
  }
358
358
  function changedBlueprintScope(candidates) {
359
359
  const slugs = new Set();
360
+ const files = new Set();
360
361
  for (const [currentPath, candidate] of candidates) {
362
+ files.add(currentPath);
361
363
  const currentSlug = blueprintSlugFromGitPath(currentPath);
362
364
  if (currentSlug)
363
365
  slugs.add(currentSlug);
364
366
  for (const previousPath of candidate.previousPaths) {
367
+ files.add(previousPath);
365
368
  const previousSlug = blueprintSlugFromGitPath(previousPath);
366
369
  if (previousSlug)
367
370
  slugs.add(previousSlug);
368
371
  }
369
372
  }
370
- return { slugs };
373
+ return { slugs, files };
371
374
  }
372
375
  /**
373
376
  * When `--affected` supplies an explicit file set (pre-commit staged files or
@@ -435,6 +438,19 @@ function readPreviousLifecycleStatusFromCandidate(cwd, row, candidate, trackedPa
435
438
  }
436
439
  return null;
437
440
  }
441
+ /**
442
+ * Decide the file scope for the per-file `runBlueprintAudit` pass. In
443
+ * changed-only mode with a resolved changed scope, audit only the changed
444
+ * blueprint files (bounded, pre-commit-fast); otherwise audit the whole corpus
445
+ * (`all: true`, the CI-grade pass). Extracted + exported so the scoping contract
446
+ * is unit-testable without standing up the full corpus.
447
+ */
448
+ export function resolveRunBlueprintAuditScope(changedOnly, changedFiles) {
449
+ if (changedOnly && changedFiles !== null) {
450
+ return { stagedFiles: [...changedFiles] };
451
+ }
452
+ return { all: true };
453
+ }
438
454
  export async function auditBlueprintLifecycleSql(cwd = process.cwd(), options = {}) {
439
455
  const budgets = loadBudgets(cwd);
440
456
  const wipInProgressMax = budgets["blueprint-wip-in-progress-max"].max ?? 3;
@@ -522,10 +538,15 @@ export async function auditBlueprintLifecycleSql(cwd = process.cwd(), options =
522
538
  if (options.changedOnly && changedScope) {
523
539
  titleNotices.push(`changed-only: ${changedScope.slugs.size} blueprint(s)`);
524
540
  }
541
+ // In changed-only mode, scope the per-file blueprint audit to the changed
542
+ // blueprints. Auditing all blueprints (`all: true`) parses and validates the
543
+ // entire corpus (~1300 files, ~70s) even for a one-blueprint change — far too
544
+ // slow for the pre-commit hot path. The whole-corpus pass is CI's job; the
545
+ // structural + SQL projection checks below still run over every blueprint.
525
546
  const { runBlueprintAudit } = await import("../blueprint/lifecycle/audit.js");
526
547
  const lifecycle = await runBlueprintAudit({
527
548
  projectRoot: cwd,
528
- all: true,
549
+ ...resolveRunBlueprintAuditScope(options.changedOnly === true, changedScope?.files ?? null),
529
550
  completedApprovalGate: options.changedOnly === true,
530
551
  inProgressApprovalGate: options.changedOnly === true,
531
552
  strict: true,
@@ -1,5 +1,6 @@
1
1
  import { spawnSync } from "node:child_process";
2
- import { relative } from "node:path";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { join, relative } from "node:path";
3
4
  import { resolveBlueprintRoot } from "#utils/blueprint-root.js";
4
5
  const TITLE = "Blueprint PR coverage";
5
6
  const BLUEPRINT_EXEMPT_PATTERN = /^Blueprint-exempt:\s*(\S.*)$/im;
@@ -39,14 +40,33 @@ export function auditBlueprintPrCoverage(rootDirectory = process.cwd(), options
39
40
  const configuredRoot = normalizeRoot(normalizePath(relative(rootDirectory, resolveBlueprintRoot(rootDirectory))));
40
41
  const blueprintRoots = [...new Set(["blueprints", configuredRoot].filter(Boolean))];
41
42
  const finalEntries = entries.filter((entry) => entry.status !== "D");
42
- const activePaths = finalEntries.filter((entry) => {
43
+ const activeEntries = finalEntries.flatMap((entry) => {
43
44
  const location = parseBlueprintLocation(entry.path, blueprintRoots);
44
- return location !== null && ACTIVE_LIFECYCLE_DIRECTORIES.has(location.lifecycle);
45
+ if (!location || !ACTIVE_LIFECYCLE_DIRECTORIES.has(location.lifecycle))
46
+ return [];
47
+ return [{ entry, location }];
45
48
  });
46
- if (activePaths.length > 0) {
47
- return fail(`non-doc landing PR leaves changed active blueprint content at ${activePaths
48
- .map((entry) => entry.path)
49
- .join(", ")}; move the owner blueprint to completed before merge`, changedFiles.length);
49
+ const ownerActive = activeEntries.filter(({ location }) => location.slug === ownerSlug);
50
+ if (ownerActive.length > 0) {
51
+ return fail(`non-doc landing PR leaves owner blueprint "${ownerSlug}" in active lifecycle at ${ownerActive
52
+ .map(({ entry }) => entry.path)
53
+ .join(", ")}; move completed/${ownerSlug}/_overview.md (or .md) into the PR and drop active-lifecycle owner paths`, changedFiles.length);
54
+ }
55
+ // Parent-roadmap program trackers may co-edit on a child land PR while still
56
+ // active (draft/planned). Executable blueprints (type: blueprint) may not.
57
+ const nonOwnerActive = activeEntries.filter(({ location }) => location.slug !== ownerSlug);
58
+ const programTrackers = [];
59
+ const blockingNonOwner = [];
60
+ for (const { entry, location } of nonOwnerActive) {
61
+ if (isParentRoadmapDocument(rootDirectory, entry.path, location)) {
62
+ programTrackers.push(entry.path);
63
+ }
64
+ else {
65
+ blockingNonOwner.push(entry.path);
66
+ }
67
+ }
68
+ if (blockingNonOwner.length > 0) {
69
+ return fail(`non-doc landing PR changes active non-owner blueprint content at ${blockingNonOwner.join(", ")}; remove those paths from the PR or complete those blueprints first (owner ${ownerSlug} is separate)`, changedFiles.length);
50
70
  }
51
71
  const matchingCompletedOwner = finalEntries.some((entry) => {
52
72
  const location = parseBlueprintLocation(entry.path, blueprintRoots);
@@ -55,6 +75,9 @@ export function auditBlueprintPrCoverage(rootDirectory = process.cwd(), options
55
75
  if (!matchingCompletedOwner) {
56
76
  return fail(`non-doc PR on ${headRef} must change its completed owner blueprint at completed/${ownerSlug}/_overview.md (or completed/${ownerSlug}.md)`, changedFiles.length);
57
77
  }
78
+ if (programTrackers.length > 0) {
79
+ return passWithWarning(`[warn] co-edited parent-roadmap program tracker(s) on non-doc land: ${programTrackers.join(", ")}`, changedFiles.length);
80
+ }
58
81
  return pass(changedFiles.length);
59
82
  }
60
83
  function pass(checked) {
@@ -134,6 +157,44 @@ function parseBlueprintLocation(filePath, roots) {
134
157
  }
135
158
  return null;
136
159
  }
160
+ /**
161
+ * True when the changed path belongs to a `type: parent-roadmap` document.
162
+ * Nested non-overview files under a parent-roadmap folder inherit the overview
163
+ * type so review artifacts co-travel. Missing paths (unit-test fakes) return
164
+ * false → fail closed as executable blueprints.
165
+ */
166
+ function isParentRoadmapDocument(rootDirectory, filePath, location) {
167
+ const normalized = normalizePath(filePath);
168
+ const overviewCandidates = [
169
+ // Prefer the changed overview when it is the document itself.
170
+ ...(location.ownerDocument ? [normalized] : []),
171
+ // folder overview: …/<lifecycle>/<slug>/_overview.md
172
+ normalized.replace(new RegExp(`/(draft|planned|in-progress|parked|completed|archived)/${escapeRegex(location.slug)}(?:/.*)?$`, "u"), `/$1/${location.slug}/_overview.md`),
173
+ // flat overview: …/<lifecycle>/<slug>.md
174
+ normalized.replace(new RegExp(`/(draft|planned|in-progress|parked|completed|archived)/${escapeRegex(location.slug)}(?:/.*|\\.md)?$`, "u"), `/$1/${location.slug}.md`),
175
+ ];
176
+ const seen = new Set();
177
+ for (const candidate of overviewCandidates) {
178
+ if (seen.has(candidate))
179
+ continue;
180
+ seen.add(candidate);
181
+ const abs = join(rootDirectory, candidate);
182
+ if (!existsSync(abs))
183
+ continue;
184
+ try {
185
+ const head = readFileSync(abs, "utf8").slice(0, 4_096);
186
+ if (/^type:\s*['"]?parent-roadmap['"]?\s*$/mu.test(head))
187
+ return true;
188
+ }
189
+ catch {
190
+ // unreadable → fail closed
191
+ }
192
+ }
193
+ return false;
194
+ }
195
+ function escapeRegex(value) {
196
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
197
+ }
137
198
  function isDependabotDependencyOnlyUpdate(cwd, options, changedFiles) {
138
199
  if (!changedFiles.every(isDependabotDependencyFile))
139
200
  return false;
@@ -201,6 +262,10 @@ function isDependabotDependencyFile(filePath) {
201
262
  normalized === "bun.lockb" ||
202
263
  normalized === "deno.lock" ||
203
264
  normalized === "pnpm-workspace.yaml" ||
265
+ normalized === "Cargo.toml" ||
266
+ normalized.endsWith("/Cargo.toml") ||
267
+ normalized === "Cargo.lock" ||
268
+ normalized.endsWith("/Cargo.lock") ||
204
269
  (normalized.startsWith(".github/workflows/") && /\.ya?ml$/u.test(basename)));
205
270
  }
206
271
  function normalizeHeadRef(value) {