@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,149 @@
1
+ # Step 5: route on the verdict
2
+
3
+ What happens after validation or exposure returns an answer - tag and publish, or
4
+ delete the candidate, or roll back. Previous: [exposure.md](exposure.md).
5
+
6
+ ### 5 — Route on the verdict
7
+
8
+ **Every terminal exit emits a durable release-evidence bundle — the run manifest is the working state, the bundle is the durable record** ([principle 5](../SKILL.md#non-negotiable-principles); #441). The manifest is session-scoped (`run-state.mjs`'s job) and its verification evidence dies with the temp dir; the bundle is a first-class artifact written **once**, at the terminal exit, **keyed to the immutable attempt id and its terminal state** ([principle 10](../SKILL.md#non-negotiable-principles)) so a **failed** attempt is as reachable months later as a successful one. **The key is the attempt id, not the rc tag** — three of the four declarable trigger shapes mint no rc, so an rc-keyed bundle was unemittable on them, and inventing a key would fabricate the artifact the bundle exists to make trustworthy (#599). The attempt id exists on every shape by construction, because the lease opens at the promotion authorization, and it is **unique per attempt** — `<version>-attempt.<n>` ([step 3](candidate.md#3--promote-then-build-the-candidate-no-exposure-yet)) — so a retry that re-cuts the same version and fails the same way writes its **own** record instead of colliding with the attempt it is retrying. `rcTag` stays a **recorded field** — required wherever an rc exists, an absent one declared by the shape rather than merely omitted, and a declared no-rc shape carrying one refused as the self-contradicting record it is. Bundles written **before** #599 are unaffected: they key off their `rcTag`, so `v1.2.0-rc.1--released.json` is byte-identical. It binds what principle 5 rests on: the attempt id, the rc tag where one exists, the shipped SHA, the build identity, the candidate receipt and validation verdicts **when that attempt reached a candidate**, the exposure approval/traffic transition when it exposed, the cleanup-or-rollback record, and the **terminal attempt state — #432's `ATTEMPT_TERMINAL_STATES`, the same enum the lease closes on, never a parallel one.** **What each exit owes is a property of `(terminal state × trigger shape)`, not of the state alone** (#604) — because "what evidence exists" is a property of both. On the three shapes that **deploy** (`rc-tag`, `branch-push`, `final-tag`) nothing changes: `released` still owes the candidate receipt, both verdicts, the approval and the traffic transition, and a deployed release that cannot produce them is still not releasable. On **`no-deploy`** those five are artifacts only a deployment produces — a 0%-traffic candidate, a smoke against it, an exposure authorization, a traffic shift, a live service — so requiring them made that shape's every terminal exit **unsatisfiable**, and this repo's own `v0.5.0` shipped with **no bundle at all** for exactly that reason. There it owes instead what the shape does produce: the **immutable final tag** (`releaseTag` — the only version claim there is, so it is bound to the attempt's version), the **Release reference** (`releaseRef`), and the **verification evidence standing in for principle 5's two observations** (`verification` — CI plus the full suite on the tagged SHA, and the consumer-facing read of [references/versioning.md](versioning.md) §5). **This makes the requirement satisfiable; it does not make it optional** — a `no-deploy` bundle **carrying** any of the five is refused as the fabrication it is, at every terminal state, exactly as a `failed-pre-promotion` bundle carrying a post-shift live verdict is. And **a field written `null` is a field that is absent** — `"rcTag": null` is *no rc tag*, not an unusable one; null is never a way to satisfy something required. It is **emitted at every terminal record**, so each `record-release-attempt` below is paired with an emit — including the `blocked-manual` hold, which emits a bundle while *holding* the lease rather than closing it: **A hand-written bundle is forbidden on the normal path.** It is a recovery artifact only, and its very next operation must be `evidence-bundle.mjs validate --bundle <recovery-bundle.json>`; an invalid recovery artifact is not emitted, copied, attached, or reported.
9
+
10
+ Non-released terminal paths continue to use the direct emit below:
11
+
12
+ ```bash
13
+ node <resolve-release>/scripts/evidence-bundle.mjs emit --bundle release-evidence.json \
14
+ --dir <durable-evidence-dir> # validates then writes <attemptId>--<terminalState>.json; exit 1 = invalid or immutability violation
15
+ ```
16
+
17
+ **Immutable once written** — a mutable summary is not evidence. `emit` refuses to overwrite an existing bundle for an `(attempt id, terminal state)` with *different* content; an evidence-identical re-emit (a resumed session re-running the same close) is a resume-safe no-op. The bundle is validated and **fails closed**: an incomplete bundle, or one **claiming an observation its state never took** (a pre-exposure discard carrying a post-shift live verdict), refuses rather than writing a durable record that looks complete. Explicit non-goals it must not degrade into: **workflow logs alone, a mutable summary, or final-tag-only evidence** — the last would lose every failed attempt, which is the whole point of emitting on the failure paths. On the **verified path** the bundle is additionally **attached to the GitHub Release** (long-term retention, co-located with the version claim it evidences); failed attempts stay indexed by their attempt id in `<durable-evidence-dir>`, reachable with `evidence-bundle.mjs path --attempt-id <id>` (`--rc-tag` is the pre-#599 spelling and still resolves on the rc shape).
18
+
19
+ **Verified** → four actions, then report. In [`verified-sha-github-flow`](verified-sha-github-flow.md#final-claim-and-metadata-ordering), use that mode's final-tag/GitHub-Release ordering and invoke its post-release metadata adapter after the final claim; the generic CHANGELOG cut/back-merge fields below do not apply. Metadata sync is complete only when `release.metadataPr.source` is `metadata-sync.mjs`. Any noncanonical manual completion is a recovery artifact: adjudicate it, file and link the adapter tooling issue, and retain that adjudication before treating metadata as complete. A manually merged PR without that record does not satisfy final closeout.
20
+
21
+ **Publication hard precondition.** Before any final-tag mint or GitHub Release creation, read the recorded standalone `release.versionAssert` result from step 4b. It must be `decision:"accept"` with exit code 0 and evidence that `/health`, `/settings`, and the frontend asset version each match the final SemVer (or the envelope's explicit recorded exception). An exit 1 refusal or exit 2 cannot-run result **refuses this entire Verified path**: do not tag, do not create a GitHub Release, and do not treat the JSON refusal as an advisory. The assertion ran in step 4b as its own process; no shell chain may bridge its nonzero exit into either publication command.
22
+
23
+ 1. **Tag the shipped SHA** (production only; skip on a dev release). The rc tags from step 3 were triggers; **this** tag is the version claim, and it is born here — so **a tag only ever names a revision observed serving production** (principle 10). Re-tagging the same SHA is a resume-safe no-op; a different SHA is refused, and no `--force` exists.
24
+ ```bash
25
+ FINAL_TAG=$(node <resolve-release>/scripts/version.mjs tag --version <v> --sha <shipped> \
26
+ --target-branch <prod> --production-branch <prod> --push)
27
+ node <resolve-release>/scripts/version.mjs notes --version <v> > release-notes.md
28
+ gh release create "$FINAL_TAG" --title "$FINAL_TAG" --notes-file release-notes.md
29
+ ```
30
+ 2. **Back-merge `main → dev`** — a **standard step after every production release** where an integration branch exists, done promptly: under principle 11 the step-1b cut commit lives only on the release branch, so `main` now holds a commit `dev` lacks and the *next* promotion cannot fast-forward until this lands. It is a **regular merge into `dev`** (allowed: principle 3 protects the *production* branch, not `dev`). If `dev` moved on, expect conflicts in the two places the cut touched — the CHANGELOG's `Unreleased` region and the version files; resolve mechanically: keep the new version heading from `main`, keep `dev`'s newer entries under a fresh empty `Unreleased` above it, keep the bumped version numbers. If `dev` hasn't moved, it's a fast-forward no-op — do it anyway. **Record the back-merge commit** (`release.backMerge`): the next release's candidate must descend from it (principle 11). (**Skip this action entirely** in the two single-branch topologies — GitHub Flow and `release/<slug>` — where there is no `dev`: under GitHub Flow the cut commit reached `main` by being merged there, so there is nothing to back-merge and `release.backMerge` stays null.)
31
+ 3. **Close the originating issue(s)** confirmed in the [pre-flight scope](preflight.md#pre-flight-gate-confirm-the-authorization-envelope-mandatory) — a deliberate step, not a no-op: in a GitFlow repo the PRs merged into `dev`, not the default branch, so GitHub's `Closes #<n>` auto-close **never fired**. Close each with an auditable comment — *why* it's done, not just that it is: `gh issue close <n> --reason completed --comment "Shipped in v<version> (<sha>) via <promotion-pr>; verified live: <evidence>"`.
32
+ 4. **Close only on verified-done, never on merge.** A merged-but-unverified PR is not a shipped issue (principle 5), so neither failure tier closes anything — a discarded candidate never shipped, and a rolled-back release was un-shipped.
33
+
34
+ **Then record the terminal closure as ONE durable transition** ([principle 5](../SKILL.md#non-negotiable-principles); #963) — [`finalize-release.mjs`](../scripts/finalize-release.mjs) validates every observation the released path owes — the checked isolated-adapter completion artifact against finalizer-owned exact suite identities and trusted positive minima, the 4a candidate verdict, the post-authorization fence readings, the serving identity/digest confirmation, the durable-processing quiescence/resume where declared, and the live prod-active verdict — and, in a single atomic manifest write, closes the Release Attempt Lease as `released`/`verified-release` (when it is still open), assembles the top-level `verification` block, and advances `step` to `done`:
35
+
36
+ ```bash
37
+ node <resolve-release>/scripts/finalize-release.mjs <run-manifest.json> \
38
+ --adapter-completion-artifact <immutable-completion.json> \
39
+ --adapter-component-head <40-hex-component-head> \
40
+ --adapter-completion-sha256 <64-hex-sha256>
41
+ ```
42
+
43
+ Completion acquisition retains `O_NOFOLLOW | O_NONBLOCK`, read-only regular <=1 MiB, stable identity, exact bounded read with growth probe, fatal UTF-8, SHA-256 binding, and descriptor cleanup. Zero or caller-weakened counts/floors and unsupported suite identities fail closed. Any observation missing, stale, mismatched, or internally inconsistent **refuses and writes nothing** — a refusal is a statement about the evidence, never a partial record. Re-running after success re-validates and no-ops; a crash before or after the write resumes from exactly one recorded state (`verify` with no `verification`, or `done` with it), and a hand-assembled in-between refuses. Until this lands, either the lease stays **held** or the step sits short of `done` — both correct: an unverified or crashed attempt must not read as free, and a verified one must not read as mid-machine (the Forex v0.1.12 hole: attempt closed `released`, `step: verify`, no `verification` — the post-mortem faulted a release production had already verified). The close the finalizer records is what lets the next release's step-3 `check-release-lease` return free. **The final tag, the GitHub Release above, and the bundle emit/attach below stay outside this filesystem transaction** — the finalizer is the manifest's terminal record, not the release's outward claims. And **`report.mjs` runs after this transition on the released path**: its step-5 evidence is the finalization record, so an unfinalized released attempt renders as owed, never as done.
44
+
45
+ **Run the verified closeout command before any final response.** It is the required released-path sequence: it invokes `finalize-release.mjs`, assembles the released bundle from the finalized manifest plus the machine-readable build and approval receipts, emits it, validates the emitted durable file, copies that validated file to the aggregate bundle path, and saves both run-level and version-level post-mortems. It prints a success response only after every step passes; any failure exits nonzero, so do not report the release as complete.
46
+
47
+ ```bash
48
+ node <resolve-release>/scripts/closeout-release.mjs \
49
+ --manifest <run-manifest.json> \
50
+ --adapter-completion-artifact <immutable-completion.json> \
51
+ --adapter-component-head <40-hex-component-head> \
52
+ --adapter-completion-sha256 <64-hex-sha256> \
53
+ --build-identity <machine-generated-build-identity.json> \
54
+ --approval <machine-generated-exposure-approval.json> \
55
+ --aggregate-bundle <release-evidence.json> \
56
+ --postmortem-dir <postmortem-dir>
57
+ ```
58
+
59
+ `--build-identity` and `--approval` are observed receipts, not prose copied into a bundle. When durable processing was declared, add `--durable-processing <canonical-durable-processing-receipts.json>` before `--aggregate-bundle`; when declared absent, the command writes `{present:false}`. The command writes `<durable-evidence-dir>/<attempt-id>--released.json`; `--aggregate-bundle` is a byte-for-byte copy of that file for the release attachment. **Do not substitute a shell chain or a hand-written `release-evidence.json` for this command.**
60
+
61
+ **Then attach the validated aggregate bundle to the GitHub Release** — `terminalState: "released"`, `closedBy: "verified-release"`, carrying both principle-5 verdicts, the approval, the traffic transition, and the candidate receipt. The Release is its long-term home (co-located with the version claim it evidences):
62
+ ```bash
63
+ gh release upload v<v> <release-evidence.json> # aggregate copy made by closeout-release.mjs
64
+ ```
65
+ The upload targets the `released` bundle specifically — never a bare `<attempt-id>.json`. The bundle is keyed by `(attempt id, terminal state)`, so an attempt that parked at `blocked-manual` and then recovered has *two* bundles under this id; attaching `<attempt-id>--released.json` puts the verified-release evidence on the Release, not the stale hold.
66
+
67
+ **Candidate failed validation** (step 4a **DEAD** — the gate ran and the candidate failed it; traffic never moved) → set `step: "discard"` (its own value precisely so a resume cannot mistake it for a production rollback), then **check the traffic split before deleting anything**:
68
+
69
+ ```bash
70
+ gcloud run services describe <svc> --region <r> \
71
+ --format='value(status.traffic.percent,status.traffic.revisionName)'
72
+ ```
73
+
74
+ **The candidate must be at 0% before you delete it.** This ordering is the whole safeguard, not a formality: the `candidate` tag URL keeps resolving after a traffic shift, so a resumed session can re-run 4a against a revision that is now serving *every user*, get a DEAD, and arrive here — where deleting it takes production down. If the candidate holds any traffic, you are in the post-exposure tier; stop and route below. Only once it reads 0% is deletion free, because no request can reach it.
75
+
76
+ Then delete by **revision name** (never by the `candidate` tag, which moves), and confirm afterwards that the previously serving revision still holds 100%. **That confirmation is the verified candidate cleanup that closes the lease as `failed-pre-promotion`** ([principle 7](../SKILL.md#non-negotiable-principles)) — a failed build/validation on its own does *not* close it (that is the workflow-failure the lease refuses); only the verified cleanup does. Close and emit through one command, never as two manually remembered operations:
77
+ ```bash
78
+ node <resolve-release>/scripts/close-attempt.mjs <run-manifest.json> \
79
+ --bundle release-evidence.json --dir <durable-evidence-dir> \
80
+ --state failed-pre-promotion \
81
+ --evidence "candidate revision deleted; incumbent confirmed at 100%"
82
+ ```
83
+ For a candidate-validation failure, the bundle carries the candidate receipt, the 4a verdict that stopped it (DEAD/EMPTY/cannot-run), and the cleanup disposition. It owes **no** live verdict or traffic transition (nothing was exposed). For a failure **before any candidate existed**, it instead carries the attempt id, SHA, build identity and verified disposition; its derived `failurePhase: "pre-candidate"` forbids candidate and exposure observations. In either case `close-attempt.mjs` refuses an incomplete or contradictory bundle before writing the terminal manifest close, and the emitted top-level artifact is indexed by attempt id for `version-postmortem.mjs` and `rc-circuit-breaker.mjs`.
84
+ Then hand the captured evidence to `app-debug`/`diagnose` and file a **normal issue**, not an incident — nothing was un-shipped because nothing shipped. **Leave the originating issue(s) open.** The fix returns through `resolve-issues` and re-enters this loop at **step 0** — a code fix means a new SHA, so it needs a fresh candidate, a fresh promotion, and the assembly gates again. Note what does *not* change: the **version is reused**, and the new SHA takes the **next rc number** (principle 10 — no tag carrying a promise was ever created, so nothing is burned). Re-cut the version only if the fix changes the computed bump.
85
+
86
+ **A step-4a CANNOT-RUN or BLOCKED verdict is not a DEAD candidate.** It means the gate itself could not produce a verdict (e.g. a smoke secret resolved to its resource-name string, not its value, producing 401/403). Do **not** delete the candidate on it; the candidate was never judged. Instead, **repair the gate** (fix the secret/config, restore the credential, repair the fixture/driver) and **re-run 4a against the same 0%-traffic candidate**. Only after a repaired gate returns DEAD does the pre-exposure discard above apply. If the gate cannot be restored, the release stops with the candidate unvalidated and the lease stays held until the repair lands through the normal PR lane; the evidence bundle records the gate as the defect, not the build.
87
+
88
+ Resist inflating this into an outage. It is the pipeline working as designed, and treating a caught bug as an incident teaches people to route around the gate.
89
+
90
+ **Failure after a pause but before traffic shifts** (durable processing declared, and the attempt ended at 4b: the quiescence bound elapsed, the quiescence proof could not run, the fence failed, or the human declined) → **nothing was exposed, and production is nevertheless not intact: its processing is stopped.** Unwind in reverse, proving *before* each step rather than reporting after it:
91
+
92
+ Mechanize the proof and reverse unwind as one typed operation:
93
+
94
+ ```bash
95
+ node <resolve-release>/scripts/durable-processing.mjs unwind-pre-shift \
96
+ --declaration <repository-release-declaration.json> \
97
+ --incumbent-revision <release.previousRevision> \
98
+ --candidate-revision <release.candidateRevision> \
99
+ --generation <shift-fence-generation> --fence <shift-fence> \
100
+ > durable-processing-unwind.json
101
+ ```
102
+
103
+ Only `state: "unwound"` licenses candidate discard. `ambiguous` stops and pages.
104
+
105
+ 1. **Prove the previous revision still serves** — `release.previousRevision` at exactly 100% and the candidate at 0%, read from the platform with the same flattened traffic read the fence uses. Resuming processing hands live durable work to whatever revision is serving, so **which** revision that is has to be established, not inferred from "we never issued a shift". A shift can have been issued and failed; a resumed session may not know which.
106
+ 2. **Then resume in the reverse of the declared pause order** — worker scheduling first, database admission last — **against that revision**, confirming each resume rather than issuing it.
107
+ 3. **Only then treat the candidate.** It is at 0%, so the ordinary discard above applies unchanged, and this stays the routine, no-incident case (principle 6) — precisely *because* production was left described and intact, which is what the ordering buys.
108
+
109
+ If step 1 cannot establish which revision serves, this is not the path: that is the ambiguous state, so **stop and page** ([principle 14](../SKILL.md#non-negotiable-principles)) rather than resuming processing into a revision nobody has identified.
110
+
111
+ **Verification failed after exposure** (traffic shifted, then production went unhealthy) → execute the **confirmed rollback policy** (principle 6, post-exposure tier): restore production, confirm restoration with the same smoke, file the **incident** issue with the captured evidence, and hand diagnosis to `app-debug`/`diagnose`. **The confirmed restoration is the verified rollback that closes the lease as `rolled-back`** ([principle 7](../SKILL.md#non-negotiable-principles)) — the proof that the previous revision serves 100% again, not the fact that a rollback command was issued:
112
+ ```bash
113
+ node <resolve-issues>/scripts/run-state.mjs record-release-attempt <run-slug> \
114
+ '{"state":"rolled-back","closedBy":"verified-rollback","evidence":"<previous revision restored to 100%; smoke ALIVE against live service>"}'
115
+ ```
116
+ Then **emit the evidence bundle** — `terminalState: "rolled-back"`, `closedBy: "verified-rollback"`, carrying the traffic transition, the live verdict that went unhealthy, and the rollback disposition (previous revision restored to 100%, smoke ALIVE). **Leave the originating issue(s) open** and cross-link the incident — the work was un-shipped, so it is not done. The fix returns through `resolve-issues` and a fresh release; this loop never retries on prod.
117
+
118
+ **When floor smoke cannot go ALIVE after a correct restore** (identity-v0.4.1 / #800) — traffic and attestation prove the previous revision is back at 100%, but the read-only `prod-active` smoke against the **public host** stays DEAD for a reason that also fails the incumbent (edge inject, CSP, env gate). Do **not** invent a lease state and do **not** claim the candidate code is bad. Classify with the pure helper, then close with an explicit smoke marker and a **required** incident. The `--traffic` JSON must carry a concrete `attestation` object (revision and/or sourceSha/resource, or `verified:true`) — percents alone fail closed as `attestation-missing`:
119
+ ```bash
120
+ node <resolve-release>/scripts/rollback-floor.mjs payload \
121
+ --traffic '{"previousRevision":"<rev>","previousPercent":100,"candidatePercent":0,"attestation":{"revision":"<rev>"}}' \
122
+ --smoke '{"verdict":"DEAD","profile":"prod-active","floorAlsoDead":true,"reason":"<pre-existing gate>"}' \
123
+ --incident '{"number":<n>,"url":"<issue-url>"}'
124
+ # → {state:"rolled-back", closedBy:"verified-rollback", smoke:"blocked-by-preexisting-gate", ...}
125
+ node <resolve-issues>/scripts/run-state.mjs record-release-attempt <run-slug> "$(…payload…)"
126
+ ```
127
+ `smoke: blocked-by-preexisting-gate` is still `closedBy: verified-rollback` — the lease closes on the verified traffic+attestation restore, and the marker says the golden-path smoke could not prove ALIVE because the **floor** fails the same check. Without `traffic.attestation`, the payload path fails closed (`attestation-missing`) rather than emitting a close that claims attestation was verified. Without `floorAlsoDead` evidence, a DEAD after restore is **not** this path: stop and page. Without a filed incident, the close is incomplete. Regression: identity#677 (CF Insights vs app CSP).
128
+
129
+ **A `blocked-manual` hold and revocation** ([principle 7](../SKILL.md#non-negotiable-principles)) cover the two states these three exits do not. When an attempt stalls on something only an operator can clear — a rotated credential, an ambiguous state that paged (step 4b) — record `blocked-manual` with the `reason`; it **holds the lease** until the operator records recovery (`recovery.operator` + `recovery.evidence`), never reading as free in the meantime. When an in-flight attempt is deliberately abandoned without shipping — a superseding release, a withdrawn change — record `revoked` with `tagDisposition:"retained"`: revocation revokes the *attempt*, never the tag ([principle 10](../SKILL.md#non-negotiable-principles) — the rc tag is immutable). Neither is `workflow-*` closing the lease; both are recorded, verified transitions. **Each emits a bundle too** — `terminalState: "blocked-manual"` (carrying the `reason` and no close cause, since it holds the lease) or `terminalState: "revoked"` (carrying `tagDisposition: "retained"`) — so these two exits are as durably evidenced as the three above. The bundle is keyed by `(attempt id, terminal state)` (`<attemptId>--<state>.json`), so a `blocked-manual` hold that later recovers and closes `released` on the *same* attempt writes a second, distinct bundle rather than colliding with the first — the immutability guarantee holds per `(id, state)`, and no new rc is minted for a recovery (principle 10). A `revoked` attempt's id remains the key its bundle is indexed by, and — having abandoned without shipping — its bundle must carry no `liveVerdict`/`trafficTransition` (a `blocked-manual` hold parked at 4b *may*, since it can be post-shift).
130
+
131
+ **Where durable processing was declared, the rollback is ordered too, and the order inverts the intuitive one: traffic first, processing second** ([principle 14](../SKILL.md#non-negotiable-principles)). Roll traffic back to `release.previousRevision`; **prove the restoration** — that revision at exactly 100%, and the read-only `prod-active` smoke profile ALIVE against the live service; and **only then** restore worker scheduling and database admission, in the reverse of the declared pause order and **against that restored revision**. Restoring processing first hands the durable queue back to the revision you have just judged unfit, on state the incumbent will then have to live with — the two-versions-on-one-state failure principle 14 exists to prevent, re-created by the recovery itself. And an ambiguous traffic or restoration state at any point stops and pages rather than proceeding: a rollback executed against a state nobody can read is how an ordinary bad release becomes a data incident.
132
+
133
+ After traffic and smoke prove the incumbent restored, run `durable-processing.mjs up` against
134
+ that incumbent and the last proven generation/fence. Its status receipt must itself observe the
135
+ named revision at exactly 100%, with `--serving-revision <release.previousRevision>`,
136
+ `--incumbent-revision <release.previousRevision>`, and
137
+ `--candidate-revision <release.candidateRevision>`; the repository job enforces
138
+ scheduling-before-admission. A split, unknown third revision, missing release identity, invalid
139
+ total, or stale generation/fence stops before either resume.
140
+
141
+ Every terminal bundle records the durable path under canonical `durableProcessing`:
142
+ `{present:false}` for a decided stateless target, or `{present:true, preflight, down, up}` /
143
+ `{present:true, preflight, down, unwind}` using writer-stamped sequence receipts.
144
+ `evidence-bundle.mjs validate` rejects a boolean/prose claim, a missing preflight or sequence
145
+ receipt, a nonzero blocker proof, a missing generation/fence, the wrong reverse order, or an
146
+ absent serving revision. Thus the terminal record cannot preserve traffic evidence while
147
+ dropping whether processing was safely restored.
148
+
149
+ - **The version, on either failure.** Under the rc scheme the final tag is minted only at step 5, after verification — so on **both** failure paths no version claim was ever published and the retry **reuses the version**. A version is burned only in the legacy shape where the pipeline fires on the *final* tag (pre-flight item 5); there the tag is already on the remote, so it is never moved, deleted, or reused, no Release is published, the retry takes the **next patch**, and the stranded CHANGELOG entry is annotated in the commit that cuts the next version rather than erased — the file is append-only, and deleting the entry destroys the only public record the version existed: `node <resolve-release>/scripts/version.mjs withdraw --version <v> --incident <#n>`.
@@ -0,0 +1,285 @@
1
+ # Verified-SHA GitHub Flow mode contract
2
+
3
+ This reference defines an **opt-in release mode** for repositories that use
4
+ GitHub Flow and want a release to preserve an already eligible `main` commit as
5
+ the exact release identity. It is self-contained: an operator or reviewer can
6
+ determine the required release ordering from this file without a checkout of
7
+ another repository.
8
+
9
+ The mode is derived from a consumer product repo's ADR 0034, "Separate validation
10
+ gates from smoke targets in GitHub Flow", at merge
11
+ `2420a0910487c87c4e6458f7203925cde0b54eff`.
12
+
13
+ ## Authority and selection
14
+
15
+ Call this mode **`verified-sha-github-flow`**. It applies only when the human
16
+ selects it in the pre-flight authorization envelope for a single-branch GitHub
17
+ Flow release. Selection is per release; adopting GitHub Flow does not select
18
+ this mode implicitly.
19
+
20
+ When selected, this reference is authoritative over the general GitHub Flow
21
+ prose in `resolve-release` for these deliberate differences:
22
+
23
+ - tag the already-merged selected `main` SHA directly, with no release branch,
24
+ promotion PR, promotion merge, rebase, or retargeting when `main` advances;
25
+ - create no pre-deployment CHANGELOG or package-version commit; and
26
+ - synchronize release metadata through the post-release adapter only after the
27
+ final release claim exists.
28
+
29
+ The general `resolve-release` doctrine still governs authorization, read-only
30
+ production validation, candidate identity, validation-before-exposure,
31
+ rollback, and evidence wherever this reference does not vary it. If this mode
32
+ is not selected, every existing topology, trigger shape, versioning path, and
33
+ release mode keeps its current behavior by default.
34
+
35
+ This reference defines decision, identity, ordering, durable-state, and resume
36
+ boundaries needed by the mode. It does not absorb the implementation ownership
37
+ of adjacent release-lane issues #431 through #442: deployment receipts, smoke
38
+ profiles, workflow identities, Cloud Build polling, traffic controls,
39
+ concurrency mechanisms, cleanup jobs, and metadata-PR mechanics remain with
40
+ their owning contracts and producers. Their implementations may supply this
41
+ mode's evidence, but may not weaken the invariants below.
42
+
43
+ ## Terms
44
+
45
+ - **Eligible `main` SHA**: an exact commit that is on `main` and has a green
46
+ Trunk Integration Verdict for that exact SHA. Branch greenness, a verdict for
47
+ another SHA, and an unverified commit at the current tip are not eligibility.
48
+ - **Production floor**: the exact commit currently verified as active in
49
+ production and named by the current final Release Tag. It is an observed
50
+ deployment boundary, not merely the highest SemVer string.
51
+ - **Selected SHA**: the eligible `main` SHA the human authorizes for the next
52
+ normal release.
53
+ - **Proposed version**: the `MAJOR.MINOR.PATCH` value computed from the release
54
+ content between the production floor and selected SHA and confirmed by the
55
+ human before the first attempt tag is created.
56
+ - **Release Attempt Tag**: an immutable tag
57
+ `vMAJOR.MINOR.PATCH-rc.N`. It pins one Release Attempt to one selected SHA and
58
+ is the only tag class in this mode that may trigger production deployment.
59
+ - **Release Attempt**: the durable record joining the proposed version, attempt
60
+ number, immutable attempt tag and SHA, workflow/check identity, candidate
61
+ receipt, validation evidence, traffic evidence, and terminal outcome.
62
+ - **Nonterminal Release Attempt**: an attempt whose lease is still held because
63
+ release, verified zero-traffic cleanup, verified rollback, or verified
64
+ revocation cleanup has not completed. `blocked-manual` remains nonterminal
65
+ for single-flight purposes even if its workflow has stopped.
66
+ - **Final Release Tag**: the immutable `vMAJOR.MINOR.PATCH` tag created on the
67
+ selected SHA only after that SHA is verified at `prod/active`. It records a
68
+ release; it never requests a deployment.
69
+ - **Post-release metadata adapter**: the deterministic process that opens a
70
+ normal PR against current `main` after the final claim, adding the released
71
+ CHANGELOG section and synchronizing package version metadata while preserving
72
+ newer unreleased work.
73
+
74
+ ## Candidate selection and the production floor
75
+
76
+ Candidate discovery returns eligible SHAs on `main`, ordered newest first. The
77
+ newest eligible SHA is the default selection. The human may explicitly confirm
78
+ an earlier SHA, but only when that exact commit is still eligible and is a
79
+ strict descendant of the production floor.
80
+
81
+ A normal release therefore requires both of these ancestry checks immediately
82
+ before `rc.1` is created:
83
+
84
+ 1. the selected SHA is reachable from current `main`; and
85
+ 2. the production floor is an ancestor of, and not equal to, the selected SHA.
86
+
87
+ Equal or older code is never assigned a higher normal-release version. A request
88
+ to return production to the floor or one of its ancestors routes to the
89
+ explicit rollback procedure, with its own authorization and evidence; it does
90
+ not create a new Release Attempt or reinterpret rollback as a normal release.
91
+ Missing or ambiguous production-floor evidence refuses selection.
92
+
93
+ ## Version confirmation and the immutable pin
94
+
95
+ Compute SemVer from the content that would actually release: changes after the
96
+ production floor through the selected SHA. Present the bump, its reason, and
97
+ the proposed version to the human. Human confirmation is required before
98
+ creating `vMAJOR.MINOR.PATCH-rc.1`; neither a green verdict nor the general
99
+ release authorization silently accepts the version.
100
+
101
+ Creating the first Release Attempt Tag pins both the selected SHA and proposed
102
+ version. After that point:
103
+
104
+ - advancing `main` does not retarget, rebase, cancel, or invalidate the attempt;
105
+ - later `main` commits do not enter this release unless the current attempt
106
+ reaches a terminal outcome and a new candidate is explicitly selected;
107
+ - the attempt tag is never moved, deleted, reused, or force-written — and the push that publishes it is a tag-ref push (`refs/tags/*` with hook-safe `--no-verify`), never a Mergify stack push (identity-v0.4.1); and
108
+ - every retry of this proposed version uses the next unused immutable rc number.
109
+
110
+ A failed attempt does not burn the proposed version because no final Release
111
+ Tag exists. After the attempt reaches a verified terminal outcome, a retry may
112
+ pin the same SHA or a newly selected eligible SHA, but it keeps the confirmed
113
+ version and takes `rc.N+1`. Recompute and reconfirm only when the release content
114
+ changes the required SemVer bump. Attempt numbers are monotonic for the
115
+ proposed version; gaps or an ambiguous next number fail closed rather than
116
+ reusing a tag.
117
+
118
+ ## Single flight and revocation
119
+
120
+ Before creating any Release Attempt Tag, prove from durable repository and
121
+ workflow state that there is no nonterminal Release Attempt for production.
122
+ Exactly one lease-holding attempt is allowed. A second or ambiguous attempt is
123
+ refused; it is not queued by cancelling, replacing, or mutating the first
124
+ attempt or its tag. Workflow completion, failure, timeout, and cancellation do
125
+ not by themselves release the lease.
126
+
127
+ Newly discovered risk may revoke an attempt only through an explicit,
128
+ human-authorized revocation transition recorded against that attempt. Revocation
129
+ never moves or deletes its Release Attempt Tag and never creates a final tag. A
130
+ revocation before exposure verifies and removes only the recorded 0%-traffic
131
+ candidate, then proves the prior production revision still serves 100%.
132
+ Revocation after exposure uses the authorized one-hop rollback and verifies the
133
+ restored revision. Only that verified cleanup or restoration makes `revoked` a
134
+ terminal outcome; ambiguous traffic or cleanup state becomes `blocked-manual`
135
+ and continues to hold the lease.
136
+
137
+ ## Final claim and metadata ordering
138
+
139
+ The final claim has a strict order:
140
+
141
+ 1. read the selected attempt's pinned SHA and candidate identity from durable
142
+ state;
143
+ 2. verify `prod/active` is serving that exact SHA and the recorded revision and
144
+ image identity at 100% traffic, with the required active smoke verdict;
145
+ 3. create the immutable Final Release Tag on that exact SHA;
146
+ 4. create the GitHub Release for that tag and attach or link the verified
147
+ attempt evidence; and
148
+ 5. invoke the post-release metadata adapter against current `main`.
149
+
150
+ A deploy/check success, a preview verdict, an approval, or a traffic-shift
151
+ request is not `prod/active` verification. Missing, stale, mismatched, or
152
+ ambiguous active evidence refuses both final tag and GitHub Release. A rolled
153
+ back, failed, revoked, or `blocked-manual` attempt receives neither.
154
+
155
+ The final tag pattern must be excluded from every production deployment trigger.
156
+ Only `vMAJOR.MINOR.PATCH-rc.N` requests a deployment in this mode. Creating or
157
+ replaying `vMAJOR.MINOR.PATCH` must therefore be incapable of starting a second
158
+ build, migration, deployment, or traffic shift.
159
+
160
+ Do not commit a CHANGELOG cut, package-version bump, generated release metadata,
161
+ or release-only identity change before deployment. Such a commit would create
162
+ a different SHA from the green selected SHA and destroy the verified-SHA pin.
163
+ The authoritative release notes are the post-verification GitHub Release.
164
+
165
+ Afterward, the post-release metadata adapter opens a required PR from the final
166
+ release evidence against current `main`. It deterministically adds the released
167
+ version section to `CHANGELOG.md`, synchronizes package version fields, and
168
+ preserves all commits and unreleased entries that arrived after the selected
169
+ SHA. The PR follows the normal review and merge-queue path. A subsequent
170
+ verified-SHA release is blocked while any existing final tag lacks its merged
171
+ metadata-sync PR; the adapter never rewrites the released SHA or either tag
172
+ class.
173
+
174
+ **Mechanized:** `node <resolve-release>/scripts/metadata-sync.mjs open
175
+ --manifest <run> --version <v> --sha <shipped> --date <YYYY-MM-DD>
176
+ [--changes <json>] [--package-file <path>]…
177
+ [--lock-file <path> --lock-command <cmd>]` branches off current `main`, cuts
178
+ the CHANGELOG section, bumps declared package files, opens the PR, and records
179
+ `release.metadataPr` on the manifest (`status:"opened"` + number/url + `source:"metadata-sync.mjs"`,
180
+ or `status:"n/a"` with a reason via `metadata-sync.mjs na`). Only entries written by
181
+ `metadata-sync.mjs open|na|migrate` satisfy the gate; a hand-written `release.metadataSync`
182
+ or a `metadataPr` from another source is rejected by `report.mjs`. A released attempt
183
+ without a valid record is incomplete in `report.mjs` and the handoff. Use
184
+ `metadata-sync.mjs migrate` to convert a legacy `release.metadataSync` record under
185
+ adapter control. Regression: identity-v0.4.1 shipped without the adapter; metadata
186
+ landed as identity#678 (and the v0.5.0 skyee cut used a hand-rolled PR recorded as
187
+ `metadataSync`, so the completeness gate never saw it — #821).
188
+
189
+ ### Isolated metadata synchronization
190
+
191
+ `metadata-sync.mjs open` fetches current `main`, creates a disposable detached
192
+ worktree, and consumes only `version.mjs changelog --dry-run --format json` with
193
+ the validated CHANGELOG bytes on stdin. Before planning or staging, every declared
194
+ CHANGELOG, package, lock, and file-form `--changes` path is validated as normalized
195
+ and relative. Existing paths must be single-link regular files reached through
196
+ contained real parents; symlinks, hardlinks, non-regular entries, escaping parents,
197
+ and identity changes during descriptor validation fail closed.
198
+
199
+ Package metadata is supported only as JSON `version` or TOML `[project]` /
200
+ `[tool.poetry]` version data (#960, forex-v0.1.12). A requested package that is
201
+ missing, unparseable, or unsupported makes `plan`, dry-run `open`, and live
202
+ `open` fail. A missing CHANGELOG is the only declared metadata path created by the
203
+ plan. Planned bytes are written as Git blobs and staged directly in the disposable
204
+ index; the caller workspace is never checked out, stashed, cleaned, staged, committed,
205
+ or used as a metadata write target.
206
+
207
+ The staged index is materialized into a second private execution tree. A declared lock
208
+ moves only through its paired repository `--lock-command` (for example, `uv lock`)
209
+ in that tree. For an npm root lockfile, declare
210
+ `--lock-file package-lock.json --lock-command "npm install --package-lock-only"`; its
211
+ top-level and root-package metadata must identify the package and hold the target
212
+ version. Every requested package and the lock's root entry must hold the target version
213
+ before commit. Ordinary commit hooks then run in the same private tree. After commit,
214
+ the adapter verifies both private disk and committed blobs,
215
+ so a hook that rewrites either disk or staged content fails before push, PR creation,
216
+ or manifest recording. Push is ordinary; only output identifying the known Mergify
217
+ pre-push hook receives one `--no-verify` retry. Any unrelated local or remote failure
218
+ stops without retry.
219
+
220
+ An existing local branch, remote branch, manifest record, commit, or PR is adopted only
221
+ when repository, base, branch, version, shipped SHA, expected content, message, parent,
222
+ and exact head commit agree. Divergence or ambiguity refuses without force. A failed
223
+ unpublished push preserves the exact commit on its local branch ref and cleans the
224
+ disposable trees. On every success or failure the caller branch, HEAD, index, tracked,
225
+ staged, unstaged, and untracked bytes remain exact; the manifest therefore must live
226
+ outside the caller repository.
227
+
228
+ After `watch-pr-delivery.mjs` reaches a terminal result, run `metadata-sync.mjs
229
+ record-delivery --manifest <run> --watch-result <json>`. A watcher
230
+ `outcome:"MERGED"` is necessary but not sufficient: the adapter independently
231
+ re-reads the exact PR, fetches fresh `main`, proves metadata commit to merge commit
232
+ to fresh-main ancestry, and verifies every expected merged file hash before recording
233
+ `release.metadataPr.status="merged"` through the canonical state contract.
234
+
235
+ ## Fail-closed state and resume boundaries
236
+
237
+ Persist state before and after every outward action. At minimum the durable
238
+ record must make these boundaries distinguishable:
239
+
240
+ 1. mode selection, production floor, eligible set, selected SHA, ancestry
241
+ result, computed bump, human version confirmation, and single-flight proof;
242
+ 2. intent to create an attempt tag, followed by the observed immutable tag name,
243
+ tag SHA, attempt number, and workflow/check identity;
244
+ 3. candidate receipt at 0%, exact candidate identity, previous 100%-traffic
245
+ revision, and preview verdict/freshness;
246
+ 4. authorization or revocation intent, followed by a fresh identity/traffic
247
+ fence immediately before mutation;
248
+ 5. observed post-mutation traffic, `prod/active` verification or verified
249
+ cleanup/rollback, and terminal outcome; and
250
+ 6. final-tag intent and observation, GitHub Release identity, metadata-adapter
251
+ invocation, PR identity, and merged result.
252
+
253
+ On resume, observe immutable tags, workflows/checks, candidate identity, and
254
+ live traffic before acting; never infer that an outward action did or did not
255
+ happen from the last local step alone. Reconcile every observation with the
256
+ pinned attempt. Missing state, malformed evidence, multiple matches, a SHA or
257
+ identity mismatch, stale evidence, an impossible transition, or an uncertain
258
+ outward-action result fails closed. Preserve the attempt lease and route to
259
+ `blocked-manual` when safety cannot be proved. Resume must be idempotent: it
260
+ may observe an existing correct artifact, but may not create a second attempt,
261
+ repeat a traffic mutation, reuse an rc number, or create a final claim early.
262
+
263
+ ## Required implementation test matrix
264
+
265
+ The #428 implementation producer must prove these as behavioral tests at the
266
+ state/adapter boundary. These are future implementation obligations, not prose
267
+ checks for this contract-only slice:
268
+
269
+ | Case | Required outcome |
270
+ |---|---|
271
+ | Newest candidate | Candidate discovery defaults to the newest eligible green `main` SHA. |
272
+ | Earlier candidate | A human-confirmed earlier eligible SHA strictly above the production floor is accepted and pinned exactly. |
273
+ | Production floor | A SHA equal to or older than the production floor, or an unknown/ambiguous floor, is refused and the equal/older request routes to rollback. |
274
+ | Moving `main` | New commits after rc creation neither retarget nor cancel the pinned attempt and are absent from its release identity. |
275
+ | Retry numbering | A terminal failed attempt reuses the confirmed version at the next unused immutable rc number; same-number reuse, movement, deletion, and ambiguity are refused. |
276
+ | Single flight | A second attempt is refused while any attempt is nonterminal, including `blocked-manual`; workflow termination alone does not release the lease. |
277
+ | Revocation | Explicit revocation preserves the rc tag, creates no final tag, and becomes terminal only after verified zero-traffic cleanup or verified rollback. |
278
+ | Final tag after verification | Final tag and GitHub Release are impossible before matching `prod/active` verification and name the exact verified SHA afterward; the final tag cannot trigger deployment. |
279
+ | Metadata ordering | No pre-deploy metadata commit changes the selected SHA; successful finalization invokes a deterministic metadata-sync PR that preserves newer `main` work. |
280
+ | Resume boundaries | A crash on either side of every outward action resumes by observation, is idempotent, and refuses missing, stale, mismatched, duplicate, or ambiguous state. |
281
+
282
+ The durable tests added by this contract slice may check only structural facts:
283
+ that this reference exists, is reachable from `SKILL.md`, and exposes its named
284
+ contract anchor. Regex vocabulary checks do not prove these prose invariants
285
+ and must not be presented as semantic coverage.