@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,494 @@
1
+ // The run's two standing reports: the PLAN (post-intake, before the first producer
2
+ // spawn) and PROGRESS (after each unit reaches a terminal state).
3
+ //
4
+ // Why these are rendered from the manifest rather than written in prose. The skill
5
+ // already mandates every fact in them — the decomposition gate's deferrals, the
6
+ // dependency-sorted roster, the component grouping, the risk flags, the units blocked on
7
+ // a design input. What it did not have was a moment where they are all said out loud at
8
+ // once, so they were reported when the run was short and attentive and quietly skipped
9
+ // when it was long — which is exactly when the human has lost track. A renderer reports
10
+ // the same fields every time, and reports them from the state the gates actually wrote,
11
+ // so a plan cannot claim a unit is scheduled that the manifest never recorded.
12
+ //
13
+ // The honesty rule this file exists to keep: **a report never invents what the manifest
14
+ // does not hold.** Where a field is missing it says so (`— not recorded`) rather than
15
+ // omitting the line, because a silently-short plan reads as a complete one. That is the
16
+ // epic-848 shape at the reporting layer: the requirement nobody owned was invisible
17
+ // precisely because nothing ever listed what was unowned.
18
+
19
+ import { gateAudit } from './fix-rounds.mjs'
20
+ import { componentRoundProfile } from './component-candidate.mjs'
21
+ import { deliveryForUnit, terminalDisposition, terminalDispositionTally } from './terminal-dispositions.mjs'
22
+ import {
23
+ blockingEdges, deriveComponents, dependencyOrder, isDoneUnit, isResolvedUnit, isUndeliveredUnit, RESOLVED,
24
+ } from './interference.mjs'
25
+ import { effectiveUnitKind, unitKindComplete } from './unit-lifecycle.mjs'
26
+
27
+ // The interference graph's primitives moved to `interference.mjs`, where the scheduler
28
+ // reads them too. Re-exported here — unchanged, one definition — so every existing
29
+ // importer (`run-state.mjs`, this skill's tests) keeps its import path.
30
+ export { dependencyOrder, isDoneUnit, isResolvedUnit, isUndeliveredUnit, RESOLVED }
31
+
32
+ const isObject = (v) => v != null && typeof v === 'object' && !Array.isArray(v)
33
+ // Every list read from the manifest is filtered to real objects, and every sha is
34
+ // stringified before slicing. These reports are the tool you reach for when a run has gone
35
+ // wrong — which is exactly when the manifest may be hand-edited or half-written — so a
36
+ // renderer that throws on a malformed field fails at the only moment it is needed. The CLI
37
+ // write paths refuse these shapes, but nothing stops a human from opening the JSON.
38
+ const nonEmpty = (v) => typeof v === 'string' && v.trim().length > 0
39
+ const arr = (v) => (Array.isArray(v) ? v : [])
40
+ const objs = (v) => arr(v).filter(isObject)
41
+ const sha7 = (v) => (nonEmpty(v) ? v.slice(0, 7) : String(v ?? ''))
42
+
43
+ // ---- what still owes the human an answer before the loop can start ----
44
+
45
+ // Collected rather than counted: the plan's job is to name each one, since "2 blocked"
46
+ // tells the human nothing they can act on.
47
+ export function openAsks(manifest) {
48
+ const asks = []
49
+ for (const u of objs(manifest.units)) {
50
+ if (terminalDisposition(u) === 'blocked') {
51
+ asks.push({ unit: u.id, ask: nonEmpty(u.blocker) ? u.blocker : 'blocked — no reason recorded (record it in units[].blocker)' })
52
+ }
53
+ const b = isObject(u.breaker) ? u.breaker : null
54
+ // A decided-but-not-re-entered design/split/descope blocks every transition until
55
+ // intake re-entry, so it is an open ask even though the decision was made.
56
+ if (b && b.decision && b.decision !== 'continue' && !b.reenteredAt) {
57
+ asks.push({ unit: u.id, ask: `circuit-breaker decided "${b.decision}" — blocked until the unit re-enters intake (record-intake-reentry)` })
58
+ }
59
+ }
60
+ for (const d of objs(manifest.decisions)) {
61
+ if (d?.status === 'pending-human') asks.push({ unit: '—', ask: `open decision: ${d.question}` })
62
+ }
63
+ return asks
64
+ }
65
+
66
+ // ---- shared framing ----
67
+
68
+ function header(manifest) {
69
+ const m = manifest
70
+ const models = isObject(m.models) ? m.models : {}
71
+ const eff = (slot) => (nonEmpty(models[`${slot}Effort`]) ? ` @ ${models[`${slot}Effort`]}` : ' @ high')
72
+ const subject = nonEmpty(m.epic) ? `epic ${m.epic}` : `run ${m.slug ?? ''}`.trim()
73
+ const lines = [
74
+ `${subject} → ${m.targetBranch ?? '(no target branch recorded)'}`,
75
+ ` delivery: ${m.deliveryMode ?? 'direct (legacy default — probe it at pre-flight)'}`
76
+ + ` merge-shippable: ${m.mergeShippable ? 'ON' : 'off (hand back merge-ready)'}`
77
+ + ` breaker: ${m.breakerAutonomy ?? 'auto'}`,
78
+ // The pre-flight autonomy level is what the human actually answered; merge-shippable
79
+ // above is one of the knobs it sets. Rendering only the knob left the human unable to
80
+ // see, in the one report they read before any code is built, how much of the loop's
81
+ // stop-and-ask surface they had pre-authorized.
82
+ ` autonomy: ${m.autonomy ?? 'supervised (not set — every park stops and asks)'}`
83
+ // The trigger belongs beside merge-shippable, not buried in the manifest: on an
84
+ // auto-merge repo the two together decide whether a routine review merges the PR,
85
+ // and that is a fact the human should see in the plan rather than discover.
86
+ + ` enqueue: ${m.enqueueTrigger ?? 'trigger not probed'}${m.enqueueTrigger && m.enqueueTrigger !== 'manual' && !m.mergeShippable ? ' ⚠ auto-merge + merge-shippable off — reviews post as comments' : ''}`
87
+ + ` workspace: ${m.workspaceMode ?? 'shared'}`,
88
+ ` implementer: ${models.implementation ?? '— not recorded'}${models.implementation ? eff('implementation') : ''}`
89
+ + ` reviewer: ${models.review ?? '— not recorded'}${models.review ? eff('review') : ''}`,
90
+ ]
91
+ if (models.implementation && models.implementation === models.review) {
92
+ lines.push(' ** reviewer === implementer — the review is NOT independent (guarantee 2) **')
93
+ }
94
+ return lines
95
+ }
96
+
97
+ // Group units by component. When the manifest records components those win — they carry
98
+ // the delivery state (`pr`, `verdict`, `mergedSha`) nothing can re-derive. When it records
99
+ // none, the grouping is DERIVED from interference rather than flattened into one bag,
100
+ // because `component` is interference's delivery view and a report that shows one blob is
101
+ // a report that cannot say which units must merge together.
102
+ //
103
+ // The derivation is where the two blocking sources part company, and getting it wrong is
104
+ // the bug ADR 0001's amendment names: a SYMBOL edge co-delivers (the dependent's diff
105
+ // references symbols only the other unit has), a PREMISE edge only ORDERS. Treating every
106
+ // `dependsOn` edge as co-delivery would have bundled #553 with #579 — two units that share
107
+ // no symbol and no surface.
108
+ //
109
+ // A unit in no component is still listed — an omitted unit is the failure this whole
110
+ // report exists to prevent.
111
+ function groups(manifest, ordered) {
112
+ const components = objs(manifest.components)
113
+ if (!components.length) {
114
+ return deriveComponents(ordered).map((c) => ({ id: c.id, units: c.units, derived: true, coDeliveryReasons: c.coDeliveryReasons }))
115
+ }
116
+ const claimed = new Set()
117
+ const out = components.map((c) => {
118
+ const ids = new Set(arr(c.units))
119
+ const units = ordered.filter((u) => ids.has(u.id))
120
+ units.forEach((u) => claimed.add(u.id))
121
+ return { id: c.id, pr: c.pr, verdict: c.verdict, mergedSha: c.delivery?.mergedSha ?? c.mergedSha, delivery: c.delivery, candidate: c.candidate, authorizationBoundary: c.authorizationBoundary, units }
122
+ })
123
+ const orphans = ordered.filter((u) => !claimed.has(u.id))
124
+ if (orphans.length) out.push({ id: '(no component)', units: orphans })
125
+ return out
126
+ }
127
+
128
+ // The roster reads as a task list, because that is the question a human actually brings
129
+ // to it — "what is done, what is left" — and a checkbox answers it before any of the tags
130
+ // are read. Deliberately only the two GitHub-renderable markers: these reports get pasted
131
+ // into PR bodies and handoffs, and `- [!]` for blocked would render as literal text there.
132
+ // Blocked stays visible where it already was, in the status word and the tally line, which
133
+ // counts it BESIDE the resolved figure rather than inside it.
134
+ //
135
+ // `isDoneUnit` is the same rule PROGRESS's tally uses — one reading of "done" across the
136
+ // reporting surfaces, so a checkbox can never disagree with the count above it. It is
137
+ // deliberately NOT `isResolvedUnit`: that one answers the scheduler's question and says yes
138
+ // to a `merge-ready` unit that never delivered, which is how every box came up ticked on
139
+ // epic-986's four undelivered units.
140
+ const checkbox = (u) => (['delivered', 'handed-back', 'already-done'].includes(terminalDisposition(u)) ? '- [x] ' : '- [ ] ')
141
+
142
+ const riskTag = (u) => (u.highRisk ? 'HIGH-RISK' : 'routine')
143
+
144
+ // The scope class (#515), rendered BESIDE the risk tag rather than folded into it —
145
+ // they are two axes and the whole point is that they are independent: `highRisk`
146
+ // decides how deep the review goes, `scopeClass` decides which coverage/evidence
147
+ // artifacts apply. A `no-surface` unit is routinely high-risk (`.mergify.yml`, CI
148
+ // workflows, IAM bindings), and a reader who sees one tag must not infer the other.
149
+ //
150
+ // An unclassified unit prints `scope:—` rather than nothing, per this file's honesty
151
+ // rule: "not classified yet" and "classified surface-bearing" are different states,
152
+ // and only the first is still owed work. Silence would make them look alike.
153
+ const scopeTag = (u) => ` · scope:${nonEmpty(u.scopeClass) ? u.scopeClass : '—'}`
154
+ const kindTag = (u) => ` · kind:${effectiveUnitKind(u)}`
155
+ const tags = (u) => `[${riskTag(u)}${scopeTag(u)}${kindTag(u)}]`
156
+
157
+ // Both blocking sources are rendered, and they are rendered DIFFERENTLY, because they tell
158
+ // the reader different things about the same roster. A symbol edge says "this ships with
159
+ // that"; a premise edge says "this ships after that" — and a premise edge is the one that
160
+ // exists nowhere else, since it can only be declared, never derived from a diff. Printing
161
+ // them alike is what made the distinction invisible in the first place.
162
+ function stacksOn(u) {
163
+ const edges = blockingEdges(u)
164
+ if (!edges.length) return ''
165
+ const symbol = edges.filter((e) => e.source === 'symbol').map((e) => e.unit)
166
+ const premise = edges.filter((e) => e.source === 'premise').map((e) => e.unit)
167
+ const parts = []
168
+ if (symbol.length) parts.push(`← stacks on ${symbol.join(', ')}`)
169
+ if (premise.length) parts.push(`← after ${premise.join(', ')} (premise)`)
170
+ return ` ${parts.join(' ')}`
171
+ }
172
+
173
+ // ---- the PLAN: what the loop is about to do ----
174
+
175
+ export function renderPlan(manifest) {
176
+ const units = objs(manifest.units)
177
+ const { order, cycles } = dependencyOrder(units)
178
+ const ordered = [...order, ...units.filter((u) => cycles.includes(u.id))]
179
+ const out = ['PLAN', ...header(manifest), '']
180
+
181
+ if (!units.length) {
182
+ out.push(' no units — intake has not normalized the input into a roster yet')
183
+ return out.join('\n')
184
+ }
185
+
186
+ const comps = groups(manifest, ordered)
187
+ const plural = (n, s) => `${n} ${s}${n === 1 ? '' : 's'}`
188
+ out.push(` ${plural(units.length, 'unit')} in ${plural(comps.length, 'component')}, dependency-sorted:`)
189
+ for (const c of comps) {
190
+ // A derived component says WHY it co-delivers, because that is the fact a reader has
191
+ // no other way to check: `component:#879 (ships together — symbol)` is falsifiable
192
+ // against the roster, while an unexplained grouping is something to take on trust.
193
+ const why = arr(c.coDeliveryReasons).length ? ` — ${arr(c.coDeliveryReasons).join(' + ')}` : ''
194
+ out.push(c.id ? ` ${c.id}${c.units.length > 1 ? ` (ships together${why})` : ''}` : ' (single component)')
195
+ for (const u of c.units) {
196
+ const contract = isObject(u.contractRevision) && nonEmpty(u.contractRevision.sha)
197
+ ? `contract ${sha7(u.contractRevision.sha)}`
198
+ : 'no contract pointer'
199
+ out.push(` ${checkbox(u)}${u.id} ${u.status ?? 'queued'} ${tags(u)} ${contract}${stacksOn(u)}`)
200
+ }
201
+ }
202
+
203
+ // The decomposition gate's output. Rendered even when empty, because "nothing was
204
+ // deferred" and "nobody ran the gate" look identical if the section is omitted — and
205
+ // telling those apart is the whole point of epic-848.
206
+ out.push('')
207
+ const deferrals = arr(manifest.deferrals)
208
+ if (deferrals.length) {
209
+ out.push(' deferred — tracked, NOT built by this run:')
210
+ for (const d of deferrals) out.push(` ${d.requirement} → ${d.trackedIn ?? '** no tracking issue — this requirement is owned by nobody **'}`)
211
+ } else if (nonEmpty(manifest.epic)) {
212
+ out.push(' deferred: none recorded — if the decomposition gate found unowned parent requirements, record them (deferrals[]) before spawning')
213
+ }
214
+
215
+ if (cycles.length) {
216
+ out.push('', ` ** dependency cycle among ${cycles.join(', ')} — these cannot be scheduled until it is broken **`)
217
+ }
218
+
219
+ // Outside the open-asks branch: the graph is a property of the roster, not of whether
220
+ // anything happens to be blocked. Nesting it there rendered it only on runs that already
221
+ // had a problem — the opposite of a plan's job, which is to show the shape before one.
222
+ out.push(...graphSection(manifest))
223
+
224
+ const asks = openAsks(manifest)
225
+ if (asks.length) {
226
+ out.push('', ` ${plural(asks.length, 'item')} need${asks.length === 1 ? 's' : ''} you before these units can move:`)
227
+ for (const a of asks) out.push(` ${a.unit} ${a.ask}`)
228
+ }
229
+ return out.join('\n')
230
+ }
231
+
232
+ // ---- PROGRESS: what has actually happened ----
233
+
234
+ // Two different questions the word "terminal" was doing double duty for, and conflating
235
+ // them let a blocked unit read as progress:
236
+ // - WHEN to report — a unit stopped moving, blocked included. That is the cadence.
237
+ // - What counts as RESOLVED — the unit is done. A blocked unit is stopped, not done,
238
+ // and folding it into the tally would inflate the number with the units that most
239
+ // need attention.
240
+ // So `blocked` triggers a report but is counted separately, on the same line, where it
241
+ // stays visible instead of either padding the numerator or vanishing from the summary.
242
+ // `RESOLVED` and `isResolvedUnit` are the ONE reading of "done", and they now live in
243
+ // `interference.mjs` (re-exported at the top of this file) because the scheduler asks the
244
+ // same question this render does. Four readers share it — PROGRESS's tally below,
245
+ // `run-state.mjs list`'s per-run tally, `resume`'s next-action derivation, and the
246
+ // runnable set — and a textually-copied rule is a rule that drifts one reader at a time,
247
+ // with the drifted copy being whichever one a recovering session happens to trust.
248
+
249
+ export function renderProgress(manifest, options = {}) {
250
+ const units = objs(manifest.units)
251
+ const { order, cycles } = dependencyOrder(units)
252
+ const ordered = [...order, ...units.filter((u) => cycles.includes(u.id))]
253
+ const out = ['PROGRESS', ...header(manifest), '']
254
+
255
+ if (!units.length) return [...out, ' no units'].join('\n')
256
+
257
+ const tally = terminalDispositionTally(ordered, manifest)
258
+ const undelivered = ordered.filter(isUndeliveredUnit)
259
+ // Undelivered sits beside the tally for the same reason blocked does: it is a unit that
260
+ // STOPPED, not one that finished. Naming it on the headline is the point — the per-unit
261
+ // UNDELIVERED flag was already there on epic-986 and the `4/4 units resolved` above it
262
+ // is what got read.
263
+ const aside = [
264
+ undelivered.length ? `${undelivered.length} undelivered` : (tally.unresolved ? `${tally.unresolved} unresolved` : null),
265
+ ].filter(Boolean)
266
+ const dispositionSummary = [
267
+ `${tally.delivered} delivered`,
268
+ tally['handed-back'] ? `${tally['handed-back']} handed back` : null,
269
+ tally['already-done'] ? `${tally['already-done']} already done` : null,
270
+ tally.descoped ? `${tally.descoped} human-descoped` : null,
271
+ tally.blocked ? `${tally.blocked} blocked` : null,
272
+ ].filter(Boolean).join(' · ')
273
+ const resolved = tally.delivered + tally['handed-back'] + tally['already-done']
274
+ out.push(` ${dispositionSummary}` + (aside.length ? ` ${aside.join(', ')}, waiting on you` : ''))
275
+ out.push(` ${resolved}/${units.length} units resolved (descopes excluded)`)
276
+ const implementations = ordered.filter((u) => effectiveUnitKind(u) === 'implementation')
277
+ const deliveredImplementations = implementations.filter((u) => terminalDisposition(u) === 'delivered')
278
+ const external = ordered.filter((u) => effectiveUnitKind(u) === 'external-verification')
279
+ const externalComplete = external.filter(unitKindComplete)
280
+ if (implementations.length) out.push(` code delivery: ${deliveredImplementations.length}/${implementations.length} implementation units delivered`)
281
+ if (external.length) out.push(` external verification: ${externalComplete.length}/${external.length} complete, ${external.length - externalComplete.length} pending`)
282
+ out.push('')
283
+
284
+ for (const c of groups(manifest, ordered)) {
285
+ // A DERIVED single-unit component is not a fact about the run — it is this renderer
286
+ // restating the unit it is about to print, one line up, plus an integration verdict that
287
+ // will never exist because there is nothing to integrate. On a single-unit run that was
288
+ // the majority of the output. Declared components always print (the human named them,
289
+ // and their verdict/mergedSha are real), as does any derived group that actually
290
+ // combines units, which is where an integration verdict means something.
291
+ const worthPrinting = c.id && (!c.derived || c.units.length > 1)
292
+ if (worthPrinting) {
293
+ const v = c.verdict ? ` integration: ${c.verdict}` : ' integration: not yet run'
294
+ const candidate = isObject(c.candidate) ? c.candidate : null
295
+ const profile = candidate ? componentRoundProfile(c) : null
296
+ const candidateState = candidate
297
+ ? ` candidate:${candidate.state}@g${candidate.generation} ${sha7(candidate.frozen?.headSha ?? candidate.updates?.at(-1)?.headSha)}`
298
+ : ''
299
+ const rounds = profile
300
+ ? ` component rounds discovery:${profile.unitDiscovery} fix:${profile.integrationFix} terminal:${profile.terminalAuthorization}`
301
+ : ''
302
+ out.push(` ${c.id}${v}${candidateState}${rounds}${c.mergedSha ? ` merged ${sha7(c.mergedSha)}` : ''}`)
303
+ }
304
+ for (const u of c.units) {
305
+ const rounds = arr(u.rounds).length || u.reviewRounds || 0
306
+ const verdict = u.lastVerdict ?? '—'
307
+ // Delivery is the part most likely to be silently in-flight: epic-986 reported four
308
+ // units merge-ready with mergedSha null on every one. Say it plainly.
309
+ let delivery = ''
310
+ const unitKind = effectiveUnitKind(u)
311
+ if (unitKind === 'external-verification') {
312
+ delivery = unitKindComplete(u)
313
+ ? ` EXTERNAL VERIFICATION COMPLETE via ${u.externalProtocol?.completionSource ?? '(no source)'}`
314
+ : ' ** PENDING EXTERNAL VERIFICATION — artifacts do not satisfy this criterion **'
315
+ } else if (unitKind === 'human-decision') {
316
+ delivery = unitKindComplete(u) ? ' HUMAN DECISION RECORDED' : ' ** PENDING HUMAN DECISION **'
317
+ } else if (unitKind === 'prerequisite') {
318
+ delivery = unitKindComplete(u) ? ' PREREQUISITE COMPLETE' : ' ** PENDING PREREQUISITE **'
319
+ } else {
320
+ const disposition = terminalDisposition(u, manifest)
321
+ const evidence = deliveryForUnit(u, manifest)
322
+ if (disposition === 'delivered') delivery = ` DELIVERED ${evidence?.mergedSha ? sha7(evidence.mergedSha) : '(no sha!)'}`
323
+ else if (disposition === 'handed-back') delivery = ` handed back: ${evidence?.blockedOn ?? '(no reason recorded)'}`
324
+ else if (disposition === 'already-done') delivery = ' ALREADY DONE (prior art)'
325
+ else if (disposition === 'descoped') delivery = ` HUMAN-DESCOPED: ${u.scopeDecision?.reason ?? '(no reason recorded)'}`
326
+ else if (disposition === 'blocked') delivery = ` BLOCKED: ${u.blocker ?? '(no reason recorded)'}`
327
+ else if (u.status === 'merge-ready') delivery = ' ** UNDELIVERED — merge-ready with no terminal outcome **'
328
+ }
329
+ const breaker = isObject(u.breaker)
330
+ ? ` breaker:${u.breaker.decision}${u.breaker.autoApplied ? '(auto)' : ''}`
331
+ : ''
332
+ out.push(` ${checkbox(u)}${u.id} ${u.status ?? 'queued'} ${tags(u)} ${rounds} round${rounds === 1 ? '' : 's'}, last ${verdict}${breaker}${delivery}`)
333
+ }
334
+ }
335
+
336
+ // This run's gate-value snapshot. `gate-audit` adds the durable cross-run window used for
337
+ // retirement; progress stays run-local so reading status does not create observations.
338
+ // Printed even when empty: "no gate results recorded" is the finding, and omitting the
339
+ // section would hide exactly what the removal path asks for.
340
+ const gates = options.gateValue ?? gateAudit(manifest)
341
+ const seen = gates.filter((g) => !g.unrecorded)
342
+ out.push(...graphSection(manifest))
343
+ out.push('', ' gates:')
344
+ if (!seen.length) {
345
+ out.push(' none recorded — a gate that passed and a gate that never ran are indistinguishable in this run')
346
+ } else {
347
+ for (const g of seen) {
348
+ const bits = [`ran ${g.ran}`]
349
+ if (g.states?.ranClean) bits.push(`clean ${g.states.ranClean}`)
350
+ if (g.skipped) bits.push(`skipped ${g.skipped}`)
351
+ if (g.states?.notRun) bits.push(`not run ${g.states.notRun}`)
352
+ if (g.states?.unreadable) bits.push(`unreadable ${g.states.unreadable}`)
353
+ if (g.findings) bits.push(`${g.findings} raw finding${g.findings === 1 ? '' : 's'}`)
354
+ if (g.uniqueFindings) bits.push(`${g.uniqueFindings} unique`)
355
+ if (g.blockingFindings) bits.push(`${g.blockingFindings} blocking`)
356
+ if (g.repeatedKnownWarnings) bits.push(`${g.repeatedKnownWarnings} repeated`)
357
+ if (g.fixesAttributed) bits.push(`${g.fixesAttributed} fixed`)
358
+ if (g.noiseFindings) bits.push(`${g.noiseFindings} noise`)
359
+ if (g.failed) bits.push(`${g.failed} rejection${g.failed === 1 ? '' : 's'}`)
360
+ out.push(` ${g.gate.padEnd(19)} ${bits.join(', ')}`
361
+ + (g.recommendations?.retirement ? ' ** durable zero-yield window — retirement review **' : '')
362
+ + (g.recommendations?.deduplication ? ' ** deduplicate repeated findings **' : '')
363
+ + (g.recommendations?.narrowing ? ' ** consider narrowing **' : ''))
364
+ }
365
+ const silent = gates.filter((g) => g.unrecorded).map((g) => g.gate)
366
+ if (silent.length) out.push(` not recorded at all: ${silent.join(', ')}`)
367
+ }
368
+
369
+ const asks = openAsks(manifest)
370
+ if (asks.length) {
371
+ out.push('', ` waiting on you:`)
372
+ for (const a of asks) out.push(` ${a.unit} ${a.ask}`)
373
+ }
374
+ return out.join('\n')
375
+ }
376
+
377
+ // ---- the dependency graph ----
378
+ //
379
+ // The roster already renders dependency-SORTED with per-unit `← stacks on` annotations, and
380
+ // that is enough to answer "what does this one unit wait for". It is not enough to answer
381
+ // the questions a human actually opens a checkpoint report to ask on an epic: what can move
382
+ // right now, what is the critical chain, and which single unit is holding up the most work.
383
+ // Those are properties of the whole graph, and a sorted list flattens them away — a unit at
384
+ // the bottom of the list looks the same whether it waits on one finished thing or on a chain
385
+ // of four that have not started.
386
+ //
387
+ // How many units transitively wait on this one — the "unblocks N" figure. A unit blocking a
388
+ // long chain is where attention pays off, and that ranking is invisible in a sorted list.
389
+ export function blockedDownstream(units, id) {
390
+ const list = objs(units)
391
+ const seen = new Set()
392
+ let frontier = [id]
393
+ while (frontier.length) {
394
+ const next = []
395
+ for (const u of list) {
396
+ if (seen.has(u.id) || u.id === id) continue
397
+ if (blockingEdges(u).some((e) => frontier.includes(e.unit))) { seen.add(u.id); next.push(u.id) }
398
+ }
399
+ frontier = next
400
+ }
401
+ return seen.size
402
+ }
403
+
404
+ const count = (n, s) => `${n} ${s}${n === 1 ? '' : 's'}`
405
+
406
+ // Plain glyphs, deliberately NOT `- [x]`/`- [ ]`. The roster's checkboxes are GitHub task-list
407
+ // syntax (see the checkbox comment above); reusing that syntax here would make every graph row
408
+ // render as a separate, tickable task in a PR body. These are status marks inside a picture.
409
+ const GLYPH = (u) => (isDoneUnit(u) ? '✓' : isUndeliveredUnit(u) || ['blocked', 'descoped'].includes(terminalDisposition(u)) ? '!' : '·')
410
+
411
+ // Appended to PLAN and PROGRESS, and only when the roster actually has edges. A run with no
412
+ // dependencies gains nothing from a graph header saying so — the same noise rule that removed
413
+ // the derived single-unit component lines. `graphSection` returns [] there, so the caller can
414
+ // splat it unconditionally and the report simply does not grow a section it cannot fill.
415
+ export function graphSection(manifest) {
416
+ const g = renderGraph(manifest)
417
+ return g ? ['', g] : []
418
+ }
419
+
420
+ export function renderGraph(manifest) {
421
+ const units = dependencyOrder(objs(manifest.units)).order
422
+ const all = objs(manifest.units)
423
+ const ordered = [...units, ...all.filter((u) => !units.includes(u))]
424
+ if (!ordered.some((u) => blockingEdges(u).length)) return ''
425
+ return textGraph(ordered)
426
+ }
427
+
428
+ function textGraph(ordered) {
429
+ const byId = new Map(ordered.map((u) => [u.id, u]))
430
+ const kids = new Map(ordered.map((u) => [u.id, []]))
431
+ for (const u of ordered) {
432
+ for (const e of blockingEdges(u)) {
433
+ if (kids.has(e.unit)) kids.get(e.unit).push({ id: u.id, source: e.source })
434
+ }
435
+ }
436
+ const roots = ordered.filter((u) => !blockingEdges(u).some((e) => byId.has(e.unit)))
437
+
438
+ // A DAG drawn as a tree has to do something about a node with two parents. Dropping the
439
+ // second edge is the thing that hides why a unit is stuck, so instead the node appears under
440
+ // EVERY parent and each appearance after the first is marked as a cross-link and not
441
+ // expanded again. That keeps the picture a tree to read while staying a DAG in fact — and
442
+ // the `seen` set is also what makes a cycle terminate rather than recurse forever.
443
+ const seen = new Set()
444
+ const out = [' dependency graph ├── ships WITH (symbol) ├┈┈ ships AFTER (premise)', '']
445
+
446
+ const label = (u) => {
447
+ const held = blockedDownstream(ordered, u.id)
448
+ const holds = held && !isDoneUnit(u) ? ` holds ${count(held, 'unit')}` : ''
449
+ // A DANGLING edge — `dependsOn` naming a unit no longer (or never) on the roster — has to
450
+ // be drawn, not dropped. It cannot be drawn as a connector because there is no node to
451
+ // connect to, so without this the unit renders as a root with no blockers: visually
452
+ // identical to a genuinely unblocked unit, while `runnableState` refuses to admit it and
453
+ // reports it waiting. Two answers to "can this move now" is the disagreement this codebase
454
+ // keeps paying for, and here the chart was the one that read as safe. The scheduler's rule
455
+ // is the right one and this now matches it: a dangling edge is visible and fixable, where
456
+ // treating it as satisfied would silently base the dependent on the wrong tree.
457
+ const dangling = blockingEdges(u).filter((e) => !byId.has(e.unit)).map((e) => e.unit)
458
+ const missing = dangling.length ? ` ** waits on ${dangling.join(', ')} — not in the roster **` : ''
459
+ return `${GLYPH(u)} ${u.id.padEnd(7)} ${(u.status ?? 'queued').padEnd(12)}${holds}${missing}`
460
+ }
461
+
462
+ const walk = (unit, prefix) => {
463
+ const children = kids.get(unit.id) ?? []
464
+ children.forEach((c, i) => {
465
+ const last = i === children.length - 1
466
+ const elbow = last ? '└' : '├'
467
+ const line = c.source === 'premise' ? '┈┈' : '──'
468
+ const child = byId.get(c.id)
469
+ if (seen.has(c.id)) {
470
+ const parents = blockingEdges(child).map((e) => e.unit).filter((x) => x !== unit.id)
471
+ out.push(`${prefix}${elbow}${line} ${GLYPH(child)} ${child.id} ↑ shown above — also waits on ${parents.join(', ')}`)
472
+ return
473
+ }
474
+ seen.add(c.id)
475
+ out.push(`${prefix}${elbow}${line} ${label(child)}`)
476
+ walk(child, `${prefix}${last ? ' ' : '│ '}`)
477
+ })
478
+ }
479
+
480
+ for (const r of roots) {
481
+ seen.add(r.id)
482
+ out.push(` ${label(r)}`)
483
+ walk(r, ' ')
484
+ }
485
+ // Anything a cycle left unreachable from a root still prints — an omitted unit is the
486
+ // failure this whole report exists to prevent.
487
+ for (const u of ordered) {
488
+ if (!seen.has(u.id)) out.push(` ${label(u)} ** unreachable — dependency cycle **`)
489
+ }
490
+ // Trailing spaces come from the column padding and would show up as diff noise the moment
491
+ // this report is pasted into a PR body.
492
+ return out.map((l) => l.replace(/\s+$/, '')).join('\n')
493
+ }
494
+