@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,488 @@
1
+ // Correctness-only run finalization. Diagnostics are deliberately outside this gate.
2
+ import { execFileSync, spawnSync } from 'node:child_process'
3
+
4
+ import { deliveryForUnit, terminalDisposition, terminalDispositionTally } from './terminal-dispositions.mjs'
5
+ import { effectiveUnitKind, unitKindComplete } from './unit-lifecycle.mjs'
6
+ import { validateComponentCandidates } from './component-candidate.mjs'
7
+
8
+ const isObject = (value) => value != null && typeof value === 'object' && !Array.isArray(value)
9
+ const arr = (value) => (Array.isArray(value) ? value.filter(isObject) : [])
10
+ const nonEmpty = (value) => typeof value === 'string' && value.trim().length > 0
11
+ const sha7 = (value) => nonEmpty(value) ? value.slice(0, 7) : '(none)'
12
+ const refNumber = (value) => {
13
+ if (Number.isInteger(value) && value > 0) return value
14
+ const match = String(value ?? '').match(/(?:^|#)(\d+)$/)
15
+ return match ? Number(match[1]) : null
16
+ }
17
+ const componentUnitIds = (component) => (Array.isArray(component?.units) ? component.units : [])
18
+ .map((unit) => typeof unit === 'string' ? unit : unit?.id).filter(nonEmpty)
19
+
20
+ function normalizedGithubObservation(kind, requestedNumber, live) {
21
+ if (!isObject(live)) throw new Error(`${kind} #${requestedNumber} returned no structured observation`)
22
+ if (!Number.isInteger(live.number) || live.number <= 0) {
23
+ throw new Error(`${kind} #${requestedNumber} returned missing or malformed numeric identity`)
24
+ }
25
+ if (live.number !== requestedNumber) {
26
+ throw new Error(`${kind} #${requestedNumber} returned identity ${live.number}`)
27
+ }
28
+ return { ...structuredClone(live), number: requestedNumber }
29
+ }
30
+
31
+ function expectedIssueState(unit, disposition) {
32
+ if (disposition === 'delivered' || disposition === 'already-done' || disposition === 'descoped') return 'CLOSED'
33
+ if (disposition === 'handed-back') return null
34
+ const kind = effectiveUnitKind(unit)
35
+ if (kind !== 'implementation') return unitKindComplete(unit) ? 'CLOSED' : 'OPEN'
36
+ return null
37
+ }
38
+
39
+ function expectedPrState(disposition, scopeDecision) {
40
+ if (disposition === 'descoped') return { state: 'CLOSED', merged: false, label: scopeDecision?.prDisposition ?? 'closed-unmerged' }
41
+ if (disposition === 'delivered') return { terminal: true, label: 'closed or merged after component delivery' }
42
+ if (disposition === 'handed-back') return { merged: false, label: 'open or closed unmerged hand-back' }
43
+ if (disposition === 'already-done') return { terminal: true, label: 'closed or merged prior art' }
44
+ return null
45
+ }
46
+
47
+ function workspaceErrors(cleanup) {
48
+ const errors = []
49
+ if (!isObject(cleanup)) return ['workspace cleanup returned no structured result']
50
+ if (nonEmpty(cleanup.commandError)) errors.push(`workspace cleanup command failed: ${cleanup.commandError}`)
51
+ if (cleanup.collection?.ran !== true) errors.push(`workspace orphan collection did not run: ${cleanup.collection?.reason ?? 'no reason recorded'}`)
52
+ for (const failure of Array.isArray(cleanup.removalFailures) ? cleanup.removalFailures : []) {
53
+ errors.push(`workspace removal failed: ${typeof failure === 'string' ? failure : failure?.path ?? JSON.stringify(failure)}`)
54
+ }
55
+ const byPath = new Map(arr(cleanup.decisions).map((row) => [row.path, row]))
56
+ for (const remaining of Array.isArray(cleanup.remaining) ? cleanup.remaining : []) {
57
+ const path = typeof remaining === 'string' ? remaining : remaining?.path
58
+ const row = byPath.get(path) ?? (isObject(remaining) ? remaining : null)
59
+ if (/orchestrator's own checkout|orchestrator's tree/i.test(row?.reason ?? '')) continue
60
+ if (row?.unpublished === true || /unpublished work|uncommitted|untracked|on no remote/i.test(row?.reason ?? '')) {
61
+ errors.push(`unpublished work was preserved, never discarded, at ${path}: ${row?.reason ?? 'reason not recorded'}`)
62
+ } else {
63
+ errors.push(`unreaped workspace remains at ${path}: ${row?.reason ?? 'cleanup did not remove it'}`)
64
+ }
65
+ }
66
+ return errors
67
+ }
68
+
69
+ // A non-implementation unit is settled two ways, not one: it completed its kind's own protocol,
70
+ // or a human descoped it. `record-scope-decision` never restricted descoping by kind, so a run
71
+ // could record an honest descope that finalization then refused forever (#1087) — and
72
+ // `external-verification`, the kind that exists precisely for work no agent session can perform,
73
+ // is the kind most likely to need one. This is not a bypass: `terminalDisposition` re-validates
74
+ // the whole scope decision on every read, so a loop-applied, non-human, or delivery-claiming
75
+ // "descope" resolves to null and the unit stays pending.
76
+ const nonImplementationSettled = (unit, manifest) => unitKindComplete(unit)
77
+ || terminalDisposition(unit, manifest) === 'descoped'
78
+
79
+ const descopedIn = (roster, manifest) => roster
80
+ .filter((unit) => !unitKindComplete(unit) && terminalDisposition(unit, manifest) === 'descoped')
81
+
82
+ function scopeTally(roster, manifest) {
83
+ return {
84
+ total: roster.length,
85
+ complete: roster.filter(unitKindComplete).length,
86
+ descoped: descopedIn(roster, manifest).length,
87
+ pending: roster.filter((unit) => !nonImplementationSettled(unit, manifest)).length,
88
+ }
89
+ }
90
+
91
+ // The two scope rosters, named once: the record, its read-back validator and the rendered handoff
92
+ // all derive from these, so a finalized run can never be rejected by a tally computed differently
93
+ // from the one that was written.
94
+ const SCOPE_ROSTERS = [
95
+ ['external', 'external verification', (unit) => effectiveUnitKind(unit) === 'external-verification'],
96
+ ['humanOrPrerequisite', 'human decisions/prerequisites', (unit) => ['human-decision', 'prerequisite'].includes(effectiveUnitKind(unit))],
97
+ ]
98
+
99
+ function scopeRecord(units, manifest) {
100
+ return Object.fromEntries(SCOPE_ROSTERS.map(([key, , belongs]) => [key, scopeTally(units.filter(belongs), manifest)]))
101
+ }
102
+
103
+ // A run finalized before `descoped` joined the tally recorded three counts, not four. Absent
104
+ // reads as 0 — the true historical value, since a descoped non-implementation unit could not
105
+ // finalize at all then. Field-by-field so the comparison is order-independent and all four
106
+ // numbers stay strictly checked rather than the whole block being waved through.
107
+ const normalizedScopeTally = (tally) => ({
108
+ total: tally?.total, complete: tally?.complete, descoped: tally?.descoped ?? 0, pending: tally?.pending,
109
+ })
110
+ // Driven off SCOPE_ROSTERS, never a second hand-written key list: a roster named in one place and
111
+ // forgotten in the other would silently drop out of the staleness comparison.
112
+ const normalizedScope = (scope) => Object.fromEntries(
113
+ SCOPE_ROSTERS.map(([key]) => [key, normalizedScopeTally(scope?.[key])]))
114
+
115
+ function autonomousDecisions(units) {
116
+ const rows = []
117
+ for (const unit of units) {
118
+ for (const decision of [...arr(unit.breakerLog), ...(isObject(unit.breaker) ? [unit.breaker] : [])]) {
119
+ if (decision.autoApplied === true) rows.push({
120
+ unit: unit.id,
121
+ decision: decision.decision,
122
+ signal: decision.signal ?? 'not recorded',
123
+ autonomyAtDecision: decision.autonomyAtDecision ?? null,
124
+ decidedAt: decision.decidedAt ?? null,
125
+ })
126
+ }
127
+ }
128
+ return rows
129
+ }
130
+
131
+ export function renderFinalHandoff(manifest, finalization) {
132
+ const units = arr(manifest.units)
133
+ const byId = new Map(units.map((unit) => [unit.id, unit]))
134
+ const lines = [
135
+ 'FINAL HANDOFF',
136
+ `run ${manifest.runSlug ?? '(unknown)'} -> ${manifest.targetBranch ?? '(unknown target)'} @ ${sha7(finalization.target?.headSha)}`,
137
+ '',
138
+ 'Delivery:',
139
+ ]
140
+ for (const unit of units.filter((entry) => effectiveUnitKind(entry) === 'implementation')) {
141
+ const disposition = terminalDisposition(unit, manifest)
142
+ const delivery = deliveryForUnit(unit, manifest)
143
+ if (disposition === 'delivered') lines.push(` - ${unit.id}: delivered via component ${unit.deliveryRef?.componentId ?? '(legacy unit)'} @ ${sha7(delivery?.mergedSha)}`)
144
+ else if (disposition === 'handed-back') lines.push(` - ${unit.id}: handed back - ${delivery?.blockedOn ?? 'reason not recorded'}`)
145
+ else if (disposition === 'already-done') lines.push(` - ${unit.id}: already done (verified prior art)`)
146
+ else if (disposition === 'descoped') lines.push(` - ${unit.id}: human-descoped - ${unit.scopeDecision?.reason ?? 'reason not recorded'}`)
147
+ }
148
+ for (const component of arr(manifest.components)) {
149
+ if (componentUnitIds(component).some((id) => terminalDisposition(byId.get(id), manifest) === 'delivered')) {
150
+ lines.push(` - component ${component.id}: merged ${sha7(component.delivery?.mergedSha ?? component.mergedSha)}`)
151
+ }
152
+ }
153
+
154
+ lines.push('', 'Scope:')
155
+ for (const [, label, belongs] of SCOPE_ROSTERS) {
156
+ const roster = units.filter(belongs)
157
+ const tally = scopeTally(roster, manifest)
158
+ lines.push(` - ${label}: ${tally.complete} complete, ${tally.descoped ? `${tally.descoped} descoped, ` : ''}${tally.pending} pending`)
159
+ // A count nobody can act on is not a handoff: name each unit the human removed, and why.
160
+ for (const unit of descopedIn(roster, manifest)) {
161
+ lines.push(` - ${unit.id}: human-descoped - ${unit.scopeDecision?.reason ?? 'reason not recorded'}`)
162
+ }
163
+ }
164
+
165
+ lines.push('', 'Cleanup:')
166
+ lines.push(` - original branch: ${finalization.branchRestore.expected ?? 'not applicable'} (${finalization.branchRestore.restored ? 'restored' : 'not restored'})`)
167
+ const cleanupRows = arr(finalization.cleanup?.decisions)
168
+ lines.push(` - workspaces: ${cleanupRows.filter((row) => row.verdict === 'absent').length} absent, ${cleanupRows.filter((row) => row.verdict === 'reap').length} reaped, ${cleanupRows.filter((row) => row.verdict === 'preserve').length} preserved`)
169
+
170
+ lines.push('', 'Deferrals and known debt:')
171
+ const deferrals = arr(manifest.deferrals)
172
+ if (!deferrals.length) lines.push(' - none recorded')
173
+ else for (const row of deferrals) lines.push(` - ${row.requirement ?? '(unnamed requirement)'} -> ${row.trackedIn ?? '(untracked)'}`)
174
+
175
+ lines.push('', 'Autonomous breaker decisions:')
176
+ if (!finalization.autonomousBreakerDecisions.length) lines.push(' - none')
177
+ else for (const row of finalization.autonomousBreakerDecisions) {
178
+ lines.push(` - ${row.unit}: ${row.decision} (${row.signal})${row.autonomyAtDecision ? ` under ${row.autonomyAtDecision}` : ''}`)
179
+ }
180
+ return lines.join('\n')
181
+ }
182
+
183
+ export async function finalizeRun(manifest, boundary) {
184
+ const input = structuredClone(manifest)
185
+ const errors = []
186
+ const units = arr(input.units)
187
+ if (input.finalization !== undefined) errors.push('run is already finalized; finalization evidence is immutable')
188
+ if (!units.length) errors.push('finalize requires at least one typed unit')
189
+ const implementations = units.filter((unit) => effectiveUnitKind(unit) === 'implementation')
190
+ if (input.completionAudit !== undefined) {
191
+ errors.push('caller-authored completionAudit cannot authorize finalization; every completion fact is re-established live')
192
+ }
193
+ for (const unit of implementations) {
194
+ const disposition = terminalDisposition(unit, input)
195
+ if (!['delivered', 'handed-back', 'already-done', 'descoped'].includes(disposition)) {
196
+ errors.push(`${unit.id ?? '(unknown unit)'} has no honest in-scope terminal disposition (expected delivered, handed-back, already-done, or human-descoped)`)
197
+ }
198
+ }
199
+ errors.push(...validateComponentCandidates(input).map((error) => `component candidate: ${error}`))
200
+ for (const unit of units.filter((entry) => effectiveUnitKind(entry) !== 'implementation')) {
201
+ if (!nonImplementationSettled(unit, input)) errors.push(`${unit.id ?? '(unknown unit)'} ${effectiveUnitKind(unit)} is still pending and prevents whole-run finalization`)
202
+ }
203
+
204
+ let target = null
205
+ try { target = await boundary.fetchTarget(input.targetBranch) } catch (error) { errors.push(`fresh target fetch failed: ${error.message ?? error}`) }
206
+ if (!isObject(target) || !nonEmpty(target.ref) || !nonEmpty(target.headSha)) errors.push('fresh target fetch returned no target ref/head SHA')
207
+
208
+ const ancestry = []
209
+ const ancestryClaims = []
210
+ const byId = new Map(units.map((unit) => [unit.id, unit]))
211
+ const deliveredComponents = arr(input.components).filter((component) => componentUnitIds(component)
212
+ .some((id) => terminalDisposition(byId.get(id), input) === 'delivered'))
213
+ const canonicallyDeliveredUnits = new Set(deliveredComponents
214
+ .filter((component) => component.delivery?.outcome === 'merged')
215
+ .flatMap(componentUnitIds))
216
+ for (const unit of implementations) {
217
+ if (terminalDisposition(unit, input) === 'delivered' && !canonicallyDeliveredUnits.has(unit.id)) {
218
+ ancestryClaims.push({ kind: 'unit', id: unit.id, sha: deliveryForUnit(unit, input)?.mergedSha })
219
+ }
220
+ }
221
+ for (const component of deliveredComponents) {
222
+ const mergedSha = component.delivery?.mergedSha ?? component.mergedSha
223
+ if (!nonEmpty(mergedSha)) errors.push(`delivered component ${component.id ?? '(unknown)'} has no recorded merge SHA`)
224
+ else ancestryClaims.push({ kind: 'component', id: component.id, sha: mergedSha })
225
+ }
226
+ if (target?.ref) {
227
+ for (const claim of ancestryClaims) {
228
+ let contained = false
229
+ try { contained = await boundary.isAncestor(claim.sha, target.ref) } catch (error) { errors.push(`ancestry check failed for ${claim.kind} ${claim.id}: ${error.message ?? error}`) }
230
+ ancestry.push({ ...claim, targetRef: target.ref, contained })
231
+ if (!contained) errors.push(`${claim.kind} ${claim.id} merge SHA ${claim.sha} is not an ancestor of freshly fetched ${target.ref}`)
232
+ }
233
+ }
234
+
235
+ const github = { issues: [], prs: [] }
236
+ for (const unit of units) {
237
+ const issue = refNumber(unit.issue ?? unit.id)
238
+ if (issue == null) { errors.push(`${unit.id ?? '(unknown unit)'} has no GitHub issue reference for live terminal verification`); continue }
239
+ try {
240
+ const observed = await boundary.readIssue(issue, input.repository)
241
+ const live = normalizedGithubObservation('issue', issue, observed)
242
+ github.issues.push({ ...live, unit: unit.id, number: issue })
243
+ const disposition = terminalDisposition(unit, input)
244
+ const expected = expectedIssueState(unit, disposition)
245
+ if (expected && live.state !== expected) errors.push(`${unit.id} issue is ${live.state ?? 'unreadable'}, expected ${expected} for ${disposition ?? effectiveUnitKind(unit)}`)
246
+ if (disposition === 'descoped' && unit.scopeDecision?.issueDisposition === 'closed-not-planned'
247
+ && live.stateReason !== undefined && live.stateReason !== null && live.stateReason !== 'NOT_PLANNED') {
248
+ errors.push(`${unit.id} issue state reason is ${live.stateReason}, expected NOT_PLANNED for closed-not-planned descope`)
249
+ }
250
+ } catch (error) { errors.push(`${unit.id} issue could not be verified live: ${error.message ?? error}`) }
251
+
252
+ const pr = refNumber(unit.pr)
253
+ if (pr != null) {
254
+ try {
255
+ const observed = await boundary.readPr(pr, input.repository)
256
+ const live = normalizedGithubObservation('PR', pr, observed)
257
+ github.prs.push({ ...live, unit: unit.id, role: 'unit', number: pr })
258
+ const expected = expectedPrState(terminalDisposition(unit, input), unit.scopeDecision)
259
+ if (expected?.merged === false && live.merged === true) errors.push(`${unit.id} PR #${pr} is merged, expected ${expected.label}`)
260
+ if (expected?.state && live.state !== expected.state) errors.push(`${unit.id} PR #${pr} is ${live.state}, expected ${expected.state} (${expected.label})`)
261
+ if (expected?.terminal && !['CLOSED', 'MERGED'].includes(live.state)) errors.push(`${unit.id} PR #${pr} is ${live.state}, expected terminal CLOSED or MERGED`)
262
+ } catch (error) { errors.push(`${unit.id} PR #${pr} could not be verified live: ${error.message ?? error}`) }
263
+ }
264
+ }
265
+ for (const component of arr(input.components)) {
266
+ const pr = refNumber(component.pr)
267
+ if (pr == null) continue
268
+ try {
269
+ const observed = await boundary.readPr(pr, input.repository)
270
+ const live = normalizedGithubObservation('PR', pr, observed)
271
+ github.prs.push({ ...live, component: component.id, role: 'component', number: pr })
272
+ const hasDelivered = componentUnitIds(component).some((id) => terminalDisposition(byId.get(id), input) === 'delivered')
273
+ if (hasDelivered && (live.state !== 'MERGED' || live.merged !== true)) errors.push(`delivered component ${component.id} PR #${pr} is ${live.state}, expected MERGED`)
274
+ const expectedMergeSha = component.delivery?.mergedSha ?? component.mergedSha
275
+ if (hasDelivered && nonEmpty(expectedMergeSha) && live.mergeCommitSha !== expectedMergeSha) {
276
+ errors.push(`delivered component ${component.id} PR #${pr} merge SHA is ${live.mergeCommitSha ?? 'missing'}, expected ${expectedMergeSha}`)
277
+ }
278
+ if (!hasDelivered && live.merged === true) errors.push(`non-delivered component ${component.id} PR #${pr} is unexpectedly merged`)
279
+ } catch (error) { errors.push(`component ${component.id} PR #${pr} could not be verified live: ${error.message ?? error}`) }
280
+ }
281
+
282
+ let branchRestore = null
283
+ try { branchRestore = await boundary.restoreOriginalBranch(input.originalBranch) } catch (error) { errors.push(`original branch restoration failed: ${error.message ?? error}`) }
284
+ if (!isObject(branchRestore) || branchRestore.restored !== true || branchRestore.observed !== input.originalBranch) {
285
+ errors.push(`original branch was not restored to ${input.originalBranch ?? '(not recorded)'} (observed ${branchRestore?.observed ?? 'unknown'})`)
286
+ }
287
+ if (Array.isArray(branchRestore?.unpublished) && branchRestore.unpublished.length) {
288
+ errors.push(`original branch restoration refused with unpublished checkout work: ${branchRestore.unpublished.join(', ')}`)
289
+ }
290
+
291
+ let cleanup = null
292
+ if (errors.length === 0) {
293
+ try { cleanup = await boundary.cleanupWorkspaces(input) } catch (error) { errors.push(`workspace cleanup failed: ${error.message ?? error}`) }
294
+ errors.push(...workspaceErrors(cleanup))
295
+ }
296
+
297
+ const tally = terminalDispositionTally(implementations, input)
298
+ const finalization = {
299
+ status: 'finalized', finalizedAt: boundary.now(),
300
+ target, ancestry, github, branchRestore, cleanup,
301
+ delivery: tally,
302
+ scope: scopeRecord(units, input),
303
+ deferrals: structuredClone(Array.isArray(input.deferrals) ? input.deferrals : []),
304
+ autonomousBreakerDecisions: autonomousDecisions(units),
305
+ }
306
+ const resultManifest = structuredClone(input)
307
+ if (errors.length) return { ok: false, errors, manifest: resultManifest, target, ancestry, github, branchRestore, cleanup, handoff: null }
308
+ delete resultManifest.completionAudit
309
+ finalization.handoff = renderFinalHandoff(resultManifest, finalization)
310
+ resultManifest.finalization = finalization
311
+ const candidateErrors = finalizationErrors(resultManifest)
312
+ if (candidateErrors.length) {
313
+ return { ok: false, errors: candidateErrors, manifest: structuredClone(input), target, ancestry, github, branchRestore, cleanup, handoff: null }
314
+ }
315
+ return { ok: true, errors: [], manifest: resultManifest, target, ancestry, github, branchRestore, cleanup, handoff: finalization.handoff }
316
+ }
317
+
318
+ function expectedAncestryClaims(manifest) {
319
+ const units = arr(manifest?.units)
320
+ const implementations = units.filter((unit) => effectiveUnitKind(unit) === 'implementation')
321
+ const byId = new Map(units.map((unit) => [unit.id, unit]))
322
+ const claims = []
323
+ const deliveredComponents = arr(manifest?.components).filter((component) => componentUnitIds(component)
324
+ .some((id) => terminalDisposition(byId.get(id), manifest) === 'delivered'))
325
+ const canonicalMembers = new Set(deliveredComponents
326
+ .filter((component) => component.delivery?.outcome === 'merged')
327
+ .flatMap(componentUnitIds))
328
+ for (const unit of implementations) {
329
+ if (terminalDisposition(unit, manifest) === 'delivered' && !canonicalMembers.has(unit.id)) {
330
+ claims.push({ kind: 'unit', id: unit.id, sha: deliveryForUnit(unit, manifest)?.mergedSha })
331
+ }
332
+ }
333
+ for (const component of deliveredComponents) {
334
+ claims.push({ kind: 'component', id: component.id, sha: component.delivery?.mergedSha ?? component.mergedSha })
335
+ }
336
+ return claims
337
+ }
338
+
339
+ function ancestryRecordErrors(manifest, record) {
340
+ const expected = expectedAncestryClaims(manifest)
341
+ const actual = arr(record?.ancestry)
342
+ const normalized = (rows) => rows.map(({ kind, id, sha }) => ({ kind, id, sha }))
343
+ if (JSON.stringify(normalized(actual)) !== JSON.stringify(normalized(expected))) {
344
+ return ['finalization.ancestry is stale or does not match the delivered unit/component claim set']
345
+ }
346
+ if (actual.some((row) => row.contained !== true || row.targetRef !== record.target?.ref)) {
347
+ return ['finalization.ancestry is stale or does not prove every claim against finalization.target.ref']
348
+ }
349
+ return []
350
+ }
351
+
352
+ function githubRecordErrors(manifest, record) {
353
+ const errors = []
354
+ const units = arr(manifest?.units)
355
+ const byId = new Map(units.map((unit) => [unit.id, unit]))
356
+ const expectedIssues = units.map((unit) => ({ unit, number: refNumber(unit.issue ?? unit.id) }))
357
+ const issues = arr(record?.github?.issues)
358
+ const issueKeys = issues.map((row) => `${row.unit}:${row.number}`)
359
+ const expectedIssueKeys = expectedIssues.map(({ unit, number }) => `${unit.id}:${number}`)
360
+ if (expectedIssues.some(({ number }) => number == null)
361
+ || issues.some((row) => !Number.isInteger(row.number) || row.number <= 0)
362
+ || JSON.stringify(issueKeys) !== JSON.stringify(expectedIssueKeys)) {
363
+ errors.push('finalization GitHub issue observations are stale or incomplete')
364
+ } else {
365
+ for (let index = 0; index < expectedIssues.length; index++) {
366
+ const { unit } = expectedIssues[index]
367
+ const live = issues[index]
368
+ const disposition = terminalDisposition(unit, manifest)
369
+ const expectedState = expectedIssueState(unit, disposition)
370
+ if (expectedState && live.state !== expectedState) errors.push('finalization GitHub issue observations are stale or incomplete')
371
+ if (disposition === 'descoped' && unit.scopeDecision?.issueDisposition === 'closed-not-planned'
372
+ && live.stateReason !== undefined && live.stateReason !== null && live.stateReason !== 'NOT_PLANNED') {
373
+ errors.push('finalization GitHub issue observations are stale or incomplete')
374
+ }
375
+ }
376
+ }
377
+
378
+ const expectedPrs = []
379
+ for (const unit of units) {
380
+ const number = refNumber(unit.pr)
381
+ if (number != null) expectedPrs.push({ role: 'unit', unit, number })
382
+ }
383
+ for (const component of arr(manifest?.components)) {
384
+ const number = refNumber(component.pr)
385
+ if (number != null) expectedPrs.push({ role: 'component', component, number })
386
+ }
387
+ const prs = arr(record?.github?.prs)
388
+ const prKey = (row) => row.role === 'unit'
389
+ ? `unit:${row.unit}:${row.number}`
390
+ : `component:${row.component}:${row.number}`
391
+ const expectedPrKeys = expectedPrs.map((row) => row.role === 'unit'
392
+ ? `unit:${row.unit.id}:${row.number}`
393
+ : `component:${row.component.id}:${row.number}`)
394
+ if (prs.some((row) => !Number.isInteger(row.number) || row.number <= 0)
395
+ || JSON.stringify(prs.map(prKey)) !== JSON.stringify(expectedPrKeys)) {
396
+ errors.push('finalization GitHub PR observations are stale or incomplete')
397
+ } else {
398
+ for (let index = 0; index < expectedPrs.length; index++) {
399
+ const expected = expectedPrs[index]
400
+ const live = prs[index]
401
+ if (expected.role === 'unit') {
402
+ const terminal = expectedPrState(terminalDisposition(expected.unit, manifest), expected.unit.scopeDecision)
403
+ if (terminal?.merged === false && live.merged === true) errors.push('finalization GitHub PR observations are stale or incomplete')
404
+ if (terminal?.state && live.state !== terminal.state) errors.push('finalization GitHub PR observations are stale or incomplete')
405
+ if (terminal?.terminal && !['CLOSED', 'MERGED'].includes(live.state)) errors.push('finalization GitHub PR observations are stale or incomplete')
406
+ } else {
407
+ const delivered = componentUnitIds(expected.component).some((id) => terminalDisposition(byId.get(id), manifest) === 'delivered')
408
+ const expectedMergeSha = expected.component.delivery?.mergedSha ?? expected.component.mergedSha
409
+ if (delivered && (live.state !== 'MERGED' || live.merged !== true || live.mergeCommitSha !== expectedMergeSha)) {
410
+ errors.push('finalization GitHub PR observations are stale or incomplete')
411
+ }
412
+ if (!delivered && live.merged === true) errors.push('finalization GitHub PR observations are stale or incomplete')
413
+ }
414
+ }
415
+ }
416
+ return [...new Set(errors)]
417
+ }
418
+
419
+ export function finalizationErrors(manifest) {
420
+ const record = manifest?.finalization
421
+ if (record === undefined) return []
422
+ if (!isObject(record)) return ['finalization must be an object written by the dedicated finalize command']
423
+ const errors = []
424
+ if (record.status !== 'finalized') errors.push('finalization.status must be "finalized"')
425
+ if (!nonEmpty(record.finalizedAt)) errors.push('finalization.finalizedAt is required')
426
+ if (!nonEmpty(record.target?.ref) || !nonEmpty(record.target?.headSha)) errors.push('finalization.target requires the freshly fetched ref and headSha')
427
+ if (!Array.isArray(record.ancestry) || record.ancestry.some((row) => !isObject(row) || row.contained !== true || !nonEmpty(row.sha))) {
428
+ errors.push('finalization.ancestry must contain only proved merge-SHA ancestry rows')
429
+ }
430
+ if (!isObject(record.github) || !Array.isArray(record.github.issues) || !Array.isArray(record.github.prs)) errors.push('finalization.github requires live issue and PR observations')
431
+ errors.push(...ancestryRecordErrors(manifest, record))
432
+ errors.push(...githubRecordErrors(manifest, record))
433
+ if (!isObject(record.branchRestore) || record.branchRestore.restored !== true || record.branchRestore.observed !== manifest.originalBranch) {
434
+ errors.push('finalization.branchRestore must prove the recorded originalBranch was restored')
435
+ }
436
+ errors.push(...workspaceErrors(record.cleanup).map((error) => `finalization: ${error}`))
437
+ const units = arr(manifest?.units)
438
+ const implementations = units.filter((unit) => effectiveUnitKind(unit) === 'implementation')
439
+ const expectedDelivery = terminalDispositionTally(implementations, manifest)
440
+ if (JSON.stringify(record.delivery) !== JSON.stringify(expectedDelivery)) errors.push('finalization.delivery is stale or does not match current typed dispositions')
441
+ const expectedScope = scopeRecord(units, manifest)
442
+ if (JSON.stringify(normalizedScope(record.scope)) !== JSON.stringify(normalizedScope(expectedScope))) errors.push('finalization.scope is stale or does not match current non-implementation completion')
443
+ if (expectedScope.external.pending || expectedScope.humanOrPrerequisite.pending) errors.push('finalization cannot coexist with pending external/human/prerequisite units')
444
+ if (JSON.stringify(record.deferrals) !== JSON.stringify(Array.isArray(manifest?.deferrals) ? manifest.deferrals : [])) errors.push('finalization.deferrals is stale')
445
+ if (JSON.stringify(record.autonomousBreakerDecisions) !== JSON.stringify(autonomousDecisions(units))) errors.push('finalization autonomous breaker decisions are stale')
446
+ const expectedHandoff = renderFinalHandoff(manifest, record)
447
+ if (record.handoff !== expectedHandoff) errors.push('finalization.handoff was not rendered from the current validated state')
448
+ return errors
449
+ }
450
+
451
+ function runJson(command, args, cwd) {
452
+ return JSON.parse(execFileSync(command, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }))
453
+ }
454
+
455
+ export function createLiveFinalizeBoundary({ cwd = process.cwd(), cleanupWorkspaces, now = () => new Date().toISOString() } = {}) {
456
+ return {
457
+ now,
458
+ fetchTarget: async (branch) => {
459
+ if (!nonEmpty(branch)) throw new Error('targetBranch is not recorded')
460
+ execFileSync('git', ['fetch', 'origin', branch], { cwd, stdio: ['ignore', 'ignore', 'pipe'] })
461
+ const ref = `origin/${branch}`
462
+ const headSha = execFileSync('git', ['rev-parse', ref], { cwd, encoding: 'utf8' }).trim()
463
+ return { remote: 'origin', branch, ref, headSha, fetchedAt: now() }
464
+ },
465
+ isAncestor: async (sha, ref) => spawnSync('git', ['merge-base', '--is-ancestor', sha, ref], { cwd }).status === 0,
466
+ readIssue: async (id, repository) => {
467
+ const number = refNumber(id)
468
+ if (number == null || !nonEmpty(repository)) throw new Error('issue number and repository are required')
469
+ const view = runJson('gh', ['issue', 'view', String(number), '--repo', repository, '--json', 'number,state,stateReason,url'], cwd)
470
+ return { id, number: view.number, state: view.state, stateReason: view.stateReason ?? null, url: view.url }
471
+ },
472
+ readPr: async (id, repository) => {
473
+ if (!Number.isInteger(id) || !nonEmpty(repository)) throw new Error('PR number and repository are required')
474
+ const view = runJson('gh', ['pr', 'view', String(id), '--repo', repository, '--json', 'number,state,mergedAt,mergeCommit,url,headRefOid'], cwd)
475
+ return { id, number: view.number, state: view.state, merged: view.state === 'MERGED' || nonEmpty(view.mergedAt), mergedAt: view.mergedAt ?? null, mergeCommitSha: view.mergeCommit?.oid ?? null, headSha: view.headRefOid ?? null, url: view.url }
476
+ },
477
+ restoreOriginalBranch: async (expected) => {
478
+ const before = execFileSync('git', ['branch', '--show-current'], { cwd, encoding: 'utf8' }).trim() || null
479
+ if (expected == null) return { expected: null, before, observed: null, restored: true, unpublished: [], reason: 'detached/disposable checkout recorded at pre-flight' }
480
+ const status = execFileSync('git', ['status', '--porcelain'], { cwd, encoding: 'utf8' }).split('\n').filter(Boolean)
481
+ if (status.length) return { expected, before, observed: before, restored: before === expected, unpublished: status }
482
+ if (before !== expected) execFileSync('git', ['switch', expected], { cwd, stdio: ['ignore', 'ignore', 'pipe'] })
483
+ const observed = execFileSync('git', ['branch', '--show-current'], { cwd, encoding: 'utf8' }).trim() || null
484
+ return { expected, before, observed, restored: observed === expected, unpublished: [] }
485
+ },
486
+ cleanupWorkspaces: cleanupWorkspaces ?? (async () => { throw new Error('no workspace cleanup boundary configured') }),
487
+ }
488
+ }