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,434 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ import { validateExternalAdapters } from "./adapter-discovery.mjs";
5
+ import {
6
+ PILOT_SKILLS,
7
+ PILOT_VERSION,
8
+ PREVIOUS_PILOT_VERSION,
9
+ } from "./pack-rules.mjs";
10
+ import {
11
+ readProjectAdapterDeclaration,
12
+ validateProjectAdapters,
13
+ } from "./project-adapter-installation.mjs";
14
+ import {
15
+ compareSemver,
16
+ parseSemver,
17
+ parseVersionPin,
18
+ satisfiesVersionPin,
19
+ } from "./semver.mjs";
20
+ import { writeSafeEvidenceJson } from "./safe-evidence-output.mjs";
21
+ import { buildAdapterUpgradeEvidence } from "./upgrade-evidence.mjs";
22
+
23
+ const DEFAULT_CORE_ROOT = path.resolve(
24
+ path.dirname(fileURLToPath(import.meta.url)),
25
+ "..",
26
+ "..",
27
+ );
28
+
29
+ function previousPatch(version) {
30
+ const parsed = parseSemver(version);
31
+ if (!parsed || parsed[2] === 0) return null;
32
+ return `${parsed[0]}.${parsed[1]}.${parsed[2] - 1}`;
33
+ }
34
+
35
+ function previousSupportedVersion(version) {
36
+ return version === PILOT_VERSION ? PREVIOUS_PILOT_VERSION : previousPatch(version);
37
+ }
38
+
39
+ function pinKind(pin) {
40
+ const parsed = parseVersionPin(pin);
41
+ return parsed?.length === 1 && parsed[0].operator === "=" ? "exact" : "range";
42
+ }
43
+
44
+ function mappedValidationCode(code) {
45
+ if (code === "secret-like-content" || code === "secret-exposure") {
46
+ return "secret-exposure";
47
+ }
48
+ if (code === "mode-override") return "mode-escalation";
49
+ if (
50
+ [
51
+ "restriction-weakening",
52
+ "restriction-removal",
53
+ "missing-shared-inheritance",
54
+ ].includes(code)
55
+ ) {
56
+ return "restriction-weakening";
57
+ }
58
+ if (code === "failure-suppression") return "failure-suppression";
59
+ if (code === "completion-override") return "completion-override";
60
+ if (code === "required-evidence-removal") return "required-evidence-removal";
61
+ if (code === "incompatible-skill-version") return "skill-compatibility-drift";
62
+ if (code === "unsupported-skill-id") return "unknown-skill-compatibility";
63
+ if (
64
+ [
65
+ "root-path-traversal",
66
+ "unsafe-project-path",
67
+ "unsafe-path",
68
+ "path-escape",
69
+ "symlink-escape",
70
+ ].includes(code)
71
+ ) {
72
+ return "path-traversal";
73
+ }
74
+ if (code === "scope-expansion") return "scope-expansion";
75
+ return null;
76
+ }
77
+
78
+ function versionOrCurrent(loaded) {
79
+ const declared = loaded.declaration?.core?.expectedVersion;
80
+ return parseSemver(declared) ? declared : PILOT_VERSION;
81
+ }
82
+
83
+ function revisionState(projectRoot, coreRoot) {
84
+ const loaded = readProjectAdapterDeclaration(projectRoot);
85
+ if (!loaded.ok) {
86
+ return {
87
+ ok: false,
88
+ loaded,
89
+ validation: null,
90
+ discovery: null,
91
+ codes: loaded.codes,
92
+ };
93
+ }
94
+
95
+ const coreVersion = versionOrCurrent(loaded);
96
+ const validation = validateProjectAdapters(projectRoot, {
97
+ coreRoot,
98
+ coreVersion,
99
+ });
100
+ const discovery = validateExternalAdapters(projectRoot, {
101
+ coreRoot,
102
+ coreVersion,
103
+ });
104
+ return {
105
+ ok: validation.ok,
106
+ loaded,
107
+ validation,
108
+ discovery,
109
+ codes: validation.codes,
110
+ };
111
+ }
112
+
113
+ function addValidationCodes(codes, state, revision) {
114
+ if (!state.loaded.ok) {
115
+ codes.add(`${revision}-project-invalid`);
116
+ for (const code of state.codes) {
117
+ codes.add(mappedValidationCode(code) ?? `${revision}-${code}`);
118
+ }
119
+ return;
120
+ }
121
+
122
+ const declaration = state.loaded.declaration;
123
+ if (declaration.adapterSchemaVersion !== "1.0.0") {
124
+ codes.add("adapter-schema-drift");
125
+ }
126
+ for (const code of state.codes) {
127
+ if (
128
+ [
129
+ "unsupported-core-version",
130
+ "core-pin-mismatch",
131
+ "expected-version-outside-pin",
132
+ ].includes(code)
133
+ ) {
134
+ continue;
135
+ }
136
+ if (code === "unsupported-adapter-version") {
137
+ codes.add("adapter-version-drift");
138
+ continue;
139
+ }
140
+ codes.add(mappedValidationCode(code) ?? `${revision}-project-invalid`);
141
+ }
142
+ }
143
+
144
+ function addCoreVersionCodes(codes, before, after, targetVersion) {
145
+ const previous = previousSupportedVersion(targetVersion);
146
+ const beforeVersion = before.loaded.declaration?.core?.expectedVersion;
147
+ const afterVersion = after.loaded.declaration?.core?.expectedVersion;
148
+ const beforePin = before.loaded.declaration?.core?.versionPin;
149
+ const afterPin = after.loaded.declaration?.core?.versionPin;
150
+
151
+ if (!parseSemver(beforeVersion) || !parseVersionPin(beforePin)) {
152
+ codes.add("before-invalid-core-version");
153
+ }
154
+ if (!parseSemver(afterVersion) || !parseVersionPin(afterPin)) {
155
+ codes.add("after-invalid-core-version");
156
+ return;
157
+ }
158
+
159
+ if (parseSemver(beforeVersion)) {
160
+ if (compareSemver(beforeVersion, targetVersion) > 0) {
161
+ codes.add("unsupported-future-core");
162
+ } else if (previous && compareSemver(beforeVersion, previous) < 0) {
163
+ codes.add("unsupported-old-core");
164
+ }
165
+ }
166
+
167
+ const afterComparison = compareSemver(afterVersion, targetVersion);
168
+ if (afterComparison > 0) {
169
+ codes.add("unsupported-future-core");
170
+ } else if (
171
+ afterComparison < 0 ||
172
+ !satisfiesVersionPin(targetVersion, afterPin)
173
+ ) {
174
+ codes.add(
175
+ pinKind(afterPin) === "exact"
176
+ ? "stale-exact-pin"
177
+ : "stale-compatible-range",
178
+ );
179
+ }
180
+ }
181
+
182
+ function byAdapterId(discovery) {
183
+ return new Map(
184
+ (discovery?.accepted ?? []).map((adapter) => [adapter.adapterId, adapter]),
185
+ );
186
+ }
187
+
188
+ function bySkillId(adapter) {
189
+ return new Map(
190
+ (adapter.skillCompatibility ?? []).map((skill) => [skill.id, skill]),
191
+ );
192
+ }
193
+
194
+ function missingValues(before, after) {
195
+ const afterSet = new Set(after);
196
+ return before.filter((value) => !afterSet.has(value));
197
+ }
198
+
199
+ function addAdapterComparisonCodes(
200
+ codes,
201
+ before,
202
+ after,
203
+ targetVersion,
204
+ requireTargetCompatibility,
205
+ ) {
206
+ const beforeAdapters = byAdapterId(before.discovery);
207
+ const afterAdapters = byAdapterId(after.discovery);
208
+
209
+ if (
210
+ JSON.stringify([...beforeAdapters.keys()].sort()) !==
211
+ JSON.stringify([...afterAdapters.keys()].sort())
212
+ ) {
213
+ codes.add("adapter-set-drift");
214
+ }
215
+
216
+ for (const [adapterId, beforeAdapter] of beforeAdapters) {
217
+ const afterAdapter = afterAdapters.get(adapterId);
218
+ if (!afterAdapter) continue;
219
+
220
+ const versionComparison = compareSemver(
221
+ afterAdapter.adapterVersion,
222
+ beforeAdapter.adapterVersion,
223
+ );
224
+ if (versionComparison === null) codes.add("adapter-version-drift");
225
+ if (versionComparison < 0) codes.add("adapter-version-downgrade");
226
+
227
+ if (
228
+ missingValues(
229
+ beforeAdapter.deniedOperationCategories,
230
+ afterAdapter.deniedOperationCategories,
231
+ ).length
232
+ ) {
233
+ codes.add("restriction-weakening");
234
+ }
235
+ if (
236
+ missingValues(
237
+ beforeAdapter.requiredEvidence,
238
+ afterAdapter.requiredEvidence,
239
+ ).length
240
+ ) {
241
+ codes.add("required-evidence-removal");
242
+ }
243
+
244
+ const beforeSkills = bySkillId(beforeAdapter);
245
+ const afterSkills = bySkillId(afterAdapter);
246
+ if (
247
+ JSON.stringify([...beforeSkills.keys()].sort()) !==
248
+ JSON.stringify([...afterSkills.keys()].sort())
249
+ ) {
250
+ codes.add("skill-compatibility-drift");
251
+ }
252
+
253
+ for (const [skillId, beforeSkill] of beforeSkills) {
254
+ const afterSkill = afterSkills.get(skillId);
255
+ if (!afterSkill) continue;
256
+ if (!PILOT_SKILLS.includes(skillId)) codes.add("unknown-skill-compatibility");
257
+ if (beforeSkill.declaredMode !== afterSkill.declaredMode) {
258
+ codes.add("mode-escalation");
259
+ }
260
+ if (
261
+ requireTargetCompatibility &&
262
+ !afterSkill.compatibleVersions.some(
263
+ (version) =>
264
+ version === targetVersion ||
265
+ version === `${targetVersion.split(".").slice(0, 2).join(".")}.x`,
266
+ )
267
+ ) {
268
+ codes.add("skill-compatibility-drift");
269
+ }
270
+ }
271
+ }
272
+ }
273
+
274
+ function safeRevisionContext(state, label) {
275
+ const declaration = state.loaded.declaration;
276
+ const discoveredById = byAdapterId(state.discovery);
277
+ const declaredAdapters = Array.isArray(declaration?.adapters)
278
+ ? declaration.adapters
279
+ : [];
280
+
281
+ return {
282
+ rootSummary: {
283
+ reference: label,
284
+ declarationStatus: state.loaded.ok ? "present" : "unavailable",
285
+ validationStatus: state.ok ? "pass" : "fail",
286
+ },
287
+ coreVersion: declaration?.core?.expectedVersion ?? null,
288
+ versionPin: declaration?.core?.versionPin ?? null,
289
+ adapterSchemaVersion: declaration?.adapterSchemaVersion ?? null,
290
+ adapters: declaredAdapters
291
+ .map((adapter) => {
292
+ const discovered = discoveredById.get(adapter.id);
293
+ return {
294
+ id: adapter.id,
295
+ version: adapter.version,
296
+ skillIds: [...(adapter.skillIds ?? [])].sort(),
297
+ skillCompatibility: discovered?.skillCompatibility ?? [],
298
+ approvalRequirements: discovered?.approvalRequirements ?? [],
299
+ };
300
+ })
301
+ .sort((left, right) => left.id.localeCompare(right.id)),
302
+ };
303
+ }
304
+
305
+ export function checkAdapterUpgrade(beforeProjectRoot, afterProjectRoot, options = {}) {
306
+ if (!beforeProjectRoot || !afterProjectRoot) {
307
+ return {
308
+ ok: false,
309
+ status: "failed",
310
+ comparedAdapters: 0,
311
+ comparedSkills: 0,
312
+ codes: ["missing-project-revision"],
313
+ };
314
+ }
315
+
316
+ const coreRoot = path.resolve(options.coreRoot ?? DEFAULT_CORE_ROOT);
317
+ const targetVersion = options.targetCoreVersion ?? PILOT_VERSION;
318
+ if (!parseSemver(targetVersion)) {
319
+ return {
320
+ ok: false,
321
+ status: "failed",
322
+ comparedAdapters: 0,
323
+ comparedSkills: 0,
324
+ codes: ["invalid-target-core-version"],
325
+ };
326
+ }
327
+ const before = revisionState(beforeProjectRoot, coreRoot);
328
+ const after = revisionState(afterProjectRoot, coreRoot);
329
+ const codes = new Set();
330
+
331
+ addValidationCodes(codes, before, "before");
332
+ addValidationCodes(codes, after, "after");
333
+ if (before.loaded.ok && after.loaded.ok) {
334
+ if (before.loaded.declaration.projectId !== after.loaded.declaration.projectId) {
335
+ codes.add("project-id-drift");
336
+ }
337
+ addCoreVersionCodes(codes, before, after, targetVersion);
338
+ addAdapterComparisonCodes(
339
+ codes,
340
+ before,
341
+ after,
342
+ targetVersion,
343
+ after.loaded.declaration.core?.expectedVersion === targetVersion,
344
+ );
345
+ }
346
+
347
+ const beforeAdapters = byAdapterId(before.discovery);
348
+ const afterAdapters = byAdapterId(after.discovery);
349
+ const sharedAdapters = [...beforeAdapters.keys()].filter((adapterId) =>
350
+ afterAdapters.has(adapterId),
351
+ );
352
+ const sharedSkills = new Set();
353
+ for (const adapterId of sharedAdapters) {
354
+ const beforeSkills = new Set(beforeAdapters.get(adapterId).skills);
355
+ for (const skill of afterAdapters.get(adapterId).skills) {
356
+ if (beforeSkills.has(skill)) sharedSkills.add(skill);
357
+ }
358
+ }
359
+
360
+ return {
361
+ ok: codes.size === 0,
362
+ status: codes.size === 0 ? "complete" : "failed",
363
+ comparedAdapters: sharedAdapters.length,
364
+ comparedSkills: sharedSkills.size,
365
+ codes: [...codes].sort(),
366
+ targetCoreVersion: targetVersion,
367
+ context: {
368
+ before: safeRevisionContext(before, "before"),
369
+ after: safeRevisionContext(after, "after"),
370
+ },
371
+ };
372
+ }
373
+
374
+ export function formatAdapterUpgradeSummary(result) {
375
+ if (result.ok) {
376
+ return [
377
+ `adapter upgrade check complete: ${result.comparedAdapters} adapters, ` +
378
+ `${result.comparedSkills} skills, target core accepted`,
379
+ ];
380
+ }
381
+ return [
382
+ `adapter upgrade check failed: ${result.comparedAdapters} adapters compared`,
383
+ `rejection codes: ${result.codes.join(",")}`,
384
+ ];
385
+ }
386
+
387
+ export function adapterUpgradeCliResult(beforeRoot, afterRoot, options = {}) {
388
+ if (!beforeRoot || !afterRoot) {
389
+ return {
390
+ exitCode: 2,
391
+ stream: "stderr",
392
+ lines: [
393
+ "usage: node scripts/check-adapter-upgrade.mjs " +
394
+ "<before-project-root> <after-project-root>",
395
+ ],
396
+ };
397
+ }
398
+
399
+ const result = checkAdapterUpgrade(beforeRoot, afterRoot, options);
400
+ const evidence = buildAdapterUpgradeEvidence(result, options);
401
+ if (options.output) {
402
+ const written = writeSafeEvidenceJson(options.output, evidence, {
403
+ baseDirectory: options.outputBase,
404
+ });
405
+ if (!written.ok) {
406
+ return {
407
+ exitCode: 2,
408
+ stream: "stderr",
409
+ lines: [`adapter upgrade evidence output failed: ${written.code}`],
410
+ result,
411
+ evidence,
412
+ };
413
+ }
414
+ }
415
+ if (options.json) {
416
+ return {
417
+ exitCode: result.ok ? 0 : 1,
418
+ stream: "stdout",
419
+ lines: [JSON.stringify(evidence, null, 2)],
420
+ result,
421
+ evidence,
422
+ };
423
+ }
424
+ return {
425
+ exitCode: result.ok ? 0 : 1,
426
+ stream: result.ok ? "stdout" : "stderr",
427
+ lines: [
428
+ ...formatAdapterUpgradeSummary(result),
429
+ ...(options.output ? ["sanitized evidence output written"] : []),
430
+ ],
431
+ result,
432
+ evidence,
433
+ };
434
+ }