coding-agent-skills 0.2.8

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 (357) hide show
  1. package/AGENTS.md +44 -0
  2. package/CHANGELOG.md +205 -0
  3. package/CONTRIBUTING.md +54 -0
  4. package/LICENSE +21 -0
  5. package/README.md +85 -0
  6. package/ROADMAP.md +87 -0
  7. package/RUNBOOK.md +47 -0
  8. package/bin/coding-agent-skills +75 -0
  9. package/contracts/evidence-pack/README.md +22 -0
  10. package/contracts/evidence-pack/evidence-pack.example.json +60 -0
  11. package/contracts/evidence-pack/evidence-pack.example.md +49 -0
  12. package/contracts/evidence-pack/evidence-pack.schema.json +156 -0
  13. package/docs/adapters/README.md +82 -0
  14. package/docs/adapters/discovery.md +50 -0
  15. package/docs/adapters/external-adapters.md +42 -0
  16. package/docs/adapters/project-installation.md +135 -0
  17. package/docs/adapters/real-project-adoption.md +193 -0
  18. package/docs/adapters/upgrade-evidence.md +67 -0
  19. package/docs/adapters/upgrades.md +83 -0
  20. package/docs/architecture/README.md +23 -0
  21. package/docs/authoring/README.md +54 -0
  22. package/docs/evidence-bundles/README.md +94 -0
  23. package/docs/privacy/README.md +26 -0
  24. package/docs/release/README.md +42 -0
  25. package/docs/release/npm-package.md +85 -0
  26. package/docs/safety/README.md +94 -0
  27. package/docs/testing/README.md +100 -0
  28. package/docs/usage/README.md +89 -0
  29. package/docs/versioning/README.md +30 -0
  30. package/docs/versioning/adapter-compatibility.md +54 -0
  31. package/examples/README.md +12 -0
  32. package/examples/adapters/README.md +9 -0
  33. package/examples/adapters/documentation-precedence.json +62 -0
  34. package/examples/adapters/narrow-repo-map.json +64 -0
  35. package/examples/adapters/runtime-status-hints.json +76 -0
  36. package/examples/command-policies/README.md +3 -0
  37. package/examples/command-policies/build-verify.json +57 -0
  38. package/examples/command-policies/git-preflight.json +44 -0
  39. package/examples/command-policies/llm-drift-control.json +45 -0
  40. package/examples/command-policies/repo-map.json +59 -0
  41. package/examples/command-policies/runtime-truth.json +59 -0
  42. package/examples/evidence-packs/README.md +3 -0
  43. package/examples/evidence-packs/build-verify.json +68 -0
  44. package/examples/evidence-packs/git-preflight.json +55 -0
  45. package/examples/evidence-packs/llm-drift-control.json +55 -0
  46. package/examples/evidence-packs/repo-map.json +55 -0
  47. package/examples/evidence-packs/runtime-truth.json +55 -0
  48. package/examples/manifests/README.md +3 -0
  49. package/examples/manifests/build-verify.json +14 -0
  50. package/examples/manifests/git-preflight.json +14 -0
  51. package/examples/manifests/llm-drift-control.json +14 -0
  52. package/examples/manifests/repo-map.json +14 -0
  53. package/examples/manifests/runtime-truth.json +14 -0
  54. package/examples/upgrade-evidence/README.md +14 -0
  55. package/examples/upgrade-evidence/chain-fail.evidence.json +155 -0
  56. package/examples/upgrade-evidence/chain-fail.evidence.md +14 -0
  57. package/examples/upgrade-evidence/chain-pass.evidence.json +156 -0
  58. package/examples/upgrade-evidence/stale-pin.evidence.json +117 -0
  59. package/examples/upgrade-evidence/unsafe-upgrade.evidence.json +128 -0
  60. package/examples/upgrade-evidence/valid-upgrade.evidence.json +105 -0
  61. package/examples/upgrade-evidence/valid-upgrade.evidence.md +13 -0
  62. package/examples/workflows/README.md +3 -0
  63. package/examples/workflows/build-verify.md +20 -0
  64. package/examples/workflows/git-preflight.md +18 -0
  65. package/examples/workflows/llm-drift-control.md +16 -0
  66. package/examples/workflows/repo-map.md +20 -0
  67. package/examples/workflows/runtime-truth.md +17 -0
  68. package/package.json +58 -0
  69. package/runs/skill-runs.md +162 -0
  70. package/schemas/adapter-upgrade-evidence.schema.json +443 -0
  71. package/schemas/archive-index.schema.json +174 -0
  72. package/schemas/archive-report.schema.json +322 -0
  73. package/schemas/command-policy.schema.json +125 -0
  74. package/schemas/evidence-bundle.schema.json +394 -0
  75. package/schemas/project-adapter-installation.schema.json +127 -0
  76. package/schemas/project-adapter.schema.json +328 -0
  77. package/schemas/skill-manifest.schema.json +40 -0
  78. package/scripts/check-adapter-upgrade-chain.mjs +32 -0
  79. package/scripts/check-adapter-upgrade.mjs +31 -0
  80. package/scripts/lib/adapter-discovery.mjs +441 -0
  81. package/scripts/lib/adapter-repo-map.mjs +358 -0
  82. package/scripts/lib/adapter-upgrade-chain.mjs +261 -0
  83. package/scripts/lib/adapter-upgrade.mjs +434 -0
  84. package/scripts/lib/evidence-bundle.mjs +831 -0
  85. package/scripts/lib/pack-rules.mjs +704 -0
  86. package/scripts/lib/project-adapter-installation.mjs +327 -0
  87. package/scripts/lib/safe-evidence-output.mjs +92 -0
  88. package/scripts/lib/schema-validator.mjs +146 -0
  89. package/scripts/lib/semver.mjs +54 -0
  90. package/scripts/lib/upgrade-evidence.mjs +276 -0
  91. package/scripts/render-adapter-repo-map.mjs +8 -0
  92. package/scripts/render-evidence-archive-report.mjs +18 -0
  93. package/scripts/run-next +220 -0
  94. package/scripts/test-pack.mjs +2232 -0
  95. package/scripts/validate-adapters.mjs +10 -0
  96. package/scripts/validate-maintainer-loop.mjs +146 -0
  97. package/scripts/validate-pack.mjs +950 -0
  98. package/scripts/validate-project-adapters.mjs +8 -0
  99. package/scripts/verify-evidence-bundle.mjs +18 -0
  100. package/skills/build-verify/SKILL.md +62 -0
  101. package/skills/build-verify/adapter-interface.md +7 -0
  102. package/skills/build-verify/agents/openai.yaml +4 -0
  103. package/skills/build-verify/checklist.md +12 -0
  104. package/skills/build-verify/evidence-template.md +11 -0
  105. package/skills/build-verify/examples.md +16 -0
  106. package/skills/build-verify/failure-modes.md +14 -0
  107. package/skills/git-preflight/SKILL.md +65 -0
  108. package/skills/git-preflight/adapter-interface.md +7 -0
  109. package/skills/git-preflight/agents/openai.yaml +4 -0
  110. package/skills/git-preflight/checklist.md +11 -0
  111. package/skills/git-preflight/evidence-template.md +10 -0
  112. package/skills/git-preflight/examples.md +18 -0
  113. package/skills/git-preflight/failure-modes.md +13 -0
  114. package/skills/llm-drift-control/SKILL.md +67 -0
  115. package/skills/llm-drift-control/adapter-interface.md +7 -0
  116. package/skills/llm-drift-control/agents/openai.yaml +4 -0
  117. package/skills/llm-drift-control/checklist.md +11 -0
  118. package/skills/llm-drift-control/evidence-template.md +13 -0
  119. package/skills/llm-drift-control/examples.md +15 -0
  120. package/skills/llm-drift-control/failure-modes.md +13 -0
  121. package/skills/repo-map/SKILL.md +71 -0
  122. package/skills/repo-map/adapter-interface.md +18 -0
  123. package/skills/repo-map/agents/openai.yaml +4 -0
  124. package/skills/repo-map/checklist.md +15 -0
  125. package/skills/repo-map/evidence-template.md +29 -0
  126. package/skills/repo-map/examples.md +19 -0
  127. package/skills/repo-map/failure-modes.md +16 -0
  128. package/skills/runtime-truth/SKILL.md +62 -0
  129. package/skills/runtime-truth/adapter-interface.md +7 -0
  130. package/skills/runtime-truth/agents/openai.yaml +4 -0
  131. package/skills/runtime-truth/checklist.md +11 -0
  132. package/skills/runtime-truth/evidence-template.md +12 -0
  133. package/skills/runtime-truth/examples.md +20 -0
  134. package/skills/runtime-truth/failure-modes.md +13 -0
  135. package/tests/README.md +44 -0
  136. package/tests/adapters/README.md +15 -0
  137. package/tests/completion/README.md +15 -0
  138. package/tests/evidence/README.md +15 -0
  139. package/tests/fixtures/README.md +23 -0
  140. package/tests/fixtures/adapters/allow-deploy.json +60 -0
  141. package/tests/fixtures/adapters/allow-git-push.json +60 -0
  142. package/tests/fixtures/adapters/expand-scope.json +53 -0
  143. package/tests/fixtures/adapters/expose-secrets.json +53 -0
  144. package/tests/fixtures/adapters/incompatible-version.json +53 -0
  145. package/tests/fixtures/adapters/override-audit-only.json +53 -0
  146. package/tests/fixtures/adapters/redefine-completion.json +53 -0
  147. package/tests/fixtures/adapters/remove-required-evidence.json +53 -0
  148. package/tests/fixtures/adapters/suppress-failures.json +53 -0
  149. package/tests/fixtures/adapters/valid-narrowing.json +53 -0
  150. package/tests/fixtures/adapters/valid-repo-map.json +53 -0
  151. package/tests/fixtures/adapters/weakening-repo-map.json +42 -0
  152. package/tests/fixtures/completion/cases.json +143 -0
  153. package/tests/fixtures/completion/false-complete.json +51 -0
  154. package/tests/fixtures/evidence-bundles/advisory-review-soon/archive/evidence-archive-index.json +52 -0
  155. package/tests/fixtures/evidence-bundles/advisory-review-soon/evidence/repo-map.evidence.json +68 -0
  156. package/tests/fixtures/evidence-bundles/advisory-review-soon/evidence/valid-upgrade.evidence.json +105 -0
  157. package/tests/fixtures/evidence-bundles/advisory-review-soon/evidence-bundle.json +109 -0
  158. package/tests/fixtures/evidence-bundles/invalid-archive/archive/evidence-archive-index.json +52 -0
  159. package/tests/fixtures/evidence-bundles/invalid-archive/evidence/repo-map.evidence.json +68 -0
  160. package/tests/fixtures/evidence-bundles/invalid-archive/evidence/valid-upgrade.evidence.json +105 -0
  161. package/tests/fixtures/evidence-bundles/invalid-archive/evidence-bundle.json +109 -0
  162. package/tests/fixtures/evidence-bundles/invalid-archive-index/archive/evidence-archive-index.json +52 -0
  163. package/tests/fixtures/evidence-bundles/invalid-archive-index/evidence/repo-map.evidence.json +68 -0
  164. package/tests/fixtures/evidence-bundles/invalid-archive-index/evidence/valid-upgrade.evidence.json +105 -0
  165. package/tests/fixtures/evidence-bundles/invalid-archive-index/evidence-bundle.json +109 -0
  166. package/tests/fixtures/evidence-bundles/invalid-hash/archive/evidence-archive-index.json +52 -0
  167. package/tests/fixtures/evidence-bundles/invalid-hash/evidence/repo-map.evidence.json +68 -0
  168. package/tests/fixtures/evidence-bundles/invalid-hash/evidence/valid-upgrade.evidence.json +105 -0
  169. package/tests/fixtures/evidence-bundles/invalid-hash/evidence-bundle.json +109 -0
  170. package/tests/fixtures/evidence-bundles/invalid-missing-entry/archive/evidence-archive-index.json +52 -0
  171. package/tests/fixtures/evidence-bundles/invalid-missing-entry/evidence/repo-map.evidence.json +68 -0
  172. package/tests/fixtures/evidence-bundles/invalid-missing-entry/evidence/valid-upgrade.evidence.json +105 -0
  173. package/tests/fixtures/evidence-bundles/invalid-missing-entry/evidence-bundle.json +109 -0
  174. package/tests/fixtures/evidence-bundles/invalid-path/archive/evidence-archive-index.json +52 -0
  175. package/tests/fixtures/evidence-bundles/invalid-path/evidence/repo-map.evidence.json +68 -0
  176. package/tests/fixtures/evidence-bundles/invalid-path/evidence/valid-upgrade.evidence.json +105 -0
  177. package/tests/fixtures/evidence-bundles/invalid-path/evidence-bundle.json +109 -0
  178. package/tests/fixtures/evidence-bundles/invalid-provenance/archive/evidence-archive-index.json +52 -0
  179. package/tests/fixtures/evidence-bundles/invalid-provenance/evidence/repo-map.evidence.json +68 -0
  180. package/tests/fixtures/evidence-bundles/invalid-provenance/evidence/valid-upgrade.evidence.json +105 -0
  181. package/tests/fixtures/evidence-bundles/invalid-provenance/evidence-bundle.json +109 -0
  182. package/tests/fixtures/evidence-bundles/invalid-regression/archive/evidence-archive-index.json +52 -0
  183. package/tests/fixtures/evidence-bundles/invalid-regression/evidence/repo-map.evidence.json +68 -0
  184. package/tests/fixtures/evidence-bundles/invalid-regression/evidence/valid-upgrade.evidence.json +105 -0
  185. package/tests/fixtures/evidence-bundles/invalid-regression/evidence-bundle.json +113 -0
  186. package/tests/fixtures/evidence-bundles/invalid-retention/archive/evidence-archive-index.json +52 -0
  187. package/tests/fixtures/evidence-bundles/invalid-retention/evidence/repo-map.evidence.json +68 -0
  188. package/tests/fixtures/evidence-bundles/invalid-retention/evidence/valid-upgrade.evidence.json +105 -0
  189. package/tests/fixtures/evidence-bundles/invalid-retention/evidence-bundle.json +109 -0
  190. package/tests/fixtures/evidence-bundles/invalid-signature-plan/archive/evidence-archive-index.json +52 -0
  191. package/tests/fixtures/evidence-bundles/invalid-signature-plan/evidence/repo-map.evidence.json +68 -0
  192. package/tests/fixtures/evidence-bundles/invalid-signature-plan/evidence/valid-upgrade.evidence.json +105 -0
  193. package/tests/fixtures/evidence-bundles/invalid-signature-plan/evidence-bundle.json +109 -0
  194. package/tests/fixtures/evidence-bundles/valid-bundle/archive/evidence-archive-index.json +52 -0
  195. package/tests/fixtures/evidence-bundles/valid-bundle/evidence/repo-map.evidence.json +68 -0
  196. package/tests/fixtures/evidence-bundles/valid-bundle/evidence/valid-upgrade.evidence.json +105 -0
  197. package/tests/fixtures/evidence-bundles/valid-bundle/evidence-bundle.json +109 -0
  198. package/tests/fixtures/external-adapters/empty/README.md +3 -0
  199. package/tests/fixtures/external-adapters/invalid-completion-override/.coding-agent/adapters/completion/adapter.json +53 -0
  200. package/tests/fixtures/external-adapters/invalid-deploy/.coding-agent/adapters/deploy/adapter.json +60 -0
  201. package/tests/fixtures/external-adapters/invalid-evidence-suppression/.coding-agent/adapters/evidence/adapter.json +53 -0
  202. package/tests/fixtures/external-adapters/invalid-failure-suppression/.coding-agent/adapters/failures/adapter.json +53 -0
  203. package/tests/fixtures/external-adapters/invalid-git-push/.coding-agent/adapters/publish/adapter.json +60 -0
  204. package/tests/fixtures/external-adapters/invalid-malformed/.coding-agent/adapters/malformed/adapter.json +1 -0
  205. package/tests/fixtures/external-adapters/invalid-malformed/malformed-adapter.txt +1 -0
  206. package/tests/fixtures/external-adapters/invalid-mode-escalation/.coding-agent/adapters/mode/adapter.json +53 -0
  207. package/tests/fixtures/external-adapters/invalid-path-traversal/.coding-agent/adapters/path/adapter.json +53 -0
  208. package/tests/fixtures/external-adapters/invalid-restriction-removal/.coding-agent/adapters/restrictions/adapter.json +52 -0
  209. package/tests/fixtures/external-adapters/invalid-scope-expansion/.coding-agent/adapters/scope/adapter.json +53 -0
  210. package/tests/fixtures/external-adapters/invalid-secret-exposure/.coding-agent/adapters/secrets/adapter.json +53 -0
  211. package/tests/fixtures/external-adapters/invalid-skill-id/.coding-agent/adapters/skill/adapter.json +53 -0
  212. package/tests/fixtures/external-adapters/invalid-skill-version/.coding-agent/adapters/skill-version/adapter.json +53 -0
  213. package/tests/fixtures/external-adapters/invalid-unknown-manifest/.coding-agent/adapters/unknown/manifest.json +1 -0
  214. package/tests/fixtures/external-adapters/invalid-version/.coding-agent/adapters/version/adapter.json +53 -0
  215. package/tests/fixtures/external-adapters/mixed/.coding-agent/adapters/invalid/adapter.json +60 -0
  216. package/tests/fixtures/external-adapters/mixed/.coding-agent/adapters/valid/adapter.json +53 -0
  217. package/tests/fixtures/external-adapters/valid-basic/.coding-agent/adapters/basic/adapter.json +53 -0
  218. package/tests/fixtures/external-adapters/valid-doc-precedence/coding-agent/adapters/docs/adapter.json +53 -0
  219. package/tests/fixtures/external-adapters/valid-runtime-status/adapters/coding-agent/runtime/adapter.json +65 -0
  220. package/tests/fixtures/mutation/cases.json +87 -0
  221. package/tests/fixtures/mutation/snapshot-target/README.md +3 -0
  222. package/tests/fixtures/mutation/snapshot-target/state.json +4 -0
  223. package/tests/fixtures/policy/commands.json +164 -0
  224. package/tests/fixtures/policy/properties.json +126 -0
  225. package/tests/fixtures/privacy/cases.json +47 -0
  226. package/tests/fixtures/project-adapter-installation/invalid-adapter-location/.agents/adapters/basic/adapter.json +53 -0
  227. package/tests/fixtures/project-adapter-installation/invalid-adapter-location/.coding-agent/skills.json +23 -0
  228. package/tests/fixtures/project-adapter-installation/invalid-adapter-schema-version/.coding-agent/adapters/basic/adapter.json +53 -0
  229. package/tests/fixtures/project-adapter-installation/invalid-adapter-schema-version/.coding-agent/skills.json +23 -0
  230. package/tests/fixtures/project-adapter-installation/invalid-adapter-version-mismatch/.coding-agent/adapters/basic/adapter.json +53 -0
  231. package/tests/fixtures/project-adapter-installation/invalid-adapter-version-mismatch/.coding-agent/skills.json +23 -0
  232. package/tests/fixtures/project-adapter-installation/invalid-bad-semver/.coding-agent/adapters/basic/adapter.json +53 -0
  233. package/tests/fixtures/project-adapter-installation/invalid-bad-semver/.coding-agent/skills.json +23 -0
  234. package/tests/fixtures/project-adapter-installation/invalid-completion-override/.coding-agent/adapters/basic/adapter.json +53 -0
  235. package/tests/fixtures/project-adapter-installation/invalid-completion-override/.coding-agent/skills.json +23 -0
  236. package/tests/fixtures/project-adapter-installation/invalid-failure-suppression/.coding-agent/adapters/basic/adapter.json +53 -0
  237. package/tests/fixtures/project-adapter-installation/invalid-failure-suppression/.coding-agent/skills.json +23 -0
  238. package/tests/fixtures/project-adapter-installation/invalid-missing-declaration/.coding-agent/adapters/basic/adapter.json +53 -0
  239. package/tests/fixtures/project-adapter-installation/invalid-mode-escalation/.coding-agent/adapters/basic/adapter.json +53 -0
  240. package/tests/fixtures/project-adapter-installation/invalid-mode-escalation/.coding-agent/skills.json +23 -0
  241. package/tests/fixtures/project-adapter-installation/invalid-path-traversal/.coding-agent/adapters/basic/adapter.json +53 -0
  242. package/tests/fixtures/project-adapter-installation/invalid-path-traversal/.coding-agent/skills.json +23 -0
  243. package/tests/fixtures/project-adapter-installation/invalid-scope-expansion/.coding-agent/adapters/basic/adapter.json +53 -0
  244. package/tests/fixtures/project-adapter-installation/invalid-scope-expansion/.coding-agent/skills.json +23 -0
  245. package/tests/fixtures/project-adapter-installation/invalid-secret-exposure/.coding-agent/adapters/basic/adapter.json +53 -0
  246. package/tests/fixtures/project-adapter-installation/invalid-secret-exposure/.coding-agent/skills.json +23 -0
  247. package/tests/fixtures/project-adapter-installation/invalid-skill-mismatch/.coding-agent/adapters/basic/adapter.json +53 -0
  248. package/tests/fixtures/project-adapter-installation/invalid-skill-mismatch/.coding-agent/skills.json +23 -0
  249. package/tests/fixtures/project-adapter-installation/invalid-unknown-skill/.coding-agent/adapters/basic/adapter.json +53 -0
  250. package/tests/fixtures/project-adapter-installation/invalid-unknown-skill/.coding-agent/skills.json +23 -0
  251. package/tests/fixtures/project-adapter-installation/invalid-unsupported-core-version/.coding-agent/adapters/basic/adapter.json +53 -0
  252. package/tests/fixtures/project-adapter-installation/invalid-unsupported-core-version/.coding-agent/skills.json +23 -0
  253. package/tests/fixtures/project-adapter-installation/invalid-weakens-restrictions/.coding-agent/adapters/basic/adapter.json +52 -0
  254. package/tests/fixtures/project-adapter-installation/invalid-weakens-restrictions/.coding-agent/skills.json +23 -0
  255. package/tests/fixtures/project-adapter-installation/valid-compatible-range/coding-agent/adapters/docs/adapter.json +53 -0
  256. package/tests/fixtures/project-adapter-installation/valid-compatible-range/coding-agent.skills.json +23 -0
  257. package/tests/fixtures/project-adapter-installation/valid-exact-pin/.coding-agent/adapters/basic/adapter.json +53 -0
  258. package/tests/fixtures/project-adapter-installation/valid-exact-pin/.coding-agent/skills.json +23 -0
  259. package/tests/fixtures/project-adapter-installation/valid-multiple-adapters/.coding-agent/skills.json +28 -0
  260. package/tests/fixtures/project-adapter-installation/valid-multiple-adapters/adapters/coding-agent/repo/adapter.json +53 -0
  261. package/tests/fixtures/project-adapter-installation/valid-multiple-adapters/adapters/coding-agent/runtime/adapter.json +58 -0
  262. package/tests/fixtures/project-adapter-upgrade-chains/broken-compatibility-chain/01-current/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  263. package/tests/fixtures/project-adapter-upgrade-chains/broken-compatibility-chain/01-current/.coding-agent/skills.json +27 -0
  264. package/tests/fixtures/project-adapter-upgrade-chains/broken-compatibility-chain/02-incompatible/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  265. package/tests/fixtures/project-adapter-upgrade-chains/broken-compatibility-chain/02-incompatible/.coding-agent/skills.json +27 -0
  266. package/tests/fixtures/project-adapter-upgrade-chains/broken-compatibility-chain/03-target/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  267. package/tests/fixtures/project-adapter-upgrade-chains/broken-compatibility-chain/03-target/.coding-agent/skills.json +27 -0
  268. package/tests/fixtures/project-adapter-upgrade-chains/schema-drift-chain/01-current/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  269. package/tests/fixtures/project-adapter-upgrade-chains/schema-drift-chain/01-current/.coding-agent/skills.json +27 -0
  270. package/tests/fixtures/project-adapter-upgrade-chains/schema-drift-chain/02-schema-drift/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  271. package/tests/fixtures/project-adapter-upgrade-chains/schema-drift-chain/02-schema-drift/.coding-agent/skills.json +27 -0
  272. package/tests/fixtures/project-adapter-upgrade-chains/skill-drift-chain/01-current/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  273. package/tests/fixtures/project-adapter-upgrade-chains/skill-drift-chain/01-current/.coding-agent/skills.json +27 -0
  274. package/tests/fixtures/project-adapter-upgrade-chains/skill-drift-chain/02-skill-drift/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  275. package/tests/fixtures/project-adapter-upgrade-chains/skill-drift-chain/02-skill-drift/.coding-agent/skills.json +27 -0
  276. package/tests/fixtures/project-adapter-upgrade-chains/stale-pin-chain/01-current/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  277. package/tests/fixtures/project-adapter-upgrade-chains/stale-pin-chain/01-current/.coding-agent/skills.json +27 -0
  278. package/tests/fixtures/project-adapter-upgrade-chains/stale-pin-chain/02-stale/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  279. package/tests/fixtures/project-adapter-upgrade-chains/stale-pin-chain/02-stale/.coding-agent/skills.json +27 -0
  280. package/tests/fixtures/project-adapter-upgrade-chains/stale-pin-chain/03-target/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  281. package/tests/fixtures/project-adapter-upgrade-chains/stale-pin-chain/03-target/.coding-agent/skills.json +27 -0
  282. package/tests/fixtures/project-adapter-upgrade-chains/unsafe-weakening-chain/01-current/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  283. package/tests/fixtures/project-adapter-upgrade-chains/unsafe-weakening-chain/01-current/.coding-agent/skills.json +27 -0
  284. package/tests/fixtures/project-adapter-upgrade-chains/unsafe-weakening-chain/02-safe/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  285. package/tests/fixtures/project-adapter-upgrade-chains/unsafe-weakening-chain/02-safe/.coding-agent/skills.json +27 -0
  286. package/tests/fixtures/project-adapter-upgrade-chains/unsafe-weakening-chain/03-weakens-restrictions/.coding-agent/adapters/fixture-chain-adapter/adapter.json +69 -0
  287. package/tests/fixtures/project-adapter-upgrade-chains/unsafe-weakening-chain/03-weakens-restrictions/.coding-agent/skills.json +27 -0
  288. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/01-current/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  289. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/01-current/.coding-agent/skills.json +27 -0
  290. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/02-upgrade/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  291. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/02-upgrade/.coding-agent/skills.json +27 -0
  292. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/03-upgrade/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  293. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/03-upgrade/.coding-agent/skills.json +27 -0
  294. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/04-upgrade/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  295. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/04-upgrade/.coding-agent/skills.json +27 -0
  296. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/05-upgrade/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  297. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/05-upgrade/.coding-agent/skills.json +27 -0
  298. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/06-upgrade/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  299. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/06-upgrade/.coding-agent/skills.json +27 -0
  300. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/07-upgrade/.coding-agent/adapters/fixture-chain-adapter/adapter.json +70 -0
  301. package/tests/fixtures/project-adapter-upgrade-chains/valid-chain/07-upgrade/.coding-agent/skills.json +27 -0
  302. package/tests/fixtures/project-adapter-upgrades/adapter-schema-drift/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  303. package/tests/fixtures/project-adapter-upgrades/adapter-schema-drift/after/.coding-agent/skills.json +27 -0
  304. package/tests/fixtures/project-adapter-upgrades/adapter-schema-drift/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  305. package/tests/fixtures/project-adapter-upgrades/adapter-schema-drift/before/.coding-agent/skills.json +27 -0
  306. package/tests/fixtures/project-adapter-upgrades/safe-upgrade-preserves-restrictions/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +71 -0
  307. package/tests/fixtures/project-adapter-upgrades/safe-upgrade-preserves-restrictions/after/.coding-agent/skills.json +27 -0
  308. package/tests/fixtures/project-adapter-upgrades/safe-upgrade-preserves-restrictions/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  309. package/tests/fixtures/project-adapter-upgrades/safe-upgrade-preserves-restrictions/before/.coding-agent/skills.json +27 -0
  310. package/tests/fixtures/project-adapter-upgrades/skill-compatibility-drift/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  311. package/tests/fixtures/project-adapter-upgrades/skill-compatibility-drift/after/.coding-agent/skills.json +27 -0
  312. package/tests/fixtures/project-adapter-upgrades/skill-compatibility-drift/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  313. package/tests/fixtures/project-adapter-upgrades/skill-compatibility-drift/before/.coding-agent/skills.json +27 -0
  314. package/tests/fixtures/project-adapter-upgrades/stale-compatible-range/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  315. package/tests/fixtures/project-adapter-upgrades/stale-compatible-range/after/.coding-agent/skills.json +27 -0
  316. package/tests/fixtures/project-adapter-upgrades/stale-compatible-range/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  317. package/tests/fixtures/project-adapter-upgrades/stale-compatible-range/before/.coding-agent/skills.json +27 -0
  318. package/tests/fixtures/project-adapter-upgrades/stale-exact-pin/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  319. package/tests/fixtures/project-adapter-upgrades/stale-exact-pin/after/.coding-agent/skills.json +27 -0
  320. package/tests/fixtures/project-adapter-upgrades/stale-exact-pin/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  321. package/tests/fixtures/project-adapter-upgrades/stale-exact-pin/before/.coding-agent/skills.json +27 -0
  322. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-mode-escalation/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  323. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-mode-escalation/after/.coding-agent/skills.json +27 -0
  324. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-mode-escalation/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  325. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-mode-escalation/before/.coding-agent/skills.json +27 -0
  326. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-removes-evidence/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +69 -0
  327. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-removes-evidence/after/.coding-agent/skills.json +27 -0
  328. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-removes-evidence/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  329. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-removes-evidence/before/.coding-agent/skills.json +27 -0
  330. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-weakens-restrictions/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +69 -0
  331. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-weakens-restrictions/after/.coding-agent/skills.json +27 -0
  332. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-weakens-restrictions/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  333. package/tests/fixtures/project-adapter-upgrades/unsafe-upgrade-weakens-restrictions/before/.coding-agent/skills.json +27 -0
  334. package/tests/fixtures/project-adapter-upgrades/unsupported-future-core/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  335. package/tests/fixtures/project-adapter-upgrades/unsupported-future-core/after/.coding-agent/skills.json +27 -0
  336. package/tests/fixtures/project-adapter-upgrades/unsupported-future-core/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  337. package/tests/fixtures/project-adapter-upgrades/unsupported-future-core/before/.coding-agent/skills.json +27 -0
  338. package/tests/fixtures/project-adapter-upgrades/unsupported-old-core/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  339. package/tests/fixtures/project-adapter-upgrades/unsupported-old-core/after/.coding-agent/skills.json +27 -0
  340. package/tests/fixtures/project-adapter-upgrades/unsupported-old-core/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  341. package/tests/fixtures/project-adapter-upgrades/unsupported-old-core/before/.coding-agent/skills.json +27 -0
  342. package/tests/fixtures/project-adapter-upgrades/valid-upgrade/after/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  343. package/tests/fixtures/project-adapter-upgrades/valid-upgrade/after/.coding-agent/skills.json +27 -0
  344. package/tests/fixtures/project-adapter-upgrades/valid-upgrade/before/.coding-agent/adapters/fixture-upgrade-adapter/adapter.json +70 -0
  345. package/tests/fixtures/project-adapter-upgrades/valid-upgrade/before/.coding-agent/skills.json +27 -0
  346. package/tests/fixtures/sample-repo/.env.example +1 -0
  347. package/tests/fixtures/sample-repo/README.md +4 -0
  348. package/tests/fixtures/sample-repo/docs/architecture.md +3 -0
  349. package/tests/fixtures/sample-repo/package.json +11 -0
  350. package/tests/fixtures/sample-repo/src/index.js +3 -0
  351. package/tests/fixtures/sample-repo/test/index.test.js +8 -0
  352. package/tests/fixtures/triggers/cases.json +101 -0
  353. package/tests/policy/README.md +16 -0
  354. package/tests/privacy/README.md +14 -0
  355. package/tests/safety/README.md +17 -0
  356. package/tests/trigger/README.md +11 -0
  357. package/work-ledger.md +159 -0
@@ -0,0 +1,276 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import { PILOT_VERSION } from "./pack-rules.mjs";
4
+
5
+ export const UPGRADE_EVIDENCE_CONTRACT_VERSION = "1.0.0";
6
+
7
+ const SUMMARY_BY_CODE = {
8
+ "adapter-schema-drift": "The adapter schema changed outside the supported contract.",
9
+ "adapter-set-drift": "The installed adapter set changed across revisions.",
10
+ "adapter-version-downgrade": "An adapter version moved backward.",
11
+ "adapter-version-drift": "An adapter version is incompatible or inconsistent.",
12
+ "after-project-invalid": "The proposed project revision did not validate.",
13
+ "before-project-invalid": "The source project revision did not validate.",
14
+ "chain-target-stale": "The final chain revision does not target the running core.",
15
+ "completion-override": "The revision attempted to redefine completion.",
16
+ "failure-suppression": "The revision attempted to suppress failures.",
17
+ "incompatible-core-chain": "Core versions do not form an adjacent compatible chain.",
18
+ "mode-escalation": "An audit-only skill was escalated.",
19
+ "path-traversal": "A revision or output path escaped its allowed boundary.",
20
+ "required-evidence-removal": "Required evidence was removed.",
21
+ "restriction-weakening": "Inherited restrictions were weakened.",
22
+ "scope-expansion": "Scope expanded without the required approval boundary.",
23
+ "secret-exposure": "Secret-like content was detected and withheld.",
24
+ "skill-compatibility-drift": "Skill compatibility changed incompatibly.",
25
+ "stale-compatible-range": "The compatible range does not represent the target core.",
26
+ "stale-exact-pin": "The exact core pin is stale.",
27
+ "unknown-skill-compatibility": "An unknown skill compatibility declaration was found.",
28
+ "unsupported-future-core": "A revision targets a core newer than the validator.",
29
+ "unsupported-old-core": "A revision is older than the supported upgrade source.",
30
+ };
31
+
32
+ function summaryForCode(code) {
33
+ return SUMMARY_BY_CODE[code] ?? "The validator reported an incompatible upgrade condition.";
34
+ }
35
+
36
+ function unique(values) {
37
+ return [...new Set(values)].sort();
38
+ }
39
+
40
+ function adapters(context) {
41
+ return context?.adapters ?? [];
42
+ }
43
+
44
+ function adapterIds(before, after) {
45
+ return unique([
46
+ ...adapters(before).map((adapter) => adapter.id),
47
+ ...adapters(after).map((adapter) => adapter.id),
48
+ ]);
49
+ }
50
+
51
+ function versions(context) {
52
+ return adapters(context).map((adapter) => ({
53
+ adapterId: adapter.id,
54
+ version: adapter.version,
55
+ }));
56
+ }
57
+
58
+ function skillIds(context) {
59
+ return unique(adapters(context).flatMap((adapter) => adapter.skillIds));
60
+ }
61
+
62
+ function compatibility(context) {
63
+ return adapters(context)
64
+ .flatMap((adapter) =>
65
+ adapter.skillCompatibility.map((skill) => ({
66
+ adapterId: adapter.id,
67
+ skillId: skill.id,
68
+ versions: [...skill.compatibleVersions],
69
+ mode: skill.declaredMode,
70
+ })),
71
+ )
72
+ .sort(
73
+ (left, right) =>
74
+ left.adapterId.localeCompare(right.adapterId) ||
75
+ left.skillId.localeCompare(right.skillId),
76
+ );
77
+ }
78
+
79
+ function approvals(before, after) {
80
+ return unique(
81
+ [...adapters(before), ...adapters(after)].flatMap(
82
+ (adapter) => adapter.approvalRequirements,
83
+ ),
84
+ );
85
+ }
86
+
87
+ function staleClassification(codes) {
88
+ if (codes.includes("stale-exact-pin")) return "stale-exact-pin";
89
+ if (codes.includes("stale-compatible-range")) return "stale-compatible-range";
90
+ if (codes.includes("chain-target-stale")) return "chain-target-stale";
91
+ return "none";
92
+ }
93
+
94
+ function pinResult(codes, before, after) {
95
+ if (!before?.versionPin || !after?.versionPin) return "unknown";
96
+ if (staleClassification(codes) !== "none") return "stale";
97
+ if (
98
+ codes.some((code) =>
99
+ [
100
+ "before-invalid-core-version",
101
+ "after-invalid-core-version",
102
+ "unsupported-old-core",
103
+ "unsupported-future-core",
104
+ "incompatible-core-chain",
105
+ ].includes(code),
106
+ )
107
+ ) {
108
+ return "invalid";
109
+ }
110
+ return "accepted";
111
+ }
112
+
113
+ function resultStatus(codes) {
114
+ return codes.length === 0 ? "pass" : "fail";
115
+ }
116
+
117
+ function restrictionCodes(codes) {
118
+ return codes.filter((code) =>
119
+ [
120
+ "restriction-weakening",
121
+ "mode-escalation",
122
+ "failure-suppression",
123
+ "completion-override",
124
+ "required-evidence-removal",
125
+ "secret-exposure",
126
+ "scope-expansion",
127
+ ].includes(code),
128
+ );
129
+ }
130
+
131
+ function evidenceBase(result, options) {
132
+ const before = result.context?.before ?? {
133
+ rootSummary: {
134
+ reference: "before",
135
+ declarationStatus: "unavailable",
136
+ validationStatus: "fail",
137
+ },
138
+ coreVersion: null,
139
+ versionPin: null,
140
+ adapterSchemaVersion: null,
141
+ adapters: [],
142
+ };
143
+ const after = result.context?.after ?? {
144
+ rootSummary: {
145
+ reference: "after",
146
+ declarationStatus: "unavailable",
147
+ validationStatus: "fail",
148
+ },
149
+ coreVersion: null,
150
+ versionPin: null,
151
+ adapterSchemaVersion: null,
152
+ adapters: [],
153
+ };
154
+ const codes = unique(result.codes ?? []);
155
+ const restrictions = restrictionCodes(codes);
156
+ const approvalRequirements = approvals(before, after);
157
+ const finalStatus = result.ok
158
+ ? approvalRequirements.length > 0
159
+ ? "warn"
160
+ : "pass"
161
+ : "fail";
162
+ const blockingFailures = codes.map((code) => ({
163
+ code,
164
+ summary: summaryForCode(code),
165
+ }));
166
+
167
+ return {
168
+ contractVersion: UPGRADE_EVIDENCE_CONTRACT_VERSION,
169
+ validator: {
170
+ name: options.validatorName,
171
+ version: PILOT_VERSION,
172
+ },
173
+ invocation: {
174
+ id: options.invocationId ?? `upgrade-${randomUUID()}`,
175
+ timestamp: options.timestamp ?? new Date().toISOString(),
176
+ },
177
+ beforeProject: before.rootSummary,
178
+ afterProject: after.rootSummary,
179
+ coreVersions: {
180
+ before: before.coreVersion,
181
+ after: after.coreVersion,
182
+ },
183
+ adapterIds: adapterIds(before, after),
184
+ adapterVersions: {
185
+ before: versions(before),
186
+ after: versions(after),
187
+ },
188
+ adapterSchemaVersions: {
189
+ before: before.adapterSchemaVersion,
190
+ after: after.adapterSchemaVersion,
191
+ },
192
+ supportedSkillIds: {
193
+ before: skillIds(before),
194
+ after: skillIds(after),
195
+ },
196
+ skillCompatibility: {
197
+ before: compatibility(before),
198
+ after: compatibility(after),
199
+ },
200
+ pinStatus: {
201
+ before: before.versionPin,
202
+ after: after.versionPin,
203
+ result: pinResult(codes, before, after),
204
+ staleClassification: staleClassification(codes),
205
+ },
206
+ compatibilityResult: {
207
+ result: resultStatus(codes),
208
+ codes,
209
+ },
210
+ restrictionInheritanceResult: {
211
+ result: resultStatus(restrictions),
212
+ codes: restrictions,
213
+ },
214
+ approvalRequirements,
215
+ detectedRisks: blockingFailures,
216
+ blockingFailures,
217
+ warnings: approvalRequirements.map((operation) => ({
218
+ code: "approval-required",
219
+ summary: `Named approval remains required for ${operation}.`,
220
+ })),
221
+ safeSummary: result.ok
222
+ ? approvalRequirements.length > 0
223
+ ? "The read-only compatibility check passed with named approvals still required."
224
+ : "The read-only compatibility check passed without applying changes."
225
+ : `The read-only compatibility check rejected ${codes.length} condition(s).`,
226
+ finalStatus,
227
+ confidence: {
228
+ level: result.context ? "high" : "low",
229
+ reason: result.context
230
+ ? "Both sanitized revision summaries and compatibility results were available."
231
+ : "One or more revision summaries were unavailable.",
232
+ },
233
+ changedState: {
234
+ changed: false,
235
+ summary:
236
+ "No project, adapter, Git, runtime, service, database, or remote state was changed.",
237
+ },
238
+ recommendedNextAction: result.ok
239
+ ? "Request human approval before adopting this upgrade in a real project."
240
+ : "Resolve every blocking failure and rerun the read-only validation.",
241
+ };
242
+ }
243
+
244
+ export function buildAdapterUpgradeEvidence(result, options = {}) {
245
+ const evidence = evidenceBase(result, {
246
+ ...options,
247
+ validatorName: "check-adapter-upgrade",
248
+ });
249
+ if (options.chainId) evidence.chainId = options.chainId;
250
+ if (Number.isInteger(options.chainStepIndex)) {
251
+ evidence.chainStepIndex = options.chainStepIndex;
252
+ }
253
+ return evidence;
254
+ }
255
+
256
+ export function buildAdapterChainEvidence(result, options = {}) {
257
+ const evidence = evidenceBase(result, {
258
+ ...options,
259
+ validatorName: "check-adapter-upgrade-chain",
260
+ });
261
+ evidence.chainId = options.chainId ?? `chain-${randomUUID()}`;
262
+ evidence.chainSummary = {
263
+ revisionCount: result.revisionCount,
264
+ transitionCount: result.transitionCount,
265
+ passedTransitions: result.passedTransitions,
266
+ failedTransitions: result.failedTransitions,
267
+ steps: result.transitions.map((transition) => ({
268
+ stepIndex: transition.stepIndex,
269
+ beforeRevision: `revision-${transition.stepIndex}`,
270
+ afterRevision: `revision-${transition.stepIndex + 1}`,
271
+ status: transition.ok ? "pass" : "fail",
272
+ codes: [...transition.codes],
273
+ })),
274
+ };
275
+ return evidence;
276
+ }
@@ -0,0 +1,8 @@
1
+ import { adapterRepoMapCliResult } from "./lib/adapter-repo-map.mjs";
2
+
3
+ const outcome = adapterRepoMapCliResult(process.argv[2]);
4
+ for (const line of outcome.lines) {
5
+ if (outcome.stream === "stdout") console.log(line);
6
+ else console.error(line);
7
+ }
8
+ process.exitCode = outcome.exitCode;
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { evidenceArchiveCliResult } from "./lib/evidence-bundle.mjs";
3
+
4
+ const args = process.argv.slice(2);
5
+ const bundleFile = args[0];
6
+ const json = args.includes("--json");
7
+
8
+ try {
9
+ const result = evidenceArchiveCliResult(bundleFile, { json });
10
+ for (const line of result.lines) {
11
+ if (result.stream === "stderr") console.error(line);
12
+ else console.log(line);
13
+ }
14
+ process.exit(result.exitCode);
15
+ } catch {
16
+ console.error("evidence archive report rendering failed safely");
17
+ process.exit(2);
18
+ }
@@ -0,0 +1,220 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ const SUPPORTED_FLAGS = [
7
+ "harness-hardening",
8
+ "docs-hardening",
9
+ "test-hardening",
10
+ "adapter-harness",
11
+ "evidence-harness",
12
+ "release-preflight",
13
+ "commit",
14
+ "tag",
15
+ "push",
16
+ ];
17
+ const BLOCKED_MILESTONE_PATTERNS = [
18
+ [/\b(?:add|create|implement)\b.*\bnew skills?\b/i, "new skills"],
19
+ [/\breal project adapters?\b/i, "real project adapters"],
20
+ [/\bmodify\b.*\breal project repositor/i, "real project repositories"],
21
+ [/\bdeploy(?:ment|s)?\b/i, "deployment"],
22
+ [/\bmigrations?\b/i, "migration"],
23
+ [/\b(?:service|process) mutation\b/i, "service or process mutation"],
24
+ [/\b(?:read|print|expose)\b.*\b(?:secret|credential|token)s?\b/i, "secret access"],
25
+ [/\bweaken\b.*\b(?:safety|restriction|policy|evidence)\b/i, "safety weakening"],
26
+ ];
27
+
28
+ function failClosed(message) {
29
+ console.error(`run-next refused: ${message}`);
30
+ process.exit(1);
31
+ }
32
+
33
+ function usage() {
34
+ return [
35
+ "usage: ./scripts/run-next --allow <permission>",
36
+ `supported permissions: ${SUPPORTED_FLAGS.join(", ")}`,
37
+ ].join("\n");
38
+ }
39
+
40
+ function parseArgs(argv) {
41
+ const allowed = new Set();
42
+ for (let index = 0; index < argv.length; index += 1) {
43
+ const value = argv[index];
44
+ if (value === "--help" || value === "-h") {
45
+ console.log(usage());
46
+ process.exit(0);
47
+ }
48
+ if (value !== "--allow") failClosed(`unknown argument ${value}`);
49
+ const permission = argv[index + 1];
50
+ if (!permission) failClosed("missing permission after --allow");
51
+ if (!SUPPORTED_FLAGS.includes(permission)) {
52
+ failClosed(`unknown permission ${permission}`);
53
+ }
54
+ allowed.add(permission);
55
+ index += 1;
56
+ }
57
+ if (allowed.size === 0) failClosed("at least one --allow flag is required");
58
+ return allowed;
59
+ }
60
+
61
+ function run(command, args, options = {}) {
62
+ const result = spawnSync(command, args, {
63
+ cwd: options.cwd,
64
+ encoding: "utf8",
65
+ stdio: options.capture ? "pipe" : "inherit",
66
+ });
67
+ if (result.error) failClosed(`${command} could not start`);
68
+ if (result.status !== 0) {
69
+ if (options.capture && result.stderr) process.stderr.write(result.stderr);
70
+ failClosed(`${command} ${args.join(" ")} failed`);
71
+ }
72
+ return options.capture ? result.stdout.trim() : "";
73
+ }
74
+
75
+ function readRequired(root, relativePath) {
76
+ const file = path.join(root, relativePath);
77
+ if (!fs.existsSync(file)) failClosed(`missing ${relativePath}`);
78
+ return fs.readFileSync(file, "utf8");
79
+ }
80
+
81
+ function latestTag(tags) {
82
+ const versions = tags
83
+ .split(/\r?\n/)
84
+ .map((tagName) => /^v(\d+)\.(\d+)\.(\d+)$/.exec(tagName))
85
+ .filter(Boolean)
86
+ .map((match) => ({
87
+ tag: match[0],
88
+ parts: match.slice(1).map(Number),
89
+ }))
90
+ .sort((left, right) => {
91
+ for (let index = 0; index < 3; index += 1) {
92
+ if (left.parts[index] !== right.parts[index]) {
93
+ return left.parts[index] - right.parts[index];
94
+ }
95
+ }
96
+ return 0;
97
+ });
98
+ return versions.at(-1)?.tag ?? "unknown";
99
+ }
100
+
101
+ function recommendedMilestone(ledger) {
102
+ const match = /^## Current Recommended Milestone\s+([\s\S]*?)(?:\n## |\s*$)/m.exec(
103
+ ledger,
104
+ );
105
+ const value = match?.[1]?.trim();
106
+ if (!value) failClosed("work-ledger.md does not declare a recommended milestone");
107
+ return value.replace(/\s+/g, " ");
108
+ }
109
+
110
+ function requiredPermissionFor(milestone) {
111
+ if (/evidence|replay|regression/i.test(milestone)) return "evidence-harness";
112
+ if (/adapter/i.test(milestone)) return "adapter-harness";
113
+ if (/test/i.test(milestone)) return "test-hardening";
114
+ if (/doc/i.test(milestone)) return "docs-hardening";
115
+ return "harness-hardening";
116
+ }
117
+
118
+ function blockedMilestoneReason(milestone) {
119
+ for (const [pattern, reason] of BLOCKED_MILESTONE_PATTERNS) {
120
+ if (pattern.test(milestone)) return reason;
121
+ }
122
+ return null;
123
+ }
124
+
125
+ function appendRunEvidence(root, entry) {
126
+ const runLog = path.join(root, "runs", "skill-runs.md");
127
+ const ledger = path.join(root, "work-ledger.md");
128
+ fs.appendFileSync(runLog, entry.runLog);
129
+ fs.appendFileSync(ledger, entry.ledger);
130
+ }
131
+
132
+ const allowed = parseArgs(process.argv.slice(2));
133
+ const initialRoot = run("git", ["rev-parse", "--show-toplevel"], {
134
+ cwd: process.cwd(),
135
+ capture: true,
136
+ });
137
+ const root = path.resolve(initialRoot);
138
+ process.chdir(root);
139
+
140
+ const status = run("git", ["status", "--short", "--branch"], {
141
+ cwd: root,
142
+ capture: true,
143
+ });
144
+ const dirty = status
145
+ .split(/\r?\n/)
146
+ .slice(1)
147
+ .some((line) => line.trim());
148
+ if (dirty) failClosed("working tree must be clean before run-next writes evidence");
149
+
150
+ const tags = run("git", ["tag", "--list"], { cwd: root, capture: true });
151
+ const latest = latestTag(tags);
152
+ const roadmap = readRequired(root, "ROADMAP.md");
153
+ const changelog = readRequired(root, "CHANGELOG.md");
154
+ const ledger = readRequired(root, "work-ledger.md");
155
+ if (!roadmap.includes("Roadmap")) failClosed("ROADMAP.md could not be recognized");
156
+ if (!changelog.includes("Changelog")) failClosed("CHANGELOG.md could not be recognized");
157
+
158
+ const milestone = recommendedMilestone(ledger);
159
+ const blockedReason = blockedMilestoneReason(milestone);
160
+ if (blockedReason) {
161
+ failClosed(`ledger milestone is out of scope: ${blockedReason}`);
162
+ }
163
+ const requiredPermission = requiredPermissionFor(milestone);
164
+ if (!allowed.has(requiredPermission)) {
165
+ failClosed(`next action requires --allow ${requiredPermission}`);
166
+ }
167
+
168
+ const validationCommands = [
169
+ ["node", ["scripts/validate-pack.mjs", "."]],
170
+ ["node", ["scripts/test-pack.mjs"]],
171
+ ["node", ["scripts/validate-maintainer-loop.mjs", "."]],
172
+ ["node", ["--test"]],
173
+ ];
174
+ for (const [command, args] of validationCommands) run(command, args, { cwd: root });
175
+
176
+ const timestamp = new Date().toISOString();
177
+ const runId = `run-${timestamp.replace(/[-:.TZ]/g, "").slice(0, 14)}`;
178
+ const permissions = [...allowed].sort().join(", ");
179
+ const commandUsed = `./scripts/run-next ${[...allowed]
180
+ .sort()
181
+ .map((permission) => `--allow ${permission}`)
182
+ .join(" ")}`;
183
+ const validationList = validationCommands
184
+ .map(([command, args]) => ` - \`${command} ${args.join(" ")}\``)
185
+ .join("\n");
186
+
187
+ appendRunEvidence(root, {
188
+ runLog: `
189
+
190
+ ## ${runId}
191
+
192
+ - Run ID: \`${runId}\`
193
+ - Timestamp: \`${timestamp}\`
194
+ - Command used: \`${commandUsed}\`
195
+ - Permissions granted: \`${permissions}\`
196
+ - Files changed: \`runs/skill-runs.md\`, \`work-ledger.md\`
197
+ - Validation commands:
198
+ ${validationList}
199
+ - Validation result: pass
200
+ - Commit/tag/push status: not performed by runner
201
+ - Next state: selected \`${milestone}\`; human approval required before implementation
202
+ `,
203
+ ledger: `
204
+
205
+ ### ${timestamp}
206
+
207
+ - Latest tag observed: \`${latest}\`
208
+ - Selected milestone: ${milestone}
209
+ - Required permission: \`${requiredPermission}\`
210
+ - Validation result: pass
211
+ - Stop boundary: implementation requires human approval
212
+ `,
213
+ });
214
+
215
+ console.log("run-next complete");
216
+ console.log(`latest tag: ${latest}`);
217
+ console.log(`selected milestone: ${milestone}`);
218
+ console.log(`required permission: ${requiredPermission}`);
219
+ console.log("validation result: pass");
220
+ console.log("next state: human approval required before implementation");