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,950 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ import { checkAdapterUpgrade } from "./lib/adapter-upgrade.mjs";
5
+ import { checkAdapterUpgradeChain } from "./lib/adapter-upgrade-chain.mjs";
6
+ import { validateExternalAdapters } from "./lib/adapter-discovery.mjs";
7
+ import {
8
+ buildEvidenceArchiveReport,
9
+ verifyEvidenceBundle,
10
+ } from "./lib/evidence-bundle.mjs";
11
+ import {
12
+ adapterIssues,
13
+ AUDIT_ONLY_SKILLS,
14
+ auditOnlyDocumentIssues,
15
+ completionIssues,
16
+ detectSensitiveValues,
17
+ PILOT_SKILLS,
18
+ PILOT_VERSION,
19
+ RESTRICTED_CATEGORIES,
20
+ restrictedShellReason,
21
+ } from "./lib/pack-rules.mjs";
22
+ import { validateProjectAdapters } from "./lib/project-adapter-installation.mjs";
23
+ import { validateValue } from "./lib/schema-validator.mjs";
24
+
25
+ const root = path.resolve(process.argv[2] ?? ".");
26
+ const failures = [];
27
+ const skillFiles = [
28
+ "SKILL.md",
29
+ "checklist.md",
30
+ "examples.md",
31
+ "failure-modes.md",
32
+ "adapter-interface.md",
33
+ "evidence-template.md",
34
+ "agents/openai.yaml",
35
+ ];
36
+ const requiredSkillHeadings = [
37
+ "Purpose And Use",
38
+ "Inputs",
39
+ "Procedure",
40
+ "Evidence, Recovery, And Dependencies",
41
+ "Approval Boundary",
42
+ "Completion",
43
+ ];
44
+ const requiredRootFiles = [
45
+ "AGENTS.md",
46
+ "README.md",
47
+ "RUNBOOK.md",
48
+ "CHANGELOG.md",
49
+ "ROADMAP.md",
50
+ "CONTRIBUTING.md",
51
+ "LICENSE",
52
+ "package.json",
53
+ "bin/coding-agent-skills",
54
+ "work-ledger.md",
55
+ "runs/skill-runs.md",
56
+ "docs/architecture/README.md",
57
+ "docs/authoring/README.md",
58
+ "docs/safety/README.md",
59
+ "docs/versioning/README.md",
60
+ "docs/privacy/README.md",
61
+ "docs/adapters/README.md",
62
+ "docs/adapters/discovery.md",
63
+ "docs/adapters/external-adapters.md",
64
+ "docs/adapters/project-installation.md",
65
+ "docs/adapters/upgrades.md",
66
+ "docs/adapters/upgrade-evidence.md",
67
+ "docs/evidence-bundles/README.md",
68
+ "docs/versioning/adapter-compatibility.md",
69
+ "docs/usage/README.md",
70
+ "docs/release/README.md",
71
+ "docs/release/npm-package.md",
72
+ "docs/testing/README.md",
73
+ "contracts/evidence-pack/README.md",
74
+ "contracts/evidence-pack/evidence-pack.schema.json",
75
+ "contracts/evidence-pack/evidence-pack.example.json",
76
+ "schemas/skill-manifest.schema.json",
77
+ "schemas/command-policy.schema.json",
78
+ "schemas/project-adapter.schema.json",
79
+ "schemas/project-adapter-installation.schema.json",
80
+ "schemas/adapter-upgrade-evidence.schema.json",
81
+ "schemas/evidence-bundle.schema.json",
82
+ "schemas/archive-report.schema.json",
83
+ "schemas/archive-index.schema.json",
84
+ "examples/upgrade-evidence/README.md",
85
+ "examples/upgrade-evidence/valid-upgrade.evidence.json",
86
+ "examples/upgrade-evidence/stale-pin.evidence.json",
87
+ "examples/upgrade-evidence/unsafe-upgrade.evidence.json",
88
+ "examples/upgrade-evidence/chain-pass.evidence.json",
89
+ "examples/upgrade-evidence/chain-fail.evidence.json",
90
+ "examples/upgrade-evidence/valid-upgrade.evidence.md",
91
+ "examples/upgrade-evidence/chain-fail.evidence.md",
92
+ "scripts/test-pack.mjs",
93
+ "scripts/run-next",
94
+ "scripts/validate-maintainer-loop.mjs",
95
+ "scripts/verify-evidence-bundle.mjs",
96
+ "scripts/render-evidence-archive-report.mjs",
97
+ "scripts/render-adapter-repo-map.mjs",
98
+ "scripts/check-adapter-upgrade.mjs",
99
+ "scripts/check-adapter-upgrade-chain.mjs",
100
+ "scripts/validate-adapters.mjs",
101
+ "scripts/validate-project-adapters.mjs",
102
+ "scripts/lib/adapter-repo-map.mjs",
103
+ "scripts/lib/adapter-upgrade.mjs",
104
+ "scripts/lib/adapter-upgrade-chain.mjs",
105
+ "scripts/lib/adapter-discovery.mjs",
106
+ "scripts/lib/project-adapter-installation.mjs",
107
+ "scripts/lib/semver.mjs",
108
+ "scripts/lib/schema-validator.mjs",
109
+ "scripts/lib/pack-rules.mjs",
110
+ "scripts/lib/safe-evidence-output.mjs",
111
+ "scripts/lib/upgrade-evidence.mjs",
112
+ "scripts/lib/evidence-bundle.mjs",
113
+ "tests/README.md",
114
+ "tests/fixtures/README.md",
115
+ "tests/safety/README.md",
116
+ "tests/evidence/README.md",
117
+ "tests/fixtures/triggers/cases.json",
118
+ "tests/fixtures/policy/commands.json",
119
+ "tests/fixtures/policy/properties.json",
120
+ "tests/fixtures/mutation/cases.json",
121
+ "tests/fixtures/privacy/cases.json",
122
+ "tests/fixtures/completion/cases.json",
123
+ "tests/fixtures/adapters/valid-narrowing.json",
124
+ "tests/fixtures/adapters/allow-deploy.json",
125
+ "tests/fixtures/adapters/allow-git-push.json",
126
+ "tests/fixtures/adapters/suppress-failures.json",
127
+ "tests/fixtures/adapters/redefine-completion.json",
128
+ "tests/fixtures/adapters/expose-secrets.json",
129
+ "tests/fixtures/adapters/override-audit-only.json",
130
+ "tests/fixtures/adapters/weakening-repo-map.json",
131
+ "tests/fixtures/adapters/incompatible-version.json",
132
+ "tests/fixtures/adapters/remove-required-evidence.json",
133
+ "tests/fixtures/adapters/expand-scope.json",
134
+ "tests/fixtures/external-adapters/valid-basic/.coding-agent/adapters/basic/adapter.json",
135
+ "tests/fixtures/external-adapters/valid-doc-precedence/coding-agent/adapters/docs/adapter.json",
136
+ "tests/fixtures/external-adapters/valid-runtime-status/adapters/coding-agent/runtime/adapter.json",
137
+ "tests/fixtures/external-adapters/invalid-deploy/.coding-agent/adapters/deploy/adapter.json",
138
+ "tests/fixtures/external-adapters/invalid-git-push/.coding-agent/adapters/publish/adapter.json",
139
+ "tests/fixtures/external-adapters/invalid-path-traversal/.coding-agent/adapters/path/adapter.json",
140
+ "tests/fixtures/project-adapter-installation/valid-exact-pin/.coding-agent/skills.json",
141
+ "tests/fixtures/project-adapter-installation/valid-exact-pin/.coding-agent/adapters/basic/adapter.json",
142
+ "tests/fixtures/evidence-bundles/valid-bundle/evidence-bundle.json",
143
+ "tests/fixtures/evidence-bundles/valid-bundle/evidence/repo-map.evidence.json",
144
+ "tests/fixtures/evidence-bundles/valid-bundle/evidence/valid-upgrade.evidence.json",
145
+ "tests/fixtures/evidence-bundles/valid-bundle/archive/evidence-archive-index.json",
146
+ "tests/fixtures/evidence-bundles/advisory-review-soon/evidence-bundle.json",
147
+ "tests/fixtures/evidence-bundles/invalid-archive-index/evidence-bundle.json",
148
+ "tests/fixtures/evidence-bundles/invalid-signature-plan/evidence-bundle.json",
149
+ "tests/fixtures/project-adapter-installation/valid-compatible-range/coding-agent.skills.json",
150
+ "tests/fixtures/project-adapter-installation/valid-multiple-adapters/.coding-agent/skills.json",
151
+ "tests/fixtures/project-adapter-installation/invalid-missing-declaration/.coding-agent/adapters/basic/adapter.json",
152
+ "tests/fixtures/project-adapter-installation/invalid-unsupported-core-version/.coding-agent/skills.json",
153
+ "tests/fixtures/project-adapter-installation/invalid-bad-semver/.coding-agent/skills.json",
154
+ "tests/fixtures/project-adapter-installation/invalid-unknown-skill/.coding-agent/skills.json",
155
+ "tests/fixtures/project-adapter-installation/invalid-adapter-version-mismatch/.coding-agent/skills.json",
156
+ "tests/fixtures/project-adapter-installation/invalid-adapter-schema-version/.coding-agent/skills.json",
157
+ "tests/fixtures/project-adapter-installation/invalid-adapter-location/.coding-agent/skills.json",
158
+ "tests/fixtures/project-adapter-installation/invalid-skill-mismatch/.coding-agent/skills.json",
159
+ "tests/fixtures/project-adapter-installation/invalid-mode-escalation/.coding-agent/skills.json",
160
+ "tests/fixtures/project-adapter-installation/invalid-failure-suppression/.coding-agent/skills.json",
161
+ "tests/fixtures/project-adapter-installation/invalid-completion-override/.coding-agent/skills.json",
162
+ "tests/fixtures/project-adapter-installation/invalid-weakens-restrictions/.coding-agent/skills.json",
163
+ "tests/fixtures/project-adapter-installation/invalid-secret-exposure/.coding-agent/skills.json",
164
+ "tests/fixtures/project-adapter-installation/invalid-scope-expansion/.coding-agent/skills.json",
165
+ "tests/fixtures/project-adapter-installation/invalid-path-traversal/.coding-agent/skills.json",
166
+ "tests/fixtures/mutation/snapshot-target/README.md",
167
+ "tests/fixtures/mutation/snapshot-target/state.json",
168
+ "examples/README.md",
169
+ "examples/adapters/README.md",
170
+ "examples/adapters/narrow-repo-map.json",
171
+ "examples/adapters/documentation-precedence.json",
172
+ "examples/adapters/runtime-status-hints.json",
173
+ ];
174
+ const sourceCheckoutFiles = [".gitignore", ".github/workflows/validate.yml"];
175
+ const upgradeFixtures = [
176
+ "valid-upgrade",
177
+ "stale-exact-pin",
178
+ "stale-compatible-range",
179
+ "unsupported-future-core",
180
+ "unsupported-old-core",
181
+ "adapter-schema-drift",
182
+ "skill-compatibility-drift",
183
+ "unsafe-upgrade-weakens-restrictions",
184
+ "unsafe-upgrade-mode-escalation",
185
+ "unsafe-upgrade-removes-evidence",
186
+ "safe-upgrade-preserves-restrictions",
187
+ ];
188
+ const chainFixtures = {
189
+ valid: ["valid-chain"],
190
+ invalid: [
191
+ "stale-pin-chain",
192
+ "broken-compatibility-chain",
193
+ "unsafe-weakening-chain",
194
+ "schema-drift-chain",
195
+ "skill-drift-chain",
196
+ ],
197
+ };
198
+
199
+ function read(relativePath) {
200
+ return fs.readFileSync(path.join(root, relativePath), "utf8");
201
+ }
202
+
203
+ function readJson(relativePath) {
204
+ try {
205
+ return JSON.parse(read(relativePath));
206
+ } catch (error) {
207
+ failures.push(`${relativePath}: ${error.message}`);
208
+ return null;
209
+ }
210
+ }
211
+
212
+ function walk(directory, output = []) {
213
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
214
+ if ([".git", "node_modules", "validation-output"].includes(entry.name)) continue;
215
+ const target = path.join(directory, entry.name);
216
+ if (entry.isDirectory()) walk(target, output);
217
+ else output.push(target);
218
+ }
219
+ return output;
220
+ }
221
+
222
+ const sourceCheckoutMode = fs.existsSync(path.join(root, ".gitignore"));
223
+ const packageInstalledMode =
224
+ !sourceCheckoutMode &&
225
+ fs.existsSync(path.join(root, "package.json")) &&
226
+ !fs.existsSync(path.join(root, ".git"));
227
+
228
+ if (sourceCheckoutMode) {
229
+ for (const file of sourceCheckoutFiles) {
230
+ if (!fs.existsSync(path.join(root, file))) failures.push(`missing ${file}`);
231
+ }
232
+ } else if (!packageInstalledMode) {
233
+ failures.push("missing .gitignore outside package-installed tree");
234
+ }
235
+
236
+ for (const file of requiredRootFiles) {
237
+ if (!fs.existsSync(path.join(root, file))) failures.push(`missing ${file}`);
238
+ }
239
+ for (const fixture of upgradeFixtures) {
240
+ for (const revision of ["before", "after"]) {
241
+ for (const relative of [
242
+ ".coding-agent/skills.json",
243
+ ".coding-agent/adapters/fixture-upgrade-adapter/adapter.json",
244
+ ]) {
245
+ const file = path.join(
246
+ "tests",
247
+ "fixtures",
248
+ "project-adapter-upgrades",
249
+ fixture,
250
+ revision,
251
+ relative,
252
+ );
253
+ if (!fs.existsSync(path.join(root, file))) failures.push(`missing ${file}`);
254
+ }
255
+ }
256
+ }
257
+ for (const fixture of [...chainFixtures.valid, ...chainFixtures.invalid]) {
258
+ const fixtureRoot = path.join(
259
+ root,
260
+ "tests",
261
+ "fixtures",
262
+ "project-adapter-upgrade-chains",
263
+ fixture,
264
+ );
265
+ if (!fs.existsSync(fixtureRoot)) failures.push(`missing chain fixture ${fixture}`);
266
+ }
267
+
268
+ const actualSkillFolders = fs
269
+ .readdirSync(path.join(root, "skills"), { withFileTypes: true })
270
+ .filter((entry) => entry.isDirectory())
271
+ .map((entry) => entry.name)
272
+ .sort();
273
+ if (JSON.stringify(actualSkillFolders) !== JSON.stringify([...PILOT_SKILLS].sort())) {
274
+ failures.push(`unexpected skill folders: ${actualSkillFolders.join(", ")}`);
275
+ }
276
+
277
+ for (const skill of PILOT_SKILLS) {
278
+ for (const file of skillFiles) {
279
+ const target = path.join(root, "skills", skill, file);
280
+ if (!fs.existsSync(target)) failures.push(`missing ${path.relative(root, target)}`);
281
+ }
282
+
283
+ for (const file of [
284
+ `examples/manifests/${skill}.json`,
285
+ `examples/command-policies/${skill}.json`,
286
+ `examples/evidence-packs/${skill}.json`,
287
+ `examples/workflows/${skill}.md`,
288
+ ]) {
289
+ if (!fs.existsSync(path.join(root, file))) failures.push(`missing ${file}`);
290
+ }
291
+
292
+ const skillText = read(`skills/${skill}/SKILL.md`);
293
+ if (!skillText.startsWith("---\nname:")) failures.push(`${skill}: invalid frontmatter`);
294
+ if (new RegExp(`\\b${"TO" + "DO"}\\b`).test(skillText)) {
295
+ failures.push(`${skill}: contains unfinished placeholder`);
296
+ }
297
+ for (const heading of requiredSkillHeadings) {
298
+ if (!skillText.includes(`## ${heading}`)) failures.push(`${skill}: missing ${heading}`);
299
+ }
300
+
301
+ const metadata = read(`skills/${skill}/agents/openai.yaml`);
302
+ for (const key of ["display_name:", "short_description:", "default_prompt:"]) {
303
+ if (!metadata.includes(key)) failures.push(`${skill}: agents/openai.yaml missing ${key}`);
304
+ }
305
+ }
306
+
307
+ for (const fixture of [
308
+ "valid-basic",
309
+ "valid-doc-precedence",
310
+ "valid-runtime-status",
311
+ ]) {
312
+ const result = validateExternalAdapters(
313
+ path.join(root, "tests", "fixtures", "external-adapters", fixture),
314
+ { coreRoot: root },
315
+ );
316
+ if (!result.ok || result.accepted.length !== 1) {
317
+ failures.push(`${fixture}: valid external adapter root was rejected`);
318
+ }
319
+ }
320
+
321
+ for (const fixture of ["valid-upgrade", "safe-upgrade-preserves-restrictions"]) {
322
+ const fixtureRoot = path.join(
323
+ root,
324
+ "tests",
325
+ "fixtures",
326
+ "project-adapter-upgrades",
327
+ fixture,
328
+ );
329
+ const result = checkAdapterUpgrade(
330
+ path.join(fixtureRoot, "before"),
331
+ path.join(fixtureRoot, "after"),
332
+ { coreRoot: root },
333
+ );
334
+ if (!result.ok) failures.push(`${fixture}: safe adapter upgrade was rejected`);
335
+ }
336
+
337
+ for (const fixture of [
338
+ "stale-exact-pin",
339
+ "stale-compatible-range",
340
+ "unsupported-future-core",
341
+ "unsupported-old-core",
342
+ "adapter-schema-drift",
343
+ "skill-compatibility-drift",
344
+ "unsafe-upgrade-weakens-restrictions",
345
+ "unsafe-upgrade-mode-escalation",
346
+ "unsafe-upgrade-removes-evidence",
347
+ ]) {
348
+ const fixtureRoot = path.join(
349
+ root,
350
+ "tests",
351
+ "fixtures",
352
+ "project-adapter-upgrades",
353
+ fixture,
354
+ );
355
+ const result = checkAdapterUpgrade(
356
+ path.join(fixtureRoot, "before"),
357
+ path.join(fixtureRoot, "after"),
358
+ { coreRoot: root },
359
+ );
360
+ if (result.ok) failures.push(`${fixture}: unsafe adapter upgrade was accepted`);
361
+ }
362
+
363
+ for (const fixture of chainFixtures.valid) {
364
+ const result = checkAdapterUpgradeChain(
365
+ path.join(root, "tests", "fixtures", "project-adapter-upgrade-chains", fixture),
366
+ { coreRoot: root },
367
+ );
368
+ if (!result.ok) failures.push(`${fixture}: safe adapter chain was rejected`);
369
+ }
370
+ for (const fixture of chainFixtures.invalid) {
371
+ const result = checkAdapterUpgradeChain(
372
+ path.join(root, "tests", "fixtures", "project-adapter-upgrade-chains", fixture),
373
+ { coreRoot: root },
374
+ );
375
+ if (result.ok) failures.push(`${fixture}: unsafe adapter chain was accepted`);
376
+ }
377
+
378
+ for (const fixture of [
379
+ "invalid-deploy",
380
+ "invalid-git-push",
381
+ "invalid-secret-exposure",
382
+ "invalid-mode-escalation",
383
+ "invalid-failure-suppression",
384
+ "invalid-completion-override",
385
+ "invalid-scope-expansion",
386
+ "invalid-version",
387
+ "invalid-skill-id",
388
+ "invalid-skill-version",
389
+ "invalid-path-traversal",
390
+ "invalid-restriction-removal",
391
+ "invalid-evidence-suppression",
392
+ "invalid-malformed",
393
+ "invalid-unknown-manifest",
394
+ "mixed",
395
+ ]) {
396
+ const result = validateExternalAdapters(
397
+ path.join(root, "tests", "fixtures", "external-adapters", fixture),
398
+ { coreRoot: root },
399
+ );
400
+ if (result.ok) {
401
+ failures.push(`${fixture}: invalid external adapter root was accepted`);
402
+ }
403
+ }
404
+
405
+ for (const fixture of [
406
+ "valid-exact-pin",
407
+ "valid-compatible-range",
408
+ "valid-multiple-adapters",
409
+ ]) {
410
+ const result = validateProjectAdapters(
411
+ path.join(root, "tests", "fixtures", "project-adapter-installation", fixture),
412
+ { coreRoot: root },
413
+ );
414
+ if (!result.ok) {
415
+ failures.push(`${fixture}: valid project adapter installation was rejected`);
416
+ }
417
+ }
418
+
419
+ for (const fixture of [
420
+ "invalid-missing-declaration",
421
+ "invalid-unsupported-core-version",
422
+ "invalid-bad-semver",
423
+ "invalid-unknown-skill",
424
+ "invalid-adapter-version-mismatch",
425
+ "invalid-adapter-schema-version",
426
+ "invalid-adapter-location",
427
+ "invalid-skill-mismatch",
428
+ "invalid-mode-escalation",
429
+ "invalid-failure-suppression",
430
+ "invalid-completion-override",
431
+ "invalid-weakens-restrictions",
432
+ "invalid-secret-exposure",
433
+ "invalid-scope-expansion",
434
+ "invalid-path-traversal",
435
+ ]) {
436
+ const result = validateProjectAdapters(
437
+ path.join(root, "tests", "fixtures", "project-adapter-installation", fixture),
438
+ { coreRoot: root },
439
+ );
440
+ if (result.ok) {
441
+ failures.push(`${fixture}: invalid project adapter installation was accepted`);
442
+ }
443
+ }
444
+
445
+ const manifestSchema = readJson("schemas/skill-manifest.schema.json");
446
+ const policySchema = readJson("schemas/command-policy.schema.json");
447
+ const adapterSchema = readJson("schemas/project-adapter.schema.json");
448
+ const projectInstallationSchema = readJson(
449
+ "schemas/project-adapter-installation.schema.json",
450
+ );
451
+ const evidenceSchema = readJson("contracts/evidence-pack/evidence-pack.schema.json");
452
+ const upgradeEvidenceSchema = readJson(
453
+ "schemas/adapter-upgrade-evidence.schema.json",
454
+ );
455
+ const evidenceBundleSchema = readJson("schemas/evidence-bundle.schema.json");
456
+ const evidenceArchiveReportSchema = readJson("schemas/archive-report.schema.json");
457
+ const evidenceArchiveIndexSchema = readJson("schemas/archive-index.schema.json");
458
+
459
+ if (
460
+ manifestSchema &&
461
+ policySchema &&
462
+ adapterSchema &&
463
+ projectInstallationSchema &&
464
+ evidenceSchema &&
465
+ upgradeEvidenceSchema &&
466
+ evidenceBundleSchema &&
467
+ evidenceArchiveReportSchema &&
468
+ evidenceArchiveIndexSchema
469
+ ) {
470
+ const policiesBySkill = Object.fromEntries(
471
+ PILOT_SKILLS.map((skill) => [
472
+ skill,
473
+ readJson(`examples/command-policies/${skill}.json`),
474
+ ]),
475
+ );
476
+ for (const skill of PILOT_SKILLS) {
477
+ const records = [
478
+ [
479
+ `examples/manifests/${skill}.json`,
480
+ manifestSchema,
481
+ ],
482
+ [
483
+ `examples/command-policies/${skill}.json`,
484
+ policySchema,
485
+ ],
486
+ [
487
+ `examples/evidence-packs/${skill}.json`,
488
+ evidenceSchema,
489
+ ],
490
+ ];
491
+
492
+ for (const [file, schema] of records) {
493
+ const value = readJson(file);
494
+ if (!value) continue;
495
+ for (const error of validateValue(schema, value)) failures.push(`${file}: ${error}`);
496
+ }
497
+
498
+ const manifest = readJson(`examples/manifests/${skill}.json`);
499
+ const policy = readJson(`examples/command-policies/${skill}.json`);
500
+ const evidence = readJson(`examples/evidence-packs/${skill}.json`);
501
+ if (!manifest || !policy || !evidence) continue;
502
+
503
+ if (manifest.name !== skill) failures.push(`${skill}: manifest name mismatch`);
504
+ if (manifest.version !== PILOT_VERSION) failures.push(`${skill}: stale manifest version`);
505
+ if (policy.version !== PILOT_VERSION) failures.push(`${skill}: stale policy version`);
506
+ if (manifest.mode !== policy.mode) failures.push(`${skill}: manifest/policy mode mismatch`);
507
+ if (manifest.adapterCompatibility?.contractVersion !== "1.0.0") {
508
+ failures.push(`${skill}: adapter contract version mismatch`);
509
+ }
510
+ if (!manifest.adapterCompatibility?.compatibleAdapterVersions?.includes("1.0.0")) {
511
+ failures.push(`${skill}: adapter version compatibility missing`);
512
+ }
513
+ if (evidence.skill.name !== skill) failures.push(`${skill}: evidence skill mismatch`);
514
+ if (evidence.skill.version !== PILOT_VERSION) {
515
+ failures.push(`${skill}: stale evidence example version`);
516
+ }
517
+ if (evidence.skill.version !== manifest.version) {
518
+ failures.push(`${skill}: evidence/manifest version mismatch`);
519
+ }
520
+
521
+ const restrictions = new Set(policy.restrictedCategories);
522
+ for (const category of RESTRICTED_CATEGORIES) {
523
+ if (!restrictions.has(category)) {
524
+ failures.push(`${skill}: command policy omits ${category}`);
525
+ }
526
+ }
527
+ for (const invariant of [
528
+ "inspectEverySegment",
529
+ "inspectScriptBodies",
530
+ "rejectUnknownExecutables",
531
+ "rejectShellWrappers",
532
+ "rejectHeredocs",
533
+ "rejectRedirection",
534
+ "providerSpecificNpx",
535
+ "authenticatedCurlRequiresApproval",
536
+ "boundedReadsRequired",
537
+ ]) {
538
+ if (policy.parserPolicy?.[invariant] !== true) {
539
+ failures.push(`${skill}: command parser invariant disabled: ${invariant}`);
540
+ }
541
+ }
542
+ for (const family of policy.allowedFamilies ?? []) {
543
+ if (!family.argumentPolicy?.allowedPatterns?.length) {
544
+ failures.push(`${skill}: ${family.name} has no allowed argument patterns`);
545
+ }
546
+ if (!family.argumentPolicy?.deniedPatterns?.length) {
547
+ failures.push(`${skill}: ${family.name} has no denied argument patterns`);
548
+ }
549
+ }
550
+ for (const issue of completionIssues(evidence)) {
551
+ failures.push(`${skill}: ${issue}`);
552
+ }
553
+ }
554
+
555
+ for (const file of [
556
+ "examples/adapters/narrow-repo-map.json",
557
+ "examples/adapters/documentation-precedence.json",
558
+ "examples/adapters/runtime-status-hints.json",
559
+ ]) {
560
+ const adapter = readJson(file);
561
+ if (!adapter) continue;
562
+ for (const error of validateValue(adapterSchema, adapter)) {
563
+ failures.push(`${file}: ${error}`);
564
+ }
565
+ for (const error of adapterIssues(adapter, { policies: policiesBySkill })) {
566
+ failures.push(`${file}: ${error}`);
567
+ }
568
+ }
569
+
570
+ for (const file of [
571
+ "tests/fixtures/adapters/allow-deploy.json",
572
+ "tests/fixtures/adapters/allow-git-push.json",
573
+ "tests/fixtures/adapters/suppress-failures.json",
574
+ "tests/fixtures/adapters/redefine-completion.json",
575
+ "tests/fixtures/adapters/expose-secrets.json",
576
+ "tests/fixtures/adapters/override-audit-only.json",
577
+ "tests/fixtures/adapters/weakening-repo-map.json",
578
+ "tests/fixtures/adapters/incompatible-version.json",
579
+ "tests/fixtures/adapters/remove-required-evidence.json",
580
+ "tests/fixtures/adapters/expand-scope.json",
581
+ ]) {
582
+ const adapter = readJson(file);
583
+ if (!adapter) continue;
584
+ const rejectionReasons = [
585
+ ...validateValue(adapterSchema, adapter),
586
+ ...adapterIssues(adapter, { policies: policiesBySkill }),
587
+ ];
588
+ if (rejectionReasons.length === 0) {
589
+ failures.push(`${file}: invalid adapter fixture was accepted`);
590
+ }
591
+ }
592
+
593
+ for (const file of [
594
+ "examples/upgrade-evidence/valid-upgrade.evidence.json",
595
+ "examples/upgrade-evidence/stale-pin.evidence.json",
596
+ "examples/upgrade-evidence/unsafe-upgrade.evidence.json",
597
+ "examples/upgrade-evidence/chain-pass.evidence.json",
598
+ "examples/upgrade-evidence/chain-fail.evidence.json",
599
+ ]) {
600
+ const evidence = readJson(file);
601
+ if (!evidence) continue;
602
+ for (const error of validateValue(upgradeEvidenceSchema, evidence)) {
603
+ failures.push(`${file}: ${error}`);
604
+ }
605
+ if (evidence.changedState?.changed !== false) {
606
+ failures.push(`${file}: upgrade evidence must declare no project state change`);
607
+ }
608
+ }
609
+
610
+ const evidenceBundle = readJson(
611
+ "tests/fixtures/evidence-bundles/valid-bundle/evidence-bundle.json",
612
+ );
613
+ if (evidenceBundle) {
614
+ for (const error of validateValue(evidenceBundleSchema, evidenceBundle)) {
615
+ failures.push(`valid evidence bundle: ${error}`);
616
+ }
617
+ const result = verifyEvidenceBundle(
618
+ path.join(
619
+ root,
620
+ "tests/fixtures/evidence-bundles/valid-bundle/evidence-bundle.json",
621
+ ),
622
+ { coreRoot: root },
623
+ );
624
+ if (!result.ok) failures.push(`valid evidence bundle was rejected: ${result.codes}`);
625
+ const archiveReport = buildEvidenceArchiveReport(
626
+ path.join(
627
+ root,
628
+ "tests/fixtures/evidence-bundles/valid-bundle/evidence-bundle.json",
629
+ ),
630
+ { coreRoot: root },
631
+ );
632
+ if (!archiveReport.ok) {
633
+ failures.push(`valid evidence archive report was rejected: ${archiveReport.codes}`);
634
+ }
635
+ for (const error of validateValue(evidenceArchiveReportSchema, archiveReport.report)) {
636
+ failures.push(`valid evidence archive report: ${error}`);
637
+ }
638
+ const archiveIndex = readJson(
639
+ "tests/fixtures/evidence-bundles/valid-bundle/archive/evidence-archive-index.json",
640
+ );
641
+ for (const error of validateValue(evidenceArchiveIndexSchema, archiveIndex)) {
642
+ failures.push(`valid evidence archive index: ${error}`);
643
+ }
644
+ }
645
+ }
646
+
647
+ const contractExample = readJson("contracts/evidence-pack/evidence-pack.example.json");
648
+ if (contractExample?.skill?.version !== PILOT_VERSION) {
649
+ failures.push("evidence-pack contract example has a stale skill version");
650
+ }
651
+
652
+ const packageJson = readJson("package.json");
653
+ if (packageJson) {
654
+ const expectedFiles = [
655
+ "bin/",
656
+ "scripts/",
657
+ "skills/",
658
+ "schemas/",
659
+ "contracts/",
660
+ "docs/",
661
+ "examples/",
662
+ "tests/",
663
+ "AGENTS.md",
664
+ "CHANGELOG.md",
665
+ "CONTRIBUTING.md",
666
+ "LICENSE",
667
+ "README.md",
668
+ "ROADMAP.md",
669
+ "RUNBOOK.md",
670
+ "work-ledger.md",
671
+ "runs/skill-runs.md",
672
+ ];
673
+ if (packageJson.name !== "coding-agent-skills") {
674
+ failures.push("package.json has unexpected package name");
675
+ }
676
+ if (packageJson.version !== "0.2.8") {
677
+ failures.push("package.json version must be 0.2.8 for public package validation");
678
+ }
679
+ if (packageJson.type !== "module") failures.push("package.json must preserve ESM mode");
680
+ if (packageJson.private !== false) {
681
+ failures.push("package.json must be public for the approved npm release");
682
+ }
683
+ if (packageJson.license !== "MIT") {
684
+ failures.push("package.json license must be MIT for the public npm release");
685
+ }
686
+ if (!read("LICENSE").includes("Copyright (c) 2026 OneClickPostFactory")) {
687
+ failures.push("LICENSE must contain the approved MIT copyright line");
688
+ }
689
+ if (
690
+ JSON.stringify(packageJson.keywords) !==
691
+ JSON.stringify([
692
+ "coding-agent",
693
+ "agent-skills",
694
+ "repo-map",
695
+ "project-adapters",
696
+ "code-validation",
697
+ "cli",
698
+ ])
699
+ ) {
700
+ failures.push("package.json keywords have drifted");
701
+ }
702
+ if (
703
+ packageJson.repository?.type !== "git" ||
704
+ packageJson.repository?.url !==
705
+ "git+https://github.com/OneClickPostFactory/coding-agent-skills.git"
706
+ ) {
707
+ failures.push("package.json repository metadata is missing or incorrect");
708
+ }
709
+ if (
710
+ packageJson.homepage !==
711
+ "https://github.com/OneClickPostFactory/coding-agent-skills#readme"
712
+ ) {
713
+ failures.push("package.json homepage metadata is missing or incorrect");
714
+ }
715
+ if (
716
+ packageJson.bugs?.url !==
717
+ "https://github.com/OneClickPostFactory/coding-agent-skills/issues"
718
+ ) {
719
+ failures.push("package.json bugs metadata is missing or incorrect");
720
+ }
721
+ if (
722
+ packageJson.publishConfig?.access !== "public" ||
723
+ packageJson.publishConfig?.registry !== "https://registry.npmjs.org/"
724
+ ) {
725
+ failures.push("package.json publishConfig must target the public npm registry");
726
+ }
727
+ if (packageJson.bin?.["coding-agent-skills"] !== "bin/coding-agent-skills") {
728
+ failures.push("package.json bin mapping is missing coding-agent-skills");
729
+ }
730
+ if (packageJson.dependencies || packageJson.devDependencies) {
731
+ failures.push("package.json must remain dependency-free");
732
+ }
733
+ if (JSON.stringify(packageJson.files) !== JSON.stringify(expectedFiles)) {
734
+ failures.push("package.json files allowlist has drifted");
735
+ }
736
+ for (const entry of expectedFiles) {
737
+ const target = path.join(root, entry);
738
+ if (entry.endsWith("/")) {
739
+ if (!fs.existsSync(target) || !fs.lstatSync(target).isDirectory()) {
740
+ failures.push(`package files allowlist directory missing: ${entry}`);
741
+ }
742
+ } else if (!fs.existsSync(target) || !fs.lstatSync(target).isFile()) {
743
+ failures.push(`package files allowlist file missing: ${entry}`);
744
+ }
745
+ }
746
+ if (packageJson.scripts?.["pack:dry-run"] !== "npm pack --dry-run") {
747
+ failures.push("package.json must expose a dry-run pack script only");
748
+ }
749
+ }
750
+
751
+ for (const [file, patterns] of [
752
+ [
753
+ "docs/adapters/README.md",
754
+ [/inherit/i, /compatib/i, /must never|cannot/i, /external/i, /discovery/i],
755
+ ],
756
+ [
757
+ "docs/adapters/discovery.md",
758
+ [/adapter\.json/i, /symlink/i, /path traversal/i, /extension-only/i],
759
+ ],
760
+ [
761
+ "docs/adapters/external-adapters.md",
762
+ [/validate-adapters\.mjs/i, /rejection/i, /real project adapters/i],
763
+ ],
764
+ [
765
+ "docs/adapters/project-installation.md",
766
+ [/skills\.json/i, /version pin/i, /extension-only/i, /validate-project-adapters/i],
767
+ ],
768
+ [
769
+ "docs/adapters/upgrades.md",
770
+ [/stale exact pin/i, /stale compatible range/i, /advisory/i, /disposable/i],
771
+ ],
772
+ [
773
+ "docs/adapters/upgrade-evidence.md",
774
+ [/changedState/i, /--json/i, /--output/i, /does not apply/i],
775
+ ],
776
+ [
777
+ "docs/evidence-bundles/README.md",
778
+ [/deterministic/i, /regression/i, /retention/i, /provenance/i, /archive/i, /read-only/i],
779
+ ],
780
+ [
781
+ "docs/release/npm-package.md",
782
+ [/npm install -g coding-agent-skills/i, /MIT/i, /public npm registry/i],
783
+ ],
784
+ [
785
+ "docs/versioning/adapter-compatibility.md",
786
+ [/schema drift/i, /skill compatibility drift/i, /preserve/i, /evidence/i],
787
+ ],
788
+ [
789
+ "docs/versioning/README.md",
790
+ [/exact pin/i, /compatible range/i, />=0\.2\.2 <0\.3\.0/],
791
+ ],
792
+ [
793
+ "docs/testing/README.md",
794
+ [/property-style/i, /not a complete POSIX parser/i],
795
+ ],
796
+ [
797
+ "docs/authoring/README.md",
798
+ [/adapter.*compatib/i, /command.*argument/i],
799
+ ],
800
+ ]) {
801
+ const text = read(file);
802
+ for (const pattern of patterns) {
803
+ if (!pattern.test(text)) failures.push(`${file}: missing ${pattern}`);
804
+ }
805
+ }
806
+
807
+ const allFiles = walk(root);
808
+ const textFiles = allFiles.filter((file) => /\.(?:md|json|yaml|yml|mjs)$/.test(file));
809
+
810
+ for (const file of textFiles.filter((target) => target.endsWith(".md"))) {
811
+ const text = fs.readFileSync(file, "utf8");
812
+ for (const match of text.matchAll(/\[[^\]]+\]\(([^)]+)\)/g)) {
813
+ const link = match[1];
814
+ if (
815
+ link.startsWith("#") ||
816
+ /^[a-z]+:/i.test(link) ||
817
+ link.includes("<") ||
818
+ link.includes(">")
819
+ ) {
820
+ continue;
821
+ }
822
+ const target = path.resolve(path.dirname(file), link.split("#")[0]);
823
+ if (!fs.existsSync(target)) {
824
+ failures.push(`${path.relative(root, file)}: broken link ${link}`);
825
+ }
826
+ }
827
+ }
828
+
829
+ if (sourceCheckoutMode) {
830
+ const gitignore = new Set(read(".gitignore").split(/\r?\n/));
831
+ for (const pattern of [
832
+ ".env",
833
+ ".env.*",
834
+ "!.env.example",
835
+ "*.log",
836
+ "tmp/",
837
+ ".vscode/",
838
+ "validation-output/",
839
+ "test-results/",
840
+ ]) {
841
+ if (!gitignore.has(pattern)) failures.push(`.gitignore missing ${pattern}`);
842
+ }
843
+ } else if (packageInstalledMode) {
844
+ if (fs.existsSync(path.join(root, ".github"))) {
845
+ failures.push("package-installed tree must not contain .github");
846
+ }
847
+ for (const file of allFiles) {
848
+ const relative = path.relative(root, file);
849
+ const basename = path.basename(file);
850
+ if (basename === ".env" || (basename.startsWith(".env.") && basename !== ".env.example")) {
851
+ failures.push(`${relative}: package-installed tree contains environment file`);
852
+ }
853
+ }
854
+ }
855
+
856
+ const secretPatterns = [
857
+ /\bgh[pousr]_[A-Za-z0-9_]{12,}\b/,
858
+ new RegExp(`\\b${"github" + "_pat_"}[A-Za-z0-9_]{12,}\\b`),
859
+ /\beyJ[A-Za-z0-9._-]{20,}\b/,
860
+ new RegExp(["-----BEGIN ", "(?:RSA |EC |OPENSSH )?", "PRIVATE KEY-----"].join("")),
861
+ /Authorization:\s*Bearer\s+[A-Za-z0-9._-]{8,}/i,
862
+ ];
863
+ for (const file of textFiles) {
864
+ const text = fs.readFileSync(file, "utf8");
865
+ for (const pattern of secretPatterns) {
866
+ if (pattern.test(text)) failures.push(`${path.relative(root, file)}: secret-like value`);
867
+ }
868
+ }
869
+
870
+ for (const skill of AUDIT_ONLY_SKILLS) {
871
+ const skillText = read(`skills/${skill}/SKILL.md`);
872
+ const metadata = read(`skills/${skill}/agents/openai.yaml`);
873
+ if (!/\baudit-only\b/i.test(skillText)) failures.push(`${skill}: audit-only boundary missing`);
874
+ if (!/no mutation|no state changed|must not change|without changing|must not alter/i.test(skillText)) {
875
+ failures.push(`${skill}: explicit no-mutation completion boundary missing`);
876
+ }
877
+ if (!/without (?:modifying|changing|rewriting)/i.test(metadata)) {
878
+ failures.push(`${skill}: agent prompt does not preserve audit-only behavior`);
879
+ }
880
+ for (const file of allFiles.filter(
881
+ (candidate) =>
882
+ candidate.startsWith(path.join(root, "skills", skill)) &&
883
+ candidate.endsWith(".md"),
884
+ )) {
885
+ for (const issue of auditOnlyDocumentIssues(fs.readFileSync(file, "utf8"))) {
886
+ failures.push(
887
+ `${path.relative(root, file)}:${issue.line}: audit-only mutation guidance: ${issue.reasons.join(", ")}`,
888
+ );
889
+ }
890
+ }
891
+ }
892
+
893
+ for (const directory of ["skills", "examples"]) {
894
+ for (const file of allFiles.filter(
895
+ (candidate) =>
896
+ candidate.startsWith(path.join(root, directory)) &&
897
+ /\.(?:md|json|yaml|yml)$/.test(candidate),
898
+ )) {
899
+ const sensitiveTypes = detectSensitiveValues(fs.readFileSync(file, "utf8"));
900
+ if (sensitiveTypes.length) {
901
+ failures.push(
902
+ `${path.relative(root, file)}: sensitive-looking reusable content: ${sensitiveTypes.join(", ")}`,
903
+ );
904
+ }
905
+ }
906
+ }
907
+
908
+ const executableExampleFiles = [
909
+ "CONTRIBUTING.md",
910
+ ...PILOT_SKILLS.map((skill) => `examples/workflows/${skill}.md`),
911
+ ];
912
+ for (const file of executableExampleFiles) {
913
+ const text = read(file);
914
+ for (const match of text.matchAll(/```(?:bash|sh|shell)\s*\n([\s\S]*?)```/g)) {
915
+ for (const line of match[1].split(/\r?\n/)) {
916
+ const reason = restrictedShellReason(line);
917
+ if (reason) failures.push(`${file}: ${reason}: ${line.trim()}`);
918
+ }
919
+ }
920
+ }
921
+
922
+ if (sourceCheckoutMode) {
923
+ const ci = read(".github/workflows/validate.yml");
924
+ for (const expected of [
925
+ "permissions:\n contents: read",
926
+ "node scripts/validate-pack.mjs .",
927
+ "node scripts/test-pack.mjs",
928
+ "node scripts/validate-maintainer-loop.mjs .",
929
+ "node scripts/validate-adapters.mjs tests/fixtures/external-adapters/valid-basic",
930
+ "node scripts/validate-project-adapters.mjs tests/fixtures/project-adapter-installation/valid-exact-pin",
931
+ "node scripts/check-adapter-upgrade.mjs tests/fixtures/project-adapter-upgrades/valid-upgrade/before tests/fixtures/project-adapter-upgrades/valid-upgrade/after",
932
+ "node scripts/check-adapter-upgrade-chain.mjs tests/fixtures/project-adapter-upgrade-chains/valid-chain",
933
+ "node scripts/verify-evidence-bundle.mjs tests/fixtures/evidence-bundles/valid-bundle/evidence-bundle.json",
934
+ "node scripts/render-evidence-archive-report.mjs tests/fixtures/evidence-bundles/valid-bundle/evidence-bundle.json",
935
+ "node --test",
936
+ ]) {
937
+ if (!ci.includes(expected)) failures.push(`CI missing safe validation step: ${expected}`);
938
+ }
939
+ for (const match of ci.matchAll(/^\s*run:\s*(.+)$/gm)) {
940
+ const reason = restrictedShellReason(match[1]);
941
+ if (reason) failures.push(`CI contains ${reason}: ${match[1].trim()}`);
942
+ }
943
+ }
944
+
945
+ if (failures.length) {
946
+ console.error(failures.join("\n"));
947
+ process.exit(1);
948
+ }
949
+
950
+ console.log(`pilot pack valid: ${PILOT_SKILLS.length} skills, ${textFiles.length} checked files`);