@webpresso/agent-kit 3.1.30 → 3.3.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.
Files changed (300) hide show
  1. package/README.md +53 -15
  2. package/bin/_run.js +183 -20
  3. package/catalog/AGENTS.md.tpl +3 -3
  4. package/catalog/agent/agents/implementer.md +45 -0
  5. package/catalog/agent/rules/parallel-orchestration-quota.md +100 -0
  6. package/catalog/agent/rules/pre-implementation.md +28 -1
  7. package/catalog/agent/rules/supported-agent-clis.md +9 -0
  8. package/catalog/agent/rules/typescript-version.md +50 -0
  9. package/catalog/agent/skills/codex/SKILL.md +25 -1
  10. package/catalog/agent/skills/verify/SKILL.md +4 -2
  11. package/catalog/docs/templates/blueprint.md +1 -1
  12. package/dist/esm/audit/agents.js +1 -0
  13. package/dist/esm/audit/blueprint-lifecycle-sql.d.ts +12 -0
  14. package/dist/esm/audit/blueprint-lifecycle-sql.js +23 -2
  15. package/dist/esm/audit/blueprint-pr-coverage.js +4 -0
  16. package/dist/esm/audit/blueprint-trust.js +14 -10
  17. package/dist/esm/audit/changeset-evidence.d.ts +23 -0
  18. package/dist/esm/audit/changeset-evidence.js +30 -0
  19. package/dist/esm/audit/changeset-required.d.ts +10 -0
  20. package/dist/esm/audit/changeset-required.js +73 -0
  21. package/dist/esm/audit/ci-guardrails-detection.d.ts +27 -0
  22. package/dist/esm/audit/ci-guardrails-detection.js +68 -0
  23. package/dist/esm/audit/ci-guardrails-wiring.d.ts +22 -0
  24. package/dist/esm/audit/ci-guardrails-wiring.js +80 -0
  25. package/dist/esm/audit/ci-test-perf.js +30 -0
  26. package/dist/esm/audit/command-surface.js +4 -2
  27. package/dist/esm/audit/host-substitution-risk.d.ts +2 -0
  28. package/dist/esm/audit/host-substitution-risk.js +256 -0
  29. package/dist/esm/audit/registry.d.ts +4 -4
  30. package/dist/esm/audit/registry.js +13 -1
  31. package/dist/esm/audit/toolchain-isolation.js +1 -2
  32. package/dist/esm/audit/typescript-version.d.ts +2 -0
  33. package/dist/esm/audit/typescript-version.js +123 -0
  34. package/dist/esm/blueprint/core/parser.js +101 -2
  35. package/dist/esm/blueprint/core/schema.d.ts +1 -0
  36. package/dist/esm/blueprint/core/schema.js +26 -0
  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 +87 -20
  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/local.d.ts +2 -1
  46. package/dist/esm/blueprint/lifecycle/local.js +19 -3
  47. package/dist/esm/blueprint/lifecycle/review-provenance.d.ts +6 -0
  48. package/dist/esm/blueprint/lifecycle/review-provenance.js +68 -12
  49. package/dist/esm/blueprint/lifecycle/rollout-anchor.d.ts +97 -0
  50. package/dist/esm/blueprint/lifecycle/rollout-anchor.js +161 -0
  51. package/dist/esm/blueprint/service/BlueprintCreationService.d.ts +1 -0
  52. package/dist/esm/blueprint/service/BlueprintCreationService.js +53 -4
  53. package/dist/esm/blueprint/service/blueprint-tech-debt-links.js +16 -2
  54. package/dist/esm/blueprint/sync/client.d.ts +2 -1
  55. package/dist/esm/blueprint/sync/client.js +1 -1
  56. package/dist/esm/blueprint/trust/command-runner.d.ts +26 -0
  57. package/dist/esm/blueprint/trust/command-runner.js +148 -0
  58. package/dist/esm/blueprint/trust/dossier.d.ts +1 -0
  59. package/dist/esm/blueprint/trust/dossier.js +40 -6
  60. package/dist/esm/blueprint/trust/gates.d.ts +7 -0
  61. package/dist/esm/blueprint/trust/gates.js +20 -0
  62. package/dist/esm/blueprint/trust/promotion.d.ts +8 -0
  63. package/dist/esm/blueprint/trust/promotion.js +74 -112
  64. package/dist/esm/blueprint/trust/scaffold.d.ts +19 -0
  65. package/dist/esm/blueprint/trust/scaffold.js +64 -0
  66. package/dist/esm/blueprint/trust/validator.d.ts +1 -0
  67. package/dist/esm/blueprint/trust/validator.js +7 -1
  68. package/dist/esm/blueprint/utils/archive.js +27 -5
  69. package/dist/esm/blueprint/utils/document-paths.d.ts +18 -0
  70. package/dist/esm/blueprint/utils/document-paths.js +45 -12
  71. package/dist/esm/build/cli-mcp-parity.js +15 -0
  72. package/dist/esm/cli/bundle/commands/blueprint.d.ts +1 -0
  73. package/dist/esm/cli/bundle/commands/blueprint.js +1 -0
  74. package/dist/esm/cli/cli.d.ts +1 -1
  75. package/dist/esm/cli/cli.js +43 -0
  76. package/dist/esm/cli/commands/agent-launch.d.ts +8 -1
  77. package/dist/esm/cli/commands/agent-launch.js +93 -4
  78. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  79. package/dist/esm/cli/commands/audit-core.js +8 -1
  80. package/dist/esm/cli/commands/audit.js +21 -5
  81. package/dist/esm/cli/commands/blueprint/execution.js +18 -6
  82. package/dist/esm/cli/commands/blueprint/mutations.js +59 -40
  83. package/dist/esm/cli/commands/blueprint/router-dispatch.d.ts +2 -1
  84. package/dist/esm/cli/commands/blueprint/router-dispatch.js +20 -1
  85. package/dist/esm/cli/commands/blueprint/router-output.d.ts +21 -0
  86. package/dist/esm/cli/commands/blueprint/router-output.js +48 -17
  87. package/dist/esm/cli/commands/blueprint/router.d.ts +7 -0
  88. package/dist/esm/cli/commands/blueprint/router.js +13 -1
  89. package/dist/esm/cli/commands/ci-preflight.d.ts +13 -2
  90. package/dist/esm/cli/commands/ci-preflight.js +30 -6
  91. package/dist/esm/cli/commands/compile.js +5 -31
  92. package/dist/esm/cli/commands/dash/delivery-status.d.ts +1 -0
  93. package/dist/esm/cli/commands/dash/delivery-status.js +11 -4
  94. package/dist/esm/cli/commands/doctor.js +5 -0
  95. package/dist/esm/cli/commands/hook.d.ts +5 -0
  96. package/dist/esm/cli/commands/hook.js +15 -9
  97. package/dist/esm/cli/commands/init/config.js +2 -2
  98. package/dist/esm/cli/commands/init/convergence-apply.d.ts +88 -0
  99. package/dist/esm/cli/commands/init/convergence-apply.js +325 -0
  100. package/dist/esm/cli/commands/init/convergence-state.d.ts +13 -0
  101. package/dist/esm/cli/commands/init/convergence-state.js +54 -0
  102. package/dist/esm/cli/commands/init/convergence.d.ts +23 -0
  103. package/dist/esm/cli/commands/init/convergence.js +57 -0
  104. package/dist/esm/cli/commands/init/git-convergence.d.ts +19 -0
  105. package/dist/esm/cli/commands/init/git-convergence.js +168 -0
  106. package/dist/esm/cli/commands/init/gitignore-patcher.js +2 -0
  107. package/dist/esm/cli/commands/init/grok-privacy-smoke.d.ts +52 -0
  108. package/dist/esm/cli/commands/init/grok-privacy-smoke.js +91 -0
  109. package/dist/esm/cli/commands/init/host-native-proof.d.ts +18 -0
  110. package/dist/esm/cli/commands/init/host-native-proof.js +88 -0
  111. package/dist/esm/cli/commands/init/host-visibility.d.ts +2 -2
  112. package/dist/esm/cli/commands/init/host-visibility.js +94 -5
  113. package/dist/esm/cli/commands/init/index.d.ts +3 -0
  114. package/dist/esm/cli/commands/init/index.js +326 -173
  115. package/dist/esm/cli/commands/init/mcp-spec.d.ts +57 -0
  116. package/dist/esm/cli/commands/init/mcp-spec.js +273 -0
  117. package/dist/esm/cli/commands/init/merge.d.ts +1 -0
  118. package/dist/esm/cli/commands/init/merge.js +30 -1
  119. package/dist/esm/cli/commands/init/package-root.d.ts +7 -0
  120. package/dist/esm/cli/commands/init/package-root.js +10 -2
  121. package/dist/esm/cli/commands/init/plugin-cache-prune.d.ts +0 -3
  122. package/dist/esm/cli/commands/init/plugin-cache-prune.js +0 -1
  123. package/dist/esm/cli/commands/init/scaffold-agents-md.d.ts +1 -1
  124. package/dist/esm/cli/commands/init/scaffold-agents-md.js +9 -3
  125. package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +20 -0
  126. package/dist/esm/cli/commands/init/scaffold-base-kit.js +61 -5
  127. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.d.ts +14 -8
  128. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/emitters/grok.js +41 -24
  129. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.d.ts +2 -0
  130. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +54 -24
  131. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +12 -31
  132. package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +288 -202
  133. package/dist/esm/cli/commands/init/scaffolders/file-transaction.d.ts +22 -0
  134. package/dist/esm/cli/commands/init/scaffolders/file-transaction.js +230 -0
  135. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.d.ts +38 -0
  136. package/dist/esm/cli/commands/init/scaffolders/grok-mcp/index.js +73 -0
  137. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.d.ts +21 -0
  138. package/dist/esm/cli/commands/init/scaffolders/opencode-plugin/index.js +559 -63
  139. package/dist/esm/cli/commands/init/untracked-collision.d.ts +14 -0
  140. package/dist/esm/cli/commands/init/untracked-collision.js +42 -0
  141. package/dist/esm/cli/commands/opencode-probe.d.ts +107 -0
  142. package/dist/esm/cli/commands/opencode-probe.js +323 -0
  143. package/dist/esm/cli/commands/opencode-rotate.d.ts +72 -0
  144. package/dist/esm/cli/commands/opencode-rotate.js +147 -0
  145. package/dist/esm/cli/commands/public-readiness.d.ts +11 -0
  146. package/dist/esm/cli/commands/public-readiness.js +42 -0
  147. package/dist/esm/cli/commands/quality-runner.js +3 -3
  148. package/dist/esm/cli/commands/review.d.ts +35 -3
  149. package/dist/esm/cli/commands/review.js +751 -209
  150. package/dist/esm/cli/commands/run-wait.d.ts +2 -0
  151. package/dist/esm/cli/commands/run-wait.js +122 -0
  152. package/dist/esm/cli/commands/rust-check.d.ts +24 -0
  153. package/dist/esm/cli/commands/rust-check.js +110 -0
  154. package/dist/esm/cli/commands/setup-help.js +1 -1
  155. package/dist/esm/cli/commands/setup-repair-help.js +1 -1
  156. package/dist/esm/cli/commands/typecheck.d.ts +1 -0
  157. package/dist/esm/cli/commands/typecheck.js +30 -1
  158. package/dist/esm/cli/commands/worktree/router-dispatch.d.ts +6 -0
  159. package/dist/esm/cli/commands/worktree/router-dispatch.js +126 -9
  160. package/dist/esm/cli/commands/worktree/router.js +10 -0
  161. package/dist/esm/cli/direct-provider-launch.js +9 -5
  162. package/dist/esm/cli/optional-tool-freshness.d.ts +27 -0
  163. package/dist/esm/cli/optional-tool-freshness.js +219 -9
  164. package/dist/esm/daemon/domains/git-actions.d.ts +29 -0
  165. package/dist/esm/daemon/domains/git-actions.js +136 -0
  166. package/dist/esm/daemon/domains/run-registry-interop.d.ts +16 -0
  167. package/dist/esm/daemon/domains/run-registry-interop.js +45 -0
  168. package/dist/esm/daemon/domains/sessions-search.d.ts +11 -0
  169. package/dist/esm/daemon/domains/sessions-search.js +29 -0
  170. package/dist/esm/daemon/handlers/blueprints-handlers.d.ts +5 -0
  171. package/dist/esm/daemon/handlers/blueprints-handlers.js +36 -0
  172. package/dist/esm/daemon/handlers/deploy-handlers.d.ts +6 -0
  173. package/dist/esm/daemon/handlers/deploy-handlers.js +5 -0
  174. package/dist/esm/daemon/handlers/fleet-handlers.d.ts +15 -0
  175. package/dist/esm/daemon/handlers/fleet-handlers.js +91 -0
  176. package/dist/esm/daemon/handlers/git-handlers.d.ts +6 -0
  177. package/dist/esm/daemon/handlers/git-handlers.js +27 -0
  178. package/dist/esm/daemon/handlers/product.d.ts +7 -0
  179. package/dist/esm/daemon/handlers/product.js +10 -119
  180. package/dist/esm/daemon/handlers/sessions-handlers.d.ts +12 -0
  181. package/dist/esm/daemon/handlers/sessions-handlers.js +31 -0
  182. package/dist/esm/daemon/handlers/shared.d.ts +5 -0
  183. package/dist/esm/daemon/handlers/shared.js +16 -0
  184. package/dist/esm/daemon/methods.d.ts +8 -1
  185. package/dist/esm/daemon/methods.js +7 -0
  186. package/dist/esm/daemon/protocol/contract.d.ts +43 -0
  187. package/dist/esm/daemon/protocol/contract.js +26 -0
  188. package/dist/esm/daemon/protocol/index.d.ts +1 -1
  189. package/dist/esm/daemon/protocol/index.js +1 -1
  190. package/dist/esm/hooks/__conformance__/matrix.d.ts +6 -0
  191. package/dist/esm/hooks/__conformance__/matrix.js +137 -0
  192. package/dist/esm/hooks/conformance/batch.js +5 -0
  193. package/dist/esm/hooks/doctor.d.ts +5 -3
  194. package/dist/esm/hooks/doctor.js +67 -16
  195. package/dist/esm/hooks/permission-request/index.js +9 -3
  196. package/dist/esm/hooks/permission-request/policy.d.ts +9 -0
  197. package/dist/esm/hooks/permission-request/policy.js +13 -0
  198. package/dist/esm/hooks/pretool-guard/dev-routing.d.ts +9 -0
  199. package/dist/esm/hooks/pretool-guard/dev-routing.js +41 -5
  200. package/dist/esm/hooks/pretool-guard/logger.d.ts +7 -0
  201. package/dist/esm/hooks/pretool-guard/logger.js +16 -0
  202. package/dist/esm/hooks/pretool-guard/runner.d.ts +6 -0
  203. package/dist/esm/hooks/pretool-guard/runner.js +68 -16
  204. package/dist/esm/hooks/pretool-guard/validators/blueprint.js +30 -10
  205. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +54 -0
  206. package/dist/esm/hooks/pretool-guard/validators/index.d.ts +7 -0
  207. package/dist/esm/hooks/pretool-guard/validators/index.js +21 -0
  208. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +19 -0
  209. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +25 -8
  210. package/dist/esm/hooks/pretool-guard/validators/worktree-discipline.js +6 -1
  211. package/dist/esm/hooks/shared/guard-outcome.d.ts +149 -0
  212. package/dist/esm/hooks/shared/guard-outcome.js +215 -0
  213. package/dist/esm/hooks/shared/hook-bootstrap.d.ts +26 -0
  214. package/dist/esm/hooks/shared/hook-bootstrap.js +64 -1
  215. package/dist/esm/hooks/shared/types.d.ts +8 -5
  216. package/dist/esm/hooks/shared/types.js +50 -9
  217. package/dist/esm/hooks/stop/qa-changed-files.d.ts +11 -0
  218. package/dist/esm/hooks/stop/qa-changed-files.js +92 -0
  219. package/dist/esm/mcp/blueprint/_shared/lifecycle.js +14 -1
  220. package/dist/esm/mcp/blueprint/handlers/document-mutations.d.ts +5 -0
  221. package/dist/esm/mcp/blueprint/handlers/document-mutations.js +109 -11
  222. package/dist/esm/mcp/blueprint/handlers/review-log.js +8 -1
  223. package/dist/esm/mcp/blueprint/handlers/task-advance.js +113 -54
  224. package/dist/esm/mcp/blueprint/handlers/task-verify.js +39 -19
  225. package/dist/esm/mcp/blueprint/registration.js +3 -2
  226. package/dist/esm/mcp/server.d.ts +1 -0
  227. package/dist/esm/mcp/server.js +27 -0
  228. package/dist/esm/mcp/tools/_names.d.ts +1 -1
  229. package/dist/esm/mcp/tools/_names.js +5 -0
  230. package/dist/esm/mcp/tools/_registry.js +10 -0
  231. package/dist/esm/mcp/tools/_shared/audit-kinds.d.ts +1 -1
  232. package/dist/esm/mcp/tools/_shared/result.js +44 -1
  233. package/dist/esm/mcp/tools/audit.d.ts +5 -1
  234. package/dist/esm/mcp/tools/audit.js +42 -0
  235. package/dist/esm/mcp/tools/audits.d.ts +4 -0
  236. package/dist/esm/mcp/tools/ci-preflight.d.ts +50 -0
  237. package/dist/esm/mcp/tools/ci-preflight.js +183 -0
  238. package/dist/esm/mcp/tools/pr-upsert.js +39 -1
  239. package/dist/esm/mcp/tools/review-run.d.ts +28 -0
  240. package/dist/esm/mcp/tools/review-run.js +216 -0
  241. package/dist/esm/mcp/tools/run-wait.d.ts +86 -0
  242. package/dist/esm/mcp/tools/run-wait.js +593 -0
  243. package/dist/esm/mcp/tools/session-fetch-and-index.d.ts +1 -1
  244. package/dist/esm/mcp/tools/session-id.d.ts +3 -0
  245. package/dist/esm/mcp/tools/session-id.js +45 -0
  246. package/dist/esm/mcp/tools/session-info.d.ts +3 -0
  247. package/dist/esm/mcp/tools/session-info.js +49 -0
  248. package/dist/esm/output-transforms/audit.d.ts +23 -0
  249. package/dist/esm/output-transforms/audit.js +47 -0
  250. package/dist/esm/output-transforms/index.js +2 -0
  251. package/dist/esm/package.json +2 -0
  252. package/dist/esm/platform/client.d.ts +7 -1
  253. package/dist/esm/platform/github-contract-source.d.ts +2 -1
  254. package/dist/esm/pr-description/contract.js +24 -4
  255. package/dist/esm/review/authority.js +27 -14
  256. package/dist/esm/review/availability.d.ts +33 -0
  257. package/dist/esm/review/availability.js +122 -20
  258. package/dist/esm/review/delivery-verifier.d.ts +27 -0
  259. package/dist/esm/review/delivery-verifier.js +115 -0
  260. package/dist/esm/review/events.d.ts +3 -2
  261. package/dist/esm/review/events.js +23 -3
  262. package/dist/esm/review/execution/adapters.d.ts +11 -1
  263. package/dist/esm/review/execution/adapters.js +36 -10
  264. package/dist/esm/review/execution/artifacts.d.ts +1 -1
  265. package/dist/esm/review/execution/output-policy.d.ts +2 -0
  266. package/dist/esm/review/execution/output-policy.js +12 -0
  267. package/dist/esm/review/execution/review-checkout.js +121 -21
  268. package/dist/esm/review/execution/supervisor.js +36 -4
  269. package/dist/esm/review/execution/types.d.ts +9 -0
  270. package/dist/esm/review/opencode-account.d.ts +24 -0
  271. package/dist/esm/review/opencode-account.js +68 -0
  272. package/dist/esm/review/opencode-auth.d.ts +33 -0
  273. package/dist/esm/review/opencode-auth.js +79 -0
  274. package/dist/esm/review/subject.d.ts +25 -0
  275. package/dist/esm/review/subject.js +116 -26
  276. package/dist/esm/runtime/opencode-account-materializer.d.ts +34 -0
  277. package/dist/esm/runtime/opencode-account-materializer.js +33 -0
  278. package/dist/esm/rust/affected-manifests.d.ts +38 -0
  279. package/dist/esm/rust/affected-manifests.js +69 -0
  280. package/dist/esm/session-memory/fetch-index.d.ts +1 -1
  281. package/dist/esm/status/snapshot.js +32 -25
  282. package/dist/esm/test/duration-sequencer.d.ts +20 -0
  283. package/dist/esm/test/duration-sequencer.js +54 -0
  284. package/dist/esm/test/shard-durations.json +922 -0
  285. package/dist/esm/test/worker-budget.d.ts +6 -0
  286. package/dist/esm/test/worker-budget.js +59 -1
  287. package/dist/esm/test-helpers/global-setup.d.ts +1 -2
  288. package/dist/esm/test-helpers/global-setup.js +79 -32
  289. package/dist/esm/typecheck/planner.d.ts +9 -1
  290. package/dist/esm/typecheck/planner.js +31 -0
  291. package/dist/esm/ultragoal/service.d.ts +7 -0
  292. package/dist/esm/ultragoal/service.js +42 -2
  293. package/dist/esm/utils/write-json-file.js +3 -1
  294. package/dist/esm/worktrees/codex-project-trust.d.ts +15 -0
  295. package/dist/esm/worktrees/codex-project-trust.js +56 -0
  296. package/dist/esm/worktrees/orphan-scan.d.ts +50 -0
  297. package/dist/esm/worktrees/orphan-scan.js +211 -0
  298. package/dist/esm/worktrees/registry.d.ts +8 -0
  299. package/dist/esm/worktrees/registry.js +18 -3
  300. package/package.json +18 -13
@@ -1,11 +1,14 @@
1
1
  import path from "node:path";
2
2
  import { z } from "zod";
3
+ import { hasChangesetEvidence } from "#audit/changeset-evidence.js";
3
4
  import { evaluateApprovalReviewers } from "#lifecycle/audit.js";
5
+ import { collectV2ReviewProvenance } from "#lifecycle/review-provenance.js";
4
6
  import { evaluateRequiredChecks } from "#mcp/tools/_shared/required-checks.js";
5
7
  import { redactText } from "#mcp/tools/_shared/redact.js";
6
8
  import { runCommand } from "#mcp/tools/_shared/run-command.js";
7
9
  import { readReviewAuthorityAtRef } from "#review/authority.js";
8
10
  import { resolveBlueprintRoot } from "#utils/blueprint-root.js";
11
+ import { parseBlueprintDocumentRelativePath } from "#utils/document-paths.js";
9
12
  export const statusLevelSchema = z.enum(["ready", "blocked", "partial", "unknown"]);
10
13
  export const requiredCheckEvaluationSchema = z.object({
11
14
  total: z.number().int().nonnegative(),
@@ -80,6 +83,11 @@ export const wpStatusSnapshotSchema = z.object({
80
83
  });
81
84
  const DEFAULT_TIMEOUT_MS = 30_000;
82
85
  const DEFAULT_MAX_OUTPUT_BYTES = 64_000;
86
+ // `gh pr view --json` includes the PR `body`, which alone can exceed the small
87
+ // caller diagnostic budget (GitHub bodies run to tens of KB). Parse that JSON
88
+ // against a generous semantic budget so mergeability/checks/blueprint-linkage
89
+ // fields are never lost to truncation; diagnostics keep the small caller budget.
90
+ const PR_VIEW_SEMANTIC_MAX_OUTPUT_BYTES = 1_048_576;
83
91
  const DISCLOSURE_FIELDS = [
84
92
  "Execution model(s)",
85
93
  "Planning/refinement model(s)",
@@ -115,8 +123,8 @@ async function probe(cwd, command, args, options = {}) {
115
123
  cwd,
116
124
  timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
117
125
  });
126
+ const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
118
127
  if ("error" in outcome) {
119
- const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
120
128
  return {
121
129
  passed: false,
122
130
  semanticStdout: "",
@@ -125,11 +133,11 @@ async function probe(cwd, command, args, options = {}) {
125
133
  missingBinary: outcome.error.code === "ENOENT",
126
134
  };
127
135
  }
128
- const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
136
+ const semanticMaxOutputBytes = options.semanticMaxOutputBytes ?? maxOutputBytes;
129
137
  return {
130
138
  passed: outcome.exitCode === 0,
131
- semanticStdout: clipBytes(outcome.stdout, maxOutputBytes),
132
- semanticTruncated: Buffer.byteLength(outcome.stdout, "utf8") > maxOutputBytes,
139
+ semanticStdout: clipBytes(outcome.stdout, semanticMaxOutputBytes),
140
+ semanticTruncated: Buffer.byteLength(outcome.stdout, "utf8") > semanticMaxOutputBytes,
133
141
  stdout: clipDiagnostic(outcome.stdout, maxOutputBytes),
134
142
  stderr: clipDiagnostic(outcome.stderr, maxOutputBytes),
135
143
  exitCode: outcome.exitCode,
@@ -203,12 +211,7 @@ function hasDisclosure(body, label) {
203
211
  return new RegExp(`(?:^|\\n)\\s*(?:-\\s*)?${escaped}:\\s*\\S`, "iu").test(body);
204
212
  }
205
213
  function hasReleaseEvidence(pr) {
206
- const files = prFiles(pr);
207
- if (files.length > 0 && files.every((file) => file.endsWith(".md")))
208
- return true;
209
- if (files.some((file) => /^\.changeset\/[^/]+\.md$/u.test(file)))
210
- return true;
211
- return /Changeset-exempt:\s*\S/iu.test(stringField(pr.body) ?? "");
214
+ return hasChangesetEvidence(prFiles(pr), [stringField(pr.body) ?? ""]);
212
215
  }
213
216
  export function evaluatePrReadiness(evidence) {
214
217
  const blockers = [];
@@ -307,33 +310,29 @@ function selectBlueprintFile(projectRoot, pr) {
307
310
  const prefix = `${root}/`;
308
311
  if (!file.path.startsWith(prefix))
309
312
  continue;
310
- const segments = file.path.slice(prefix.length).split("/");
311
- if (segments.length < 3 ||
312
- segments.at(-1) !== "_overview.md" ||
313
- segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")) {
314
- continue;
315
- }
316
- const stableSlug = segments.slice(1, -1).join("/");
317
- if (stableSlug)
318
- return [{ ...file, stableSlug }];
313
+ const parsed = parseBlueprintDocumentRelativePath(file.path.slice(prefix.length));
314
+ if (parsed)
315
+ return [{ ...file, stableSlug: parsed.slug }];
319
316
  }
320
317
  return [];
321
318
  });
322
319
  const priority = (file) => file.changeType === "ADDED" ? 0 : file.changeType === "RENAMED" ? 1 : 2;
323
320
  return candidates.toSorted((left, right) => priority(left) - priority(right))[0];
324
321
  }
325
- function resolveBlueprintEvidence(cwd, projectRoot, pr, targetHash) {
322
+ function resolveBlueprintEvidence(projectRoot, pr, targetHash) {
326
323
  const blueprintFile = selectBlueprintFile(projectRoot, pr);
327
324
  if (!blueprintFile || !targetHash)
328
325
  return undefined;
329
326
  try {
330
- const authority = readReviewAuthorityAtRef(cwd, targetHash, blueprintFile.stableSlug, "delivery");
327
+ const authority = readReviewAuthorityAtRef(projectRoot, targetHash, blueprintFile.stableSlug, "delivery");
331
328
  if (authority.blueprintPath !== blueprintFile.path)
332
329
  return undefined;
330
+ const approvals = collectV2ReviewProvenance(path.resolve(projectRoot, blueprintFile.path), "delivery", targetHash);
333
331
  return {
334
332
  path: blueprintFile.path,
335
333
  lifecycle: authority.lifecycle,
336
- approvalsSatisfied: evaluateApprovalReviewers(authority.approvals.map((approval) => approval.reviewer)).satisfied,
334
+ approvalsSatisfied: evaluateApprovalReviewers(approvals.map((approval) => approval.reviewer))
335
+ .satisfied,
337
336
  };
338
337
  }
339
338
  catch {
@@ -582,7 +581,10 @@ export async function buildStatusSnapshot(options = {}) {
582
581
  "files",
583
582
  ].join(",");
584
583
  const [view, checksProbe] = await Promise.all([
585
- probe(cwd, "gh", ["pr", "view", ...selector, "--json", fields], probeOptions),
584
+ probe(cwd, "gh", ["pr", "view", ...selector, "--json", fields], {
585
+ ...probeOptions,
586
+ semanticMaxOutputBytes: PR_VIEW_SEMANTIC_MAX_OUTPUT_BYTES,
587
+ }),
586
588
  probe(cwd, "gh", ["pr", "checks", ...selector, "--required", "--json", "name,state,bucket,link,description"], probeOptions),
587
589
  ]);
588
590
  pr = view.passed ? parseJsonObject(view.semanticStdout) : undefined;
@@ -599,7 +601,7 @@ export async function buildStatusSnapshot(options = {}) {
599
601
  readGreptileComments(cwd, pr, probeOptions),
600
602
  ])
601
603
  : [{ complete: false, warning: "PR metadata unavailable." }, { comments: [] }];
602
- const blueprint = resolveBlueprintEvidence(cwd, firstLine(topLevel.semanticStdout) ?? cwd, pr, localHead);
604
+ const blueprint = resolveBlueprintEvidence(firstLine(topLevel.semanticStdout) ?? cwd, pr, localHead);
603
605
  const readiness = evaluatePrReadiness({
604
606
  localHead,
605
607
  dirtyWorktree,
@@ -649,9 +651,14 @@ export async function buildStatusSnapshot(options = {}) {
649
651
  threadsComplete: threads.complete,
650
652
  greptile: classifyGreptile(checks ?? [], greptileComments.comments, stringField(pr?.headRefOid)),
651
653
  };
654
+ // `body` is fully consumed above (release-evidence + disclosure via
655
+ // `evaluatePrReadiness`, blueprint linkage via `resolveBlueprintEvidence`),
656
+ // so drop it from the emitted metadata to keep the payload from re-ballooning
657
+ // to the size that truncated the parse in the first place.
658
+ const { body: _body, ...metadataWithoutBody } = pr ?? {};
652
659
  context.pr = {
653
660
  selector: selector[0],
654
- metadata: pr,
661
+ metadata: pr ? metadataWithoutBody : undefined,
655
662
  checks: readiness.checks
656
663
  ? { ...readiness.checks, checks: [...readiness.checks.checks] }
657
664
  : undefined,
@@ -0,0 +1,20 @@
1
+ import { BaseSequencer, type TestSpecification } from "vitest/node";
2
+ export declare function weightFor(project: string, relativePath: string): number;
3
+ interface WeightedSpec {
4
+ readonly spec: TestSpecification;
5
+ readonly weight: number;
6
+ readonly key: string;
7
+ }
8
+ /**
9
+ * Deterministic greedy LPT partition of `specs` into `count` bins. Files are
10
+ * sorted heaviest-first (ties broken by path so the order is stable across
11
+ * every shard job), then each is placed into the currently-lightest bin (ties
12
+ * broken by lowest bin index). Returns all bins in index order.
13
+ *
14
+ * Exported for the contract test; the sequencer only needs one bin.
15
+ */
16
+ export declare function partitionByDuration(specs: readonly WeightedSpec[], count: number): readonly (readonly WeightedSpec[])[];
17
+ export declare class DurationSequencer extends BaseSequencer {
18
+ shard(files: TestSpecification[]): Promise<TestSpecification[]>;
19
+ }
20
+ export {};
@@ -0,0 +1,54 @@
1
+ import { relative } from "node:path";
2
+ import { BaseSequencer } from "vitest/node";
3
+ import rawSnapshot from "./shard-durations.json" with { type: "json" };
4
+ const snapshot = rawSnapshot;
5
+ // A generated snapshot always carries a positive defaultWeight; clamp to 1 only
6
+ // to keep LPT well-defined if the JSON is ever hand-truncated to nothing.
7
+ const DEFAULT_WEIGHT = snapshot.defaultWeight > 0 ? snapshot.defaultWeight : 1;
8
+ export function weightFor(project, relativePath) {
9
+ return snapshot.durations[project]?.[relativePath] ?? DEFAULT_WEIGHT;
10
+ }
11
+ /**
12
+ * Deterministic greedy LPT partition of `specs` into `count` bins. Files are
13
+ * sorted heaviest-first (ties broken by path so the order is stable across
14
+ * every shard job), then each is placed into the currently-lightest bin (ties
15
+ * broken by lowest bin index). Returns all bins in index order.
16
+ *
17
+ * Exported for the contract test; the sequencer only needs one bin.
18
+ */
19
+ export function partitionByDuration(specs, count) {
20
+ const bins = Array.from({ length: count }, () => []);
21
+ const loads = Array.from({ length: count }, () => 0);
22
+ const ordered = [...specs].sort((a, b) => b.weight !== a.weight ? b.weight - a.weight : a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
23
+ for (const item of ordered) {
24
+ let target = 0;
25
+ let targetLoad = loads[0] ?? 0;
26
+ for (let i = 1; i < count; i += 1) {
27
+ const load = loads[i] ?? 0;
28
+ if (load < targetLoad) {
29
+ target = i;
30
+ targetLoad = load;
31
+ }
32
+ }
33
+ // target is always in [0, count): bins/loads were sized to `count`.
34
+ (bins[target] ??= []).push(item);
35
+ loads[target] = targetLoad + item.weight;
36
+ }
37
+ return bins;
38
+ }
39
+ export class DurationSequencer extends BaseSequencer {
40
+ async shard(files) {
41
+ const { config } = this.ctx;
42
+ // No --shard (serial lane, local full runs): nothing to partition.
43
+ if (!config.shard)
44
+ return files;
45
+ const { index, count } = config.shard;
46
+ const weighted = files.map((spec) => {
47
+ const key = relative(config.root, spec.moduleId);
48
+ return { spec, key, weight: weightFor(spec.project.name, key) };
49
+ });
50
+ const bins = partitionByDuration(weighted, count);
51
+ // index is 1-based in [1, count]; the bin is always present.
52
+ return (bins[index - 1] ?? []).map((item) => item.spec);
53
+ }
54
+ }