@intentius/chant 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (453) hide show
  1. package/dist/audit/catalog.d.ts +45 -5
  2. package/dist/audit/catalog.d.ts.map +1 -1
  3. package/dist/audit/fetch.d.ts.map +1 -1
  4. package/dist/audit/proof.d.ts +3 -0
  5. package/dist/audit/proof.d.ts.map +1 -1
  6. package/dist/audit/report-model.d.ts +4 -1
  7. package/dist/audit/report-model.d.ts.map +1 -1
  8. package/dist/audit/report.d.ts +3 -0
  9. package/dist/audit/report.d.ts.map +1 -1
  10. package/dist/audit/rules-doc.d.ts +8 -2
  11. package/dist/audit/rules-doc.d.ts.map +1 -1
  12. package/dist/cli/commands/audit.d.ts.map +1 -1
  13. package/dist/cli/commands/doctor.d.ts.map +1 -1
  14. package/dist/cli/commands/lexicon-rolling-upgrade.d.ts +37 -0
  15. package/dist/cli/commands/lexicon-rolling-upgrade.d.ts.map +1 -0
  16. package/dist/cli/commands/lexicon-surface-diff.d.ts +48 -0
  17. package/dist/cli/commands/lexicon-surface-diff.d.ts.map +1 -0
  18. package/dist/cli/commands/lint.d.ts.map +1 -1
  19. package/dist/cli/commands/pinned-upgrade.d.ts +41 -0
  20. package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -0
  21. package/dist/cli/handlers/build.d.ts.map +1 -1
  22. package/dist/cli/handlers/components.d.ts +39 -0
  23. package/dist/cli/handlers/components.d.ts.map +1 -0
  24. package/dist/cli/handlers/dev.d.ts +3 -0
  25. package/dist/cli/handlers/dev.d.ts.map +1 -1
  26. package/dist/cli/handlers/graph.d.ts +4 -2
  27. package/dist/cli/handlers/graph.d.ts.map +1 -1
  28. package/dist/cli/handlers/misc.d.ts.map +1 -1
  29. package/dist/cli/handlers/run.d.ts +49 -0
  30. package/dist/cli/handlers/run.d.ts.map +1 -1
  31. package/dist/cli/main.d.ts.map +1 -1
  32. package/dist/cli/registry.d.ts +35 -0
  33. package/dist/cli/registry.d.ts.map +1 -1
  34. package/dist/codegen/fetch.d.ts +22 -0
  35. package/dist/codegen/fetch.d.ts.map +1 -1
  36. package/dist/codegen/lexicon-regen.d.ts +110 -0
  37. package/dist/codegen/lexicon-regen.d.ts.map +1 -0
  38. package/dist/codegen/pinned-upgrade.d.ts +153 -0
  39. package/dist/codegen/pinned-upgrade.d.ts.map +1 -0
  40. package/dist/codegen/rolling-upgrade.d.ts +138 -0
  41. package/dist/codegen/rolling-upgrade.d.ts.map +1 -0
  42. package/dist/codegen/surface-snapshot.d.ts +173 -0
  43. package/dist/codegen/surface-snapshot.d.ts.map +1 -0
  44. package/dist/codegen/version-bump.d.ts +21 -0
  45. package/dist/codegen/version-bump.d.ts.map +1 -0
  46. package/dist/components/auto-release.d.ts +93 -0
  47. package/dist/components/auto-release.d.ts.map +1 -0
  48. package/dist/components/builders.d.ts +37 -0
  49. package/dist/components/builders.d.ts.map +1 -0
  50. package/dist/components/capability-plugin-loader.d.ts +111 -0
  51. package/dist/components/capability-plugin-loader.d.ts.map +1 -0
  52. package/dist/components/capability-plugin-schema.d.ts +24 -0
  53. package/dist/components/capability-plugin-schema.d.ts.map +1 -0
  54. package/dist/components/capability-plugin.d.ts +85 -0
  55. package/dist/components/capability-plugin.d.ts.map +1 -0
  56. package/dist/components/capability.d.ts +89 -0
  57. package/dist/components/capability.d.ts.map +1 -0
  58. package/dist/components/cli-support.d.ts +204 -0
  59. package/dist/components/cli-support.d.ts.map +1 -0
  60. package/dist/components/component.d.ts +179 -0
  61. package/dist/components/component.d.ts.map +1 -0
  62. package/dist/components/config-defaults.d.ts +41 -0
  63. package/dist/components/config-defaults.d.ts.map +1 -0
  64. package/dist/components/discover.d.ts +60 -0
  65. package/dist/components/discover.d.ts.map +1 -0
  66. package/dist/components/driver-output.d.ts +20 -0
  67. package/dist/components/driver-output.d.ts.map +1 -0
  68. package/dist/components/driver.d.ts +209 -0
  69. package/dist/components/driver.d.ts.map +1 -0
  70. package/dist/components/index.d.ts +22 -0
  71. package/dist/components/index.d.ts.map +1 -0
  72. package/dist/components/manifest-persistence.d.ts +79 -0
  73. package/dist/components/manifest-persistence.d.ts.map +1 -0
  74. package/dist/components/pilots/alb-ecs.pilot.d.ts +27 -0
  75. package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -0
  76. package/dist/components/pilots/dynamodb.pilot.d.ts +22 -0
  77. package/dist/components/pilots/dynamodb.pilot.d.ts.map +1 -0
  78. package/dist/components/pilots/jar-emr.pilot.d.ts +37 -0
  79. package/dist/components/pilots/jar-emr.pilot.d.ts.map +1 -0
  80. package/dist/components/pilots/lambda.pilot.d.ts +35 -0
  81. package/dist/components/pilots/lambda.pilot.d.ts.map +1 -0
  82. package/dist/components/pilots/neo4j-fanout.pilot.d.ts +17 -0
  83. package/dist/components/pilots/neo4j-fanout.pilot.d.ts.map +1 -0
  84. package/dist/components/pilots/project.d.ts +13 -0
  85. package/dist/components/pilots/project.d.ts.map +1 -0
  86. package/dist/components/presets/ecs-fargate.d.ts +59 -0
  87. package/dist/components/presets/ecs-fargate.d.ts.map +1 -0
  88. package/dist/components/presets/index.d.ts +29 -0
  89. package/dist/components/presets/index.d.ts.map +1 -0
  90. package/dist/components/presets/lambda.d.ts +35 -0
  91. package/dist/components/presets/lambda.d.ts.map +1 -0
  92. package/dist/components/presets/single-host-compose.d.ts +43 -0
  93. package/dist/components/presets/single-host-compose.d.ts.map +1 -0
  94. package/dist/components/registry.d.ts +29 -0
  95. package/dist/components/registry.d.ts.map +1 -0
  96. package/dist/components/starter-plugin.d.ts +51 -0
  97. package/dist/components/starter-plugin.d.ts.map +1 -0
  98. package/dist/components/temporal-codegen-loader.d.ts +27 -0
  99. package/dist/components/temporal-codegen-loader.d.ts.map +1 -0
  100. package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts +35 -0
  101. package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts.map +1 -0
  102. package/dist/components/verbs/__tests__/mock-process-runner.d.ts +45 -0
  103. package/dist/components/verbs/__tests__/mock-process-runner.d.ts.map +1 -0
  104. package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts +33 -0
  105. package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts.map +1 -0
  106. package/dist/components/verbs/bom-writer.d.ts +155 -0
  107. package/dist/components/verbs/bom-writer.d.ts.map +1 -0
  108. package/dist/components/verbs/build-archive.d.ts +205 -0
  109. package/dist/components/verbs/build-archive.d.ts.map +1 -0
  110. package/dist/components/verbs/build.d.ts +150 -0
  111. package/dist/components/verbs/build.d.ts.map +1 -0
  112. package/dist/components/verbs/cloud-executor.d.ts +88 -0
  113. package/dist/components/verbs/cloud-executor.d.ts.map +1 -0
  114. package/dist/components/verbs/component-bom.d.ts +103 -0
  115. package/dist/components/verbs/component-bom.d.ts.map +1 -0
  116. package/dist/components/verbs/index.d.ts +49 -0
  117. package/dist/components/verbs/index.d.ts.map +1 -0
  118. package/dist/components/verbs/license-policy.d.ts +56 -0
  119. package/dist/components/verbs/license-policy.d.ts.map +1 -0
  120. package/dist/components/verbs/lockfile-sbom-generator.d.ts +81 -0
  121. package/dist/components/verbs/lockfile-sbom-generator.d.ts.map +1 -0
  122. package/dist/components/verbs/process-runner.d.ts +64 -0
  123. package/dist/components/verbs/process-runner.d.ts.map +1 -0
  124. package/dist/components/verbs/reproducibility.d.ts +80 -0
  125. package/dist/components/verbs/reproducibility.d.ts.map +1 -0
  126. package/dist/components/verbs/sbom-generator.d.ts +157 -0
  127. package/dist/components/verbs/sbom-generator.d.ts.map +1 -0
  128. package/dist/components/verbs/sbom.d.ts +79 -0
  129. package/dist/components/verbs/sbom.d.ts.map +1 -0
  130. package/dist/components/verbs/shell.d.ts +35 -0
  131. package/dist/components/verbs/shell.d.ts.map +1 -0
  132. package/dist/components/verbs/sign.d.ts +222 -0
  133. package/dist/components/verbs/sign.d.ts.map +1 -0
  134. package/dist/components/verbs/stub.d.ts +18 -0
  135. package/dist/components/verbs/stub.d.ts.map +1 -0
  136. package/dist/components/verbs/tool-sbom-generator.d.ts +51 -0
  137. package/dist/components/verbs/tool-sbom-generator.d.ts.map +1 -0
  138. package/dist/components/verbs/verify.d.ts +106 -0
  139. package/dist/components/verbs/verify.d.ts.map +1 -0
  140. package/dist/components/verbs/vex.d.ts +65 -0
  141. package/dist/components/verbs/vex.d.ts.map +1 -0
  142. package/dist/components/verbs/vuln-gate.d.ts +91 -0
  143. package/dist/components/verbs/vuln-gate.d.ts.map +1 -0
  144. package/dist/components/verbs/vuln-scan.d.ts +116 -0
  145. package/dist/components/verbs/vuln-scan.d.ts.map +1 -0
  146. package/dist/components/verbs/wait-verify.d.ts +85 -0
  147. package/dist/components/verbs/wait-verify.d.ts.map +1 -0
  148. package/dist/config.d.ts +205 -0
  149. package/dist/config.d.ts.map +1 -1
  150. package/dist/index.d.ts +4 -0
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/lexicon.d.ts +78 -0
  153. package/dist/lexicon.d.ts.map +1 -1
  154. package/dist/lifecycle/build-ledger-store.d.ts +121 -0
  155. package/dist/lifecycle/build-ledger-store.d.ts.map +1 -0
  156. package/dist/lifecycle/build-ledger.d.ts +225 -0
  157. package/dist/lifecycle/build-ledger.d.ts.map +1 -0
  158. package/dist/lifecycle/git.d.ts +84 -0
  159. package/dist/lifecycle/git.d.ts.map +1 -1
  160. package/dist/lifecycle/index.d.ts +5 -0
  161. package/dist/lifecycle/index.d.ts.map +1 -1
  162. package/dist/lifecycle/oras-referrer-lookup.d.ts +41 -0
  163. package/dist/lifecycle/oras-referrer-lookup.d.ts.map +1 -0
  164. package/dist/lifecycle/release-ledger.d.ts +122 -0
  165. package/dist/lifecycle/release-ledger.d.ts.map +1 -0
  166. package/dist/lifecycle/status.d.ts +150 -0
  167. package/dist/lifecycle/status.d.ts.map +1 -0
  168. package/dist/lint/component-checks.d.ts +95 -0
  169. package/dist/lint/component-checks.d.ts.map +1 -0
  170. package/dist/lint/engine.d.ts +23 -0
  171. package/dist/lint/engine.d.ts.map +1 -1
  172. package/dist/lint/presets/strict.json +8 -1
  173. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts +4 -0
  174. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts.map +1 -0
  175. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts +4 -0
  176. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts.map +1 -0
  177. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts +4 -0
  178. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts.map +1 -0
  179. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts +4 -0
  180. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts.map +1 -0
  181. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts +4 -0
  182. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts.map +1 -0
  183. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts +10 -0
  184. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts.map +1 -0
  185. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts +3 -0
  186. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts.map +1 -0
  187. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts +4 -0
  188. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts.map +1 -0
  189. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts +4 -0
  190. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts.map +1 -0
  191. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts +4 -0
  192. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts.map +1 -0
  193. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts +4 -0
  194. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts.map +1 -0
  195. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts +4 -0
  196. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts.map +1 -0
  197. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +4 -0
  198. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -0
  199. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +4 -0
  200. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -0
  201. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts +4 -0
  202. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts.map +1 -0
  203. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts +4 -0
  204. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts.map +1 -0
  205. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts +4 -0
  206. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts.map +1 -0
  207. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts +4 -0
  208. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts.map +1 -0
  209. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts +4 -0
  210. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts.map +1 -0
  211. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts +4 -0
  212. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts.map +1 -0
  213. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts +3 -0
  214. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts.map +1 -0
  215. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts +4 -0
  216. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts.map +1 -0
  217. package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts +20 -0
  218. package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts.map +1 -0
  219. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts +28 -0
  220. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts.map +1 -0
  221. package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +39 -0
  222. package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -0
  223. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +37 -0
  224. package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +1 -0
  225. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts +43 -0
  226. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts.map +1 -0
  227. package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts +22 -0
  228. package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts.map +1 -0
  229. package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts +33 -0
  230. package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts.map +1 -0
  231. package/dist/lint/rules/comp/index.d.ts +18 -0
  232. package/dist/lint/rules/comp/index.d.ts.map +1 -0
  233. package/dist/lint/rules/comp/support.d.ts +71 -0
  234. package/dist/lint/rules/comp/support.d.ts.map +1 -0
  235. package/dist/lsp/lexicon-providers.d.ts.map +1 -1
  236. package/dist/op/activity-registry.d.ts +11 -6
  237. package/dist/op/activity-registry.d.ts.map +1 -1
  238. package/dist/op/activity-runtime.d.ts +24 -0
  239. package/dist/op/activity-runtime.d.ts.map +1 -0
  240. package/dist/op/builders.d.ts +56 -0
  241. package/dist/op/builders.d.ts.map +1 -1
  242. package/dist/op/index.d.ts +2 -1
  243. package/dist/op/index.d.ts.map +1 -1
  244. package/dist/ownership.d.ts +20 -14
  245. package/dist/ownership.d.ts.map +1 -1
  246. package/package.json +14 -1
  247. package/src/audit/catalog.test.ts +74 -22
  248. package/src/audit/catalog.ts +74 -471
  249. package/src/audit/fetch.test.ts +112 -8
  250. package/src/audit/fetch.ts +53 -8
  251. package/src/audit/proof.ts +4 -2
  252. package/src/audit/report-html.test.ts +14 -7
  253. package/src/audit/report-model.ts +20 -9
  254. package/src/audit/report.test.ts +36 -13
  255. package/src/audit/report.ts +2 -0
  256. package/src/audit/rules-doc.test.ts +8 -6
  257. package/src/audit/rules-doc.ts +13 -5
  258. package/src/cli/commands/audit.ts +23 -18
  259. package/src/cli/commands/component-lint.test.ts +158 -0
  260. package/src/cli/commands/doctor.test.ts +116 -2
  261. package/src/cli/commands/doctor.ts +46 -0
  262. package/src/cli/commands/lexicon-rolling-upgrade.ts +198 -0
  263. package/src/cli/commands/lexicon-surface-diff.test.ts +104 -0
  264. package/src/cli/commands/lexicon-surface-diff.ts +185 -0
  265. package/src/cli/commands/lint.ts +142 -1
  266. package/src/cli/commands/pinned-upgrade.ts +204 -0
  267. package/src/cli/handlers/build.ts +58 -1
  268. package/src/cli/handlers/components.test.ts +504 -0
  269. package/src/cli/handlers/components.ts +404 -0
  270. package/src/cli/handlers/dev.ts +60 -1
  271. package/src/cli/handlers/graph.ts +47 -2
  272. package/src/cli/handlers/misc.ts +45 -1
  273. package/src/cli/handlers/run.test.ts +967 -3
  274. package/src/cli/handlers/run.ts +618 -11
  275. package/src/cli/main.test.ts +66 -0
  276. package/src/cli/main.ts +105 -2
  277. package/src/cli/registry.ts +35 -0
  278. package/src/codegen/fetch.test.ts +84 -3
  279. package/src/codegen/fetch.ts +76 -2
  280. package/src/codegen/lexicon-regen.test.ts +298 -0
  281. package/src/codegen/lexicon-regen.ts +545 -0
  282. package/src/codegen/pinned-upgrade.test.ts +399 -0
  283. package/src/codegen/pinned-upgrade.ts +423 -0
  284. package/src/codegen/rolling-upgrade.test.ts +333 -0
  285. package/src/codegen/rolling-upgrade.ts +320 -0
  286. package/src/codegen/surface-snapshot.test.ts +461 -0
  287. package/src/codegen/surface-snapshot.ts +546 -0
  288. package/src/codegen/version-bump.test.ts +47 -0
  289. package/src/codegen/version-bump.ts +39 -0
  290. package/src/components/README.md +130 -0
  291. package/src/components/SPRAWL-VALIDATION.md +181 -0
  292. package/src/components/__fixtures__/alb-ecs-service.json +51 -0
  293. package/src/components/__fixtures__/dynamodb-infra.json +32 -0
  294. package/src/components/__fixtures__/emr-job-consumer.json +26 -0
  295. package/src/components/__fixtures__/jar-lib-producer.json +16 -0
  296. package/src/components/__fixtures__/lambda-image-processor.json +28 -0
  297. package/src/components/__fixtures__/neo4j-fanout.json +34 -0
  298. package/src/components/__fixtures__/single-host-compose.json +29 -0
  299. package/src/components/auto-release.test.ts +217 -0
  300. package/src/components/auto-release.ts +216 -0
  301. package/src/components/builders.test.ts +45 -0
  302. package/src/components/builders.ts +71 -0
  303. package/src/components/capability-plugin-loader.ts +218 -0
  304. package/src/components/capability-plugin-schema.ts +56 -0
  305. package/src/components/capability-plugin.test.ts +235 -0
  306. package/src/components/capability-plugin.ts +108 -0
  307. package/src/components/capability.ts +117 -0
  308. package/src/components/cli-support.test.ts +579 -0
  309. package/src/components/cli-support.ts +481 -0
  310. package/src/components/component-schema.test.ts +265 -0
  311. package/src/components/component.schema.json +235 -0
  312. package/src/components/component.test.ts +251 -0
  313. package/src/components/component.ts +255 -0
  314. package/src/components/config-defaults.test.ts +263 -0
  315. package/src/components/config-defaults.ts +145 -0
  316. package/src/components/discover.test.ts +352 -0
  317. package/src/components/discover.ts +167 -0
  318. package/src/components/driver-output.ts +71 -0
  319. package/src/components/driver.test.ts +638 -0
  320. package/src/components/driver.ts +690 -0
  321. package/src/components/index.ts +113 -0
  322. package/src/components/manifest-persistence.test.ts +152 -0
  323. package/src/components/manifest-persistence.ts +164 -0
  324. package/src/components/pilots/README.md +33 -0
  325. package/src/components/pilots/alb-ecs.pilot.ts +63 -0
  326. package/src/components/pilots/dynamodb.pilot.ts +59 -0
  327. package/src/components/pilots/jar-emr.pilot.ts +69 -0
  328. package/src/components/pilots/lambda.pilot.ts +55 -0
  329. package/src/components/pilots/neo4j-fanout.pilot.ts +92 -0
  330. package/src/components/pilots/pilots-lint-clean.test.ts +78 -0
  331. package/src/components/pilots/pilots.test.ts +126 -0
  332. package/src/components/pilots/project.ts +13 -0
  333. package/src/components/presets/comp007-reduction.test.ts +122 -0
  334. package/src/components/presets/ecs-fargate.test.ts +84 -0
  335. package/src/components/presets/ecs-fargate.ts +103 -0
  336. package/src/components/presets/index.ts +32 -0
  337. package/src/components/presets/lambda.test.ts +35 -0
  338. package/src/components/presets/lambda.ts +53 -0
  339. package/src/components/presets/single-host-compose.test.ts +65 -0
  340. package/src/components/presets/single-host-compose.ts +64 -0
  341. package/src/components/registry.test.ts +112 -0
  342. package/src/components/registry.ts +37 -0
  343. package/src/components/starter-plugin.ts +105 -0
  344. package/src/components/temporal-codegen-loader.ts +41 -0
  345. package/src/components/verbs/__fixtures__/package-lock.json +45 -0
  346. package/src/components/verbs/__fixtures__/pom.xml +37 -0
  347. package/src/components/verbs/__fixtures__/schemas/cyclonedx-1.5.schema.json +3800 -0
  348. package/src/components/verbs/__fixtures__/schemas/cyclonedx-spdx-license.schema.json +621 -0
  349. package/src/components/verbs/__fixtures__/schemas/jsf-0.82.schema.json +240 -0
  350. package/src/components/verbs/__fixtures__/schemas/spdx-2.3.schema.json +740 -0
  351. package/src/components/verbs/__tests__/mock-cloud-executor.ts +102 -0
  352. package/src/components/verbs/__tests__/mock-process-runner.ts +79 -0
  353. package/src/components/verbs/__tests__/mock-sbom-generator.ts +85 -0
  354. package/src/components/verbs/bom-writer.test.ts +331 -0
  355. package/src/components/verbs/bom-writer.ts +386 -0
  356. package/src/components/verbs/build-archive.test.ts +251 -0
  357. package/src/components/verbs/build-archive.ts +296 -0
  358. package/src/components/verbs/build.test.ts +222 -0
  359. package/src/components/verbs/build.ts +252 -0
  360. package/src/components/verbs/cloud-executor.ts +181 -0
  361. package/src/components/verbs/component-bom.test.ts +219 -0
  362. package/src/components/verbs/component-bom.ts +189 -0
  363. package/src/components/verbs/index.ts +49 -0
  364. package/src/components/verbs/license-policy.ts +115 -0
  365. package/src/components/verbs/lockfile-sbom-generator.test.ts +195 -0
  366. package/src/components/verbs/lockfile-sbom-generator.ts +236 -0
  367. package/src/components/verbs/process-runner.test.ts +79 -0
  368. package/src/components/verbs/process-runner.ts +113 -0
  369. package/src/components/verbs/reproducibility.test.ts +24 -0
  370. package/src/components/verbs/reproducibility.ts +100 -0
  371. package/src/components/verbs/sbom-generator.test.ts +96 -0
  372. package/src/components/verbs/sbom-generator.ts +209 -0
  373. package/src/components/verbs/sbom.test.ts +184 -0
  374. package/src/components/verbs/sbom.ts +152 -0
  375. package/src/components/verbs/shell.test.ts +36 -0
  376. package/src/components/verbs/shell.ts +51 -0
  377. package/src/components/verbs/sign.test.ts +210 -0
  378. package/src/components/verbs/sign.ts +350 -0
  379. package/src/components/verbs/stub.ts +34 -0
  380. package/src/components/verbs/tool-sbom-generator.test.ts +194 -0
  381. package/src/components/verbs/tool-sbom-generator.ts +192 -0
  382. package/src/components/verbs/verify.test.ts +159 -0
  383. package/src/components/verbs/verify.ts +179 -0
  384. package/src/components/verbs/vex.ts +182 -0
  385. package/src/components/verbs/vuln-gate.test.ts +201 -0
  386. package/src/components/verbs/vuln-gate.ts +170 -0
  387. package/src/components/verbs/vuln-scan.test.ts +145 -0
  388. package/src/components/verbs/vuln-scan.ts +266 -0
  389. package/src/components/verbs/wait-verify.test.ts +111 -0
  390. package/src/components/verbs/wait-verify.ts +171 -0
  391. package/src/config.test.ts +74 -1
  392. package/src/config.ts +219 -0
  393. package/src/index.ts +32 -0
  394. package/src/lexicon.ts +88 -0
  395. package/src/lifecycle/build-ledger-store.test.ts +217 -0
  396. package/src/lifecycle/build-ledger-store.ts +165 -0
  397. package/src/lifecycle/build-ledger.test.ts +349 -0
  398. package/src/lifecycle/build-ledger.ts +305 -0
  399. package/src/lifecycle/git.test.ts +118 -0
  400. package/src/lifecycle/git.ts +149 -14
  401. package/src/lifecycle/index.ts +5 -0
  402. package/src/lifecycle/oras-referrer-lookup.test.ts +116 -0
  403. package/src/lifecycle/oras-referrer-lookup.ts +110 -0
  404. package/src/lifecycle/release-ledger.test.ts +209 -0
  405. package/src/lifecycle/release-ledger.ts +185 -0
  406. package/src/lifecycle/status.test.ts +330 -0
  407. package/src/lifecycle/status.ts +278 -0
  408. package/src/lint/component-checks.ts +148 -0
  409. package/src/lint/config.test.ts +21 -0
  410. package/src/lint/engine.ts +11 -2
  411. package/src/lint/presets/relaxed.json +8 -1
  412. package/src/lint/presets/strict.json +8 -1
  413. package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.ts +9 -0
  414. package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.ts +9 -0
  415. package/src/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.ts +11 -0
  416. package/src/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.ts +13 -0
  417. package/src/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.ts +11 -0
  418. package/src/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.ts +27 -0
  419. package/src/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.ts +10 -0
  420. package/src/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.ts +23 -0
  421. package/src/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.ts +10 -0
  422. package/src/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.ts +19 -0
  423. package/src/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.ts +10 -0
  424. package/src/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.ts +20 -0
  425. package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +23 -0
  426. package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +10 -0
  427. package/src/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.ts +14 -0
  428. package/src/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.ts +18 -0
  429. package/src/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.ts +10 -0
  430. package/src/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.ts +14 -0
  431. package/src/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.ts +13 -0
  432. package/src/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.ts +13 -0
  433. package/src/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.ts +12 -0
  434. package/src/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.ts +18 -0
  435. package/src/lint/rules/comp/comp.test.ts +378 -0
  436. package/src/lint/rules/comp/comp001-publishes-never-applies.ts +78 -0
  437. package/src/lint/rules/comp/comp002-dangling-wiring-ref.ts +94 -0
  438. package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +115 -0
  439. package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +66 -0
  440. package/src/lint/rules/comp/comp005-capability-kind-is-noun.ts +113 -0
  441. package/src/lint/rules/comp/comp006-shell-needs-reason.ts +55 -0
  442. package/src/lint/rules/comp/comp007-composition-sprawl.ts +71 -0
  443. package/src/lint/rules/comp/index.ts +37 -0
  444. package/src/lint/rules/comp/support.ts +173 -0
  445. package/src/lsp/lexicon-providers.test.ts +55 -0
  446. package/src/lsp/lexicon-providers.ts +13 -3
  447. package/src/op/activity-registry.test.ts +38 -0
  448. package/src/op/activity-registry.ts +31 -12
  449. package/src/op/activity-runtime.ts +73 -0
  450. package/src/op/builders.ts +92 -0
  451. package/src/op/index.ts +3 -1
  452. package/src/ownership.test.ts +24 -26
  453. package/src/ownership.ts +26 -38
@@ -0,0 +1,423 @@
1
+ /**
2
+ * Pinned-version upgrade detection for k8s, gcp, docker, gitlab lexicons.
3
+ *
4
+ * For each lexicon with a pinned upstream version constant, this module:
5
+ * 1. Reads the currently pinned version from the source file.
6
+ * 2. Queries upstream for the latest stable release tag (no pre-release/rc).
7
+ * 3. Compares using semver ordering. If a newer version exists:
8
+ * a. Edits the version constant in the source file.
9
+ * b. Invokes regenLexicon to regenerate and surface-diff.
10
+ * c. Reverts the constant edit (dry-run mode — never commits the bump).
11
+ * 4. Returns a structured report per lexicon.
12
+ *
13
+ * The upstream-query functions are injectable — pass a mock for unit tests.
14
+ * The actual HTTP calls use the GitHub Releases/Tags API.
15
+ *
16
+ * Design decisions:
17
+ * - "Latest stable" = highest semver excluding tags containing rc/alpha/beta/preview.
18
+ * - The bump is always reverted after regen so the working tree is unchanged.
19
+ * Only the CLI reporter (#527) actually creates branches/PRs.
20
+ * - Each lexicon's upstream query is a pure async function: () => Promise<string | null>
21
+ * (returns the latest version tag, or null when no stable release is found).
22
+ */
23
+
24
+ import { readFileSync, writeFileSync } from "fs";
25
+ import { join } from "path";
26
+ import { regenLexicon, type RegenResult } from "./lexicon-regen";
27
+ import { fetchWithRetry } from "./fetch";
28
+ import { isLexiconPlugin, type UpstreamPin } from "../lexicon";
29
+
30
+ // ── Public types ──────────────────────────────────────────────────────
31
+
32
+ /**
33
+ * A pinned, self-upgradable lexicon's name (e.g. "k8s"). Any lexicon whose
34
+ * plugin declares `upstreamPin` (../lexicon.ts) is eligible — the set is no
35
+ * longer hard-coded here.
36
+ */
37
+ export type LexiconId = string;
38
+
39
+ export type { UpstreamPin };
40
+
41
+ export interface UpgradeCheckResult {
42
+ /** Lexicon identifier. */
43
+ lexicon: LexiconId;
44
+ /** Whether a newer stable upstream version was found. */
45
+ hasUpgrade: boolean;
46
+ /** Current pinned version string (e.g. "v1.32.0"). */
47
+ from: string;
48
+ /** Latest upstream version string, if one was found (e.g. "v1.33.0"). */
49
+ to: string | null;
50
+ /** Regen/surface-diff result — only present when hasUpgrade is true. */
51
+ validation: RegenResult | null;
52
+ /** Human-readable error when the upstream query itself failed. */
53
+ fetchError: string | null;
54
+ }
55
+
56
+ /** Injectable upstream version resolver. Returns the latest stable tag or null. */
57
+ export type UpstreamResolver = () => Promise<string | null>;
58
+
59
+ export interface CheckPinnedUpgradeOptions {
60
+ /** Resolved path to the lexicon root (e.g. /repo/lexicons/k8s). */
61
+ lexiconDir: string;
62
+ /** Which lexicon to check. */
63
+ lexicon: LexiconId;
64
+ /**
65
+ * Override the upstream resolver (useful in tests to inject mocks).
66
+ * When omitted the real GitHub API is called.
67
+ */
68
+ resolverOverride?: UpstreamResolver;
69
+ /**
70
+ * When true, pass force=true to regenLexicon so the spec cache is bypassed.
71
+ * Default: false (use cached spec for the upgrade check).
72
+ */
73
+ force?: boolean;
74
+ /** Forward to regenLexicon. */
75
+ verbose?: boolean;
76
+ /** Forward to regenLexicon — skip tsc step for speed in tests. */
77
+ skipBuild?: boolean;
78
+ /** Forward to regenLexicon. */
79
+ skipBundle?: boolean;
80
+ /** Forward to regenLexicon. */
81
+ skipLint?: boolean;
82
+ }
83
+
84
+ // ── Version comparison ────────────────────────────────────────────────
85
+
86
+ /**
87
+ * Parse a version string into numeric segments.
88
+ *
89
+ * Strips leading "v" and any build-metadata suffix after "-".
90
+ * Returns null when the string is not a parseable version.
91
+ */
92
+ export function parseVersion(tag: string): number[] | null {
93
+ // Strip leading "v"
94
+ const core = tag.startsWith("v") ? tag.slice(1) : tag;
95
+ // Strip build metadata suffix (e.g. "-ee" from "17.8.1-ee")
96
+ const base = core.split("-")[0];
97
+ if (!base) return null;
98
+ const parts = base.split(".").map(Number);
99
+ if (parts.some((n) => Number.isNaN(n) || n < 0)) return null;
100
+ if (parts.length === 0) return null;
101
+ return parts;
102
+ }
103
+
104
+ /**
105
+ * Compare two version tuples lexicographically.
106
+ * Returns -1 when a < b, 0 when equal, +1 when a > b.
107
+ */
108
+ export function compareVersionTuples(a: number[], b: number[]): -1 | 0 | 1 {
109
+ const len = Math.max(a.length, b.length);
110
+ for (let i = 0; i < len; i++) {
111
+ const av = a[i] ?? 0;
112
+ const bv = b[i] ?? 0;
113
+ if (av < bv) return -1;
114
+ if (av > bv) return 1;
115
+ }
116
+ return 0;
117
+ }
118
+
119
+ /**
120
+ * Return true when `candidate` is strictly newer than `current`.
121
+ *
122
+ * Strips build-metadata suffixes (e.g. "-ee") before comparing so that
123
+ * "v17.9.0-ee" and "v17.9.0" compare by numeric part only.
124
+ */
125
+ export function isNewer(candidate: string, current: string): boolean {
126
+ const a = parseVersion(candidate);
127
+ const b = parseVersion(current);
128
+ if (!a || !b) return false;
129
+ return compareVersionTuples(a, b) > 0;
130
+ }
131
+
132
+ /**
133
+ * Return true when a release tag looks like a pre-release.
134
+ * Filters out rc, alpha, beta, preview, nightly, dev, canary suffixes.
135
+ */
136
+ export function isPreRelease(tag: string): boolean {
137
+ return /[\-_\.](rc|alpha|beta|preview|nightly|dev|canary)\d*/i.test(tag);
138
+ }
139
+
140
+ // ── Pin constant locations ────────────────────────────────────────────
141
+
142
+ interface PinLocation {
143
+ /** Absolute path to the file containing the version constant. */
144
+ filePath: string;
145
+ /** Regex that matches the full constant line (must have a capture for the version). */
146
+ pattern: RegExp;
147
+ /** Function to build the replacement line given the new version string. */
148
+ buildReplacement: (newVersion: string, oldVersion: string, line: string) => string;
149
+ }
150
+
151
+ /**
152
+ * Read the current pinned version from a source file using a regex pattern.
153
+ * Returns null when the pattern is not found.
154
+ */
155
+ export function readPinnedVersion(location: PinLocation): string | null {
156
+ let content: string;
157
+ try {
158
+ content = readFileSync(location.filePath, "utf-8");
159
+ } catch {
160
+ return null;
161
+ }
162
+ const match = location.pattern.exec(content);
163
+ return match ? (match[1] ?? null) : null;
164
+ }
165
+
166
+ /**
167
+ * Apply a version bump by replacing the constant in the source file.
168
+ * Returns the original file content so it can be reverted.
169
+ */
170
+ export function applyVersionBump(location: PinLocation, newVersion: string): string {
171
+ const original = readFileSync(location.filePath, "utf-8");
172
+ const lines = original.split("\n");
173
+ const updated = lines.map((line) => {
174
+ const match = location.pattern.exec(line);
175
+ if (!match) return line;
176
+ const currentVersion = match[1] ?? "";
177
+ return location.buildReplacement(newVersion, currentVersion, line);
178
+ });
179
+ writeFileSync(location.filePath, updated.join("\n"), "utf-8");
180
+ return original;
181
+ }
182
+
183
+ /**
184
+ * Revert a file to its original content (undo a bump).
185
+ */
186
+ export function revertVersionBump(filePath: string, original: string): void {
187
+ writeFileSync(filePath, original, "utf-8");
188
+ }
189
+
190
+ // ── Pin descriptor, loaded from the lexicon plugin ────────────────────
191
+
192
+ /**
193
+ * Load a lexicon's `upstreamPin` descriptor from its plugin package
194
+ * (`@intentius/chant-lexicon-<name>`) — the lexicon's own declaration of where
195
+ * its version constant lives and which upstream repo to check. Returns null
196
+ * when the package can't be resolved or declares no `upstreamPin` (i.e. it is
197
+ * not self-upgradable). Mirrors ../components/capability-plugin-loader.ts's
198
+ * lexicon-borne loading.
199
+ */
200
+ export async function loadUpstreamPin(lexicon: LexiconId): Promise<UpstreamPin | null> {
201
+ let mod: Record<string, unknown>;
202
+ try {
203
+ mod = (await import(`@intentius/chant-lexicon-${lexicon}`)) as Record<string, unknown>;
204
+ } catch {
205
+ return null;
206
+ }
207
+ for (const value of Object.values(mod)) {
208
+ if (isLexiconPlugin(value) && value.upstreamPin) return value.upstreamPin;
209
+ }
210
+ return null;
211
+ }
212
+
213
+ /** Build a concrete `PinLocation` (absolute path + patterns) from a lexicon's descriptor and its checkout dir. */
214
+ function pinLocationFrom(pin: UpstreamPin, lexiconDir: string): PinLocation {
215
+ return {
216
+ filePath: join(lexiconDir, pin.file),
217
+ pattern: pin.pattern,
218
+ buildReplacement: (newVer, _old, line) => pin.replace(newVer, line),
219
+ };
220
+ }
221
+
222
+ // ── Real upstream resolvers ───────────────────────────────────────────
223
+
224
+ /**
225
+ * Fetch GitHub releases or tags from the given repo and return the
226
+ * latest stable version tag (highest semver, no pre-release).
227
+ *
228
+ * `kind` selects whether to use the releases API (which has published
229
+ * stable releases) or the tags API (which has every git tag).
230
+ *
231
+ * `tagSuffix` filters tags to only those ending with the given string
232
+ * (e.g. "-ee" for GitLab).
233
+ */
234
+ async function latestGitHubRelease(
235
+ owner: string,
236
+ repo: string,
237
+ kind: "releases" | "tags",
238
+ tagSuffix?: string,
239
+ ): Promise<string | null> {
240
+ const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;
241
+ const headers: Record<string, string> = {
242
+ Accept: "application/vnd.github+json",
243
+ "X-GitHub-Api-Version": "2022-11-28",
244
+ };
245
+ if (token) headers["Authorization"] = `Bearer ${token}`;
246
+
247
+ const url = `https://api.github.com/repos/${owner}/${repo}/${kind}?per_page=50`;
248
+
249
+ const resp = await fetchWithRetry(url, 4, 1000, { headers });
250
+
251
+ const items = (await resp.json()) as Array<{
252
+ tag_name?: string;
253
+ name?: string;
254
+ prerelease?: boolean;
255
+ }>;
256
+
257
+ let best: string | null = null;
258
+ let bestParsed: number[] | null = null;
259
+
260
+ for (const item of items) {
261
+ const rawTag = kind === "releases" ? (item.tag_name ?? "") : (item.name ?? "");
262
+ if (!rawTag) continue;
263
+
264
+ // For releases, the GitHub API pre-release flag is authoritative
265
+ if (kind === "releases" && item.prerelease === true) continue;
266
+
267
+ // Additional pre-release guard on tag name
268
+ if (isPreRelease(rawTag)) continue;
269
+
270
+ // Apply optional suffix filter (e.g. "-ee" for GitLab)
271
+ if (tagSuffix && !rawTag.endsWith(tagSuffix)) continue;
272
+
273
+ const parsed = parseVersion(rawTag);
274
+ if (!parsed) continue;
275
+
276
+ if (!bestParsed || compareVersionTuples(parsed, bestParsed) > 0) {
277
+ best = rawTag;
278
+ bestParsed = parsed;
279
+ }
280
+ }
281
+
282
+ return best;
283
+ }
284
+
285
+ /** Build the real GitHub-backed upstream resolver from a lexicon's declared `upstream` descriptor. */
286
+ function resolverFor(pin: UpstreamPin): UpstreamResolver {
287
+ return () => latestGitHubRelease(pin.upstream.owner, pin.upstream.repo, pin.upstream.kind, pin.upstream.tagSuffix);
288
+ }
289
+
290
+ // ── Main function ─────────────────────────────────────────────────────
291
+
292
+ /**
293
+ * Check whether a newer upstream release exists for a pinned lexicon.
294
+ *
295
+ * When a newer version is found:
296
+ * 1. Applies the version bump to the source constant.
297
+ * 2. Runs regenLexicon (surface-diff pipeline).
298
+ * 3. Reverts the bump unconditionally.
299
+ *
300
+ * The caller receives the full result including the regen validation output
301
+ * without any lasting change to the working tree.
302
+ */
303
+ export async function checkPinnedUpgrade(opts: CheckPinnedUpgradeOptions): Promise<UpgradeCheckResult> {
304
+ const { lexiconDir, lexicon, force = false, verbose = false, skipBuild, skipBundle, skipLint } = opts;
305
+
306
+ const pin = await loadUpstreamPin(lexicon);
307
+ if (!pin) {
308
+ return {
309
+ lexicon,
310
+ hasUpgrade: false,
311
+ from: "(unknown)",
312
+ to: null,
313
+ validation: null,
314
+ fetchError: `Lexicon "${lexicon}" declares no upstreamPin (not self-upgradable), or its plugin package could not be loaded.`,
315
+ };
316
+ }
317
+ const location = pinLocationFrom(pin, lexiconDir);
318
+
319
+ // Read current pin
320
+ const from = readPinnedVersion(location);
321
+ if (!from) {
322
+ return {
323
+ lexicon,
324
+ hasUpgrade: false,
325
+ from: "(unknown)",
326
+ to: null,
327
+ validation: null,
328
+ fetchError: `Could not read pinned version constant from ${location.filePath}`,
329
+ };
330
+ }
331
+
332
+ // Query upstream
333
+ const resolver = opts.resolverOverride ?? resolverFor(pin);
334
+ let latestTag: string | null;
335
+ try {
336
+ latestTag = await resolver();
337
+ } catch (e) {
338
+ return {
339
+ lexicon,
340
+ hasUpgrade: false,
341
+ from,
342
+ to: null,
343
+ validation: null,
344
+ fetchError: String(e),
345
+ };
346
+ }
347
+
348
+ if (!latestTag || !isNewer(latestTag, from)) {
349
+ return {
350
+ lexicon,
351
+ hasUpgrade: false,
352
+ from,
353
+ to: latestTag,
354
+ validation: null,
355
+ fetchError: null,
356
+ };
357
+ }
358
+
359
+ // Apply bump, regen, then revert
360
+ let originalContent: string;
361
+ try {
362
+ originalContent = applyVersionBump(location, latestTag);
363
+ } catch (e) {
364
+ return {
365
+ lexicon,
366
+ hasUpgrade: true,
367
+ from,
368
+ to: latestTag,
369
+ validation: null,
370
+ fetchError: `Failed to apply version bump to ${location.filePath}: ${String(e)}`,
371
+ };
372
+ }
373
+
374
+ let validation: RegenResult;
375
+ try {
376
+ validation = await regenLexicon({
377
+ lexiconDir,
378
+ force,
379
+ verbose,
380
+ skipBuild: skipBuild ?? false,
381
+ skipBundle: skipBundle ?? false,
382
+ skipLint: skipLint ?? false,
383
+ skipExamples: true,
384
+ });
385
+ } finally {
386
+ // Always revert — even if regenLexicon throws
387
+ revertVersionBump(location.filePath, originalContent);
388
+ }
389
+
390
+ return {
391
+ lexicon,
392
+ hasUpgrade: true,
393
+ from,
394
+ to: latestTag,
395
+ validation,
396
+ fetchError: null,
397
+ };
398
+ }
399
+
400
+ // ── Branch-commit helper ──────────────────────────────────────────────
401
+
402
+ /**
403
+ * Apply a version bump for a lexicon permanently (without reverting).
404
+ *
405
+ * Called by LexiconUpgradeOp when it has already decided to commit the bump
406
+ * to a branch. Returns the absolute path to the modified file so the caller
407
+ * can stage it with `git add`.
408
+ *
409
+ * Unlike `applyVersionBump` (which is generic), this function takes only a
410
+ * lexicon id and directory — it resolves the pin location from the lexicon's
411
+ * declared `upstreamPin` descriptor.
412
+ */
413
+ export async function applyPinnedVersionBump(
414
+ lexicon: LexiconId,
415
+ lexiconDir: string,
416
+ newVersion: string,
417
+ ): Promise<{ filePath: string }> {
418
+ const pin = await loadUpstreamPin(lexicon);
419
+ if (!pin) throw new Error(`Lexicon "${lexicon}" declares no upstreamPin (not self-upgradable).`);
420
+ const location = pinLocationFrom(pin, lexiconDir);
421
+ applyVersionBump(location, newVersion);
422
+ return { filePath: location.filePath };
423
+ }