@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,256 @@
1
+ // detect-target-branch — the MECHANIZED pre-flight step 3. It fetches, reads the
2
+ // remote's real long-lived heads, and recommends the branch that holds the current
3
+ // development head (or reports a conflict for the human to resolve). Pure git; no
4
+ // network beyond the initial fetch.
5
+ //
6
+ // Why this exists as a script and not prose: pre-flight step 3 is a load-bearing
7
+ // decision every later spawn rests on (implementers fork from it, the epic
8
+ // integration gate forks its integration branch off it). Described as prose the
9
+ // agent runs by hand, the GitFlow-vs-trunk content check degrades to a
10
+ // commit-count guess — the exact mistake ("both sides are ahead, so it's a
11
+ // conflict") the `git cherry` content check exists to avoid. Mechanized, the rule
12
+ // runs the same way every time and shows its evidence.
13
+ //
14
+ // node detect-target-branch.mjs # fetch, detect, recommend (JSON on stdout)
15
+ // node detect-target-branch.mjs --no-fetch # skip the fetch (tests / already-fresh)
16
+ // node detect-target-branch.mjs --help # usage + exit 0
17
+ //
18
+ // OUTPUT (stdout, always JSON):
19
+ // { recommended: <branch>|null, reason, candidates: [{name, ahead, behind, lastCommitDate}], conflict: bool }
20
+ // The human still confirms in the pre-flight gate — this recommends and shows the
21
+ // evidence, it does not decide silently.
22
+ //
23
+ // EXIT CODES:
24
+ // 0 a recommendation was produced (recommended set, conflict false)
25
+ // 1 genuine conflict / needs a human choice (recommended null, conflict true)
26
+ // 2 usage error, or no long-lived branches found to compare
27
+ //
28
+ // The decision follows pre-flight.md step 3 exactly:
29
+ // - GitFlow → dev (it contains main's tip and holds the development head)
30
+ // - trunk → main (no long-lived dev branch)
31
+ // - nominal divergence (main holds promotion-merge commits dev lacks) is NOT a
32
+ // conflict: check CONTENT, not commit counts, with `git cherry` — if main has
33
+ // no non-merge commit dev lacks, dev still holds the development head.
34
+ // - genuine conflict (unique non-merge commits on BOTH sides, or dev behind main,
35
+ // or two plausible long-lived branches of the same family) → never pick; emit
36
+ // the candidates + evidence for the human to choose.
37
+
38
+ import { execFileSync } from 'node:child_process'
39
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
40
+
41
+ // The long-lived branch names we look for on the remote, in family-precedence order:
42
+ // dev-family (the development line) and main-family (production). We compare the
43
+ // real heads that exist, never convention or the local checkout.
44
+ const DEV_FAMILY = ['dev', 'develop']
45
+ const MAIN_FAMILY = ['main', 'master']
46
+
47
+ // ---- pure, unit-testable core (no git, no network) ----
48
+
49
+ // Count the `+` lines in `git cherry` output — commits present on the head branch
50
+ // that are NOT in upstream and have no equivalent patch upstream (a `-` line means
51
+ // an equivalent commit already exists upstream; merge commits are skipped entirely).
52
+ // This is the CONTENT check: `+` count > 0 means genuinely unique non-merge content.
53
+ export function countCherryUnique(cherryOutput) {
54
+ if (!cherryOutput) return 0
55
+ return cherryOutput
56
+ .split('\n')
57
+ .filter((l) => l.trim().startsWith('+'))
58
+ .length
59
+ }
60
+
61
+ // The whole decision, as a pure function of gathered facts so it is testable
62
+ // without a git repo. `facts`:
63
+ // devFamily, mainFamily : existing branch names of each family (subset of the
64
+ // family lists above, in precedence order)
65
+ // candidates : [{name, ahead, behind, lastCommitDate}] evidence for
66
+ // every existing long-lived branch (ahead/behind measured
67
+ // against the reference — the main-family primary)
68
+ // mainUnique, devUnique : `git cherry` `+` counts for the dev-vs-main pair
69
+ // (main-not-in-dev, dev-not-in-main); null when there is
70
+ // not exactly one dev and one main to compare
71
+ // Returns { recommended, reason, candidates, conflict }.
72
+ export function decideTargetBranch({ devFamily, mainFamily, candidates, mainUnique, devUnique }) {
73
+ const conflict = (reason) => ({ recommended: null, reason, candidates, conflict: true })
74
+ const recommend = (name, reason) => ({ recommended: name, reason, candidates, conflict: false })
75
+
76
+ // Two plausible long-lived branches of the same family both exist (e.g. dev AND
77
+ // develop, or main AND master) — a tie: we cannot say which is the long-lived
78
+ // line. Never pick; hand the candidates to the human.
79
+ if (devFamily.length > 1) {
80
+ return conflict(`two long-lived development branches exist (${devFamily.join(', ')}) — ambiguous which is the development line; choose one`)
81
+ }
82
+ if (mainFamily.length > 1) {
83
+ return conflict(`two long-lived production branches exist (${mainFamily.join(', ')}) — ambiguous which is production; choose one`)
84
+ }
85
+
86
+ const dev = devFamily[0]
87
+ const main = mainFamily[0]
88
+
89
+ // Trunk-based: no long-lived dev branch → main holds the development head.
90
+ if (!dev && main) {
91
+ return recommend(main, `trunk-based: ${main} is the only long-lived branch, so it holds the development head`)
92
+ }
93
+ // Only a dev-family branch exists (no main/master at all) — unusual, but the sole
94
+ // long-lived branch is the development head by default.
95
+ if (dev && !main) {
96
+ return recommend(dev, `${dev} is the only long-lived branch, so it holds the development head`)
97
+ }
98
+
99
+ // Exactly one dev and one main: the GitFlow-vs-trunk content decision.
100
+ // `mainUnique` is the count of non-merge commits main has that dev lacks. Zero
101
+ // means main has no CONTENT dev lacks — dev still holds the development head,
102
+ // whether main is a strict ancestor (classic GitFlow) or diverged only by
103
+ // promotion-merge commits (nominal divergence). Recommend dev.
104
+ if (mainUnique === 0) {
105
+ const devEvidence = candidates.find((c) => c.name === dev)
106
+ const kind = devEvidence && devEvidence.behind === 0
107
+ ? `${main} is an ancestor of ${dev}`
108
+ : `${main}'s extra commits carry no content ${dev} lacks (git cherry: no unique non-merge commits)`
109
+ return recommend(dev, `${dev} holds the development head — ${kind}`)
110
+ }
111
+
112
+ // main has genuine non-merge content dev lacks. If dev has none of its own, dev
113
+ // sits BEHIND main — a conflict the human must resolve (do not silently promote
114
+ // main). If both sides carry unique content, they have genuinely diverged.
115
+ if (devUnique === 0) {
116
+ return conflict(`${dev} sits behind ${main}: ${main} has ${mainUnique} unique non-merge commit(s) ${dev} lacks and ${dev} has none of its own — choose the target`)
117
+ }
118
+ return conflict(`${dev} and ${main} have diverged: unique non-merge commits on both sides (${dev}: ${devUnique}, ${main}: ${mainUnique}) — choose the target`)
119
+ }
120
+
121
+ // ---- git live facts (side-effecting; not unit-tested, like combine-and-verify's) ----
122
+
123
+ function git(args, opts = {}) {
124
+ return execFileSync('git', args, { encoding: 'utf8', ...opts }).trim()
125
+ }
126
+
127
+ // Does origin/<name> resolve to a commit? Fails closed (false) on any error so a
128
+ // missing remote-tracking ref simply means "that candidate does not exist".
129
+ function remoteRefExists(name) {
130
+ try {
131
+ execFileSync('git', ['rev-parse', '--verify', '--quiet', `origin/${name}^{commit}`], { stdio: 'ignore' })
132
+ return true
133
+ } catch {
134
+ return false
135
+ }
136
+ }
137
+
138
+ // ahead/behind of `name` relative to `ref`, both remote heads. `git rev-list
139
+ // --left-right --count origin/ref...origin/name` prints "<left>\t<right>" where
140
+ // left = commits reachable from ref not name, right = commits reachable from name
141
+ // not ref. So ahead (name has, ref lacks) = right; behind (ref has, name lacks) = left.
142
+ function aheadBehind(ref, name) {
143
+ if (ref === name) return { ahead: 0, behind: 0 }
144
+ const out = git(['rev-list', '--left-right', '--count', `origin/${ref}...origin/${name}`])
145
+ const [left, right] = out.split(/\s+/).map((n) => parseInt(n, 10))
146
+ return { ahead: right || 0, behind: left || 0 }
147
+ }
148
+
149
+ // Committer date (ISO 8601) of the tip of origin/<name>.
150
+ function lastCommitDate(name) {
151
+ try {
152
+ return git(['log', '-1', '--format=%cI', `origin/${name}`])
153
+ } catch {
154
+ return null
155
+ }
156
+ }
157
+
158
+ // `+`-count of `git cherry <upstream> <head>` — non-merge commits on head not in
159
+ // upstream and without an equivalent patch there. See countCherryUnique.
160
+ function cherryUnique(upstream, head) {
161
+ let out = ''
162
+ try {
163
+ out = git(['cherry', `origin/${upstream}`, `origin/${head}`])
164
+ } catch {
165
+ return 0
166
+ }
167
+ return countCherryUnique(out)
168
+ }
169
+
170
+ // Gather every fact decideTargetBranch needs from the live remote heads.
171
+ export function gatherFacts() {
172
+ const existing = [...DEV_FAMILY, ...MAIN_FAMILY].filter(remoteRefExists)
173
+ const devFamily = existing.filter((n) => DEV_FAMILY.includes(n))
174
+ const mainFamily = existing.filter((n) => MAIN_FAMILY.includes(n))
175
+
176
+ // Reference for the ahead/behind evidence: the production primary when present,
177
+ // else the development primary — so every candidate's counts are read against a
178
+ // single, interpretable baseline (for the standard one-dev/one-main repo this is
179
+ // exactly dev-vs-main).
180
+ const reference = mainFamily[0] || devFamily[0] || existing[0]
181
+ const candidates = existing.map((name) => ({
182
+ name,
183
+ ...aheadBehind(reference, name),
184
+ lastCommitDate: lastCommitDate(name),
185
+ }))
186
+
187
+ // The content check only applies when there is exactly one dev and one main to
188
+ // compare; otherwise the family-tie / trunk / dev-only branches decide it.
189
+ let mainUnique = null
190
+ let devUnique = null
191
+ if (devFamily.length === 1 && mainFamily.length === 1) {
192
+ mainUnique = cherryUnique(devFamily[0], mainFamily[0]) // main commits not in dev
193
+ devUnique = cherryUnique(mainFamily[0], devFamily[0]) // dev commits not in main
194
+ }
195
+
196
+ return { devFamily, mainFamily, candidates, mainUnique, devUnique }
197
+ }
198
+
199
+ // ---- CLI ----
200
+
201
+ const USAGE = `detect-target-branch — recommend the source/base branch from the remote's long-lived heads.
202
+ Usage:
203
+ detect-target-branch [--no-fetch]
204
+ Options:
205
+ --no-fetch skip \`git fetch origin\` (for tests, or when the remote is already fresh)
206
+ --help, -h show this help and exit 0
207
+ Output: JSON on stdout — { recommended, reason, candidates: [{name, ahead, behind, lastCommitDate}], conflict }.
208
+ Exit codes: 0 = recommendation produced, 1 = genuine conflict (human chooses), 2 = usage error / no long-lived branches.
209
+ The human confirms the recommendation in the pre-flight gate; this recommends + shows evidence, it does not decide silently.`
210
+
211
+ function parseArgs(argv) {
212
+ const f = {}
213
+ for (const a of argv) {
214
+ if (a === '--help' || a === '-h' || a === 'help') f.help = true
215
+ else if (a === '--no-fetch') f.noFetch = true
216
+ else f.unknown = a
217
+ }
218
+ return f
219
+ }
220
+
221
+ export function runCli(argv) {
222
+ const f = parseArgs(argv)
223
+ if (f.help) {
224
+ console.log(USAGE)
225
+ return 0
226
+ }
227
+ if (f.unknown) {
228
+ console.error(`detect-target-branch: unknown argument "${f.unknown}"\n${USAGE}`)
229
+ return 2
230
+ }
231
+
232
+ if (!f.noFetch) {
233
+ try {
234
+ execFileSync('git', ['fetch', 'origin'], { stdio: 'ignore' })
235
+ } catch {
236
+ console.error(' ⚠ git fetch origin failed; detecting against the last-known remote heads')
237
+ }
238
+ }
239
+
240
+ const facts = gatherFacts()
241
+ if (facts.devFamily.length === 0 && facts.mainFamily.length === 0) {
242
+ console.error('detect-target-branch: no long-lived branches (origin/{dev,develop,main,master}) found — is this a fresh remote?')
243
+ return 2
244
+ }
245
+
246
+ const result = decideTargetBranch(facts)
247
+ console.log(JSON.stringify(result, null, 2))
248
+ // A one-line human cue on stderr so someone running it by hand sees the verdict.
249
+ if (result.conflict) console.error(`detect-target-branch: ⚠ conflict — ${result.reason}`)
250
+ else console.error(`detect-target-branch: ✓ recommend ${result.recommended} — confirm in the pre-flight gate`)
251
+ return result.conflict ? 1 : 0
252
+ }
253
+
254
+ if (isMainModule(import.meta.url)) {
255
+ process.exit(runCli(process.argv.slice(2)))
256
+ }
@@ -0,0 +1,168 @@
1
+ // detect-workspace-mode — where the run's code-writing happens: the human's checkout, or
2
+ // a worktree of its own.
3
+ //
4
+ // This is a SETTING WITH A PROBED DEFAULT, deliberately not another pre-flight question.
5
+ // The neutral batch already carries implementer · reviewer when required · branch ·
6
+ // autonomy, and another question can overflow the selected adapter's one-call capacity.
7
+ // It is also the wrong thing to ask: the
8
+ // answer turns on facts about the tree (is it dirty, are we already isolated) that the
9
+ // human usually cannot recall at the prompt, and that a probe reads exactly. Same reasoning
10
+ // as deliveryMode, and the same shape as breakerAutonomy — a default the human can override
11
+ // by naming it, surfaced in the pre-flight summary so a wrong guess is correctable before
12
+ // any work runs.
13
+ //
14
+ // node detect-workspace-mode.mjs # probe the cwd, recommend (JSON on stdout)
15
+ // node detect-workspace-mode.mjs --repo-dir DIR # probe a specific checkout
16
+ // node detect-workspace-mode.mjs --help
17
+ //
18
+ // OUTPUT (stdout, always JSON):
19
+ // { mode: "shared"|"worktree"|null, reason, signals: {dirty, insideWorktree, gitDir}, probed }
20
+ //
21
+ // EXIT CODES:
22
+ // 0 a mode was determined
23
+ // 2 UNDETERMINED (not a git repo, or git unreadable) or usage error — never a silent default.
24
+ //
25
+ // The trade this encodes, and why `worktree` is NOT the blanket default: a fresh worktree
26
+ // has no `node_modules`, no `.env`, no build cache. On a product repo that means an install
27
+ // before the first test can run, which is a real cost paid on every run. So `shared` stays
28
+ // the default for a clean tree, and `worktree` is reserved for the case where sharing is
29
+ // actively unsafe — plus any run where the human asks for it.
30
+
31
+ import { execFileSync } from 'node:child_process'
32
+ import { realpathSync } from 'node:fs'
33
+ import { fileURLToPath } from 'node:url'
34
+
35
+ export const WORKSPACE_MODES = ['shared', 'worktree']
36
+
37
+ // ---- pure, unit-testable core ----
38
+
39
+ // The one case where `shared` is not a preference but a hazard: a dirty tree. The current
40
+ // rule stops the run and asks the human to commit or stash (never stashing for them),
41
+ // because a branch switch can fail on uncommitted changes or silently carry them into a
42
+ // unit's diff. A worktree dissolves that dilemma — the run gets a clean tree of its own and
43
+ // the human's work is never touched — so the dirty case recommends `worktree` rather than
44
+ // stopping. That is a strictly better answer than the stop it replaces.
45
+ export function decideWorkspaceMode({ isRepo, dirty, insideWorktree, disposable = false } = {}) {
46
+ if (!isRepo) {
47
+ return { mode: null, probed: false, reason: 'not a git repository (or git was unreadable) — the workspace mode is UNKNOWN; settle it before any spawn writes code' }
48
+ }
49
+ // Already isolated. Nesting a worktree inside a worktree, or inside a throwaway CI clone,
50
+ // buys nothing and costs a second dependency install.
51
+ if (insideWorktree || disposable) {
52
+ return { mode: 'shared', probed: true, reason: `already an isolated checkout (${insideWorktree ? 'a linked git worktree' : 'a disposable clone'}) — the run has nothing to gain from another one, and its branch switches touch no working tree the human is using` }
53
+ }
54
+ if (dirty) {
55
+ return { mode: 'worktree', probed: true, reason: 'the working tree has uncommitted changes — running here would switch branches under them, which can fail or silently carry them into a unit diff. A worktree leaves the human\'s tree untouched, so this replaces the dirty-tree stop rather than blocking the run' }
56
+ }
57
+ return { mode: 'shared', probed: true, reason: 'the working tree is clean, so branch switches are safe here — and a fresh worktree would owe a dependency install before the first test could run. Ask for `worktree` explicitly to keep the checkout free while the run works' }
58
+ }
59
+
60
+ // ---- impure probe ----
61
+
62
+ function git(args, cwd) {
63
+ try { return { ok: true, out: execFileSync('git', args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() } }
64
+ catch (error) { return { ok: false, out: '', error } }
65
+ }
66
+
67
+ export function gatherWorkspaceSignals(cwd) {
68
+ const top = git(['rev-parse', '--show-toplevel'], cwd)
69
+ if (!top.ok) return { isRepo: false, dirty: false, insideWorktree: false, gitDir: null, toplevel: null }
70
+ // `--untracked-files=no` deliberately. The hazard this check exists for is a branch
71
+ // switch failing on, or silently carrying, *tracked* modifications. Untracked files are
72
+ // carried across a switch harmlessly — and counting them made this probe recommend
73
+ // `worktree` for essentially every real checkout, since almost all of them carry a
74
+ // stray `.env`, a log, or an editor file. That inverted the documented default (clean
75
+ // tree → shared) and would have imposed a dependency install on every run.
76
+ //
77
+ // The residual case is narrow and git handles it loudly: an untracked file whose path
78
+ // the target branch also contains makes checkout refuse with a clear error, rather than
79
+ // corrupting anything. A loud stop on a rare collision is a better trade than a silent
80
+ // default flip on the common path.
81
+ const status = git(['status', '--porcelain', '--untracked-files=no'], cwd)
82
+ // A LINKED worktree's `.git` is a file pointing at the parent's admin dir, so
83
+ // --git-common-dir and --git-dir differ. In the primary checkout they are the same.
84
+ const gitDir = git(['rev-parse', '--absolute-git-dir'], cwd)
85
+ const commonDir = git(['rev-parse', '--path-format=absolute', '--git-common-dir'], cwd)
86
+ const insideWorktree = gitDir.ok && commonDir.ok && gitDir.out !== commonDir.out
87
+ return {
88
+ isRepo: true,
89
+ // An unreadable status is NOT "clean" — that would be the fabricated-evidence failure
90
+ // the delivery probe exists to avoid. Treat it as dirty: the conservative direction.
91
+ dirty: !status.ok || status.out.length > 0,
92
+ insideWorktree,
93
+ gitDir: gitDir.ok ? gitDir.out : null,
94
+ toplevel: top.out,
95
+ }
96
+ }
97
+
98
+ // The path a `worktree`-mode run should use. Kept beside the repo rather than inside it so
99
+ // it never lands in `git status`, never collides with the run's own branch switches, and is
100
+ // obvious to a human cleaning up by hand.
101
+ export function worktreePathFor(toplevel, slug) {
102
+ const base = String(toplevel || '').replace(/\/+$/, '')
103
+ const name = String(slug || 'run').replace(/[^\w.-]+/g, '-')
104
+ return `${base}-worktrees/${name}`
105
+ }
106
+
107
+ function parseArgs(argv) {
108
+ const f = {}
109
+ for (let i = 0; i < argv.length; i++) {
110
+ const a = argv[i]
111
+ if (a === '--repo-dir') f.repoDir = argv[++i]
112
+ else if (a === '--slug') f.slug = argv[++i]
113
+ else if (a === '--disposable') f.disposable = true
114
+ else if (a === '--help' || a === '-h') f.help = true
115
+ }
116
+ return f
117
+ }
118
+
119
+ export function runCli(argv) {
120
+ const f = parseArgs(argv)
121
+ if (f.help) {
122
+ console.log(`detect-workspace-mode [--repo-dir <dir>] [--slug <run-slug>] [--disposable]
123
+ Recommends workspaceMode (shared|worktree) for a run's code-writing spawns.
124
+
125
+ shared every spawn works in the current checkout (today's behavior)
126
+ worktree the run gets a checkout of its own; the human's tree is never touched
127
+
128
+ Probed, not asked: pre-flight already has a complete adapter-planned question batch,
129
+ and the answer turns on tree state the human cannot recall at a prompt. A dirty tree
130
+ recommends worktree — which
131
+ replaces the dirty-tree stop rather than blocking the run. Override by naming it.
132
+ exit 0 = mode determined · 2 = UNDETERMINED (not a git repo) or usage error.`)
133
+ return 0
134
+ }
135
+ const cwd = f.repoDir || process.cwd()
136
+ const signals = gatherWorkspaceSignals(cwd)
137
+ const decision = decideWorkspaceMode({ ...signals, disposable: f.disposable })
138
+ const out = { ...decision, signals }
139
+ if (decision.mode === 'worktree' && signals.toplevel) {
140
+ out.worktreePath = worktreePathFor(signals.toplevel, f.slug || 'run')
141
+ out.setup = `git worktree add ${out.worktreePath} <targetBranch>`
142
+ out.teardown = `git worktree remove ${out.worktreePath}`
143
+ }
144
+ console.log(JSON.stringify(out, null, 2))
145
+ return decision.mode ? 0 : 2
146
+ }
147
+
148
+ let launchedDirectly = false
149
+ let mainModuleError = null
150
+ try {
151
+ const { isMainModule } = await import('../../engineering-runtime/scripts/main-module.mjs')
152
+ if (typeof isMainModule !== 'function') throw new Error('main-module.mjs does not export isMainModule')
153
+ launchedDirectly = isMainModule(import.meta.url)
154
+ } catch (error) {
155
+ mainModuleError = error
156
+ try {
157
+ launchedDirectly = realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))
158
+ } catch {
159
+ launchedDirectly = false
160
+ }
161
+ }
162
+
163
+ if (launchedDirectly && mainModuleError) {
164
+ console.error(`detect-workspace-mode: cannot load engineering-runtime main-module helper: ${mainModuleError.message}`)
165
+ process.exitCode = 1
166
+ } else if (launchedDirectly) {
167
+ process.exit(runCli(process.argv.slice(2)))
168
+ }
@@ -0,0 +1,9 @@
1
+ // Compatibility wrapper: canonical ownership lives in harness-runtime.
2
+ export * from '../../harness-runtime/discover-models.mjs'
3
+
4
+ import { runCli } from '../../harness-runtime/discover-models.mjs'
5
+ import { isMainModule } from '../../engineering-runtime/scripts/main-module.mjs'
6
+
7
+ if (isMainModule(import.meta.url)) {
8
+ process.exit(runCli(process.argv.slice(2)))
9
+ }
@@ -0,0 +1,62 @@
1
+ // The resolve-issues doctrine as ONE document, however it happens to be split across files.
2
+ //
3
+ // Why this exists: SKILL.md used to hold the whole loop — 226 lines, but 57KB, the densest file
4
+ // in this repo at ~250 bytes a line. Several tests here assert that a rule is *stated*, and they
5
+ // did that by reading SKILL.md directly. That premise broke when the doctrine moved into
6
+ // `references/`, and it broke for a reason worth keeping written down: an agent harness loaded
7
+ // the sibling `resolve-release/SKILL.md` as lines 1-260 of 491 and silently dropped its
8
+ // traffic-shift and rollback steps. A skill does not fail when it is truncated; it quietly
9
+ // becomes a shorter, different skill. The defence is an index small enough that no plausible
10
+ // budget reaches its end, with the phases in files an agent fetches deliberately.
11
+ //
12
+ // These tests grade the *doctrine* — that a rule exists, that its incident is cited, that a
13
+ // default is stated with its escape hatch. None of that is a claim about which file the sentence
14
+ // lives in, so the doctrine is reassembled here in its original document order and the tests read
15
+ // it from this module instead of from a path.
16
+ //
17
+ // The reassembly is faithful rather than approximate: each phase file was extracted as a
18
+ // contiguous line range, in order, so concatenating them in that order reproduces the original.
19
+ // Each reference opens with a NEW `# Title` and orientation paragraph that did not exist before;
20
+ // those are stripped, resuming at the first heading that came from the original document — which
21
+ // is why each entry below names it.
22
+ //
23
+ // SKILL.md is included whole. Unlike resolve-release, it kept no duplicate heading of a moved
24
+ // section (its pre-flight section was always just a pointer at references/pre-flight.md), so
25
+ // there is no shadowing heading to exclude.
26
+ //
27
+ // If a future split moves a section again, update ORDER in the same commit. A test that fails
28
+ // because prose moved is this module being stale, not doctrine being lost — but confirm which
29
+ // before editing anything here.
30
+ import fs from 'node:fs'
31
+ import path from 'node:path'
32
+ import { fileURLToPath } from 'node:url'
33
+
34
+ const skillDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
35
+ const read = (rel) => fs.readFileSync(path.join(skillDir, rel), 'utf8')
36
+
37
+ const ORDER = [
38
+ // The four guarantees keep their bars on SKILL.md; their detail moved here (2026-08-16).
39
+ { file: 'references/guarantees.md', resumeAt: '## The four guarantees' },
40
+ { file: 'references/intake.md', resumeAt: '## Intake & scheduling' },
41
+ { file: 'references/loop.md', resumeAt: '## The loop (per unit)' },
42
+ { file: 'references/deliverables.md', resumeAt: '## Deliverables:' },
43
+ ]
44
+
45
+ function bodyFrom({ file, resumeAt }) {
46
+ const text = read(file)
47
+ const idx = text.indexOf(`\n${resumeAt}`)
48
+ if (idx < 0) {
49
+ throw new Error(
50
+ `doctrine.mjs: ${file} no longer contains "${resumeAt}". Either the heading was reworded ` +
51
+ '(update ORDER here, same commit) or the section moved again (update ORDER, and check the ' +
52
+ 'section still exists somewhere before assuming it is only a rename).',
53
+ )
54
+ }
55
+ return text.slice(idx + 1)
56
+ }
57
+
58
+ export function loadDoctrine() {
59
+ return [read('SKILL.md'), ...ORDER.map(bodyFrom)].join('\n')
60
+ }
61
+
62
+ export const DOCTRINE = loadDoctrine()