@1aboveio/skills 0.10.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 (397) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +90 -0
  3. package/bin/1aboveio-skills.mjs +18 -0
  4. package/package.json +28 -0
  5. package/runtime/skills/distribution/generated/recipes.json +1189 -0
  6. package/runtime/skills/distribution/scripts/bundles.mjs +280 -0
  7. package/runtime/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  8. package/skills/backend/airflow-dag-develop/LICENSE +3 -0
  9. package/skills/backend/airflow-dag-develop/SKILL.md +111 -0
  10. package/skills/backend/app-debug/LICENSE +3 -0
  11. package/skills/backend/app-debug/SKILL.md +109 -0
  12. package/skills/backend/app-debug/references/common-errors.md +128 -0
  13. package/skills/backend/python-backend/LICENSE +3 -0
  14. package/skills/backend/python-backend/SKILL.md +326 -0
  15. package/skills/cicd-pipeline/cloud-build/LICENSE +3 -0
  16. package/skills/cicd-pipeline/cloud-build/SKILL.md +707 -0
  17. package/skills/cicd-pipeline/cloud-debug/LICENSE +3 -0
  18. package/skills/cicd-pipeline/cloud-debug/SKILL.md +316 -0
  19. package/skills/cicd-pipeline/cloud-debug/references/build-failures.md +238 -0
  20. package/skills/cicd-pipeline/cloud-debug/references/deploy-failures.md +376 -0
  21. package/skills/cicd-pipeline/cloud-debug/references/pipeline-failures.md +378 -0
  22. package/skills/cicd-pipeline/cloud-deploy/LICENSE +3 -0
  23. package/skills/cicd-pipeline/cloud-deploy/SKILL.md +229 -0
  24. package/skills/cicd-pipeline/cloud-deploy/references/config-templates.md +257 -0
  25. package/skills/cicd-pipeline/docker/LICENSE +3 -0
  26. package/skills/cicd-pipeline/docker/SKILL.md +126 -0
  27. package/skills/cicd-pipeline/google-cloud/LICENSE +3 -0
  28. package/skills/cicd-pipeline/google-cloud/SKILL.md +118 -0
  29. package/skills/cicd-pipeline/google-cloud/references/gcs.md +469 -0
  30. package/skills/cicd-pipeline/google-cloud/references/iam.md +451 -0
  31. package/skills/cicd-pipeline/google-cloud/references/project.md +349 -0
  32. package/skills/cicd-pipeline/google-cloud/references/secrets.md +336 -0
  33. package/skills/cicd-pipeline/google-cloud/references/vpc.md +312 -0
  34. package/skills/cicd-pipeline/google-cloud/scripts/create-sa.sh +36 -0
  35. package/skills/cicd-pipeline/google-cloud/scripts/gcp-config.sh +31 -0
  36. package/skills/cicd-pipeline/google-cloud/scripts/grant-iap.sh +41 -0
  37. package/skills/cicd-pipeline/google-cloud/scripts/setup-secrets.sh +48 -0
  38. package/skills/cicd-pipeline/mergify/LICENSE +3 -0
  39. package/skills/cicd-pipeline/mergify/SKILL.md +138 -0
  40. package/skills/cicd-pipeline/mergify/assets/templates/mergify.yml +237 -0
  41. package/skills/cicd-pipeline/mergify/assets/templates/ruleset.json +46 -0
  42. package/skills/cicd-pipeline/mergify/references/branch-protection.md +277 -0
  43. package/skills/cicd-pipeline/mergify/references/configuration.md +183 -0
  44. package/skills/cicd-pipeline/mergify/references/diagnosis.md +73 -0
  45. package/skills/cicd-pipeline/mergify/references/traps.md +78 -0
  46. package/skills/cicd-pipeline/mergify/references/watch-contract.md +218 -0
  47. package/skills/cicd-pipeline/mergify/scripts/audit-core.mjs +131 -0
  48. package/skills/cicd-pipeline/mergify/scripts/audit.mjs +4 -0
  49. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery-core.mjs +663 -0
  50. package/skills/cicd-pipeline/mergify/scripts/watch-pr-delivery.mjs +4 -0
  51. package/skills/cicd-pipeline/podman/LICENSE +3 -0
  52. package/skills/cicd-pipeline/podman/SKILL.md +70 -0
  53. package/skills/cicd-pipeline/podman/agents/openai.yaml +4 -0
  54. package/skills/cicd-pipeline/podman/assets/templates/podman-compose-socket-directory.yml +6 -0
  55. package/skills/cicd-pipeline/podman/assets/templates/podman-service-override.conf +3 -0
  56. package/skills/cicd-pipeline/podman/references/compose-compatibility.md +70 -0
  57. package/skills/cicd-pipeline/podman/references/networking-and-ports.md +74 -0
  58. package/skills/cicd-pipeline/podman/references/rootless-services-and-sockets.md +156 -0
  59. package/skills/cicd-pipeline/podman/references/troubleshooting.md +98 -0
  60. package/skills/engineering/e2e-test/LICENSE +3 -0
  61. package/skills/engineering/e2e-test/SKILL.md +156 -0
  62. package/skills/engineering/e2e-test/assets/ci-gates.cloudbuild.yaml +272 -0
  63. package/skills/engineering/e2e-test/assets/ci-gates.github.yml +451 -0
  64. package/skills/engineering/e2e-test/assets/e2e-workflow.yml +282 -0
  65. package/skills/engineering/e2e-test/references/authoring/auth-flows.md +159 -0
  66. package/skills/engineering/e2e-test/references/authoring/playwright-config.md +71 -0
  67. package/skills/engineering/e2e-test/references/authoring/playwright-patterns.md +219 -0
  68. package/skills/engineering/e2e-test/references/authoring/test-skipping.md +44 -0
  69. package/skills/engineering/e2e-test/references/ci-integration.md +121 -0
  70. package/skills/engineering/e2e-test/references/ci-playwright-container.md +280 -0
  71. package/skills/engineering/e2e-test/references/debugging.md +36 -0
  72. package/skills/engineering/e2e-test/references/presentation-sweep.md +131 -0
  73. package/skills/engineering/e2e-test/references/reviewing.md +39 -0
  74. package/skills/engineering/e2e-test/references/route-discovery.md +50 -0
  75. package/skills/engineering/e2e-test/references/route-manifest.md +44 -0
  76. package/skills/engineering/e2e-test/scripts/detect-routes-fastapi.py +290 -0
  77. package/skills/engineering/e2e-test/scripts/detect-routes-nextjs.mjs +200 -0
  78. package/skills/engineering/e2e-test/scripts/post-visual-evidence.mjs +158 -0
  79. package/skills/engineering/e2e-test/scripts/presentation-checks.mjs +171 -0
  80. package/skills/engineering/e2e-test/scripts/presentation-perceivability.mjs +179 -0
  81. package/skills/engineering/e2e-test/scripts/presentation-reachability.mjs +154 -0
  82. package/skills/engineering/e2e-test/scripts/presentation-render-health.mjs +141 -0
  83. package/skills/engineering/e2e-test/scripts/presentation-sweep.mjs +148 -0
  84. package/skills/engineering/e2e-test/scripts/presentation-temporal.mjs +127 -0
  85. package/skills/engineering/e2e-test/scripts/presentation-visual.mjs +84 -0
  86. package/skills/engineering/e2e-test/scripts/project-route-manifest.mjs +75 -0
  87. package/skills/engineering/e2e-test/scripts/validate-manifest.mjs +106 -0
  88. package/skills/engineering/engineering-runtime/LICENSE +3 -0
  89. package/skills/engineering/engineering-runtime/SKILL.md +10 -0
  90. package/skills/engineering/engineering-runtime/agents/openai.yaml +6 -0
  91. package/skills/engineering/engineering-runtime/coherence/workflow.json +553 -0
  92. package/skills/engineering/engineering-runtime/scripts/exact-head-artifact.mjs +131 -0
  93. package/skills/engineering/engineering-runtime/scripts/head-check-set.mjs +398 -0
  94. package/skills/engineering/engineering-runtime/scripts/main-module.mjs +80 -0
  95. package/skills/engineering/engineering-runtime/scripts/mergify-yaml.mjs +11 -0
  96. package/skills/engineering/engineering-runtime/scripts/package-lock.json +43 -0
  97. package/skills/engineering/engineering-runtime/scripts/package.json +10 -0
  98. package/skills/engineering/engineering-runtime/scripts/required-check-plan.mjs +223 -0
  99. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +576 -0
  100. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +166 -0
  101. package/skills/engineering/ensure-coverage/LICENSE +3 -0
  102. package/skills/engineering/ensure-coverage/SKILL.md +136 -0
  103. package/skills/engineering/ensure-coverage/evals/evals.json +125 -0
  104. package/skills/engineering/ensure-coverage/references/breadth/coverage-ledger.md +91 -0
  105. package/skills/engineering/ensure-coverage/references/breadth/inventory-contract.md +83 -0
  106. package/skills/engineering/ensure-coverage/references/breadth/surface-baseline.md +44 -0
  107. package/skills/engineering/ensure-coverage/references/breadth/surface-discovery.md +16 -0
  108. package/skills/engineering/ensure-coverage/references/depth/characterization.md +68 -0
  109. package/skills/engineering/ensure-coverage/references/depth/coverage.config.example.json +25 -0
  110. package/skills/engineering/ensure-coverage/references/depth/grading.md +35 -0
  111. package/skills/engineering/ensure-coverage/references/depth/mock-policy.md +87 -0
  112. package/skills/engineering/ensure-coverage/references/depth/test-smells.md +23 -0
  113. package/skills/engineering/ensure-coverage/references/enforcement/ci-contract.md +164 -0
  114. package/skills/engineering/ensure-coverage/references/enforcement/hooks.md +85 -0
  115. package/skills/engineering/ensure-coverage/references/examples/coverage-ledger.md +109 -0
  116. package/skills/engineering/ensure-coverage/references/examples/refund-flow.md +33 -0
  117. package/skills/engineering/ensure-coverage/references/presentation/axis.md +78 -0
  118. package/skills/engineering/ensure-coverage/references/presentation/runner-contract.md +74 -0
  119. package/skills/engineering/ensure-coverage/references/process/audit-mode.md +33 -0
  120. package/skills/engineering/ensure-coverage/references/process/output-template.md +139 -0
  121. package/skills/engineering/ensure-coverage/references/process/review-contract-template.md +119 -0
  122. package/skills/engineering/ensure-coverage/references/process/scope-class.md +178 -0
  123. package/skills/engineering/ensure-coverage/references/process/test-strategy.md +55 -0
  124. package/skills/engineering/ensure-coverage/schemas/coverage-config.schema.json +45 -0
  125. package/skills/engineering/ensure-coverage/schemas/coverage-file.schema.json +93 -0
  126. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.mjs +178 -0
  127. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.mjs +101 -0
  128. package/skills/engineering/ensure-coverage/scripts/ci-audit.mjs +358 -0
  129. package/skills/engineering/ensure-coverage/scripts/coverage-checklist.mjs +494 -0
  130. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.mjs +663 -0
  131. package/skills/engineering/ensure-coverage/scripts/design-parity.mjs +591 -0
  132. package/skills/engineering/ensure-coverage/scripts/evidence-block.mjs +367 -0
  133. package/skills/engineering/ensure-coverage/scripts/lint-tests.mjs +269 -0
  134. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.mjs +176 -0
  135. package/skills/engineering/ensure-coverage/scripts/package-lock.json +76 -0
  136. package/skills/engineering/ensure-coverage/scripts/package.json +19 -0
  137. package/skills/engineering/ensure-coverage/scripts/scope-class.mjs +554 -0
  138. package/skills/engineering/harness-runtime/LICENSE +3 -0
  139. package/skills/engineering/harness-runtime/SKILL.md +18 -0
  140. package/skills/engineering/harness-runtime/agents/openai.yaml +6 -0
  141. package/skills/engineering/harness-runtime/bin/discover-models.mjs +4 -0
  142. package/skills/engineering/harness-runtime/bin/model-catalog.mjs +4 -0
  143. package/skills/engineering/harness-runtime/contracts.md +15 -0
  144. package/skills/engineering/harness-runtime/discover-models.mjs +392 -0
  145. package/skills/engineering/harness-runtime/fixtures/native-question-schemas.json +33 -0
  146. package/skills/engineering/harness-runtime/fixtures/question-responses.json +54 -0
  147. package/skills/engineering/harness-runtime/index.mjs +767 -0
  148. package/skills/engineering/harness-runtime/model-catalog.mjs +787 -0
  149. package/skills/engineering/harness-runtime/native-question-contracts.md +37 -0
  150. package/skills/engineering/harness-runtime/references/model-catalog-seed.json +159 -0
  151. package/skills/engineering/harness-runtime/references/model-catalog.md +57 -0
  152. package/skills/engineering/implement-and-pr/LICENSE +3 -0
  153. package/skills/engineering/implement-and-pr/SKILL.md +176 -0
  154. package/skills/engineering/implement-and-pr/references/ci-iteration.md +10 -0
  155. package/skills/engineering/implement-and-pr/references/closeout.md +27 -0
  156. package/skills/engineering/implement-and-pr/references/contract-complete-fix-rounds.md +34 -0
  157. package/skills/engineering/implement-and-pr/references/evidence-rules.md +39 -0
  158. package/skills/engineering/implement-and-pr/references/incremental-plan.md +16 -0
  159. package/skills/engineering/implement-and-pr/references/self-review.md +23 -0
  160. package/skills/engineering/implement-and-pr/references/tdd-mode.md +18 -0
  161. package/skills/engineering/resolve-issues/LICENSE +3 -0
  162. package/skills/engineering/resolve-issues/SKILL.md +167 -0
  163. package/skills/engineering/resolve-issues/generated/workflow-repair-policy.json +448 -0
  164. package/skills/engineering/resolve-issues/references/breaker.md +82 -0
  165. package/skills/engineering/resolve-issues/references/deliverables.md +27 -0
  166. package/skills/engineering/resolve-issues/references/delivery.md +108 -0
  167. package/skills/engineering/resolve-issues/references/evidence-lane.md +21 -0
  168. package/skills/engineering/resolve-issues/references/exact-head-ci.md +287 -0
  169. package/skills/engineering/resolve-issues/references/fan-out.md +33 -0
  170. package/skills/engineering/resolve-issues/references/finalization.md +68 -0
  171. package/skills/engineering/resolve-issues/references/guarantees.md +10 -0
  172. package/skills/engineering/resolve-issues/references/high-risk.md +29 -0
  173. package/skills/engineering/resolve-issues/references/incidents/848/README.md +156 -0
  174. package/skills/engineering/resolve-issues/references/intake.md +86 -0
  175. package/skills/engineering/resolve-issues/references/integration-gate.md +53 -0
  176. package/skills/engineering/resolve-issues/references/interference.md +87 -0
  177. package/skills/engineering/resolve-issues/references/loop.md +134 -0
  178. package/skills/engineering/resolve-issues/references/model-catalog.md +9 -0
  179. package/skills/engineering/resolve-issues/references/postmortem.md +27 -0
  180. package/skills/engineering/resolve-issues/references/pre-flight-model-slots.md +41 -0
  181. package/skills/engineering/resolve-issues/references/pre-flight-recording-and-checkout.md +48 -0
  182. package/skills/engineering/resolve-issues/references/pre-flight.md +41 -0
  183. package/skills/engineering/resolve-issues/references/regression-checklist.md +26 -0
  184. package/skills/engineering/resolve-issues/references/run-state.md +288 -0
  185. package/skills/engineering/resolve-issues/references/sandboxed-testing.md +48 -0
  186. package/skills/engineering/resolve-issues/references/spawn-contract.md +96 -0
  187. package/skills/engineering/resolve-issues/references/terminal-evidence-journal.md +40 -0
  188. package/skills/engineering/resolve-issues/references/why.md +653 -0
  189. package/skills/engineering/resolve-issues/schemas/fix-round.schema.json +49 -0
  190. package/skills/engineering/resolve-issues/scripts/combine-and-verify.mjs +721 -0
  191. package/skills/engineering/resolve-issues/scripts/component-candidate.mjs +962 -0
  192. package/skills/engineering/resolve-issues/scripts/contract-revision.mjs +220 -0
  193. package/skills/engineering/resolve-issues/scripts/detect-delivery-mode.mjs +420 -0
  194. package/skills/engineering/resolve-issues/scripts/detect-target-branch.mjs +256 -0
  195. package/skills/engineering/resolve-issues/scripts/detect-workspace-mode.mjs +168 -0
  196. package/skills/engineering/resolve-issues/scripts/discover-models.mjs +9 -0
  197. package/skills/engineering/resolve-issues/scripts/doctrine.mjs +62 -0
  198. package/skills/engineering/resolve-issues/scripts/evidence-lifecycle-contract.mjs +191 -0
  199. package/skills/engineering/resolve-issues/scripts/exact-head-ci.mjs +413 -0
  200. package/skills/engineering/resolve-issues/scripts/exact-head-github-provider.mjs +332 -0
  201. package/skills/engineering/resolve-issues/scripts/finalize.mjs +488 -0
  202. package/skills/engineering/resolve-issues/scripts/fix-rounds.mjs +3307 -0
  203. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-circular-1001.json +16 -0
  204. package/skills/engineering/resolve-issues/scripts/fixtures/evidence-lifecycle-valid-sequencing.json +51 -0
  205. package/skills/engineering/resolve-issues/scripts/fixtures/fmm-express-830-component-candidate.json +17 -0
  206. package/skills/engineering/resolve-issues/scripts/fixtures/head-check-set-1081.json +166 -0
  207. package/skills/engineering/resolve-issues/scripts/gate-value-series.mjs +92 -0
  208. package/skills/engineering/resolve-issues/scripts/guide-index.mjs +73 -0
  209. package/skills/engineering/resolve-issues/scripts/head-check-set.mjs +159 -0
  210. package/skills/engineering/resolve-issues/scripts/interference.mjs +427 -0
  211. package/skills/engineering/resolve-issues/scripts/model-catalog.mjs +9 -0
  212. package/skills/engineering/resolve-issues/scripts/next-operations.mjs +419 -0
  213. package/skills/engineering/resolve-issues/scripts/postmortem.mjs +909 -0
  214. package/skills/engineering/resolve-issues/scripts/preflight-questions.mjs +322 -0
  215. package/skills/engineering/resolve-issues/scripts/reconcile-contained-unit-prs.mjs +415 -0
  216. package/skills/engineering/resolve-issues/scripts/release-state-contract.mjs +697 -0
  217. package/skills/engineering/resolve-issues/scripts/report.mjs +494 -0
  218. package/skills/engineering/resolve-issues/scripts/required-check-plan.mjs +172 -0
  219. package/skills/engineering/resolve-issues/scripts/round-metadata.mjs +79 -0
  220. package/skills/engineering/resolve-issues/scripts/run-state-review6-cases.mjs +334 -0
  221. package/skills/engineering/resolve-issues/scripts/run-state.mjs +4784 -0
  222. package/skills/engineering/resolve-issues/scripts/sandbox-selftest.mjs +395 -0
  223. package/skills/engineering/resolve-issues/scripts/spawn-contract.mjs +290 -0
  224. package/skills/engineering/resolve-issues/scripts/terminal-dispositions.mjs +170 -0
  225. package/skills/engineering/resolve-issues/scripts/terminal-evidence-journal.mjs +293 -0
  226. package/skills/engineering/resolve-issues/scripts/unit-kind.mjs +197 -0
  227. package/skills/engineering/resolve-issues/scripts/unit-lifecycle.mjs +127 -0
  228. package/skills/engineering/resolve-issues/scripts/watch-delivery.mjs +893 -0
  229. package/skills/engineering/resolve-issues/scripts/workspaces.mjs +829 -0
  230. package/skills/engineering/resolve-issues/workflows/independent-review.workflow.js +290 -0
  231. package/skills/engineering/resolve-issues/workflows/prior-art-scan.workflow.js +80 -0
  232. package/skills/engineering/resolve-issues/workflows/workflow-smoke.mjs +102 -0
  233. package/skills/engineering/resolve-release/LICENSE +3 -0
  234. package/skills/engineering/resolve-release/SKILL.md +112 -0
  235. package/skills/engineering/resolve-release/references/assembly.md +137 -0
  236. package/skills/engineering/resolve-release/references/auto-when-green.md +56 -0
  237. package/skills/engineering/resolve-release/references/candidate.md +167 -0
  238. package/skills/engineering/resolve-release/references/exposure.md +178 -0
  239. package/skills/engineering/resolve-release/references/handoff.md +24 -0
  240. package/skills/engineering/resolve-release/references/postmortem.md +230 -0
  241. package/skills/engineering/resolve-release/references/preflight.md +207 -0
  242. package/skills/engineering/resolve-release/references/principles.md +94 -0
  243. package/skills/engineering/resolve-release/references/regression-checklist.md +36 -0
  244. package/skills/engineering/resolve-release/references/related-skills.md +12 -0
  245. package/skills/engineering/resolve-release/references/routing.md +149 -0
  246. package/skills/engineering/resolve-release/references/verified-sha-github-flow.md +285 -0
  247. package/skills/engineering/resolve-release/references/versioning.md +202 -0
  248. package/skills/engineering/resolve-release/references/why.md +53 -0
  249. package/skills/engineering/resolve-release/scripts/adapter-completion-artifact.mjs +389 -0
  250. package/skills/engineering/resolve-release/scripts/build-changes.mjs +209 -0
  251. package/skills/engineering/resolve-release/scripts/candidate-hygiene.mjs +407 -0
  252. package/skills/engineering/resolve-release/scripts/candidate-identity.mjs +904 -0
  253. package/skills/engineering/resolve-release/scripts/candidate-traffic.mjs +81 -0
  254. package/skills/engineering/resolve-release/scripts/checked-adapter-loader.mjs +612 -0
  255. package/skills/engineering/resolve-release/scripts/close-attempt.mjs +135 -0
  256. package/skills/engineering/resolve-release/scripts/closeout-release.mjs +161 -0
  257. package/skills/engineering/resolve-release/scripts/doctrine.mjs +106 -0
  258. package/skills/engineering/resolve-release/scripts/durable-processing.mjs +522 -0
  259. package/skills/engineering/resolve-release/scripts/ensure-target-green.mjs +659 -0
  260. package/skills/engineering/resolve-release/scripts/evidence-bundle.mjs +1014 -0
  261. package/skills/engineering/resolve-release/scripts/finalize-release.mjs +526 -0
  262. package/skills/engineering/resolve-release/scripts/fixtures/durable-processing-adapter.mjs +169 -0
  263. package/skills/engineering/resolve-release/scripts/green-gate.mjs +599 -0
  264. package/skills/engineering/resolve-release/scripts/isolated-adapter-evaluator.mjs +752 -0
  265. package/skills/engineering/resolve-release/scripts/metadata-pr-status.mjs +56 -0
  266. package/skills/engineering/resolve-release/scripts/metadata-sync.mjs +1538 -0
  267. package/skills/engineering/resolve-release/scripts/postmortem.mjs +381 -0
  268. package/skills/engineering/resolve-release/scripts/preflight-probes.mjs +498 -0
  269. package/skills/engineering/resolve-release/scripts/production-endpoints.mjs +326 -0
  270. package/skills/engineering/resolve-release/scripts/rc-circuit-breaker.mjs +272 -0
  271. package/skills/engineering/resolve-release/scripts/report.mjs +417 -0
  272. package/skills/engineering/resolve-release/scripts/reprobe-credentials.mjs +114 -0
  273. package/skills/engineering/resolve-release/scripts/revalidate-candidate.mjs +238 -0
  274. package/skills/engineering/resolve-release/scripts/review-packet.mjs +503 -0
  275. package/skills/engineering/resolve-release/scripts/rollback-floor.mjs +263 -0
  276. package/skills/engineering/resolve-release/scripts/version-assert.mjs +339 -0
  277. package/skills/engineering/resolve-release/scripts/version-postmortem.mjs +485 -0
  278. package/skills/engineering/resolve-release/scripts/version.mjs +1199 -0
  279. package/skills/engineering/resolve-release/scripts/watch-candidate-delivery.mjs +449 -0
  280. package/skills/engineering/resolve-release/vendor/ACORN-LICENSE +21 -0
  281. package/skills/engineering/resolve-release/vendor/README.md +60 -0
  282. package/skills/engineering/resolve-release/vendor/acorn.mjs +6233 -0
  283. package/skills/engineering/resolve-release/vendor/quickjs/core/LICENSE +21 -0
  284. package/skills/engineering/resolve-release/vendor/quickjs/core/README.md +341 -0
  285. package/skills/engineering/resolve-release/vendor/quickjs/core/README.template.md +70 -0
  286. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs +2 -0
  287. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-TAV5CUKK.mjs.map +1 -0
  288. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs +7 -0
  289. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/chunk-V2S4ZYJR.mjs.map +1 -0
  290. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.mts +2033 -0
  291. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.d.ts +2033 -0
  292. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js +7 -0
  293. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.js.map +1 -0
  294. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs +2 -0
  295. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/index.mjs.map +1 -0
  296. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs +2 -0
  297. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-ES6BEMUI.mjs.map +1 -0
  298. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs +2 -0
  299. package/skills/engineering/resolve-release/vendor/quickjs/core/dist/module-asyncify-2EFITU5U.mjs.map +1 -0
  300. package/skills/engineering/resolve-release/vendor/quickjs/core/package.json +49 -0
  301. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/LICENSE +21 -0
  302. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/README.md +5 -0
  303. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.mts +549 -0
  304. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.d.ts +549 -0
  305. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js +2 -0
  306. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.js.map +1 -0
  307. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs +2 -0
  308. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/dist/index.mjs.map +1 -0
  309. package/skills/engineering/resolve-release/vendor/quickjs/ffi-types/package.json +36 -0
  310. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/LICENSE +47 -0
  311. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/README.md +82 -0
  312. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.d.ts +11 -0
  313. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.browser.mjs +22 -0
  314. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cjs +21 -0
  315. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.cjs +21 -0
  316. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.cloudflare.d.ts +11 -0
  317. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.d.ts +11 -0
  318. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.mjs +25 -0
  319. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/emscripten-module.wasm +0 -0
  320. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.mts +85 -0
  321. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.d.ts +85 -0
  322. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js +2 -0
  323. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.js.map +1 -0
  324. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs +2 -0
  325. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/ffi.mjs.map +1 -0
  326. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.mts +20 -0
  327. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.d.ts +20 -0
  328. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js +2 -0
  329. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.js.map +1 -0
  330. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs +2 -0
  331. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/dist/index.mjs.map +1 -0
  332. package/skills/engineering/resolve-release/vendor/quickjs/release-sync/package.json +61 -0
  333. package/skills/engineering/review-pr/LICENSE +3 -0
  334. package/skills/engineering/review-pr/SKILL.md +123 -0
  335. package/skills/engineering/review-pr/references/adversarial-reviewer-prompt.md +42 -0
  336. package/skills/engineering/review-pr/references/code-correctness.md +5 -0
  337. package/skills/engineering/review-pr/references/contract-freshness.md +9 -0
  338. package/skills/engineering/review-pr/references/coordination.md +18 -0
  339. package/skills/engineering/review-pr/references/domain-hazards.md +123 -0
  340. package/skills/engineering/review-pr/references/finding-themes.md +7 -0
  341. package/skills/engineering/review-pr/references/github-posting.md +98 -0
  342. package/skills/engineering/review-pr/references/golden-path-smoke.md +5 -0
  343. package/skills/engineering/review-pr/references/incremental-output.md +16 -0
  344. package/skills/engineering/review-pr/references/inputs-and-discovery.md +31 -0
  345. package/skills/engineering/review-pr/references/output-format.md +99 -0
  346. package/skills/engineering/review-pr/references/over-mock-screen.md +7 -0
  347. package/skills/engineering/review-pr/references/promotion-prs.md +16 -0
  348. package/skills/engineering/review-pr/references/re-review.md +18 -0
  349. package/skills/engineering/review-pr/references/review-method.md +199 -0
  350. package/skills/engineering/review-pr/references/review-mode.md +30 -0
  351. package/skills/engineering/review-pr/references/review-posture.md +53 -0
  352. package/skills/engineering/review-pr/references/round1-depth.md +62 -0
  353. package/skills/engineering/review-pr/references/scripts.md +17 -0
  354. package/skills/engineering/review-pr/references/workflow.md +16 -0
  355. package/skills/engineering/review-pr/schemas/findings.schema.json +282 -0
  356. package/skills/engineering/review-pr/scripts/finding-contract.mjs +285 -0
  357. package/skills/engineering/review-pr/scripts/post-review.mjs +405 -0
  358. package/skills/engineering/review-pr/scripts/pr-context.mjs +207 -0
  359. package/skills/engineering/review-pr/scripts/scan-diff.mjs +365 -0
  360. package/skills/engineering/review-pr/scripts/theme-contract.mjs +57 -0
  361. package/skills/engineering/smoke/LICENSE +3 -0
  362. package/skills/engineering/smoke/SKILL.md +131 -0
  363. package/skills/engineering/smoke/assets/smoke.manifest.example.json +53 -0
  364. package/skills/engineering/smoke/references/manifest.md +192 -0
  365. package/skills/engineering/smoke/scripts/smoke.mjs +713 -0
  366. package/skills/fullstack/better-auth/LICENSE +3 -0
  367. package/skills/fullstack/better-auth/SKILL.md +601 -0
  368. package/skills/fullstack/better-auth/references/feishu-api.md +270 -0
  369. package/skills/fullstack/monorepo/LICENSE +3 -0
  370. package/skills/fullstack/monorepo/SKILL.md +465 -0
  371. package/skills/fullstack/nextjs-fullstack/LICENSE +3 -0
  372. package/skills/fullstack/nextjs-fullstack/SKILL.md +210 -0
  373. package/skills/fullstack/nextjs-fullstack/conventions.md +318 -0
  374. package/skills/fullstack/nextjs-fullstack/frontend-conventions.md +61 -0
  375. package/skills/fullstack/nextjs-fullstack/nextjs16.md +287 -0
  376. package/skills/fullstack/nextjs-fullstack/server-actions.md +409 -0
  377. package/skills/fullstack/prisma-setup/LICENSE +3 -0
  378. package/skills/fullstack/prisma-setup/SKILL.md +180 -0
  379. package/skills/fullstack/prisma-setup/nextjs.md +258 -0
  380. package/skills/fullstack/prisma-setup/turborepo.md +301 -0
  381. package/skills/fullstack/shadcn/LICENSE +3 -0
  382. package/skills/fullstack/shadcn/SKILL.md +119 -0
  383. package/skills/fullstack/shadcn/assets/shadcn-small.png +0 -0
  384. package/skills/fullstack/shadcn/assets/shadcn.png +0 -0
  385. package/skills/fullstack/shadcn/cli.md +411 -0
  386. package/skills/fullstack/shadcn/customization.md +224 -0
  387. package/skills/fullstack/shadcn/evals/evals.json +90 -0
  388. package/skills/fullstack/shadcn/mcp.md +101 -0
  389. package/skills/fullstack/shadcn/rules/base-vs-radix.md +323 -0
  390. package/skills/fullstack/shadcn/rules/component-selection.md +67 -0
  391. package/skills/fullstack/shadcn/rules/composition.md +195 -0
  392. package/skills/fullstack/shadcn/rules/data-table.md +201 -0
  393. package/skills/fullstack/shadcn/rules/forms.md +255 -0
  394. package/skills/fullstack/shadcn/rules/icons.md +103 -0
  395. package/skills/fullstack/shadcn/rules/styling.md +167 -0
  396. package/skills/fullstack/zod-v4/LICENSE +3 -0
  397. package/skills/fullstack/zod-v4/SKILL.md +287 -0
@@ -0,0 +1,653 @@
1
+ # Why — the incident record behind each rule
2
+
3
+ **Not a runtime file. Never read this during a run.** It is the archive behind the rules — the incident, the measurement, the audit — kept so a rule can be re-judged rather than re-litigated, and so an edit knows what it is deleting. It is read when you **edit this skill**, when you audit a decision, or when a rule looks wrong and you need to know what produced it. The `→ [why]` citations in the runtime files point here as provenance, not as a step: everything needed to run a unit is stated where its rule is, and a loop that stops to read this file is spending a run's context on history. Keeping it out of the loop is also what lets it stay long — nothing here competes for the budget the runtime files live under.
4
+
5
+ ## Typed unit kinds
6
+
7
+ A consumer product repo's #830/#839 required physically present Application and Terminal
8
+ operators on a live development Lane. The resolver normalized the child into the code loop
9
+ and spent six review rounds hardening an offline certification harness. The harness became
10
+ reviewed and CI-clean while the human-operated FMMPAY criterion remained blocked and
11
+ untouched. Typed intake, explicit confirmation, protocol-bound completion, and separate
12
+ code/external progress prevent that false delivery.
13
+
14
+ SKILL.md states **what** to do and **how** to do it. This file holds the **why**: the incident, the measurement, or the audit that put each rule there. Read the section for a rule when you are deciding whether it applies to an unusual case, when you are tempted to skip it, or when you are editing it — the [removal path](../SKILL.md#the-removal-path-keep-this-skill-small) requires a rule's justification to survive its rewrite, and a rule whose incident no longer reproduces is a candidate for deletion rather than for another clause.
15
+
16
+ A note on how to read these. They are **not** a hierarchy of severity, and none of them is an argument for applying more process to a routine unit. Several exist specifically to record the *mirror* failure — process weight applied where it bought nothing — because that failure is the one this skill regresses toward on its own.
17
+
18
+ | Rule in SKILL.md | Why |
19
+ |---|---|
20
+ | the four guarantees | [#the-four-guarantees](#the-four-guarantees) |
21
+ | main-loop only; the leaf-spawn contract | [#main-loop-only-and-the-spawn-contract](#main-loop-only-and-the-spawn-contract) |
22
+ | the spawn contract is rendered, not composed | [#the-spawn-contract-is-rendered-not-composed](#the-spawn-contract-is-rendered-not-composed) |
23
+ | epic-876: external review, slot env, empty CI commits | [#epic-876-external-review-slot-env-inject-and-empty-ci-commits-941](#epic-876-external-review-slot-env-inject-and-empty-ci-commits-941) |
24
+ | pre-flight: slots, branch, merge path | [#pre-flight](#pre-flight) |
25
+ | the reviewer slot is filled, not asked | [#the-reviewer-slot-is-filled-not-asked](#the-reviewer-slot-is-filled-not-asked) |
26
+ | the enqueue trigger (what merges without us) | [#the-enqueue-trigger](#the-enqueue-trigger) |
27
+ | decomposition gate | [#decomposition-gate](#decomposition-gate) |
28
+ | a roster that grows mid-run | [#a-roster-that-grows-mid-run](#a-roster-that-grows-mid-run) |
29
+ | a surface every sibling disclaims | [#a-surface-every-sibling-disclaims](#a-surface-every-sibling-disclaims) |
30
+ | scope double-check | [#scope-double-check](#scope-double-check) |
31
+ | design gate | [#design-gate](#design-gate) |
32
+ | high-risk units owe an invariant list | [#high-risk-units-owe-an-invariant-list](#high-risk-units-owe-an-invariant-list) |
33
+ | the gates bind resumed units | [#the-gates-bind-resumed-units](#the-gates-bind-resumed-units) |
34
+ | contract-revision gate | [#contract-revision-gate](#contract-revision-gate) |
35
+ | plan and progress reports | [#plan-and-progress-reports](#plan-and-progress-reports) |
36
+ | one producer spawn per unit | [#one-producer-spawn-per-unit](#one-producer-spawn-per-unit) |
37
+ | the screens, and the terminal-round attestation | [#the-screens-and-the-terminal-round-attestation](#the-screens-and-the-terminal-round-attestation) |
38
+ | the checklist screens resolve locators | [#the-checklist-screens-resolve-locators](#the-checklist-screens-resolve-locators) |
39
+ | review ∥ CI, and not blocking the fix on CI | [#review--ci-and-not-blocking-the-fix-on-ci](#review--ci-and-not-blocking-the-fix-on-ci) |
40
+ | delta re-reviews and the round log | [#delta-re-reviews-and-the-round-log](#delta-re-reviews-and-the-round-log) |
41
+ | every fix closes the invariant class | [#every-fix-closes-the-invariant-class](#every-fix-closes-the-invariant-class) |
42
+ | the evidence lane's two signals | [#the-evidence-lanes-two-signals](#the-evidence-lanes-two-signals) |
43
+ | the circuit-breaker, and bounded autonomy | [#the-circuit-breaker-and-bounded-autonomy](#the-circuit-breaker-and-bounded-autonomy) |
44
+ | the produce-pass breaker, removed | [#the-produce-pass-breaker-removed](#the-produce-pass-breaker-removed) |
45
+ | a fix never changes the scope class | [#a-fix-never-changes-the-scope-class](#a-fix-never-changes-the-scope-class) |
46
+ | the no-surface checklist exception | [#the-no-surface-checklist-exception](#the-no-surface-checklist-exception) |
47
+ | interference is the scheduling primitive | [#interference-is-the-scheduling-primitive](#interference-is-the-scheduling-primitive) |
48
+ | the orchestrator is a writer too | [#the-orchestrator-is-a-writer-too](#the-orchestrator-is-a-writer-too) |
49
+ | preserved on death, reaped only on success | [#preserved-on-death-reaped-only-on-success](#preserved-on-death-reaped-only-on-success) |
50
+ | the in-flight cap and its default | [#the-in-flight-cap-and-its-default](#the-in-flight-cap-and-its-default) |
51
+ | the component, not the epic | [#the-component-not-the-epic](#the-component-not-the-epic) |
52
+ | delivery: only ancestry is a result | [#delivery-only-ancestry-is-a-result](#delivery-only-ancestry-is-a-result) |
53
+ | the removal path | [#the-removal-path](#the-removal-path) |
54
+
55
+ ## The four guarantees
56
+
57
+ Each traces to a bug class this loop has actually caught, which is why a step serving none of them does not belong in the skill.
58
+
59
+ **Honest green.** CI green produced by weakening a test is not a result — it is the defect wearing the result's clothes. The recurring shapes: a skipped or `.only`'d test, a first-party internal seam mocked so the seam under test never runs, a journey intercepting its own routes, an assertion that passes against a 404 or an empty page. A missing precondition is the test's *arrange* step; guarding around it instead of seeding it is how a test stops testing anything while still reporting green.
60
+
61
+ **An independent review that actually ran.** Same-model review is the implementer grading its own kind of mistakes — the failure is not laziness, it is a shared blind spot, and it is invisible from inside. A prose review-shaped answer reads exactly like a real one; requiring `review-pr`'s two proof artifacts is what makes the difference legible.
62
+
63
+ **Exit on a fresh verdict, never a claim.** "I addressed the findings" is the most common terminal state in a run that did not converge.
64
+
65
+ **Merging requires explicit authorization.** Merges are outward-facing and hard to reverse; the default is to hand back.
66
+
67
+ ## Main-loop only, and the spawn contract
68
+
69
+ Nesting `resolve-issues` inside a subagent caps the reviewer spawn and silently degrades guarantee 2 to a same-context self-review — the run still produces a verdict, and the verdict is worthless. Inline implementation has the same shape one level down: it makes the session model the implementation model and makes the orchestrator the author adjudicating its own review.
70
+
71
+ Every clause of the leaf-spawn contract fails **silently** when omitted, which is why each is stated rather than assumed:
72
+
73
+ - **Read the skill at an absolute path.** A relative `skills/engineering/...` path resolves to nothing once this skill is installed into a consumer repo by symlink — and the spawn does not error. It reconstructs a plausible lookalike from memory that reads like a real review and gets graded like one.
74
+ - **Name the proof.** Output without its proof artifact did not run the skill.
75
+ - **Use the harness's own agent primitive.** What is required is a result channel back into this session, not a same-turn return: sync and async primitives both qualify, and what is not a spawn is a launch whose result never returns at all (a detached job, a background CLI, a queued task). Every gate here refuses a transition that is *attempted*, so a round that never comes back through a write is one no gate can refuse. The clause used to say "recordable in the same turn", meaning *before you act on it*; a Pi-harness run read that as a capability requirement and declared its issue blocked before implementation, since `subagent_spawn` delivers on a later turn — a correct reading of the text, and the wrong outcome (2026-07-25).
76
+ - **Pass the model *and* its effort.** A slot is an operating point, not a model. Carrying the id and dropping the effort runs a different capability tier than the human confirmed, and the read-back cannot tell, because the id matches.
77
+ - **Pass the working directory.** A spawn inherits the orchestrator's cwd unless told otherwise, so a `worktree` run whose spawns carry no path writes into the human's checkout anyway — the mode probed, recorded, rendered, and honoured by nothing.
78
+
79
+ Full incident detail: [spawn-contract.md](spawn-contract.md).
80
+
81
+ ## Pre-flight
82
+
83
+ `deliveryMode`/`queueProvider` are **probed** because a queue is a runtime fact whose configuration commonly lives dashboard-side, outside the repo — a file check answers the wrong question. Picking the merge path wrong fails silently in both directions: `gh pr merge` on a queue repo bypasses or errors, and an enqueue on a direct repo does nothing at all.
84
+
85
+ The probe was documented as a pre-flight decision long before any pre-flight step performed it. The number that exposed the omission: **`delivery` was written 0 times across 522 audited units**, fully mechanized, with dedicated commands. A gate nobody was told to open is indistinguishable from a gate nobody needed. (Fixed 2026-07-23 by [pre-flight.md](pre-flight.md) step 3a.)
86
+
87
+ **No silent fallback** exists because a spawn-time model substitution is invisible in the result: the verdict comes back looking exactly the same, and the diversity guard compares a pair that never ran.
88
+
89
+ ### The reviewer slot is filled, not asked
90
+
91
+ **A question whose answer is derivable is an interruption, not a choice.** The reviewer slot has exactly one hard constraint — `≠ implementer` — and a ranking that decides the rest (team default, then diversity-first ladder). Both are known before the human is asked anything, and the only input that can move the answer is the implementer, which the same gate collects. So the slot is resolved, stated, and overridable in one message, and the gate costs three questions on every run instead of three-or-four.
92
+
93
+ **What made this a rule rather than a preference is that the ask kept coming back on invented grounds.** The default's own paragraph lists the two situations that retire it; twice, an orchestrator found a third. **2026-08-03:** a discovered frontier model was read as outranking the default — and since every run the default was written for discovers a frontier, it fired **0 times**. **2026-08-16 (`epic-184-ssh-bg-tasks`):** an OpenAI implementer made the pairing `reduced diversity — same family`, and the flag was read as needing confirmation; the human answered the exact model the default names and said the question should not have been asked. Both inventions are the same move — turning a rule about *how the pairing is recorded* into a reason the fill does not apply — and prose refuting each new one is a race the prose loses.
94
+
95
+ So the rule is enforced where it cannot be reasoned around: `preflight-questions.mjs` plans **no** `review` question in any input shape it accepts, and resolves the fill at `record` against the answered implementer, reporting `reviewFill.reason` (`team-default` · `ladder` · `human-named` · `no-distinct-candidate`). A collision moves the fill down the ranking and is restated; only a single-model harness yields the implementer's own id, recorded `NOT INDEPENDENT` — asking there would offer one answer. This is the [mechanize-the-load-bearing-step](#the-spawn-contract-is-rendered-not-composed) shape applied to a gate: the doctrine explains the ranking, the script owns whether a human is interrupted.
96
+
97
+ **What the ranking is arguing about.** Judging a diff against a contract is cheaper than writing it, and what review buys is a second set of blind spots — a model that wasn't in the room when the code was written. Hence diversity before tier. Hence also the floor: the trade holds only among deep reasoners, which can hold the diff and the contract in mind and argue about them. Below that bar it inverts — a reviewer that can't follow the implementer's reasoning rubber-stamps or objects to the wrong things — so the ranking never reaches balanced-coder, whatever the family. A same-family lower-tier reviewer is the worst of both: the implementer's blind spots *and* less capacity to catch what remains. Between the two middle rungs, a *different* model of the same family still carries somewhat different blind spots, and that holds across generations, since deep-reasoner is a capability band rather than a chronology.
98
+
99
+ **What the default costs elsewhere, stated once here rather than re-argued at each slot.** Since 2026-08-02 the frontier band has no home slot: it is never recommended to implement, and the reviewer default sits a band below it, so on a routine run a discovered frontier model is spent on *nothing* unless a human names it. Two consequences the how-file carries as bare instructions. First, the never-implement bar now rests on the risk-profile claim alone — the older "frontier capability is spent on review" argument stopped being true that day, and the bar survives because the implementer choice never depended on it. Second, "routine units land in ~1–2 rounds with a balanced-coder implementer" was measured with a *frontier* reviewer, so it is an estimate carrying an untested change; climbing rounds on routine units are the first thing to suspect and the cheapest to test. That `gpt-5.5` is banded below frontier is the point rather than an oversight: the default is a preference about whose blind spots we want on review, not a claim about the strongest model available — the same independence-not-superiority argument, applied to the team's own choice.
100
+
101
+ **`autonomy` is one ask, not five, and it exists because a mid-run question is the expensive kind.** Every park this loop takes — a design-gated unit, a scope split, merge authorization — interrupts a human who has since moved on, and the run stops dead until they return. The same decision costs nothing at pre-flight, where they are already paying attention and have the whole roster in front of them. So the parks became a level rather than a set of mid-run asks. It rides one question because pre-flight's complete neutral batch already carries every required slot ([pre-flight.md](pre-flight.md) step 3), and it **subsumes** `mergeShippable` rather than joining it — otherwise pre-authorizing more of the loop would cost another interruption, which is the thing being removed.
102
+
103
+ Three things it deliberately cannot lift, and each is a constant or a state rule rather than prose, so no future level can quietly clear one:
104
+
105
+ - **The design gate**, at every level — see [below](#the-design-gate-hands-back). On auth/authz, money, tenancy and migrations especially: the enumerated invariant list is the artifact a human is still measurably better at, and it is exactly the class this loop's own first-pass review rate (~40–55%, auth/money semantic bugs dominating) says it loses. An AI-drafted invariant list graded by AI is a shared-blind-spot bet placed on the losing class.
106
+ - **The breaker's `descope`** — and, until 2026-07-26, `split` alongside it. Deciding to deliver less than the issue asked for is the one autonomous decision that leaves no trace in the handoff; every other shows up as rounds spent, which is visible. `descope` has **0 uses in 602 units** and stays human at every level.
107
+
108
+ **`split` was let go on measurement, and the measurement it replaced was stale.** `breaker.md` reported an early audit as "`split` never on a real unit", and that sentence was quoted — by me, in this repo, on 2026-07-26 — to argue against automating it. Re-measuring 246 live manifests / 602 units: **continue 17 · design 6 · split 5 · descope 0**, plus three further splits in epic-848 recorded only as blocker prose ("approved implementation split is #936…") that never reached the breaker, so the real rate is higher than 5. A split *re-slices* rather than shipping less, and it fires exactly where the loop hurts most — a unit that survived three failing review rounds plus a class-complete mandate carries the largest diff and the longest finding list, so each further round costs the producer and the reviewer their scarcest resource. It is now auto-decidable under `autonomy: autonomous` only, with the authorizing level stamped on the breaker record itself so the guard is self-contained and the handoff can say why the loop was allowed to take it. A split that drops a slice still owes a tracked `deferrals[]` entry — otherwise it is a descope wearing another label.
109
+
110
+ The transferable lesson is about the citation, not the decision: **an audit number quoted without re-running it is a claim about the past presented as a fact about the present.** This one had been stale long enough to nearly freeze a rule the data no longer supported.
111
+ - **The breaker's round ceiling.** Already a hard stop-and-ask; "autonomous" must never read as "unbounded".
112
+
113
+ The level is **answered, not described** — `run-state.mjs autonomy <slug>` returns the resolved policy and the parks that remain, the same shape as `delivery-flow`, because a policy the orchestrator re-derives from prose is one it will eventually re-derive differently. Exit 1 when the level was never set: it still resolves to the safe `supervised` default, but "nobody chose" and "the human chose supervised" are different facts.
114
+
115
+ ## The design gate hands back
116
+
117
+ **The incident (2026-07-25, Pi session `019f9865`, issue #5 — Linux `bwrap` sandbox support).** The design gate fired **correctly**: security-sensitive platform work, two implementers would plausibly have built different things (`bwrap` dependency vs. a native namespace/Landlock helper), and the failure semantics were unstated. What happened next cost the run everything:
118
+
119
+ | Measure | Result |
120
+ |---|---|
121
+ | Elapsed | **64 minutes** |
122
+ | Subagent spawns | **5** |
123
+ | Spend | **~$2** |
124
+ | Lines of the feature implemented | **0** |
125
+
126
+ The gate blocked, and then the run tried to *resolve the block in-session*. It interviewed the human inline across **seven** `AskUserQuestion` rounds, then banked the resulting ADR through the entire pipeline: a producer spawn to write it, an **independent review spawn at $1.07** against a 91-line docs-only diff (whose `scan-diff` returned `[]`, because there is no code in an ADR), `@mergifyio queue`, two watchers, a merge, and an ancestry proof. Then it did the same thing again for the test-criteria document — where the first criteria spawn died at **13 minutes** returning no parseable result and had to be reconstructed from its branch. The implementation never started.
127
+
128
+ **Nothing in that chain was an agent error.** Every step follows from a rule: the design gate says don't spawn the producer; the [contract-revision gate](#contract-revision-gate) says the approved contract must exist at a commit on the target branch; a commit implies a branch, a branch implies a PR, and a PR is owed guarantee 2's independent review, guarantee 3's fresh verdict on HEAD, and delivery's ancestry proof. The skill had no rule saying where that stops, so it didn't.
129
+
130
+ Two rules, both subtractive, close it:
131
+
132
+ 1. **The design gate's answer is to hand back, not to produce.** Say what is missing, name `/grill-with-docs`, stop the unit. Do not interview the human yourself — that is `/grill-with-docs`'s job, in its own session, and doing it inline is what makes the loop feel obliged to bank the result. [Pre-flight](pre-flight.md) step 0 now also skims for this before models, branch and delivery mode are settled, so the common case is caught at the cheapest possible moment; the intake gate stays as the backstop.
133
+ 2. **[Prerequisite artifacts are not units](intake.md#prerequisite-artifacts-are-not-units).** No producer spawn, no review spawn, no PR, no queue, no ancestry gate for a document. If it contains no code, it does not enter the loop.
134
+
135
+ **And the level that would have re-created it was cut.** `autonomous+design` — a third autonomy level that drafted a missing contract from a third model — existed for about an hour on 2026-07-25 and never ran. Its entire job was to produce, in-run, the artifact rule 1 says to hand back; it would have walked straight into rule 2's failure with an AI-authored contract instead of a human one. `AUTONOMY_LEVELS` is two levels, and a test pins that the drafting level was **cut, not renamed**.
136
+
137
+ ## The enqueue trigger
138
+
139
+ `deliveryMode` and `queueProvider` answer **how you enqueue**. Neither answers the question guarantee 4 actually rests on: **can this PR reach the target branch with no further action from the loop?**
140
+
141
+ A repo can carry an auto-merge rule that fires the moment its conditions hold, and the loop's own ordinary acts are what satisfy them — marking a PR ready, pushing the commit that turns CI green, posting the review verdict as an approval. Where that is true, `mergeShippable: false` is **unenforceable**: the loop never decides to merge, it merges as a side effect of reviewing, and nothing downstream reports it. That is the same silent-wrong-mode shape the mode probe exists to prevent, one axis over.
142
+
143
+ **The live configuration that produced this** (a consumer harness repo, 2026-07-25):
144
+
145
+ ```yaml
146
+ merge_protections_settings:
147
+ auto_merge_conditions:
148
+ - base = main
149
+ - "-draft"
150
+ - "#approved-reviews-by >= 1"
151
+ - "#changes-requested-reviews-by = 0"
152
+ - *gate # check-success = ci
153
+ ```
154
+
155
+ Its GitHub rulesets require **zero** approving reviews, so that one review condition *is* the entire merge authorization. A reviewer spawn posting its PASS as a GitHub approval on a ready, CI-green PR merges it — no enqueue, no decision, nothing left to refuse.
156
+
157
+ **What the trigger is not.** It is not manual-versus-auto as alternatives. Manual enqueue remains available on an auto repo, so the loop never loses a path — `hybrid` (both live) is the common real shape, and it is what both configs examined actually are. The trigger records that a *second* path exists which the loop does not drive; for authorization `auto` and `hybrid` are identical, and every gate reads them as `trigger !== 'manual'`.
158
+
159
+ **Three consequences, all mechanized rather than left to prose:**
160
+
161
+ - **The probe fails closed toward the hazard.** A config it could not read is UNKNOWN, never `manual`. Assuming `manual` costs a merge nobody authorized; assuming the hazard costs one human confirmation.
162
+ - **An unresolved YAML alias counts as trippable.** Both real configs hide the CI condition behind `*gate`. Resolving anchors means writing a YAML parser; calling the unread condition harmless means deciding on no evidence that the thing you could not read is safe.
163
+ - **On an auto-merge repo with `mergeShippable` off, a PASSING review is posted as a comment, not an approval.** This is the counterintuitive one and the reason it is a gate rather than a note: the verdict is good, the code is merge-ready, and the approval must still be withheld, because with `mergeShippable` off this run hands back rather than merges, and an approval there would merge it anyway. `approval-gate <slug> [componentId]` answers this; on auto/hybrid repos a preliminary unit review has no component id and stays comment-only even when mergeShippable is on. Only a terminally authorized frozen component can unlock approval, and `combine-and-verify mergeable --component` still runs first.
164
+
165
+ ## Decomposition gate
166
+
167
+ An epic's children are not evidence they cover it, and every downstream gate is *unit*-scoped: the producer builds to the child, the reviewer grades the net diff against the child's contract, CI grades the tree. So a parent requirement absent from all children is invisible to all of them, and the exit audit finds it only after units have merged and closed.
168
+
169
+ **Named incident — epic-848.** The parent's thirteen named report buckets, its already-correct counting, and its unrepairable-row reporting appeared in no child. A child passed review, merged, and closed while the epic's repair job could not run against the legacy data it existed to repair.
170
+
171
+ The gate is cheap on purpose — a set-difference over two issue bodies — which is why it fires once per epic rather than per unit.
172
+
173
+ ## A roster that grows mid-run
174
+
175
+ The gate fires at intake and again at the exit audit, which leaves uncovered the case where the epic changes shape *between* them. New sub-issues arrive with their own dependency claims, and the loop inherits them as if they had been there at intake. The failure is silent: finished work simply stops moving while the loop works the new frontier.
176
+
177
+ **Named incident — epic-986.** A blocker about four failing tests grew to sixteen units of release architecture in one comment. The four repairs, already merge-ready and independently reviewed, then sat behind an architecture unit none of them depended on.
178
+
179
+ Hence the default answer to "which new units block an already-merge-ready component": **none**. A unit that did not exist when a component reached its bar cannot retroactively become its prerequisite.
180
+
181
+ ## A surface every sibling disclaims
182
+
183
+ Out-of-scope language — *"X changes only indirectly"*, *"X remains agnostic"*, *"X is handled by \<sibling\>"* — is written as a guard and reads as one. It is also how work disappears between children: every child is green, and the parent's user-visible fix is still broken.
184
+
185
+ **Named incident — epic-848.** The case-reading UI was disclaimed by both UI children, left to corrected data by the repair child, and gated post-epic by the scalar-removal child. The database was repaired while the reviewer-facing surface kept rendering the legacy field.
186
+
187
+ ## Scope double-check
188
+
189
+ An issue arriving here is not evidence it is loop-sized; the human may have underestimated it. The circuit-breaker does catch a mis-sized unit, but late — at round 3, after three producer passes have been spent building the wrong shape.
190
+
191
+ **Named incident.** An issue queued as one unit was actually a whole repair subsystem: nine rounds before anyone re-sized it.
192
+
193
+ Scope is the human's call, which is why this produces a *proposal* rather than a decision — but the proposal is the loop's job, made from the issue's content rather than inherited from the fact that someone queued it.
194
+
195
+ ## Design gate
196
+
197
+ Leaf spawns cannot ask the human, so a design question that reaches a producer becomes a design question answered by guessing.
198
+
199
+ **Named incident.** A repair-subsystem issue spent ten review rounds re-deriving its unwritten contract one invariant at a time — roughly 6.5 unattended hours.
200
+
201
+ **The mirror failure matters as much.** Most routine units answer no to both questions: the issue *is* the design. Blocking those on a brief is over-triggering, not rigor, and it is the failure mode this gate regresses toward when read as a checklist.
202
+
203
+ ## High-risk units owe an invariant list
204
+
205
+ On auth/authz/token/session, money/tax/pricing, tenancy/org-scope and migrations, orderings/failures/retries/partial states are not edge cases — they *are* the surface. [high-risk.md](high-risk.md) names **spec maturity**, not code quality, as the reason these surfaces have low first-pass rates.
206
+
207
+ **Named incidents — the 127-run audit.** Of the six units that reached the circuit-breaker and were routed to a design pass, **five were high-risk units that had already passed the design gate**: #3, #5 and #7 of one epic, plus #936. Each spent 3–7 rounds "discovering new invariant classes" one per round until a human landed the ADR that ended it; #936 spent seven of those rounds building an obsolete route-based control plane.
208
+
209
+ The gate had been applied uniformly, and the risk flag already sitting in the manifest never reached it. Every one of those units had a contract *pointer* — which is why a pointer does not clear the gate and an enumerated list does.
210
+
211
+ ## The gates bind resumed units
212
+
213
+ Mid-loop is a late moment to discover a missing design; spawning the next fix round into a design vacuum is later.
214
+
215
+ **Observed.** A breaker-stopped unit resumed straight into a producer that re-implemented its subsystem with no ADR, because the gates were read as intake-only.
216
+
217
+ ## Contract-revision gate
218
+
219
+ An approved revision that lands on the target branch after a unit's base silently invalidates every verdict, CI result and runtime observation the unit has accumulated — none of which announce that they are now historical.
220
+
221
+ **Named incident.** Seven review rounds implemented an obsolete route-based control plane before a human-approved Cloud Run Job contract landed on the target branch; stale PR narration and evidence kept the obsolete implementation alive across all of them.
222
+
223
+ The related failure it also closes: an implementation PR making itself compliant by weakening its own source or test criteria.
224
+
225
+ ## Plan and progress reports
226
+
227
+ A long run is exactly where a human loses the thread. Both reports are **rendered from the manifest** rather than narrated because a hand-written report is complete on a short attentive run and quietly abridged on a long one — which is backwards, since the long run is the one that needs it.
228
+
229
+ Rendering also forces intake to *record* what it decided (`dependsOn`, `deferrals`) instead of holding it in context, and a rendered report cannot claim a unit is scheduled that the gates never recorded.
230
+
231
+ **Named incidents.** epic-848: a deferred requirement mentioned in passing and never tracked — which is why an untracked deferral is refused, since a requirement owned by nobody reads exactly like a requirement nobody needed. epic-986: units sitting merge-ready-but-undelivered for twelve hours while every summary read "done", which the progress render now surfaces as one flagged row.
232
+
233
+ Progress counts a blocked unit *beside* the resolved tally rather than inside it, because folding it in would pad the numerator with exactly the units that need a human.
234
+
235
+ ## Recovering a dead run is a command, not archaeology
236
+
237
+ A session dies mid-run and its successor has the repo and nothing else. Both halves of that were unmechanized: every read command took a `<slug>` — the one thing the dead session took with it (`list`, measured at 246 unenumerable manifests on one machine) — and once you had the slug, "what do I do now?" was answered by reading doctrine and reconstructing state by hand (`resume`).
238
+
239
+ **Named incident — #554, `pi-better-subagents` epic-5.** A spawn died at 13 minutes returning `(no final answer parsed)` with an empty log tail. Recovery worked only because the agent happened to have committed to a branch, which the orchestrator then guessed at: nothing in state pointed at the work. Grepped at the time: zero artifact paths recorded anywhere in the manifest.
240
+
241
+ Two rules keep `resume` a recovery tool rather than a pretty-printed manifest. The two in-flight situations — a unit `in-progress` and a unit `merge-ready` with no terminal delivery outcome — stay **distinct**, because they need opposite moves (one owes a spawn, the other owes a delivery) and one merged list gets one of them wrong. And where recorded state does not determine a next action, the report **says so** instead of naming one: a recovery tool that confidently names the wrong next step is worse than one that admits the gap, since the wrong step gets taken while the honest gap gets investigated. Same discipline as `list`'s unreadable-but-listed manifest — "could not look" must never read back as "looked and found nothing".
242
+
243
+ Mechanics: [run-state.md](run-state.md).
244
+
245
+ ## One producer spawn per unit
246
+
247
+ Separate implement / e2e / gate spawns each re-read the doctrine stack and re-derive context — the single largest fixed cost per unit. `implement-and-pr` already sequences all three.
248
+
249
+ The conditional-reference rule exists because `implement-and-pr` routes its heavier material behind caller-computed conditions, and the caller knows all of them: terminal round, `highRisk`, TDD mode, multi-slice. None require leaf-side judgment, and withholding them silently downgrades the round rather than failing it.
250
+
251
+ ## The screens, and the terminal-round attestation
252
+
253
+ `evidence-block.mjs validate` is deliberately not a per-round precondition. It asserts that a generated block still matches current HEAD — a claim void the moment the next fix commit lands — so demanding it every round forces a whole-document rewrite per round for a stamp that survives an hour.
254
+
255
+ It was also **unsatisfiable as specified**: whether a round is terminal is only knowable *after* the verdict and CI return, i.e. after the producer has already finished. `implement-and-pr` specified the attestation as terminal-round-only while this gate demanded it per round. (Fixed 2026-07-22 — the loop had been buying an evidence-fidelity finding class it manufactured itself.)
256
+
257
+ The screens stayed because they cost seconds and are what keep the review honest.
258
+
259
+ **What the retiming moved, and what it concentrated (2026-07-30).** Dropping the per-round precondition removed the churn but left the check with no caller at all: the attestation was owed on the terminal round and verified by nobody until the reviewer read it. So the one round whose stamp is genuinely load-bearing became the one round the stamp is unscreened on — and a stale stamp there is an evidence-class finding on the *terminal* review, which is the worst place in the unit to find one. It does not merely cost a fix; it costs the fix **plus a fresh re-review to exit**, because guarantee 3 will not take a claim. The narrow form — run `validate` before the reviewer spawn *on the round you flagged terminal, and only that round* — keeps the whole reason for the retiming (no per-round document rewrite) and closes the hole. The producer is already running `collect` on that round, so the marginal cost is one process.
260
+
261
+ Note this is the retiming's own logic applied one step further, not a reversal of it: the objection was to paying a rewrite on rounds that would be invalidated within the hour, and the terminal round is by construction the round that will not be.
262
+
263
+ ## The checklist screens resolve locators
264
+
265
+ `coverage-checklist.mjs validate` checked the **shape** of evidence and was read as checking its **truth**. `hasLocator` is three regexes — does this look like `file:line`, does it have backticks, is there a `#123` — so three rows that are well-formed and false passed it, and every one of them is an evidence-class review finding:
266
+
267
+ | Row as written | Why it passed | What it actually was |
268
+ |---|---|---|
269
+ | `PASS` \| `_run_ ` \`coverage-ledger.mjs validate\` | backticks | the generated skeleton with a decision typed over it — the gate never ran |
270
+ | `PASS` \| `src/gone.ts:9999 — looks fine` | `file:line` shape | a locator into a file that does not exist |
271
+ | `PASS` \| `see #1` | `#\d+` | a reference to anything at all |
272
+
273
+ The gap is structural rather than incidental: a shape check cannot fail on a claim that is merely untrue, so **every untrue-but-well-formed row is routed to the reviewer by construction** — and the reviewer is the expensive party. That is the answer to the question [evidence-lane.md](evidence-lane.md) asks about itself ("if this lane is still the common path, chase why the screens are not catching what the reviewer is catching").
274
+
275
+ The three checks added, each against an incident this loop already recorded:
276
+
277
+ - **A cited `path:line` must resolve in the tree** — the file exists and the line is inside it. The two halves have different certainty and are treated differently: a line **past the end of an existing file** is unambiguous and blocks, while a **missing file** is only decidable with the diff, since a deletion this PR made looks identical to a stale locator — so with `--diff` it blocks and without it warns. *Incident:* a reviewer that wrote *"the implementation itself is correct at this head"* and blocked solely on a checklist citing a pre-restack base, then spent the following round rejecting the checklist fix — two rounds, no production code.
278
+ - **A `gate-lint` row must carry the gate's result, not just its command** — an exit code, a `→ N findings`, or the `file:line` hits. *Incident:* a hand-written attestation claiming `leadCount=0` for a diff whose real scan had 1,749 leads (recorded in `evidence-block.mjs`'s header) — a full review round spent on a transcription error.
279
+ - **Locators entirely outside the net diff warn, never block.** The stale-locator smell is real but a row may legitimately cite unchanged code it reasons about, and a screen that fires on honest evidence costs exactly the round it exists to save. Warned, exit 0.
280
+
281
+ Three carve-outs keep the check from firing on true evidence, and they matter as much as the checks — a screen that blocks an honest claim costs exactly the round it was built to save, so on every ambiguity this one fails **open** and leaves the catch to the reviewer who is still downstream:
282
+
283
+ - **A path this PR deletes is exempt.** *"Removed the over-mocked test at `tests/foo.spec.ts:40`"* is a true locator that resolves to nothing on purpose.
284
+ - **Without `--diff`, a missing file warns instead of blocking** — stale and deleted are indistinguishable there, so blocking would be a guess. **Pass `--diff <merge-base>`**: it is what converts that warning into a decision, which is why it is part of the call rather than an optimization.
285
+ - **Locators are anchored at the git toplevel, then retried against the cwd.** Checklist locators are repo-relative — every generator emits them that way — so anchoring at `process.cwd()` made the same honest checklist pass from the repo root and fail from `apps/web/`, reporting live files as missing.
286
+
287
+ `--no-resolve` restores the shape-only behaviour for a caller with no tree to resolve against.
288
+
289
+ (The last two were found by auditing this change rather than by an incident, and both were the *same* mistake the checks exist to prevent, pointed the other way: a guard that is wrong about the evidence. The gate-result check made it a third time — its first version enumerated outcome markers (`→`, `exit N`, "0 findings") and rejected `` `coverage-ledger.mjs validate` — clean``, an ordinary honest result. It is now a subtraction rather than a vocabulary: strip the row's catalog command and the skeleton's own `_run_` annotation, and a skeleton has nothing left while any real result does. A catalog-derived test asserts no skeleton the renderer can emit survives, which is what caught the vocabulary version failing on a row whose command carried un-backticked prose.)
290
+
291
+ ## Review ∥ CI, and not blocking the fix on CI
292
+
293
+ Most rounds bounce. Waiting for `max(review, CI)` before starting the fix pays the CI wait on every one of them; starting on the review verdict pays it once, at the end. A CI failure that lands mid-fix rides an unfixed head forward, fails again next round, and is fixed there in the same producer spawn — so decoupling costs no extra spawn.
294
+
295
+ What it does **not** move is the exit bar: a review APPROVE with CI still pending is not terminal, because guarantee 3 is about the same final HEAD.
296
+
297
+ ## Delta re-reviews and the round log
298
+
299
+ Re-reviewing the whole diff every round prices a nitpick like a rewrite. Delta scope is bounded by the triggers that make a full pass genuinely necessary (high-risk, round 3+, delta outside the original files, rebase, changed contract).
300
+
301
+ The round log exists because a verdict you acted on but did not record is one the breaker cannot count and no later gate can recover. The original `productionMoved` decision could not distinguish product runtime, tests, executable verification harnesses, evidence, and docs. New records use Git-derived `changedSurfaces`; old booleans read back only as explicit `unknown`, because a rebase prevents honest retroactive classification. A typed write fails closed when required metadata is absent or contradictory: accepting an incomplete transition would create a record the breaker cannot authorize truthfully.
302
+
303
+ Adoption is the evidence for that design. From 522 units: `units[].rounds` 0 → 83% (the breaker reads it), `skillsRoot` 0 → 90% (`validate` reads it), `contractRevision` 0 → 57% (`contract-revision.mjs` reads it), and `delivery` **0 of 522** — fully mechanized, documented, with dedicated commands, and never written, because nothing consumed it. The distinguishing property is never mechanization; it is whether a later gate reads the value.
304
+
305
+ ## Every fix closes the invariant class
306
+
307
+ This is the single largest source of long units. A finding is an *instance*; the rule it violates has siblings, and a fix that merely generalizes the previous counterexample is proof the previous fix was not class-complete.
308
+
309
+ **Named incidents.** A design-input unit fixed two invariants twice each — instance first, class one round later. A unit spent rounds 3–8 on one serialization invariant re-raised at a wider scope each round: one path, then two concurrent writers, then three. Another made one column immutable and spent the next round making the column beside it immutable under the same rule.
310
+
311
+ **The mirror failure is equally real.** Most findings *are* their own class — a typo, a missing null check on the only field that has one, a copy string. Demanding a class enumeration on a CRUD fix is the same over-triggering failure as demanding a design brief for one, and a finding with no adjacent member owes no enumeration.
312
+
313
+ ## A fix never changes the scope class
314
+
315
+ Scope-class creep resets the review — prior approvals cover a PR that no longer exists — and buys FAIL rounds on work nobody scoped.
316
+
317
+ **Named incident.** A twice-approved docs-only ADR PR grew three workflow commits and two FAIL rounds, for a CI gap that had meanwhile been fixed on the base anyway.
318
+
319
+ ## The no-surface checklist exception
320
+
321
+ The exception is the manifest's to grant rather than the producer's because the classification is deny-by-default over the net diff, and a producer asserting its own exemption is the thing the screen exists to check.
322
+
323
+ Without the recorded field, a config-only unit bounces back to the fix step forever, waiting on a checklist that will never be generated — which is why *absent* must not read as `no-surface`: absent means not classified yet.
324
+
325
+ ## The evidence lane's two signals
326
+
327
+ Both signals are required because a forced full-scope round can surface a genuine code defect in code that has not moved, and routing that to the evidence lane skips exactly the adversarial review it needs. Neither signal is the orchestrator's judgment about code it did not read: the diff comparison is mechanized, and the `subject: evidence` classification comes from the reviewer, which read the diff.
328
+
329
+ **Observed.** A reviewer wrote "the implementation itself is correct at this head" while blocking on a stale checklist, and a further round then rejected the checklist fix.
330
+
331
+ **A measured evidence-round rate is usually a recording artifact first.** `epic-25-proposal-generator` read as **54% evidence rounds** and was **15%**: the difference was rounds recorded once per loop *action* rather than once per verdict, so an evidence-subject round shared a HEAD with the round before it and no commit sat between them. That is why `evidence-audit` reports `sameHeadAsPrevious` and why it is read before the count — the repair is `fix-the-recording`, and no screen, existing or new, would ever have caught it.
332
+
333
+ The lane should now be **rare** — retiming the attestation to the terminal round removed the *cause* of most evidence-only rounds rather than making them cheap. If it is still the common path, the question is why the screens are not catching what the reviewer is catching.
334
+
335
+ ## A PASS is terminal
336
+
337
+ Guarantee 3 says the loop exits on a fresh independent verdict on the current HEAD. It has always been readable in both directions, and only one of them is a rule: a verdict is the *floor* the unit must clear, not a *ceiling* on how much more the orchestrator may want. The loop's exit line already said `APPROVE (or PASS with only notes)`. What was missing was the negative half — that a PASS the orchestrator finds unsatisfying is still a PASS.
338
+
339
+ **Measured, `epic-563-admin-transactions` (2026-08-07).** 8 review rounds across 4 units; **3 re-reviewed a head that had already passed**. Round-by-round, from its manifest:
340
+
341
+ | Unit | R1 | R2 | R3 |
342
+ |---|---|---|---|
343
+ | #571 | PASS | PASS | — |
344
+ | #572 | PASS | PASS | PASS |
345
+ | #573 | NEEDS_CHANGES | PASS | — |
346
+ | #574 | PASS | — | — |
347
+
348
+ `#574` is the control: one producer, one review, PASS, delivered — 147 minutes. `#572` reached the same verdict at minute 220 and did not merge until 367. One of its two extra cycles was a rebase, which is legitimate (the tree moved, so the delta is genuinely unreviewed). The other was spent closing two findings the reviewer had itself classed non-blocking — and the re-review agreed with the original verdict, as it was always going to.
349
+
350
+ **Why this is a doctrine bug rather than an orchestrator bug.** Every extra round here was individually defensible and locally cheap: a P2 is a real if minor finding, and a fix plus a delta re-review is 40-60 minutes. What has no defence is the *stopping rule*, because there isn't one — "the reviewer passed but I'd like this tighter" recurses. The reviewer is the calibrated instrument (review-pr § Verdicts and the blocking bar); an orchestrator that overrides its calibration upward has replaced an independent verdict with its own, which is the failure guarantee 2 exists to prevent, just pointed the other way.
351
+
352
+ The three carve-outs — red CI on that HEAD, a rewritten head, a contract revision — are all the same fact: **the diff moved**. That is the only thing that makes a passed verdict stale, and it is mechanically checkable, which is what makes it a rule rather than a preference.
353
+
354
+ ## Component wait is measured at component readiness
355
+
356
+ **Named incident — epic-892 truthful lifecycle.** The automatic postmortem reported eight
357
+ `delivery-wait` findings ranging from 2h14m to 6h34m, one per unit. All eight units were one
358
+ real co-delivery component: shared resolver state, reporting, workflow and test surfaces
359
+ made every early unit PASS preliminary evidence rather than an independently shippable
360
+ artifact. The report therefore multiplied one integration interval by eight and recommended
361
+ checking whether units should have shipped earlier, even though the component decision had
362
+ already proved they could not.
363
+
364
+ The clock now follows the deliverable. A singleton starts at its first PASS. A multi-unit
365
+ component starts at its component-ready PASS: the first terminal PASS of every member,
366
+ advanced only by a typed or reconstructable reopen. Consecutive unowed PASS rounds do not
367
+ reset it. Only then can the complete component enter assembly and terminal authorization. Every member must carry a real merge
368
+ clock or the profiler makes no timing claim. Replaying epic-892 changes the diagnosis from
369
+ eight apparent waits to one 2h14m component interval. That interval contains assembly,
370
+ integrated review/fix cycles, exact-head CI repair and queue delivery; candidate
371
+ update/freeze/authorization timestamps are the right split points when the current typed
372
+ manifest records them.
373
+
374
+ ## The run-start skill installation remains lifecycle authority
375
+
376
+ **Named incident — epic-892 self-hosting protocol drift.** The run began before typed
377
+ component candidates existed in its manifest. The integrated branch added that schema and
378
+ a stronger `mergeable --component` gate. Near delivery, invoking the candidate-tree gate
379
+ against the historical manifest correctly refused because no typed component authorization
380
+ existed; adding one after terminal review would have fabricated history. Delivery had to
381
+ return to the installed run-start gate, which could validate the authorization model the
382
+ run had actually recorded.
383
+
384
+ A self-hosting run therefore freezes lifecycle authority at pre-flight: the absolute
385
+ `skillsRoot` installation that initialized the manifest drives state transitions, merge
386
+ gates, cleanup and finalization until the run ends. Candidate-tree scripts are exercised as
387
+ code under test and may be independently reviewed, but they do not upgrade the live
388
+ protocol mid-run. A future explicit migration can move authority only if the old authority
389
+ provides it and preserves every authorization boundary; "the new script wants this field"
390
+ is not a migration.
391
+
392
+ ## Required PR checks are an integration input
393
+
394
+ **Named incident — epic-892 combined PR #932.** Local terminal verification passed the
395
+ resolver, distribution, coherence and lifecycle suites, then GitHub failed the required
396
+ `skill-script-tests` workflow because `resolve-issues/SKILL.md` was 25,261 bytes against a
397
+ 25,000-byte budget. The missing command was deterministic and runnable locally. Fixing it
398
+ moved the exact reviewed head, regenerated workflow identities, and required another
399
+ independent delta review before queue delivery.
400
+
401
+ The integration gate now treats required published-PR checks as a closed list to map before
402
+ freeze. Each check is reproduced on the candidate HEAD with its exact command/artifact, or
403
+ marked publish-only with the provider reason. "CI green" is not transitive from a handpicked
404
+ suite to a required job whose command never ran. Reproducible checks run before freeze;
405
+ publish-only checks keep authorization provisional until the combined PR reports them green.
406
+
407
+ **Named incident — PR #1001 terminal review.** The plan flattened every Mergify condition tree, including `merge_conditions`' `skill-script-tests-queue`, into PR-head authorization. That queue job runs only on Mergify's synthetic batch SHA, so requiring provider evidence at the frozen PR SHA was impossible before enqueue; omitting it would have made delivery unconstrained. The same flattening ignored GitHub ruleset `ref_name` scope, so rules for unrelated target branches could become requirements. The phase-aware plan now preserves applicable ruleset source conditions and every Mergify source tree. Exact-head authorization validates PR-head evidence only; queue-head conditions remain in the plan and `mergeable` requires a provider-issued `queue-execution` artifact on a distinct synthetic SHA. Skipped and changed-path exemptions retain their phase-local structural meaning. This gate catches both false authorization before enqueue and false delivery after it.
408
+
409
+ The correction still arrived during terminal review, after implementation had encoded the circular state machine. Issue #1014 moves that detection to intake for the narrow class of evidence-backed workflow authorization changes. `unit-kind.mjs` classifies declared scope and changed surfaces deny-by-default; `evidence-lifecycle-contract.mjs` requires every discovered condition to name its phase, immutable subject kind, producer/provider, acquisition operation, consumer, and failure behavior; and `spawn-contract` refuses classified work until that artifact validates. The regression fixture rejects `ALIVE`/pre-enqueue authorization that consumes future synthetic queue evidence, while the accepted fixture preserves PR-head authorization, queue admission, queue-head execution, then fresh target ancestry. The contract exposes ordering before code, but independent review and provider evidence remain separate authorization inputs.
410
+
411
+ ## The frozen component candidate is the delivery authorization boundary
412
+
413
+ **Named incident: a consumer product repo, #830.** Eight high-risk tax units retained 26 preliminary review rounds, including four rounds on #831 and six on #838, while the artifact that could actually ship was combined PR #850. Eight review rounds followed earlier PASSes on moved heads. The old post-mortem could prove those heads moved but could not distinguish legitimate assembly from integration-only repair or a fix for a non-blocking note, because every PASS authorized a unit head while delivery was component-shaped.
414
+
415
+ **Why progressive assembly, then one terminal review.** Waiting for the entire roster before assembling makes conflicts and red integrated tests the latest possible feedback. Re-reviewing each passed unit whenever the assembled head moves spends full reviews on a boundary that will move again. The candidate log separates the work instead: `unit-discovery` adds preserved preliminary evidence, `integration-fix` owns combined-tree-only repair without rewriting unit branches, and `terminal-authorization` is the one full review after the complete clean head is frozen. The #830 regression fixture keeps all 26 unit rounds and reduces eight historical full component-shaped reviews to one terminal full review; exact-head integrated CI, code review, high-risk depth, and smoke remain mandatory.
416
+
417
+ **Why this is a gate, not reporting.** A stale `integration-verdict.json` and a live integration branch that moved after PASS look equally `ALIVE` to gate arithmetic. `run-state` therefore protects candidate history behind dedicated transitions, and `combine-and-verify.mjs mergeable --component <id>` reads the published PR's live `headRefOid` and refuses unless it equals the current frozen generation's authorized component HEAD. Any later movement preserves the prior authorization as history, requires #888's typed reopen reason and changed boundary, and owes fresh terminal evidence.
418
+
419
+ ## The circuit-breaker, and bounded autonomy
420
+
421
+ **Founding incident — epic-848 unit #848.** Nine review rounds without converging, and its round-6 PASS was reversed by later rounds. The distilled record: [incidents/848/README.md](incidents/848/README.md#what-the-incident-established).
422
+
423
+ There is deliberately no cheaper advisory rung above the breaker: a stuck unit needs a decision, and another model's opinion defers one by a round rather than making it.
424
+
425
+ The diagnosis is computed rather than remembered because the recurring-theme branch had **never once been taken**: an audit of 127 manifests found `continue` taken on themes recurring 3, 4 and 5 rounds running, and `descope` chosen **zero times in 522 units**. A recurring theme therefore buys a mandated class-complete round — the remedy this skill already prescribes and had never actually applied — before it buys a human.
426
+
427
+ `descope` stays the human's at every level because it decides that less ships than was asked for, and a loop that can quietly decide to build less is the one failure that leaves no trace in the handoff; every other autonomous decision shows up as rounds spent. `split` is the loop's under `autonomy: autonomous` and the human's under `supervised` — it *re-slices* rather than shipping less, and the measurement that moved it is [above](#pre-flight). The 8-round ceiling exists because autonomy removed the human stop that used to bound the loop, and epic-848's nine rounds are the measured point past which no observed unit converged.
428
+
429
+ ## The produce-pass breaker, removed
430
+
431
+ There was once a **second** breaker (issue #382) beside the review-rounds one. It counted producer/fix *spawns* and fired at 3 with no passing review — the "the contract keeps changing" (#376) shape, whose whole point was to fire *before* any review ran. It was removed.
432
+
433
+ **The incident.** It counted passes AT SPAWN TIME — `record-produce-pass`, run "in the same turn you spawn" the producer. So a spawn that died mid-flight with zero code still incremented the count. This session a run's passes 1–2 produced nothing (each spawn killed early), no review had run, and the count still reached 3 and false-fired "the contract keeps changing" — recovered only by a human `continue`. Counting at spawn time also contradicted [`spawn-contract.md`](spawn-contract.md)'s own rule that "a partial counts exactly as a missing one for every gate": a partial spawn is a missing one, yet the produce breaker banked it.
434
+
435
+ **The fix is deletion, not a patch.** The surviving review-rounds breaker counts only *completed* review rounds, so a dead spawn can never inflate it — the false-fire cannot recur. What we deliberately give up is the #376 capability of firing before any review runs; a specification that keeps changing now surfaces as review rounds that keep failing, one round later than the produce breaker would have caught it. That later signal is the accepted tradeoff for a breaker that cannot fire on nothing. (Legacy manifests that recorded `firedOn: produce-passes` still validate on read-back; the code never writes that value again.)
436
+
437
+ ## Interference is the scheduling primitive
438
+
439
+ **The measurement.** epic-5 in a consumer harness repo ran four units strictly serially, 10:07 → 13:21. Nothing in that run needed serializing except the checkout they shared, and the rule that shared it — "every implement/fix spawn works in the run's single checkout, so code-writing spawns run one at a time" — existed only because two spawns switching branches under one tree corrupt both diffs. Per-unit workspaces remove the reason, so the rule had to go with it.
440
+
441
+ **Why a new primitive rather than a scheduling rule.** #553 proposed the rule "no dependency edge **and** no shared-surface membership". That is the *component* predicate negated — it restated the existing delivery boundary without noticing, because `component` names only one of interference's two consequences. Naming the relation first makes both boundaries derivable and makes their difference visible: the scheduling view is a strict subset of the delivery view, and shared-surface units belong in the delivery one only.
442
+
443
+ **Why assembly interference does not serialize, stated as the cost it accepts.** Parallel edits move a conflict from write-time, where git names the file and shows both sides, to assembly-time, where a red integration gate names no culprit. That is a real regression in debuggability and a future reader will want to re-tighten it. It was accepted because the integration gate is already mandatory for every multi-unit component — the detection exists either way — and because the units most likely to share a surface are an epic's slices of one feature, which is the common epic shape and therefore exactly where serializing costs the most.
444
+
445
+ **Why the two blocking sources are named by effect.** The ADR first defined blocking interference as a diff *referencing symbols* the other unit creates, and it broke on the first real pair it met: #553 depends on #579, but #553's diff references nothing #579 creates — it depends on the invariant #579 establishes. Under the original wording those two were not blocking-interfering and the scheduler was free to build them concurrently, which is precisely the ordering that ships parallelism on top of a live lost-update race. The fix was not a third grade: blocking had been defined by its *mechanism* while assembly was defined by its *effect*, so the two were not parallel and the mechanism-shaped one could not stretch.
446
+
447
+ **A premise edge cannot be inferred, so intake must declare it.** A symbol edge is visible in the diff. A premise edge exists only in the reasoning that says one unit's invariant is another's foundation, and nothing downstream recovers it — the reviewer sees a green PR, the integration gate sees two units that never touched the same file. Every gate agrees the work is fine and it ships in the wrong order.
448
+
449
+ **What a premise edge blocks, amended 2026-08-04: delivery, not the build.** As first implemented the edge also held the dependent out of the *runnable set*, and that reading is what made epic-scale runs serial. Measured over 63 run manifests: runs declared either no edges (depth 1, 10–33× parallelism) or a chain (depth 5–19, 1.2–2.4×), with almost nothing in between. `epic-25-proposal-generator` ran **12 units at 1.7×** behind 18 premise edges, with `sharedSurfaces` of 0 or 1 on every unit — eleven units queued behind an ordering assumption while its head unit spent 9 rounds and 167 minutes. Against an `inFlightCap` of 4–5, a depth-7 graph can never use the slots: the floor is depth × per-unit time whatever the cap says.
450
+
451
+ The block was also **redundant**. `componentDependencies` lifts every cross-component edge whatever its source, and `combine-and-verify.mjs mergeable` refuses "a component whose dependencies are not yet in the target" — so ship-order was already enforced twice, and the schedule was the third and most expensive place. The motivating incident above (#553/#579) was a *ship-order* failure — parallelism on top of a live lost-update race — and nothing in it required build serialization.
452
+
453
+ The hazard the block was defending — a dependent that "silently encodes a false premise" — is cured by **declaration**, which is what the paragraph above already argues for. Ordering the build last does not remove the premise from the dependent's code; it makes the premise true at that moment. So the edge now carries an `invariant`, `runnable` prints it under the admitted unit, and the producer and reviewer spawns quote it verbatim. This is the skill's own asymmetry doctrine applied to the grade that was exempt from it — [interference.md](interference.md) already said "an edge you are not sure about costs a serialization". Measured effect on the two all-premise epics: depth 7 → 1 and 5 → 1, so the graph stops being the constraint and `inFlightCap` starts being it.
454
+
455
+ ## The orchestrator is a writer too
456
+
457
+ The old doctrine said code-writing *spawns* run one at a time in the shared checkout. It said nothing about the **orchestrator** doing git work in that checkout while a spawn was live, because nobody had written down that the coordinator is also a writer.
458
+
459
+ **Named incident — 2026-07-26, ~16:19–16:24 +0800, this skills repo, the #579 unit.** The orchestrator ran git in the shared checkout while a producer spawn was working in it. Four of the producer's commits landed on local `main` — the reflog shows `5891b45`, `4d18b38`, `a800549` and `ba257a7` all reached with HEAD on `main`, after which the branch had to be created from `main` and rebased onto `origin/main` by hand to recover. Nothing failed loudly at any point; `main` simply had four commits on it that belonged to a unit branch.
460
+
461
+ It follows from a workspace belonging to a unit that **the orchestrator's checkout is not a unit's workspace and no unit's workspace is the orchestrator's checkout**. That is now mechanized in three places rather than asserted once: `validate` refuses a unit whose `workspacePath` is the run's own checkout, `validate` refuses two units sharing one path, and the reap refuses to remove the orchestrator's checkout before it looks at the tree at all.
462
+
463
+ The failure generalizes past git. Any writer in a tree somebody else is working in produces the same class of damage, and the count of writers went **up** with parallelism, not down — which is why the rule is stated for the coordinator rather than left implied by the spawn rule.
464
+
465
+ ## Preserved on death, reaped only on success
466
+
467
+ **The live defect.** `git worktree list` in this repo on 2026-07-26 showed **ten** leftover worktrees across **four** naming schemes (`/tmp/resolver-worktrees/…`, `~/projects/.worktrees/…`, `~/projects/ai-wt/…`, `.claude/worktrees/agent-…`) — at *one* workspace per run. Per-unit multiplies that by the roster size, so a reap had to land with the parallelism rather than after it.
468
+
469
+ **Why the asymmetry runs the whole design.** A workspace kept too long is a directory a human deletes in ten seconds. A workspace removed too early is work that existed nowhere else — an uncommitted edit, an untracked file, a commit on no remote. So every rule fails closed: unreadable preserves, ambiguous preserves, still-held-by-its-unit preserves, and the plan is the default while removal needs `--apply`.
470
+
471
+ **The case a `git status` check gets wrong.** A worktree whose branch was never pushed has a spotless tree and holds the entire unit. That is why the observation reads three things — uncommitted, untracked, **and commits contained in no remote-tracking ref** — rather than the one a status check offers.
472
+
473
+ **Why preserved on death rather than reclaimed.** A dead spawn's partial beats a clean slate (the spawn contract's own rule), and the replacement resumes in place only if the tree is still there. That also rules out a recycled pool: reassignment would destroy exactly the partial that makes resumption worth more than restarting.
474
+
475
+ **Named incident — epic-892 standalone producer clones.** Two delivered unit paths were
476
+ recorded as linked worktrees in the orchestrator repo, but producer isolation had replaced
477
+ their `.git` pointers with private object stores (`.git-local` and `.pi-git`). Both trees
478
+ were clean and fully published, so the reap planned them as ordinary worktrees; `git
479
+ worktree remove` then failed with `does not point back to .git/worktrees/<id>`. The late
480
+ failure forced manual Git archaeology during finalization. Workspace observation now
481
+ records the canonical Git common directory and compares it with the orchestrator's. A
482
+ different object store is preserved and named as a standalone clone before any removal is
483
+ attempted, with the reversible recovery path: move aside, prune the stale parent
484
+ registration, then Trash the moved clone after rechecking publication. Automatic cleanup
485
+ still never force-removes or raw-deletes a workspace.
486
+
487
+ ## The in-flight cap and its default
488
+
489
+ The cap bounds disk and dependency-install cost. It is **not** a correctness bound — the scheduling predicate is what keeps units apart, and the cap only decides how many run at once. A run at cap 1 is the old serial behaviour and is equally correct.
490
+
491
+ **The default is 4 (raised from 2 on 2026-07-29).** The cost per workspace is not portable: a fresh tree has no `node_modules`, no `.env`, no build cache, so on a product repo each admitted unit owes an install before its first test runs. The original 2 was the smallest non-serial value, chosen so the worst case — a repo where parallelism is a net loss — cost one extra install rather than N-1. That trade was deliberately re-made: on a roster with independent units the cap, not the graph, was the thing limiting throughput, and waiting for a human to notice and raise it meant most runs never got the parallelism the scheduler was built to provide. At 4 the bad case pays three extra installs, which is a bounded and visible cost, while the good case — the common one — finishes materially sooner.
492
+
493
+ **What did not change is the escape hatch, and it is the reason raising this is safe.** The cap is still a *cost* bound: `inFlightCap: 1` restores exactly the old serial behaviour, and `2` restores the old default, with every other property of the design intact.
494
+
495
+ **Amended 2026-08-07: the cap is 4 unconditionally, and the loop no longer chooses it.** The escape hatch survives as a field a *human* may write. What was removed is the loop's invitation to write it — pre-flight used to settle the cap "in the same block as the models and the branch," which made a throughput decision an agent's judgement call about a repo it had just met.
496
+
497
+ The measurement that forced it, `epic-563-admin-transactions` (2026-08-07, 4 units, 626 minutes): pre-flight set `inFlightCap: 2`. Replaying that run's own manifest through `runnableState` at the moment the first two producers were in flight gives the whole story in two lines —
498
+
499
+ ```
500
+ cap 2 (what the run set) -> ADMIT NOW: (none)
501
+ cap 4 (the documented default) -> ADMIT NOW: #573
502
+ ```
503
+
504
+ `#573` was held by the cap and nothing else: its only blocking edge was a **premise** edge, which since 2026-08-04 orders delivery rather than the build (above). It was admitted at minute **347** of a 626-minute run. Average concurrency across the run was 1.5 agents, with **300 of 626 minutes at exactly one agent working**.
505
+
506
+ Two things about that number are worth keeping. First, **nobody revisits a cap mid-run** — it is written once at pre-flight and then it is simply the environment, so a conservative guess made in the first three minutes silently prices the next ten hours. Second, the guess was *invited*: the instruction asked the orchestrator to weigh "what a fresh tree costs to create, and what it owes for a dependency install," which is a question an agent will answer conservatively on any repo with a `node_modules`. Removing the tuning removes the failure; the bad case is still bounded at three extra installs, and it is now the only case the loop can produce.
507
+
508
+ Third, and separately: [run-state.md](run-state.md)'s field reference still read "default **2**" on the day of that run, nine days after the default became 4. A default documented in two places is a default with two values, and the stale one is the one that gets read.
509
+
510
+ **Measured in this repo (2026-07-26).** `git worktree add` took **0.13s real**; the working tree is **16 MB** against a 26 MB `.git`; and there is no root `package.json`, so the dependency install cost here is **zero**. Cheap enough that a higher cap would be free — which is exactly why the default is not set from this measurement. This repo is the favourable case, and the consumer repos this skill installs into are the ones that pay.
511
+
512
+ **The finding the ADR asked to be recorded rather than discovered:** on a repo with a slow install, per-unit workspaces can be a net loss. The lever is `inFlightCap: 1`, which keeps every other property of this design — the interference model, the workspace lifecycle, the reap — while paying for one tree at a time. **That lever is a human's to pull, on measured evidence, and the loop does not offer it** — see the 2026-08-07 amendment above for what happened when it did.
513
+
514
+ ## The component, not the epic
515
+
516
+ Per-unit green proves each PR **in isolation** — the blind spot where individually-green slices contradict once combined.
517
+
518
+ **Named incident — epic-848.** Units #879 and #880 sat merge-ready for hours behind a sibling stuck at seven review rounds, because the deliverable was the epic rather than the component.
519
+
520
+ Note the direction that fixes it: a completed *upstream* component ships even while downstream dependents are stuck. A dependency never waits on its dependents.
521
+
522
+ ## Delivery: only ancestry is a result
523
+
524
+ A merge tool's return code, a queue acknowledgement and an auto-merge flag are all *requests*.
525
+
526
+ **Named incident — epic-986.** The manifest recorded `mergeShippable: true`, four units `merge-ready` with `lastVerdict: PASS` and their PR refs, and `mergedSha: null` on every one. The loop posted its queue request, got "waiting for queue conditions", and moved to the next unit. Twelve hours on one unsatisfied condition — `-draft`.
527
+
528
+ **Named incident — issue-664 / identity#669 (hybrid merge unobserved).** On `enqueueTrigger: hybrid` (and pure `auto`), a PR reached `targetBranch` without the loop posting `@mergifyio queue`. GitHub/Mergify merged on auto conditions. The skill still optimised for enqueue → watch queue → record outcome, so the unit was **actually merged** while the run manifest said `merge-ready` / **UNDELIVERED**, and the postmortem invented a multi-hour co-delivery hold. Measured: PASS ~02:48, PR merged 03:01:28, `record-delivery-outcome` only at 10:23 after a human "check the progress." The fix is the hybrid/auto observation path in [delivery.md](delivery.md): launch `watch-delivery` without requiring prior enqueue, record `mergedAt` on the outcome, and split postmortem `outcome-write-lag` from queue/co-delivery wait (#791).
529
+
530
+ **Same incident, three P1 holes that made the P0 incomplete (#792).** (1) CI-watch did not chain into delivery — a background Vitest watcher succeeded and nothing forced the next orchestrator step; the outcome waited on a human progress ping. Fix: one `watch-delivery.mjs --head <sha>` pipeline after PASS that reaches terminal delivery or exit 5 `ci-failed` without a human turn. (2) `record-review-round` rejected `headSha` and `record-fix-round` demanded `migrate-unit` + the deep-audit matrix for a simple env-guard fix — schema thrash mid-loop. Fix: lean payloads for non-deep-audit units; deep matrix only when high-risk deep protocol is active. (3) Review child launched as `openai/gpt-5.5@high` but reported `GPT-5 / Codex` because `PI_*` was unset in the sandbox, so guarantee 2 had no hard proof. Fix: inject `RESOLVE_SLOT_MODEL` + `RESOLVE_SLOT_EFFORT` on every spawn-contract render; launch id is authoritative when child read-back is missing/unknown.
531
+
532
+ `merge-ready` had been terminal with no transition out of it: nothing could be refused, and a unit could sit there forever with the manifest still valid.
533
+
534
+ **Named observation — PR #529 (2026-07-23).** An acknowledged `@mergifyio queue`, every condition green, and the queue CLI answering "not in the merge queue" for several minutes — a pre-admission phase the state machine had no name for, where the un-nudged rules would have burned the full stall bound and handed back a healthy unit. The same PR merged as a merge commit while its head SHA was different, which is the case that makes `delivered --sha <head>` pass on a merge-commit queue and fail on a squash or rebase one.
535
+
536
+ **Named incident — issue-799-800-resolve-release #807 / PR #810 (stall key ignored membership + CI).** The hybrid observation path from #791/#792 launched correctly, but the stall key was built from the `gh pr view` observation alone while Mergify membership lived in a separate `qv` object that never fed it. A PR sat OPEN with `labels=['queued']` and position frozen at 0 ("Preparing checks") for the whole 10m bound while `skill-script-tests` was still running; every poll looked identical, so the watch exited `conditions-unmet`. The PR merged two minutes later. `record-delivery-outcome` only landed after a multi-hour session gap — the postmortem's `outcome-write-lag`. Two fixes in [delivery.md](delivery.md) / `watch-delivery.mjs`: (1) the stall key is now (PR state, queue state, position, labels, queue membership, CI fingerprint), so CI progress under a frozen queue picture restarts the bound; (2) a stall while the queue still holds the PR is reason `stall-while-queued`, which routes to re-observe/relaunch, never unit-level hand-back or re-enqueue of the same HEAD.
537
+
538
+ **Named incident — PR #1001 / synthetic PR #1003 (provider IPC and queue-head progress invisible).** The source PR's queue-only job was correctly skipped while the required job ran on Mergify's synthetic draft. The source observation therefore remained unchanged long enough to stall twice even as the authoritative synthetic execution advanced. After the PR merged, artifact capture failed with `Unexpected end of JSON input`: the watcher supplied `input`, but its standard `stdio` set stdin to `ignore`, so the real provider received EOF. The repair keeps one exact provider request through the whole watch, pipes stdin explicitly, includes synthetic identity/check states in the progress fingerprint, and validates the final artifact. Distinct empty/malformed/non-zero/timeout/stderr failures remain evidence-blocked; no progress signal disables either stall or absolute bounds.
539
+
540
+ Mechanics: [delivery.md](delivery.md).
541
+
542
+ ## The removal path
543
+
544
+ This skill accretes: every incident tempts a new mechanized gate, and gates never remove themselves. Process weight is a regression, not a virtue.
545
+
546
+ Rule 2 — retire gates that produced nothing — had **never once been executable**, because a gate that passed and a gate that never ran were indistinguishable in the record. Measured on merged PRs in the window where all four newer gates existed (n=79): Self-Review evidenced on 35%, reviewer-parity 27%, runtime smoke 10%, evidence-block 9%. Under this skill's own rule — output without its proof did not run the skill — those are gates that mostly did not run, and their value is therefore unmeasurable. So is the cost argument for removing any of them.
547
+
548
+ **Named incident — a consumer product repo, #830 / issue #887.** Raw gate counts made repeated checklist locator warnings look like 28 distinct defects while one clean run marked cheap safety screens as retirement candidates. `runtime-smoke` found one rare issue and `self-review` found four, demonstrating why low-frequency blocking value cannot be inferred from one run's zero.
549
+
550
+ The repair has three independent outputs. Finding identity is the stable `class + locator` fingerprint across rounds and units; raw occurrences stay visible but never stand in for unique value. The report separates unique, blocking, repeated known warnings, gate-attributable fixes, and noise. Narrowing/deduplication recommendations can fire on repeated/noise findings without implying retirement.
551
+
552
+ Retirement reads the durable append-only cross-run series written by `gate-audit`. Its configured minimum (`RESOLVER_GATE_RETIREMENT_MIN_RUNS`, default 10) applies to the **trailing per-gate zero-yield streak**, not one run and not all history forever. A readable execution with zero unique findings/rejections extends the streak; a finding, rejection, explicit not-run, skip, or unreadable observation resets it. The full series still supplies the value totals. Approximate `durationMs` is included only when the harness already provided it.
553
+
554
+ Every committed artifact being green is survivorship, not a result: a producer commits an artifact once it is green, so a gate that caught something and got fixed looks exactly like one that never fired. Structured `findingDetails` and legacy `fixed` records break that tie.
555
+
556
+ ## The spawn contract is rendered, not composed
557
+
558
+ **Measured 2026-08-04, 33 Pi sessions, 163 producer spawns.** The leaf-spawn contract was
559
+ prose, and prose gets composed into a template at the first unit and then repeated for the
560
+ rest of the run — never re-derived. The signature is within-session uniformity: **10 of 17
561
+ sessions with 4+ producer spawns varied by at most one gate across every spawn in the run.**
562
+ One session sat at exactly 2 of 5 gates for 27 consecutive spawns; another named all 5
563
+ eighteen times; another named none of them nine times.
564
+
565
+ Three explanations were tested and two died. It is **not the doctrine** —
566
+ `implement-and-pr/SKILL.md` already mandates `coverage-checklist.mjs validate … --diff
567
+ <merge-base>`, and `closeout.md` repeats it. It is **not the orchestrator model** — that
568
+ looked clean (one model at 100%, another at 0%) until the session spread was checked: the
569
+ 100% model's spawns were all from a *single* session, while the 0% model was uniform at 2
570
+ gates across 16 sessions, so it is not a capability ceiling either. What survives is the
571
+ template: composed once, unanchored, and where it moves it decays rather than improves
572
+ (7 sessions down, 3 up, 7 flat), with the decays on the longest runs — the shape of context
573
+ pressure eroding something remembered rather than re-read.
574
+
575
+ The cost is not stylistic. `coverage-checklist.mjs validate` answers a strictly weaker
576
+ question without `--diff` (a missing locator warns instead of blocking), and `--diff`
577
+ reached **10%** of producer spawns. 1above-official #35 is the instance: the producer's
578
+ `validate --root .` passed, the reviewer's `validate --diff` found 9 PASS rows with no
579
+ resolving locator, and the unit bought an evidence round for the gap between two runs of one
580
+ command. That is the mechanism behind the 2:1 evidence-to-code fix ratio.
581
+
582
+ So the load-bearing step is mechanized rather than described ([`spawn-contract.mjs`](../scripts/spawn-contract.mjs)):
583
+ the contract is rendered from the run's own state, identical on spawn 1 and spawn 33, and a
584
+ clause the manifest cannot fill is **named** rather than quietly omitted (exit 4). This is a
585
+ net deletion from [loop.md](loop.md) — the paragraph that described the contract is replaced
586
+ by the command that emits it. It is the same repair the `progress` render got the same week,
587
+ for the same reason: a rule stated where the work is not happening is a rule that does not
588
+ happen.
589
+
590
+ ## Epic-876: external review, slot env inject, and empty CI commits (#941)
591
+
592
+ **Named incident: a consumer product repo, #876 / run `epic-876-shared-pure-twins`.** Two-unit expand→contract of byte-identical pure modules. Outcome was green (both merged, dev deploy verified, ~91m), but five friction points taught the loop something the progressive-component work had not:
593
+
594
+ 1. **Independent PASS, then bot CHANGES_REQUESTED.** `openai/gpt-5.5` PASSed #877; `vera932` then requested changes for a dropped pre-move matrix row (`Refund succeeded → neutral`). Body byte-identity had been proven; **matrix completeness had not**. The fix was correct; postmortem demoted the round as a probable rebase because `reopenReason` could not name "external review."
595
+
596
+ 2. **`RESOLVE_SLOT_*` empty in every child.** Spawn-contract *text* named the vars; Pi `subagent_spawn` never received `env:`. Children fell back to `PI_*`. Guarantee 2 held only because launch id is authoritative — soft telemetry looked like a diversity proof until read carefully.
597
+
598
+ 3. **Empty commit for CI re-trigger under a live reviewer.** After rebase+retarget, force-push did not fire CI Stages. An empty commit moved HEAD → reviewer BLOCKED head-drift → full re-review of an identical production tree.
599
+
600
+ 4. **Self-authored COMMENT is the only legal GitHub event** for this identity chain. Mergify never consumed the independent APPROVE; a later bot APPROVE did. Guarantee 2 must not be equated with a GitHub APPROVE event.
601
+
602
+ 5. **Mergify first `@mergifyio queue` often needs refresh+re-queue** before `queue show` reports position, while 👍 arrives earlier.
603
+
604
+ **What changed:** `reopenReason: external-review` (boundary `head`); pre-enqueue CHANGES_REQUESTED check in delivery.md; spawn-contract `--json` + stderr env footer; matrix-completeness characterization rule for twin consolidations; no-empty-commit-while-review-in-flight rule; `reviewPostedAs: comment-self-authored` from post-review.
605
+
606
+ **What this is not:** a license to re-open PASSed units for note-chasing. `external-review` is for open non-self CHANGES_REQUESTED that name a real AC/code gap. Notes inside a PASS still become `deferrals[]`.
607
+
608
+ ## Epic-894: the legacy round shape, the reap under a live agent, and an inert env clause
609
+
610
+ Three findings from the `fmm-express` epic #894 run (2026-08-13, 4 units, 3 review rounds, **0 fix rounds**, merged `cc3147c`). The code went through clean; every defect was in the loop's own machinery or in how the orchestrator drove it. Each of the three gates added alongside this section names its incident here, per [the removal path](../SKILL.md#the-removal-path-keep-this-skill-small).
611
+
612
+ ### A legacy-shape round is a silent dead end for component authorization
613
+
614
+ `record-round` accepts the legacy shape (`productionMoved`) as well as the typed one, and `classifyRoundMetadata` projects a legacy record to `reviewSubject: 'unknown'`. But `record-component-candidate` **requires** a typed `reviewSubject` on the unit's latest round before it will accept the unit's preliminary PASS. The round log is strictly append-only (`validateRoundLog`: `round === previous + 1`), so the two facts compose into a trap: by the time the component gate refuses, the omission cannot be repaired.
615
+
616
+ Epic-894 wrote all three units in the legacy shape. `validate` returned `valid` at every checkpoint. `progress` rendered each unit merge-ready with `last PASS`. Roughly four hours later, at delivery, `combine-and-verify mergeable` refused and `record-component-candidate` named the cause — at a boundary with no way back. The only routes to a green gate were then a fabricated second round at the same head (the [epic-25 double-record pathology](run-state.md) this skill already names) or hand-editing a protected log. Both were correctly refused; the orchestrator verified the full bar by hand, merged under the recorded authorization, and reported the gap.
617
+
618
+ Note what was **not** wrong: the documentation. `loop.md` carries the exact typed `record-round` payload and, one paragraph later, the `record-component-candidate` step that consumes it. The orchestrator never opened `loop.md` — it worked from `SKILL.md`'s index, whose one-line summary for that file ("review on a different model, same breath, same HEAD") is a rule easy to already know and honour, so the summary read as sufficient. Hence two changes rather than one: `validate` now **warns** when a `merge-ready` unit's latest round is legacy-shaped, and the index row now names the recording contract instead of only the review-independence rule. The warning fires at the last moment the next round can still be written correctly.
619
+
620
+ ### The reap reads the tree; it never read the process table
621
+
622
+ Every rule in `workspaces.mjs` answered a question about a workspace's *contents* — clean, published, owned, claimed. None asked whether anything was **running** in it. A tree can satisfy the entire ladder while an agent is mid-execution inside it.
623
+
624
+ The orchestrator pre-authorized an agent to keep running repeat E2E measurements, read its interim report as terminal, and ran `reap --apply`. The tree was clean and its unit delivered, so the plan said `REAP`; git de-registered the worktree and half-deleted `node_modules` under a live Playwright worker. One run collapsed with 36 `worker process exited unexpectedly`, the next could not start at all.
625
+
626
+ The sharp part is not the lost run. **The crash fabricated evidence.** In the collapsed run the epic's one suspect test showed red *on `main`* — the single observation that would have turned a retracted flake back into a real regression on an already-merged money refactor. It survived only because the agent opened the JSON before reporting and found `worker process exited unexpectedly` rather than an assertion failure. A destroyed measurement does not merely vanish; it returns a plausible wrong answer.
627
+
628
+ This was also the **second** instance of its class in one run — the first being a reviewer spawned into a producer's live tree, for which the repair had already been written up before the reap happened. Writing under a live agent costs a round; deleting under one costs the work. Hence both a mechanized preserve (a tree with a live process, or an unreadable process table, now preserves) and the doctrine in [interference.md](interference.md): a pre-authorization to keep working is a lock on those trees.
629
+
630
+ ### The spawn contract rendered an env clause the harness could not honour
631
+
632
+ Clause (d) of the [leaf-spawn contract](spawn-contract.md) injects the confirmed slot into the child's environment and asks for a read-back — the mechanism behind guarantee 2's no-silent-fallback rule. It was written for a harness that launches a subagent as a process whose env the orchestrator controls.
633
+
634
+ Claude Code's `Agent` tool exposes no env parameter. Epic-894 rendered the injection clause to **7 of 7** spawns; all seven reported both variables empty, and every prompt after the second had to be hand-patched to ask for a session-identity read-back instead. The guard did not fail loudly — it degraded to an honour system, and nothing in the run recorded that the mechanism never ran. It happened to hold (every agent reported its own identity, and every read-back matched the confirmed slot), which is precisely why it could have gone unnoticed.
635
+
636
+ Pre-flight step 0 already records `currentTurnCapabilities` for exactly this kind of adaptation. `spawn-contract` now consults it and renders the read-back in the form the harness can actually satisfy, defaulting to the injecting shape when capabilities are unknown — an extra sentence where it does not apply is cheap; withholding a real guard is not.
637
+
638
+ ### The audit pass: two library modules that answered with silence
639
+
640
+ A post-audit sweep of the same run found a third defect of the same family as the first two, and it had already fired — on the run's very first spawn.
641
+
642
+ `spawn-contract.mjs` and `postmortem.mjs` are **libraries**. The entry points are `run-state.mjs spawn-contract` and `run-state.mjs postmortem`, and they are entry points for a reason: the subcommand derives `orderedAfter` from the whole roster (the premise-edge invariant the producer must quote verbatim) and resolves the manifest, durable directory and cross-run series. A CLI inside either module would not be a convenience — it would be a second, quieter renderer disagreeing with the real one.
643
+
644
+ But **a Node module with no entry point exits 0 and prints nothing when executed**, and that is indistinguishable from "there was nothing to say". Meanwhile `SKILL.md` linked to both by path while the link *text* was the `run-state.mjs` command — so following the href and running the file is the natural move. Epic-894 did exactly that on its first spawn contract, got `exit=0` and an empty stdout, and only recovered because it happened to retry through `run-state.mjs`. A less suspicious reader concludes "no contract needed" and hand-composes the spawn — the decay [the rendered-not-composed rule](#the-spawn-contract-is-rendered-not-composed) exists to prevent, produced by the tool meant to prevent it.
645
+
646
+ Both modules now fail loudly and name their real entry point. Two details were learned by getting them wrong first, and are pinned by tests:
647
+
648
+ - **`--help` must still be answered** on stdout with exit 0. This repo already pins that every bundled script does (`watch-delivery.test.mjs`), and the first version of the guard broke it — trading a silent trap for a loud regression.
649
+ - **A doc link whose visible text is a `run-state.mjs <cmd>` invocation must target the runnable entry point**, never the module. That is now asserted rather than trusted, because the next doc edit would otherwise reintroduce it.
650
+
651
+ The same sweep fixed `readArg`'s message for a missing required payload. `JSON.parse(undefined)` reports `"undefined" is not valid JSON` — a parse failure of real data, which sends the reader hunting for a quoting bug in a payload that was never passed, and never mentions `--stdin`. The usual way to land there is piping or heredoc-ing a payload *without* the flag: you supplied the JSON and were told the JSON is malformed. Epic-894 hit it twice. The fix is a separate `parseJsonArg` rather than a change to `readArg`, because commands like `next` accept no payload at all and making absence fatal for them was a second bug on top of the first — also learned by doing it.
652
+
653
+ Six broken relative links across `intake.md`, `loop.md` and `deliverables.md` were corrected in the same pass (off-by-one `../` depth). All 257 relative links in the skill now resolve.