@intentius/chant 0.100.0 → 0.102.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 (608) hide show
  1. package/dist/agents/checks.d.ts.map +1 -1
  2. package/dist/attrref.d.ts.map +1 -1
  3. package/dist/audit/discover.d.ts.map +1 -1
  4. package/dist/audit/nginx.d.ts.map +1 -1
  5. package/dist/audit/prior-art.d.ts +48 -0
  6. package/dist/audit/prior-art.d.ts.map +1 -1
  7. package/dist/behaviour-kinds.d.ts.map +1 -1
  8. package/dist/build.d.ts +6 -0
  9. package/dist/build.d.ts.map +1 -1
  10. package/dist/builder.d.ts.map +1 -1
  11. package/dist/cli/build-options.d.ts +2 -0
  12. package/dist/cli/build-options.d.ts.map +1 -1
  13. package/dist/cli/commands/build.d.ts.map +1 -1
  14. package/dist/cli/commands/carve-emit.d.ts.map +1 -1
  15. package/dist/cli/commands/check-lexicon.d.ts +16 -0
  16. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  17. package/dist/cli/commands/import.d.ts +8 -0
  18. package/dist/cli/commands/import.d.ts.map +1 -1
  19. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  20. package/dist/cli/commands/init.d.ts +19 -0
  21. package/dist/cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/commands/onboard.d.ts +9 -0
  23. package/dist/cli/commands/onboard.d.ts.map +1 -1
  24. package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
  25. package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
  26. package/dist/cli/handlers/dev.d.ts.map +1 -1
  27. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  28. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  29. package/dist/cli/handlers/misc.d.ts.map +1 -1
  30. package/dist/cli/handlers/operator.d.ts +9 -0
  31. package/dist/cli/handlers/operator.d.ts.map +1 -1
  32. package/dist/cli/handlers/run.d.ts.map +1 -1
  33. package/dist/cli/lsp/server.d.ts.map +1 -1
  34. package/dist/cli/main.d.ts.map +1 -1
  35. package/dist/cli/mcp/server.d.ts.map +1 -1
  36. package/dist/cli/mcp/tools/build.d.ts.map +1 -1
  37. package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
  38. package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
  39. package/dist/cli/mcp/tools/import.d.ts.map +1 -1
  40. package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
  41. package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
  42. package/dist/cli/mcp/tools/search.d.ts.map +1 -1
  43. package/dist/cli/mcp/workspace-tools.d.ts +9 -1
  44. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  45. package/dist/cli/registry.d.ts +33 -2
  46. package/dist/cli/registry.d.ts.map +1 -1
  47. package/dist/codegen/fetch.d.ts.map +1 -1
  48. package/dist/codegen/naming.d.ts.map +1 -1
  49. package/dist/codegen/pinned-upgrade.d.ts +67 -3
  50. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  51. package/dist/codegen/registry.d.ts.map +1 -1
  52. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  53. package/dist/components/capability.d.ts.map +1 -1
  54. package/dist/components/driver.d.ts.map +1 -1
  55. package/dist/components/fan-out.d.ts.map +1 -1
  56. package/dist/components/starter-plugin.d.ts.map +1 -1
  57. package/dist/components/verbs/process-runner.d.ts.map +1 -1
  58. package/dist/components/verbs/r2-sync.d.ts.map +1 -1
  59. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  60. package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
  61. package/dist/components/verbs/sign.d.ts.map +1 -1
  62. package/dist/components/verbs/verify.d.ts.map +1 -1
  63. package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
  64. package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
  65. package/dist/components/verbs/wrangler.d.ts.map +1 -1
  66. package/dist/composite.d.ts.map +1 -1
  67. package/dist/config.d.ts +30 -7
  68. package/dist/config.d.ts.map +1 -1
  69. package/dist/declarable.d.ts +16 -0
  70. package/dist/declarable.d.ts.map +1 -1
  71. package/dist/discovery/cache.d.ts.map +1 -1
  72. package/dist/discovery/fold-import.d.ts +15 -5
  73. package/dist/discovery/fold-import.d.ts.map +1 -1
  74. package/dist/discovery/param-deps.d.ts +16 -0
  75. package/dist/discovery/param-deps.d.ts.map +1 -1
  76. package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
  77. package/dist/discovery/specifier-resolve.d.ts +37 -0
  78. package/dist/discovery/specifier-resolve.d.ts.map +1 -0
  79. package/dist/errors.d.ts.map +1 -1
  80. package/dist/fold/fold.d.ts +3 -1
  81. package/dist/fold/fold.d.ts.map +1 -1
  82. package/dist/graph-detail.d.ts.map +1 -1
  83. package/dist/graph-ir.d.ts.map +1 -1
  84. package/dist/graph-layout.d.ts.map +1 -1
  85. package/dist/import/base-parser.d.ts.map +1 -1
  86. package/dist/import/embedded.d.ts +7 -0
  87. package/dist/import/embedded.d.ts.map +1 -1
  88. package/dist/import/parser-options.d.ts +14 -0
  89. package/dist/import/parser-options.d.ts.map +1 -0
  90. package/dist/import/parser.d.ts +17 -0
  91. package/dist/import/parser.d.ts.map +1 -1
  92. package/dist/kubectl-context.d.ts.map +1 -1
  93. package/dist/lexicon-output.d.ts.map +1 -1
  94. package/dist/lexicon-schema.d.ts +3 -3
  95. package/dist/lexicon.d.ts +78 -3
  96. package/dist/lexicon.d.ts.map +1 -1
  97. package/dist/lifecycle/assert-live.d.ts.map +1 -1
  98. package/dist/lifecycle/gate-ledger.d.ts +15 -0
  99. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  100. package/dist/lifecycle/git.d.ts.map +1 -1
  101. package/dist/lifecycle/member-ledger.d.ts.map +1 -1
  102. package/dist/lifecycle/observe.d.ts.map +1 -1
  103. package/dist/lifecycle/plan-digest.d.ts +26 -5
  104. package/dist/lifecycle/plan-digest.d.ts.map +1 -1
  105. package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
  106. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  107. package/dist/lifecycle/scenario.d.ts.map +1 -1
  108. package/dist/lifecycle/status.d.ts.map +1 -1
  109. package/dist/lifecycle/work-lease.d.ts +61 -2
  110. package/dist/lifecycle/work-lease.d.ts.map +1 -1
  111. package/dist/lint/config.d.ts +4 -4
  112. package/dist/lint/engine.d.ts +6 -0
  113. package/dist/lint/engine.d.ts.map +1 -1
  114. package/dist/lsp/lexicon-providers.d.ts.map +1 -1
  115. package/dist/op/activities/activity-contracts.d.ts +12 -11
  116. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  117. package/dist/op/activities/apply.d.ts +79 -9
  118. package/dist/op/activities/apply.d.ts.map +1 -1
  119. package/dist/op/activities/decide.d.ts.map +1 -1
  120. package/dist/op/activities/index.d.ts +1 -1
  121. package/dist/op/activities/index.d.ts.map +1 -1
  122. package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
  123. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
  124. package/dist/op/activities/propose-upgrade.d.ts +2 -0
  125. package/dist/op/activities/propose-upgrade.d.ts.map +1 -1
  126. package/dist/op/activity-contract.d.ts +1 -1
  127. package/dist/op/activity-failure.d.ts.map +1 -1
  128. package/dist/op/activity-profiles.d.ts.map +1 -1
  129. package/dist/op/builders.d.ts.map +1 -1
  130. package/dist/op/composites/apply-op.d.ts +12 -5
  131. package/dist/op/composites/apply-op.d.ts.map +1 -1
  132. package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
  133. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
  134. package/dist/op/decide-backend.d.ts.map +1 -1
  135. package/dist/op/decide-read-inputs.d.ts.map +1 -1
  136. package/dist/op/emulator-lifecycle.d.ts +21 -2
  137. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  138. package/dist/op/gate-approval.d.ts +5 -1
  139. package/dist/op/gate-approval.d.ts.map +1 -1
  140. package/dist/op/gate-wait.d.ts.map +1 -1
  141. package/dist/op/gate.d.ts +19 -3
  142. package/dist/op/gate.d.ts.map +1 -1
  143. package/dist/op/index.d.ts +3 -1
  144. package/dist/op/index.d.ts.map +1 -1
  145. package/dist/op/local-executor.d.ts +6 -0
  146. package/dist/op/local-executor.d.ts.map +1 -1
  147. package/dist/op/operator.d.ts.map +1 -1
  148. package/dist/op/run-context.d.ts +39 -0
  149. package/dist/op/run-context.d.ts.map +1 -0
  150. package/dist/op/run-live.d.ts.map +1 -1
  151. package/dist/op/runtimes/local.d.ts.map +1 -1
  152. package/dist/op/source-archive.d.ts.map +1 -1
  153. package/dist/op/steward-beside.d.ts.map +1 -1
  154. package/dist/op/steward-points.d.ts.map +1 -1
  155. package/dist/op/steward.d.ts.map +1 -1
  156. package/dist/op/types.d.ts +8 -3
  157. package/dist/op/types.d.ts.map +1 -1
  158. package/dist/op/work-lease-run.d.ts +24 -4
  159. package/dist/op/work-lease-run.d.ts.map +1 -1
  160. package/dist/project-root.d.ts.map +1 -1
  161. package/dist/provenance.d.ts +21 -0
  162. package/dist/provenance.d.ts.map +1 -1
  163. package/dist/pseudo-parameter.d.ts.map +1 -1
  164. package/dist/reconcile.d.ts.map +1 -1
  165. package/dist/secret-materialization.d.ts.map +1 -1
  166. package/dist/serializer.d.ts +8 -0
  167. package/dist/serializer.d.ts.map +1 -1
  168. package/dist/telemetry-attribution.d.ts +77 -0
  169. package/dist/telemetry-attribution.d.ts.map +1 -0
  170. package/dist/terraform/emit-source.d.ts.map +1 -1
  171. package/dist/terraform/parse.d.ts.map +1 -1
  172. package/dist/testing.d.ts.map +1 -1
  173. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  174. package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
  175. package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
  176. package/dist/workspace/agent-cli.d.ts +88 -0
  177. package/dist/workspace/agent-cli.d.ts.map +1 -0
  178. package/dist/workspace/box-factory.d.ts +73 -0
  179. package/dist/workspace/box-factory.d.ts.map +1 -0
  180. package/dist/workspace/changes-cli.d.ts.map +1 -1
  181. package/dist/workspace/changes.d.ts +8 -1
  182. package/dist/workspace/changes.d.ts.map +1 -1
  183. package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
  184. package/dist/workspace/checks/boxes.d.ts.map +1 -1
  185. package/dist/workspace/checks/links.d.ts +1 -0
  186. package/dist/workspace/checks/links.d.ts.map +1 -1
  187. package/dist/workspace/checks/live.d.ts +40 -0
  188. package/dist/workspace/checks/live.d.ts.map +1 -0
  189. package/dist/workspace/checks.d.ts +26 -2
  190. package/dist/workspace/checks.d.ts.map +1 -1
  191. package/dist/workspace/compose-graph.d.ts +73 -0
  192. package/dist/workspace/compose-graph.d.ts.map +1 -1
  193. package/dist/workspace/conformance/index.d.ts +67 -6
  194. package/dist/workspace/conformance/index.d.ts.map +1 -1
  195. package/dist/workspace/conformance/vitest.d.ts +12 -3
  196. package/dist/workspace/conformance/vitest.d.ts.map +1 -1
  197. package/dist/workspace/conformance/writer.d.ts +368 -0
  198. package/dist/workspace/conformance/writer.d.ts.map +1 -0
  199. package/dist/workspace/decide.d.ts +1 -1
  200. package/dist/workspace/decide.d.ts.map +1 -1
  201. package/dist/workspace/declaration.d.ts +119 -0
  202. package/dist/workspace/declaration.d.ts.map +1 -1
  203. package/dist/workspace/declaration.schema.json +368 -4
  204. package/dist/workspace/export-cli.d.ts +12 -0
  205. package/dist/workspace/export-cli.d.ts.map +1 -0
  206. package/dist/workspace/export.d.ts +145 -0
  207. package/dist/workspace/export.d.ts.map +1 -0
  208. package/dist/workspace/generated-files.d.ts.map +1 -1
  209. package/dist/workspace/graph-cache.d.ts.map +1 -1
  210. package/dist/workspace/graph-cli.d.ts +2 -0
  211. package/dist/workspace/graph-cli.d.ts.map +1 -1
  212. package/dist/workspace/identity.d.ts +111 -0
  213. package/dist/workspace/identity.d.ts.map +1 -0
  214. package/dist/workspace/import.d.ts +73 -0
  215. package/dist/workspace/import.d.ts.map +1 -0
  216. package/dist/workspace/intent-cli.d.ts +7 -4
  217. package/dist/workspace/intent-cli.d.ts.map +1 -1
  218. package/dist/workspace/intent-record.d.ts +8 -1
  219. package/dist/workspace/intent-record.d.ts.map +1 -1
  220. package/dist/workspace/intent.d.ts +149 -5
  221. package/dist/workspace/intent.d.ts.map +1 -1
  222. package/dist/workspace/kinds.d.ts +24 -6
  223. package/dist/workspace/kinds.d.ts.map +1 -1
  224. package/dist/workspace/lineage-adopt-cli.d.ts +15 -0
  225. package/dist/workspace/lineage-adopt-cli.d.ts.map +1 -0
  226. package/dist/workspace/lineage-adopt.d.ts +106 -0
  227. package/dist/workspace/lineage-adopt.d.ts.map +1 -0
  228. package/dist/workspace/lineage-check.d.ts +9 -2
  229. package/dist/workspace/lineage-check.d.ts.map +1 -1
  230. package/dist/workspace/lineage-cli.d.ts +6 -1
  231. package/dist/workspace/lineage-cli.d.ts.map +1 -1
  232. package/dist/workspace/lineage-hash-index.d.ts +110 -0
  233. package/dist/workspace/lineage-hash-index.d.ts.map +1 -0
  234. package/dist/workspace/lineage-init.d.ts +10 -0
  235. package/dist/workspace/lineage-init.d.ts.map +1 -1
  236. package/dist/workspace/lineage-lock.d.ts +149 -2
  237. package/dist/workspace/lineage-lock.d.ts.map +1 -1
  238. package/dist/workspace/lineage-migrations.d.ts +15 -3
  239. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  240. package/dist/workspace/lineage-provenance.d.ts +18 -0
  241. package/dist/workspace/lineage-provenance.d.ts.map +1 -0
  242. package/dist/workspace/lineage-upgrade-cli.d.ts +2 -0
  243. package/dist/workspace/lineage-upgrade-cli.d.ts.map +1 -1
  244. package/dist/workspace/lineage-upgrade.d.ts +30 -1
  245. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  246. package/dist/workspace/lineage-versions.d.ts +116 -0
  247. package/dist/workspace/lineage-versions.d.ts.map +1 -0
  248. package/dist/workspace/links.d.ts +31 -5
  249. package/dist/workspace/links.d.ts.map +1 -1
  250. package/dist/workspace/ls-generated.d.ts +37 -0
  251. package/dist/workspace/ls-generated.d.ts.map +1 -0
  252. package/dist/workspace/ls.d.ts +4 -0
  253. package/dist/workspace/ls.d.ts.map +1 -1
  254. package/dist/workspace/member-commands.d.ts.map +1 -1
  255. package/dist/workspace/nested-graph.d.ts +56 -0
  256. package/dist/workspace/nested-graph.d.ts.map +1 -0
  257. package/dist/workspace/nesting.d.ts +21 -0
  258. package/dist/workspace/nesting.d.ts.map +1 -0
  259. package/dist/workspace/pin-cli.d.ts +10 -0
  260. package/dist/workspace/pin-cli.d.ts.map +1 -0
  261. package/dist/workspace/pin-integrity.d.ts +51 -0
  262. package/dist/workspace/pin-integrity.d.ts.map +1 -0
  263. package/dist/workspace/points.d.ts.map +1 -1
  264. package/dist/workspace/principal-classes.d.ts +114 -0
  265. package/dist/workspace/principal-classes.d.ts.map +1 -0
  266. package/dist/workspace/reason-codes.d.ts +47 -3
  267. package/dist/workspace/reason-codes.d.ts.map +1 -1
  268. package/dist/workspace/record-assets.d.ts.map +1 -1
  269. package/dist/workspace/record-sessions.d.ts +7 -11
  270. package/dist/workspace/record-sessions.d.ts.map +1 -1
  271. package/dist/workspace/records-checkout.d.ts +54 -0
  272. package/dist/workspace/records-checkout.d.ts.map +1 -0
  273. package/dist/workspace/records-cli.d.ts +57 -2
  274. package/dist/workspace/records-cli.d.ts.map +1 -1
  275. package/dist/workspace/records-close.d.ts +5 -2
  276. package/dist/workspace/records-close.d.ts.map +1 -1
  277. package/dist/workspace/records-since.d.ts.map +1 -1
  278. package/dist/workspace/records-write.d.ts +23 -4
  279. package/dist/workspace/records-write.d.ts.map +1 -1
  280. package/dist/workspace/records.d.ts +58 -5
  281. package/dist/workspace/records.d.ts.map +1 -1
  282. package/dist/workspace/returns.d.ts +129 -0
  283. package/dist/workspace/returns.d.ts.map +1 -0
  284. package/dist/workspace/runs-cli.d.ts +164 -0
  285. package/dist/workspace/runs-cli.d.ts.map +1 -0
  286. package/dist/workspace/runs.d.ts +423 -0
  287. package/dist/workspace/runs.d.ts.map +1 -0
  288. package/dist/workspace/source-block.d.ts +1 -1
  289. package/dist/workspace/source-block.d.ts.map +1 -1
  290. package/dist/workspace/status-gates.d.ts +15 -3
  291. package/dist/workspace/status-gates.d.ts.map +1 -1
  292. package/dist/workspace/status.d.ts +10 -0
  293. package/dist/workspace/status.d.ts.map +1 -1
  294. package/dist/workspace/symbols.d.ts +52 -0
  295. package/dist/workspace/symbols.d.ts.map +1 -0
  296. package/dist/workspace/template-manifest.d.ts +11 -3
  297. package/dist/workspace/template-manifest.d.ts.map +1 -1
  298. package/dist/workspace/trailer-joins.d.ts +46 -0
  299. package/dist/workspace/trailer-joins.d.ts.map +1 -0
  300. package/dist/workspace/trailers.d.ts +89 -0
  301. package/dist/workspace/trailers.d.ts.map +1 -0
  302. package/dist/workspace/trust/attestor.d.ts +8 -0
  303. package/dist/workspace/trust/attestor.d.ts.map +1 -1
  304. package/dist/workspace/trust/dsse.d.ts +58 -0
  305. package/dist/workspace/trust/dsse.d.ts.map +1 -0
  306. package/dist/workspace/trust/evidence-cli.d.ts +66 -0
  307. package/dist/workspace/trust/evidence-cli.d.ts.map +1 -0
  308. package/dist/workspace/trust/evidence.d.ts +93 -0
  309. package/dist/workspace/trust/evidence.d.ts.map +1 -0
  310. package/dist/workspace/trust/policy.d.ts +54 -1
  311. package/dist/workspace/trust/policy.d.ts.map +1 -1
  312. package/dist/workspace/trust/provenance.d.ts +21 -1
  313. package/dist/workspace/trust/provenance.d.ts.map +1 -1
  314. package/dist/workspace/trust/rotation.d.ts +132 -0
  315. package/dist/workspace/trust/rotation.d.ts.map +1 -0
  316. package/dist/workspace/trust/seal.d.ts +33 -0
  317. package/dist/workspace/trust/seal.d.ts.map +1 -1
  318. package/dist/workspace/trust/signers-cli.d.ts +49 -0
  319. package/dist/workspace/trust/signers-cli.d.ts.map +1 -0
  320. package/dist/workspace/trust/ssh-commit.d.ts +12 -0
  321. package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
  322. package/dist/workspace/trust/test-repo.d.ts +13 -0
  323. package/dist/workspace/trust/test-repo.d.ts.map +1 -1
  324. package/dist/workspace/trust/verify.d.ts +15 -0
  325. package/dist/workspace/trust/verify.d.ts.map +1 -1
  326. package/dist/workspace/work-cli.d.ts +39 -3
  327. package/dist/workspace/work-cli.d.ts.map +1 -1
  328. package/dist/workspace/work-evidence.d.ts +1 -1
  329. package/dist/workspace/work-evidence.d.ts.map +1 -1
  330. package/dist/workspace/work.d.ts +26 -1
  331. package/dist/workspace/work.d.ts.map +1 -1
  332. package/dist/workspace/workspace-principals.schema.json +60 -0
  333. package/dist/workspace/write-scope.d.ts +259 -0
  334. package/dist/workspace/write-scope.d.ts.map +1 -0
  335. package/dist/yaml.d.ts +21 -39
  336. package/dist/yaml.d.ts.map +1 -1
  337. package/package.json +2 -2
  338. package/src/audit/prior-art.ts +15 -0
  339. package/src/build.ts +8 -0
  340. package/src/cli/build-options.ts +4 -1
  341. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
  342. package/src/cli/commands/build.ts +2 -0
  343. package/src/cli/commands/carve-emit-state.test.ts +4 -0
  344. package/src/cli/commands/carve-emit.ts +5 -19
  345. package/src/cli/commands/check-lexicon.test.ts +62 -1
  346. package/src/cli/commands/check-lexicon.ts +36 -6
  347. package/src/cli/commands/import-live.test.ts +87 -1
  348. package/src/cli/commands/import-parser-options.test.ts +133 -0
  349. package/src/cli/commands/import.ts +69 -25
  350. package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
  351. package/src/cli/commands/init.test.ts +8 -1
  352. package/src/cli/commands/init.ts +23 -8
  353. package/src/cli/commands/lint.test.ts +37 -0
  354. package/src/cli/commands/onboard.test.ts +53 -3
  355. package/src/cli/commands/onboard.ts +52 -4
  356. package/src/cli/commands/pinned-upgrade.ts +73 -33
  357. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
  358. package/src/cli/handlers/components.ts +2 -2
  359. package/src/cli/handlers/dev.ts +8 -6
  360. package/src/cli/handlers/fan-out.test.ts +6 -6
  361. package/src/cli/handlers/fan-out.ts +2 -1
  362. package/src/cli/handlers/graph.test.ts +42 -0
  363. package/src/cli/handlers/graph.ts +22 -0
  364. package/src/cli/handlers/lifecycle.test.ts +67 -0
  365. package/src/cli/handlers/lifecycle.ts +6 -5
  366. package/src/cli/handlers/misc.ts +2 -0
  367. package/src/cli/handlers/operator.ts +88 -4
  368. package/src/cli/handlers/run.test.ts +111 -0
  369. package/src/cli/handlers/run.ts +85 -24
  370. package/src/cli/handlers/scenario.ts +2 -2
  371. package/src/cli/main.test.ts +33 -0
  372. package/src/cli/main.ts +168 -17
  373. package/src/cli/mcp/workspace-tools.test.ts +5 -2
  374. package/src/cli/mcp/workspace-tools.ts +62 -4
  375. package/src/cli/registry.ts +33 -2
  376. package/src/cli/serve-mcp-workspace.test.ts +1 -1
  377. package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
  378. package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
  379. package/src/codegen/pinned-upgrade.test.ts +104 -0
  380. package/src/codegen/pinned-upgrade.ts +250 -56
  381. package/src/codegen/release-wiring.test.ts +5 -1
  382. package/src/codegen/testdata/postgres-tags.json +242 -0
  383. package/src/components/fan-out-output.test.ts +1 -1
  384. package/src/components/fan-out.test.ts +1 -1
  385. package/src/components/promote.test.ts +1 -1
  386. package/src/config.test.ts +21 -0
  387. package/src/config.ts +27 -0
  388. package/src/content-digest.test.ts +2 -2
  389. package/src/declarable.test.ts +21 -0
  390. package/src/declarable.ts +19 -0
  391. package/src/discovery/fold-composite.test.ts +41 -5
  392. package/src/discovery/fold-import.test.ts +129 -0
  393. package/src/discovery/fold-import.ts +643 -131
  394. package/src/discovery/fold-package-composite.test.ts +264 -0
  395. package/src/discovery/fold-specifiers.test.ts +191 -0
  396. package/src/discovery/param-deps.test.ts +66 -1
  397. package/src/discovery/param-deps.ts +45 -0
  398. package/src/discovery/specifier-resolve.ts +344 -0
  399. package/src/fold/fold.test.ts +39 -1
  400. package/src/fold/fold.ts +83 -9
  401. package/src/fold-provenance.test.ts +140 -0
  402. package/src/graph-ir.test.ts +83 -0
  403. package/src/graph-ir.ts +29 -0
  404. package/src/import/embedded.test.ts +20 -0
  405. package/src/import/embedded.ts +13 -0
  406. package/src/import/parser-options.ts +46 -0
  407. package/src/import/parser.ts +20 -0
  408. package/src/lexicon.ts +79 -3
  409. package/src/lifecycle/gate-ledger.test.ts +14 -0
  410. package/src/lifecycle/gate-ledger.ts +18 -1
  411. package/src/lifecycle/observe.test.ts +18 -0
  412. package/src/lifecycle/observe.ts +6 -4
  413. package/src/lifecycle/plan-digest.test.ts +54 -3
  414. package/src/lifecycle/plan-digest.ts +38 -8
  415. package/src/lifecycle/snapshot.ts +2 -2
  416. package/src/lifecycle/work-lease.test.ts +1 -1
  417. package/src/lifecycle/work-lease.ts +93 -2
  418. package/src/lint/engine.test.ts +55 -0
  419. package/src/lint/engine.ts +30 -4
  420. package/src/lint/output-docs.test.ts +59 -56
  421. package/src/op/activities/activity-contracts.ts +1 -0
  422. package/src/op/activities/apply.test.ts +189 -5
  423. package/src/op/activities/apply.ts +230 -8
  424. package/src/op/activities/index.ts +3 -0
  425. package/src/op/activities/lexicon-upgrade.test.ts +160 -6
  426. package/src/op/activities/lexicon-upgrade.ts +154 -51
  427. package/src/op/activities/propose-upgrade.ts +8 -5
  428. package/src/op/composites/apply-op.ts +12 -5
  429. package/src/op/composites/composites.test.ts +30 -3
  430. package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
  431. package/src/op/composites/lexicon-upgrade-op.ts +29 -8
  432. package/src/op/emulator-lifecycle.test.ts +23 -0
  433. package/src/op/emulator-lifecycle.ts +52 -14
  434. package/src/op/gate-approval.test.ts +91 -0
  435. package/src/op/gate-approval.ts +5 -1
  436. package/src/op/gate.ts +34 -8
  437. package/src/op/index.ts +3 -1
  438. package/src/op/local-executor.test.ts +15 -0
  439. package/src/op/local-executor.ts +40 -12
  440. package/src/op/local-output.ts +1 -1
  441. package/src/op/operator.ts +4 -0
  442. package/src/op/run-context.test.ts +141 -0
  443. package/src/op/run-context.ts +51 -0
  444. package/src/op/runtimes/local.test.ts +14 -0
  445. package/src/op/runtimes/local.ts +2 -0
  446. package/src/op/steward-beside.ts +2 -0
  447. package/src/op/types.ts +8 -3
  448. package/src/op/work-lease-run.test.ts +47 -0
  449. package/src/op/work-lease-run.ts +73 -11
  450. package/src/provenance.ts +35 -0
  451. package/src/serializer.ts +9 -0
  452. package/src/telemetry-attribution.test.ts +91 -0
  453. package/src/telemetry-attribution.ts +145 -0
  454. package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
  455. package/src/workspace/agent-cli.ts +138 -0
  456. package/src/workspace/agent.schema.json +378 -0
  457. package/src/workspace/behold-kinds.test.ts +1 -1
  458. package/src/workspace/box-factory.test.ts +320 -0
  459. package/src/workspace/box-factory.ts +103 -0
  460. package/src/workspace/changes-cli.ts +5 -0
  461. package/src/workspace/changes.schema.json +171 -1
  462. package/src/workspace/changes.ts +61 -4
  463. package/src/workspace/check-live.test.ts +192 -0
  464. package/src/workspace/check.schema.json +64 -0
  465. package/src/workspace/checks/boxes.test.ts +2 -0
  466. package/src/workspace/checks/links.ts +23 -2
  467. package/src/workspace/checks/live.ts +113 -0
  468. package/src/workspace/checks.test.ts +2 -2
  469. package/src/workspace/checks.ts +49 -8
  470. package/src/workspace/compose-graph.test.ts +47 -0
  471. package/src/workspace/compose-graph.ts +127 -3
  472. package/src/workspace/conformance/__fixture__/decisions/decision.kind.mjs +7 -1
  473. package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +5 -0
  474. package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +27 -0
  475. package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +95 -0
  476. package/src/workspace/conformance/__writer_fixture__/decisions/points.json +132 -0
  477. package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +48 -0
  478. package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +108 -0
  479. package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  480. package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  481. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +578 -0
  482. package/src/workspace/conformance/conformance.e2e.test.ts +35 -3
  483. package/src/workspace/conformance/index.mjs +30 -3
  484. package/src/workspace/conformance/index.ts +103 -15
  485. package/src/workspace/conformance/vitest.ts +44 -2
  486. package/src/workspace/conformance/writer-conformance.e2e.test.ts +131 -0
  487. package/src/workspace/conformance/writer.test.ts +156 -0
  488. package/src/workspace/conformance/writer.ts +880 -0
  489. package/src/workspace/decide.ts +7 -1
  490. package/src/workspace/declaration.schema.json +368 -4
  491. package/src/workspace/declaration.ts +270 -1
  492. package/src/workspace/declared-kinds.test.ts +33 -0
  493. package/src/workspace/evidence.schema.json +279 -0
  494. package/src/workspace/export-cli.ts +180 -0
  495. package/src/workspace/export-import.test.ts +282 -0
  496. package/src/workspace/export.ts +486 -0
  497. package/src/workspace/graph-cli.ts +51 -2
  498. package/src/workspace/graph-contract.test.ts +89 -4
  499. package/src/workspace/graph.schema.json +453 -1
  500. package/src/workspace/identity.test.ts +196 -0
  501. package/src/workspace/identity.ts +186 -0
  502. package/src/workspace/import.ts +325 -0
  503. package/src/workspace/intent-cli.ts +64 -10
  504. package/src/workspace/intent-record.schema.json +208 -0
  505. package/src/workspace/intent-record.ts +35 -1
  506. package/src/workspace/intent-why.test.ts +274 -0
  507. package/src/workspace/intent.schema.json +718 -7
  508. package/src/workspace/intent.test.ts +11 -2
  509. package/src/workspace/intent.ts +495 -32
  510. package/src/workspace/kinds.test.ts +5 -5
  511. package/src/workspace/kinds.ts +62 -33
  512. package/src/workspace/lineage-adopt-cli.ts +103 -0
  513. package/src/workspace/lineage-adopt.test.ts +552 -0
  514. package/src/workspace/lineage-adopt.ts +452 -0
  515. package/src/workspace/lineage-check.ts +26 -5
  516. package/src/workspace/lineage-cli.ts +12 -2
  517. package/src/workspace/lineage-hash-index.ts +305 -0
  518. package/src/workspace/lineage-init.test.ts +9 -0
  519. package/src/workspace/lineage-init.ts +29 -9
  520. package/src/workspace/lineage-lock.ts +54 -0
  521. package/src/workspace/lineage-migrations.test.ts +27 -0
  522. package/src/workspace/lineage-migrations.ts +44 -14
  523. package/src/workspace/lineage-provenance.ts +40 -0
  524. package/src/workspace/lineage-upgrade-cli.ts +9 -5
  525. package/src/workspace/lineage-upgrade.test.ts +92 -1
  526. package/src/workspace/lineage-upgrade.ts +111 -16
  527. package/src/workspace/lineage-versions.ts +348 -0
  528. package/src/workspace/links.test.ts +121 -2
  529. package/src/workspace/links.ts +97 -6
  530. package/src/workspace/ls-contract.test.ts +84 -1
  531. package/src/workspace/ls-generated.ts +111 -0
  532. package/src/workspace/ls.schema.json +19 -0
  533. package/src/workspace/ls.ts +8 -1
  534. package/src/workspace/member-commands.ts +3 -1
  535. package/src/workspace/nested-graph.test.ts +176 -0
  536. package/src/workspace/nested-graph.ts +169 -0
  537. package/src/workspace/nesting.ts +37 -0
  538. package/src/workspace/pin-cli.test.ts +71 -0
  539. package/src/workspace/pin-cli.ts +57 -0
  540. package/src/workspace/pin-integrity.test.ts +121 -0
  541. package/src/workspace/pin-integrity.ts +104 -0
  542. package/src/workspace/points-write.schema.json +2 -0
  543. package/src/workspace/principal-classes.test.ts +175 -0
  544. package/src/workspace/principal-classes.ts +307 -0
  545. package/src/workspace/read-contract.test.ts +24 -0
  546. package/src/workspace/reason-codes.test.ts +20 -2
  547. package/src/workspace/reason-codes.ts +53 -3
  548. package/src/workspace/record-sessions.ts +12 -14
  549. package/src/workspace/records-amend.schema.json +6 -0
  550. package/src/workspace/records-checkout.ts +106 -0
  551. package/src/workspace/records-cli.ts +195 -22
  552. package/src/workspace/records-close.schema.json +7 -2
  553. package/src/workspace/records-close.ts +10 -2
  554. package/src/workspace/records-formats.test.ts +13 -5
  555. package/src/workspace/records-new.schema.json +6 -0
  556. package/src/workspace/records-review.schema.json +6 -0
  557. package/src/workspace/records-sessions.test.ts +23 -6
  558. package/src/workspace/records-uncommitted.test.ts +171 -0
  559. package/src/workspace/records-write.test.ts +65 -8
  560. package/src/workspace/records-write.ts +92 -6
  561. package/src/workspace/records.schema.json +127 -4
  562. package/src/workspace/records.ts +123 -5
  563. package/src/workspace/returns.ts +328 -0
  564. package/src/workspace/runs-cli.ts +381 -0
  565. package/src/workspace/runs-write.schema.json +583 -0
  566. package/src/workspace/runs.schema.json +810 -0
  567. package/src/workspace/runs.test.ts +242 -0
  568. package/src/workspace/runs.ts +709 -0
  569. package/src/workspace/signers.schema.json +206 -0
  570. package/src/workspace/status-contract.test.ts +5 -0
  571. package/src/workspace/status-gates.ts +24 -9
  572. package/src/workspace/status.schema.json +127 -2
  573. package/src/workspace/status.ts +21 -1
  574. package/src/workspace/symbols.ts +180 -0
  575. package/src/workspace/template-manifest.ts +22 -4
  576. package/src/workspace/trailer-joins.test.ts +171 -0
  577. package/src/workspace/trailer-joins.ts +82 -0
  578. package/src/workspace/trailers.ts +148 -0
  579. package/src/workspace/trust/attestor.ts +15 -0
  580. package/src/workspace/trust/dsse.ts +134 -0
  581. package/src/workspace/trust/evidence-cli.ts +195 -0
  582. package/src/workspace/trust/evidence.test.ts +241 -0
  583. package/src/workspace/trust/evidence.ts +207 -0
  584. package/src/workspace/trust/policy.ts +110 -3
  585. package/src/workspace/trust/provenance.ts +41 -4
  586. package/src/workspace/trust/record-seal.test.ts +1 -1
  587. package/src/workspace/trust/rotation.test.ts +258 -0
  588. package/src/workspace/trust/rotation.ts +336 -0
  589. package/src/workspace/trust/seal.ts +63 -1
  590. package/src/workspace/trust/signers-cli.ts +178 -0
  591. package/src/workspace/trust/ssh-commit.ts +53 -4
  592. package/src/workspace/trust/test-repo.ts +18 -0
  593. package/src/workspace/trust/trust.test.ts +8 -2
  594. package/src/workspace/trust/verify-cli.ts +1 -0
  595. package/src/workspace/trust/verify.ts +22 -0
  596. package/src/workspace/work-cli.e2e.test.ts +28 -1
  597. package/src/workspace/work-cli.ts +133 -8
  598. package/src/workspace/work-evidence.schema.json +6 -0
  599. package/src/workspace/work-history.schema.json +73 -1
  600. package/src/workspace/work-history.test.ts +48 -5
  601. package/src/workspace/work-kind-fields.test.ts +154 -0
  602. package/src/workspace/work-lease.schema.json +14 -1
  603. package/src/workspace/work.ts +82 -0
  604. package/src/workspace/workspace-principals.schema.json +60 -0
  605. package/src/workspace/write-scope.test.ts +466 -0
  606. package/src/workspace/write-scope.ts +573 -0
  607. package/src/yaml.test.ts +111 -1
  608. package/src/yaml.ts +141 -549
@@ -75,6 +75,8 @@ export interface ParsedArgs {
75
75
  migrateFrom?: string;
76
76
  /** `chant import --kustomize <dir>` — render the kustomization, then import (#1548) */
77
77
  kustomize?: string;
78
+ /** `chant import --parser-option key[=value]`, repeatable (#2994): options for the lexicon's template parser */
79
+ parserOption?: string[];
78
80
  /** `chant carve advise --state <path>` — opt-in .tfstate for accurate instance counts */
79
81
  statePath?: string;
80
82
  /** `chant carve emit --select <tf-address>` — the Terraform resource to carve */
@@ -133,6 +135,16 @@ export interface ParsedArgs {
133
135
  namespace?: string;
134
136
  /** `chant workspace upgrade --allow-code` (#2550) — run migrations whose body is the template's own code. */
135
137
  allowCode?: boolean;
138
+ /** `chant workspace upgrade --source <repo>[#<member>]` (#2551): move the scope to another template. */
139
+ source?: string;
140
+ /** `chant workspace adopt-lineage --tags <glob>` and `hash-index --tags` (#2551): the tags to compare. */
141
+ tags?: string;
142
+ /** `chant workspace adopt-lineage --index <file>` (#2551): a cached hash index. */
143
+ index?: string;
144
+ /** `chant workspace versions --available` (#2551): list each git template's version tags. */
145
+ available?: boolean;
146
+ /** `chant workspace import --remove` (#2552): remove the export member instead of writing it again. */
147
+ remove?: boolean;
136
148
  /** `chant lifecycle rollback --dry-run` — compute the rollback delta and print it; open no PR, push nothing, leave no branch. */
137
149
  dryRun?: boolean;
138
150
  /** `chant lifecycle teardown <env> --yes` — execute the planned deletion
@@ -303,7 +315,7 @@ export interface ParsedArgs {
303
315
  noCache?: boolean;
304
316
  /** `chant workspace graph --composites` (#2662): print each composite instance with the components that can deploy it. */
305
317
  composites?: boolean;
306
- /** `chant workspace graph --intent <path[:start-end]>` (#2651): the region the intent graph is over. Empty with `--record`. */
318
+ /** `chant workspace graph --intent <path[:start-end]|path#symbol>` (#2651): the region the intent graph is over. Empty with `--record`. */
307
319
  intent?: string;
308
320
  /** `chant workspace graph --intent --record <id>`: walk one decision record over every entry its constrains lists. */
309
321
  record?: string;
@@ -319,6 +331,8 @@ export interface ParsedArgs {
319
331
  severity?: string;
320
332
  /** `chant workspace records --current` (#2546): leave out records a closed record supersedes. */
321
333
  current?: boolean;
334
+ /** `chant workspace records --uncommitted` (#3160): only the records the working tree holds modified or new against HEAD. */
335
+ uncommitted?: boolean;
322
336
  /** `chant workspace records amend <id> --set <file|->` (#2670): the JSON fields to set. */
323
337
  set?: string;
324
338
  /** `chant workspace records review <id> --verdict <v>` (#2670): agree, dissent or abstain. */
@@ -334,6 +348,7 @@ export interface ParsedArgs {
334
348
  /**
335
349
  * `chant workspace records review <id> --sign [<key file>]` (#2687): the key that seals the verdict, or true for git's user.signingkey.
336
350
  * On `records new` and `records amend`, the key that seals the record's author (#2688).
351
+ * On `chant approve` and `chant run approve`, the key that seals the gate approval (#3163).
337
352
  */
338
353
  sign?: string | true;
339
354
  /** `chant workspace records review <id> --session <id>` (#2670): the review session the verdict was given in. */
@@ -342,6 +357,18 @@ export interface ParsedArgs {
342
357
  prefix?: string;
343
358
  /** `chant workspace records|verify --require attested` (#2547): the provenance level a gate requires. */
344
359
  require?: string;
360
+ /** `chant workspace evidence sign --key` (a runner's Ed25519 PEM) and `signers sign --key` (an ssh private key) (#2553). */
361
+ key?: string;
362
+ /** `chant workspace evidence sign --check-id <id>` (#2553): the check the evidence is for. */
363
+ checkId?: string;
364
+ /** `chant workspace evidence sign --claim <file>` (#2553): hashed into the evidence. */
365
+ claim?: string;
366
+ /** `chant workspace evidence sign --environment <file>` (#2553): the runner environment, hashed into the evidence. */
367
+ environment?: string;
368
+ /** `chant workspace evidence verify --envelope <file>` (#2553). */
369
+ envelope?: string;
370
+ /** `chant workspace signers rotate --threshold <n>` (#2553). */
371
+ threshold?: string;
345
372
  /**
346
373
  * `chant build --root-only` and `chant lint --root-only` (#2537): run on the
347
374
  * root project of a declared workspace, members left out, instead of
@@ -454,6 +481,10 @@ export interface ParsedArgs {
454
481
  * project's only steward.
455
482
  */
456
483
  steward?: string;
484
+ /** `chant workspace runs --unit <id>` (#3033): only the agent runs on this work item. */
485
+ unit?: string;
486
+ /** `chant workspace runs --decision <id>` (#3033): only the agent runs that carried out this decision. */
487
+ decision?: string;
457
488
  /** `chant workspace work claim|renew|release <id> --holder <name>` (#2732): who holds, or releases, the work lease. */
458
489
  holder?: string;
459
490
  /** `chant run <op> --work <id>` (#2748): the work item an Op with a work lease runs under. `chant workspace check --changes --work <id>` (#2773): the work item in hand. */
@@ -462,7 +493,7 @@ export interface ParsedArgs {
462
493
  ttl?: string;
463
494
  /** `chant workspace work renew|release <id> --token <token>` (#2732): the fencing token the caller holds. */
464
495
  token?: string;
465
- /** `chant workspace work release <id> --outcome <text>` (#2732): how the work ended, such as done or not_done. */
496
+ /** `chant workspace work release <id> --outcome <outcome>` (#2732): how the work ended, one of the closed list WORK_LEASE_OUTCOMES (#3147). */
466
497
  outcome?: string;
467
498
  /** `chant operator --once` (#1485) — run a single round and exit, instead of looping until Ctrl-C. Also the offline test/cron-invoker story. */
468
499
  once?: boolean;
@@ -70,7 +70,7 @@ describe("chant serve mcp at a workspace root with no lexicon of its own (#2700)
70
70
  expect(init.serverInfo.name).toBe("chant");
71
71
  for (const name of CORE_TOOLS) expect(tools).toContain(name);
72
72
  expect(tools).toContain("docker:diff");
73
- expect(init.instructions).toContain("Member delivery (delivery/) declares docker.");
73
+ expect(init.instructions).toContain("Member delivery (delivery/) declares docker, otel.");
74
74
  }, TIMEOUT);
75
75
 
76
76
  test("a lexiconless root, lexicons only in a member, serves core and the lexicons that load", () => {
@@ -0,0 +1,157 @@
1
+ import { describe, test, expect, afterEach, vi } from "vitest";
2
+ import { readFileSync } from "fs";
3
+ import { join } from "path";
4
+ import { loadUpstreamPins, checkPinnedUpgrades, checkPinnedUpgrade, pinsOfPlugin } from "./pinned-upgrade";
5
+ import { printPinnedUpgradeResults } from "../cli/commands/pinned-upgrade";
6
+ import type { UpstreamPin } from "../lexicon";
7
+
8
+ // The sql lexicon declares ClickHouse's pin and five Postgres pins (#3288).
9
+ const sqlDir = join(__dirname, "../../../../lexicons/sql");
10
+
11
+ // Recorded shape of GET /repos/postgres/postgres/tags (see pinned-upgrade-tags.test.ts),
12
+ // with two newer minors added so the 14 and 17 pins have something to report.
13
+ const recorded = JSON.parse(readFileSync(join(__dirname, "testdata", "postgres-tags.json"), "utf-8")) as Array<{ name: string }>;
14
+ const tags = [...recorded, { name: "REL_17_12" }, { name: "REL_14_25" }, { name: "REL_19_BETA1" }];
15
+
16
+ function stubGitHub() {
17
+ const urls: string[] = [];
18
+ vi.stubGlobal(
19
+ "fetch",
20
+ vi.fn(async (url: string) => {
21
+ urls.push(url);
22
+ const u = new URL(url);
23
+ if (u.pathname.startsWith("/repos/postgres/postgres/tags")) {
24
+ const page = Number(u.searchParams.get("page"));
25
+ return new Response(JSON.stringify(page === 1 ? tags : []), { status: 200 });
26
+ }
27
+ if (u.pathname.startsWith("/repos/ClickHouse/ClickHouse/releases")) {
28
+ return new Response(JSON.stringify([{ tag_name: "v99.1.1.1-lts" }, { tag_name: "v26.8.15.10-lts" }]), { status: 200 });
29
+ }
30
+ return new Response("not found", { status: 404 });
31
+ }),
32
+ );
33
+ return urls;
34
+ }
35
+
36
+ afterEach(() => vi.unstubAllGlobals());
37
+
38
+ describe("pinsOfPlugin", () => {
39
+ const pin = (label?: string): UpstreamPin => ({
40
+ ...(label ? { label } : {}),
41
+ file: "f",
42
+ pattern: /x/,
43
+ replace: (v) => v,
44
+ upstream: { owner: "o", repo: "r", kind: "releases" },
45
+ });
46
+
47
+ test("a lone upstreamPin is labelled by its own label, else the lexicon", () => {
48
+ expect(pinsOfPlugin({ upstreamPin: pin() }, "k8s").map((p) => p.label)).toEqual(["k8s"]);
49
+ expect(pinsOfPlugin({ upstreamPin: pin("main") }, "k8s").map((p) => p.label)).toEqual(["main"]);
50
+ });
51
+
52
+ test("upstreamPin comes first, then upstreamPins in order", () => {
53
+ const labels = pinsOfPlugin({ upstreamPin: pin("a"), upstreamPins: [pin("b"), pin("c")] }, "x").map((p) => p.label);
54
+ expect(labels).toEqual(["a", "b", "c"]);
55
+ });
56
+
57
+ test("no pins", () => {
58
+ expect(pinsOfPlugin({}, "aws")).toEqual([]);
59
+ });
60
+ });
61
+
62
+ describe("sql declares six pins", () => {
63
+ test("clickhouse first, then postgres-14 to postgres-18", async () => {
64
+ const pins = await loadUpstreamPins("sql", sqlDir);
65
+ expect(pins.map((p) => p.label)).toEqual(["clickhouse", "postgres-14", "postgres-15", "postgres-16", "postgres-17", "postgres-18"]);
66
+ // The digest sits beside the version in both, so neither is rewritten blind.
67
+ for (const { pin } of pins) expect(pin.alsoMoves).toMatch(/digest/);
68
+ });
69
+ });
70
+
71
+ describe("checkPinnedUpgrades on the sql lexicon (network mocked)", () => {
72
+ test("reports each pin, in order, and edits nothing", async () => {
73
+ stubGitHub();
74
+ const pinFiles = ["src/spec/pin.ts", "src/spec/postgres-pin.ts"].map((f) => join(sqlDir, f));
75
+ const before = pinFiles.map((f) => readFileSync(f, "utf-8"));
76
+ const results = await checkPinnedUpgrades({ lexiconDir: sqlDir, lexicon: "sql" });
77
+ expect(pinFiles.map((f) => readFileSync(f, "utf-8"))).toEqual(before);
78
+
79
+ const byPin = Object.fromEntries(results.map((r) => [r.pin, r]));
80
+ expect(results.map((r) => r.pin)).toEqual(["clickhouse", "postgres-14", "postgres-15", "postgres-16", "postgres-17", "postgres-18"]);
81
+ expect(results.every((r) => r.fetchError === null)).toBe(true);
82
+
83
+ expect(byPin["clickhouse"]).toMatchObject({ hasUpgrade: true, to: "v99.1.1.1-lts" });
84
+ // Each Postgres pin sees only its own major: 17 reports 17.12, never 18.6.
85
+ expect(byPin["postgres-14"]).toMatchObject({ hasUpgrade: true, from: "14.24", to: "14.25" });
86
+ expect(byPin["postgres-15"]).toMatchObject({ hasUpgrade: false, from: "15.19", to: "15.19" });
87
+ expect(byPin["postgres-16"]).toMatchObject({ hasUpgrade: false, from: "16.15", to: "16.15" });
88
+ expect(byPin["postgres-17"]).toMatchObject({ hasUpgrade: true, from: "17.11", to: "17.12" });
89
+ expect(byPin["postgres-18"]).toMatchObject({ hasUpgrade: false, from: "18.6", to: "18.6" });
90
+
91
+ // alsoMoves pins are report-only: instructions, no regen.
92
+ for (const label of ["clickhouse", "postgres-14", "postgres-17"]) {
93
+ expect(byPin[label]!.validation, label).toBeNull();
94
+ expect(byPin[label]!.manualPin?.instructions, label).toMatch(/digest/);
95
+ }
96
+ expect(byPin["postgres-17"]!.manualPin?.file).toBe("src/spec/postgres-pin.ts");
97
+ expect(byPin["postgres-15"]!.manualPin).toBeUndefined();
98
+ });
99
+
100
+ test("a pin label checks one pin and queries only its upstream", async () => {
101
+ const urls = stubGitHub();
102
+ const results = await checkPinnedUpgrades({ lexiconDir: sqlDir, lexicon: "sql", pin: "postgres-17" });
103
+ expect(results).toHaveLength(1);
104
+ expect(results[0]).toMatchObject({ pin: "postgres-17", to: "17.12" });
105
+ expect(urls.every((u) => u.includes("/repos/postgres/postgres/tags"))).toBe(true);
106
+
107
+ const ch = await checkPinnedUpgrades({ lexiconDir: sqlDir, lexicon: "sql", pin: "clickhouse" });
108
+ expect(ch).toHaveLength(1);
109
+ expect(ch[0]).toMatchObject({ pin: "clickhouse", hasUpgrade: true });
110
+ });
111
+
112
+ test("an unknown label names the pins there are", async () => {
113
+ const [r] = await checkPinnedUpgrades({ lexiconDir: sqlDir, lexicon: "sql", pin: "postgres-13" });
114
+ expect(r!.fetchError).toMatch(/no pin labelled "postgres-13"/);
115
+ expect(r!.fetchError).toMatch(/clickhouse, postgres-14/);
116
+ });
117
+
118
+ test("a network failure on one pin leaves the others reported", async () => {
119
+ vi.stubGlobal(
120
+ "fetch",
121
+ vi.fn(async (url: string) =>
122
+ url.includes("/repos/ClickHouse/") ? new Response("boom", { status: 404 }) : new Response(JSON.stringify(url.includes("page=1") ? tags : []), { status: 200 }),
123
+ ),
124
+ );
125
+ const results = await checkPinnedUpgrades({ lexiconDir: sqlDir, lexicon: "sql" });
126
+ expect(results[0]!.fetchError).toBeTruthy();
127
+ expect(results[4]).toMatchObject({ pin: "postgres-17", to: "17.12", fetchError: null });
128
+ });
129
+
130
+ test("checkPinnedUpgrade (singular) still checks the first pin, ClickHouse", async () => {
131
+ stubGitHub();
132
+ const r = await checkPinnedUpgrade({ lexiconDir: sqlDir, lexicon: "sql" });
133
+ expect(r.pin).toBe("clickhouse");
134
+ });
135
+ });
136
+
137
+ describe("printPinnedUpgradeResults", () => {
138
+ test("several results print as a JSON array carrying each pin", async () => {
139
+ stubGitHub();
140
+ const results = await checkPinnedUpgrades({ lexiconDir: sqlDir, lexicon: "sql" });
141
+ const out: string[] = [];
142
+ const spy = vi.spyOn(console, "log").mockImplementation((...a: unknown[]) => void out.push(a.join(" ")));
143
+ try {
144
+ printPinnedUpgradeResults(results, true);
145
+ const parsed = JSON.parse(out.join("\n")) as Array<{ pin: string; to: string }>;
146
+ expect(parsed.map((p) => p.pin)).toEqual(results.map((r) => r.pin));
147
+ out.length = 0;
148
+ process.env.NO_COLOR = "1";
149
+ printPinnedUpgradeResults(results, false);
150
+ expect(out.join("\n")).toContain("[sql/postgres-17] upgrade available 17.11 -> 17.12");
151
+ expect(out.join("\n")).toContain("[sql/postgres-18] up to date");
152
+ } finally {
153
+ delete process.env.NO_COLOR;
154
+ spy.mockRestore();
155
+ }
156
+ });
157
+ });
@@ -0,0 +1,112 @@
1
+ import { describe, test, expect, afterEach, vi } from "vitest";
2
+ import { readFileSync } from "fs";
3
+ import { join } from "path";
4
+ import { pickLatest, resolverFor } from "./pinned-upgrade";
5
+ import type { UpstreamPin } from "../lexicon";
6
+
7
+ // Recorded shape of GET /repos/postgres/postgres/tags: names only, no releases exist.
8
+ const tags = JSON.parse(readFileSync(join(__dirname, "testdata", "postgres-tags.json"), "utf-8")) as Array<{
9
+ name: string;
10
+ }>;
11
+
12
+ /** What a postgres pin declares: REL_18_6 maps to 18.6, everything else is skipped. */
13
+ const relTag = (t: string): string | null => {
14
+ const m = /^REL_(\d+)_(\d+)$/.exec(t);
15
+ return m ? `${m[1]}.${m[2]}` : null;
16
+ };
17
+
18
+ describe("pickLatest with tagVersion (postgres REL_ tags)", () => {
19
+ test("maps REL_18_6 to 18.6 and picks the highest GA version", () => {
20
+ expect(pickLatest(tags, "tags", { tagVersion: relTag })).toBe("18.6");
21
+ });
22
+
23
+ test("orders numerically, not lexically (17.11 beats 17.9)", () => {
24
+ const t = ["REL_17_9", "REL_17_11", "REL_17_10"].map((name) => ({ name }));
25
+ expect(pickLatest(t, "tags", { tagVersion: relTag })).toBe("17.11");
26
+ });
27
+
28
+ test("skips betas and release candidates even if the mapper would take them", () => {
29
+ const t = ["REL_19_BETA4", "REL_18_RC1", "REL_18_BETA3", "REL_18_5"].map((name) => ({ name }));
30
+ expect(pickLatest(t, "tags", { tagVersion: (x) => x.replace(/^REL_/, "").replace(/_/g, ".") })).toBe("18.5");
31
+ expect(pickLatest(t, "tags", { tagVersion: relTag })).toBe("18.5");
32
+ });
33
+
34
+ test("sameMajorAs stays inside one major line", () => {
35
+ expect(pickLatest(tags, "tags", { tagVersion: relTag, sameMajorAs: "17.9" })).toBe("17.11");
36
+ expect(pickLatest(tags, "tags", { tagVersion: relTag, sameMajorAs: "14.1" })).toBe("14.24");
37
+ });
38
+
39
+ test("sameMajorAs accepts a pin that holds the raw tag", () => {
40
+ expect(pickLatest(tags, "tags", { tagVersion: relTag, sameMajorAs: "REL_16_2" })).toBe("16.15");
41
+ });
42
+
43
+ test("a major with no stable tag yields null", () => {
44
+ expect(pickLatest(tags, "tags", { tagVersion: relTag, sameMajorAs: "19.0" })).toBeNull();
45
+ });
46
+ });
47
+
48
+ describe("pickLatest without the new options is unchanged", () => {
49
+ test("REL_ tags are not versions, so nothing is found", () => {
50
+ expect(pickLatest(tags, "tags")).toBeNull();
51
+ });
52
+
53
+ test("plain semver tags with a suffix filter and pre-release skip", () => {
54
+ const t = ["v17.9.0-ee", "v17.10.0-rc1-ee", "v17.8.1-ee", "v18.0.0"].map((name) => ({ name }));
55
+ expect(pickLatest(t, "tags", { tagSuffix: "-ee" })).toBe("v17.9.0-ee");
56
+ });
57
+
58
+ test("releases honour the prerelease flag", () => {
59
+ const r = [
60
+ { tag_name: "v1.33.0", prerelease: true },
61
+ { tag_name: "v1.32.1" },
62
+ { tag_name: "v1.32.0" },
63
+ ];
64
+ expect(pickLatest(r, "releases")).toBe("v1.32.1");
65
+ });
66
+ });
67
+
68
+ describe("resolverFor reads every page of tags when tagVersion is set", () => {
69
+ afterEach(() => vi.unstubAllGlobals());
70
+
71
+ const pin = (upstream: Partial<UpstreamPin["upstream"]>): UpstreamPin => ({
72
+ file: "src/spec/pin.ts",
73
+ pattern: /x/,
74
+ replace: (v, l) => l + v,
75
+ upstream: { owner: "postgres", repo: "postgres", kind: "tags", ...upstream },
76
+ });
77
+
78
+ function stubPages(pages: Array<Array<{ name: string }>>) {
79
+ const urls: string[] = [];
80
+ vi.stubGlobal(
81
+ "fetch",
82
+ vi.fn(async (url: string) => {
83
+ urls.push(url);
84
+ const n = Number(new URL(url).searchParams.get("page"));
85
+ return new Response(JSON.stringify(pages[n - 1] ?? []), { status: 200 });
86
+ }),
87
+ );
88
+ return urls;
89
+ }
90
+
91
+ test("finds a version that is only on the second page", async () => {
92
+ const filler = Array.from({ length: 100 }, (_, i) => ({ name: `REL9_${i}_0` }));
93
+ const urls = stubPages([filler, [{ name: "REL_18_6" }, { name: "REL_18_BETA1" }]]);
94
+ const latest = await resolverFor(pin({ tagVersion: relTag }), "18.5")();
95
+ expect(latest).toBe("18.6");
96
+ expect(urls).toHaveLength(2);
97
+ expect(urls[0]).toContain("per_page=100&page=1");
98
+ });
99
+
100
+ test("trackMajor uses the pinned value", async () => {
101
+ stubPages([tags]);
102
+ expect(await resolverFor(pin({ tagVersion: relTag, trackMajor: true }), "16.2")()).toBe("16.15");
103
+ expect(await resolverFor(pin({ tagVersion: relTag }), "16.2")()).toBe("18.6");
104
+ });
105
+
106
+ test("without tagVersion only the first page is read, as before", async () => {
107
+ const urls = stubPages([Array.from({ length: 50 }, () => ({ name: "v1.0.0" })), [{ name: "v9.0.0" }]]);
108
+ expect(await resolverFor(pin({ kind: "tags" }), "v1.0.0")()).toBe("v1.0.0");
109
+ expect(urls).toHaveLength(1);
110
+ expect(urls[0]).toContain("per_page=50");
111
+ });
112
+ });
@@ -12,8 +12,11 @@ import {
12
12
  revertVersionBump,
13
13
  checkPinnedUpgrade,
14
14
  loadUpstreamPin,
15
+ lexiconNameOf,
16
+ applyPinnedVersionBump,
15
17
  type LexiconId,
16
18
  } from "./pinned-upgrade";
19
+ import { runPinnedUpgrade } from "../cli/commands/pinned-upgrade";
17
20
 
18
21
  // ── Version parsing / comparison ──────────────────────────────────────
19
22
 
@@ -397,3 +400,104 @@ describe("loadUpstreamPin — pin descriptors come from the lexicon plugins (#68
397
400
  expect(await loadUpstreamPin("definitely-not-a-lexicon")).toBeNull();
398
401
  });
399
402
  });
403
+
404
+ // ── #3258: any lexicon that declares upstreamPin, loaded from its directory ──
405
+
406
+ describe("loadUpstreamPin from a lexicon directory (#3258)", () => {
407
+ const repoLexicons = join(__dirname, "../../../../lexicons");
408
+
409
+ test("sql: -lts tag suffix, a replace that strips the tag, and a companion-digest note", async () => {
410
+ const dir = join(repoLexicons, "sql");
411
+ const pin = await loadUpstreamPin(lexiconNameOf(dir), dir);
412
+ expect(pin?.upstream).toEqual({ owner: "ClickHouse", repo: "ClickHouse", kind: "releases", tagSuffix: "-lts" });
413
+ expect(pin?.alsoMoves).toMatch(/CLICKHOUSE_IMAGE_DIGEST/);
414
+ expect(pin?.replace("v26.8.20.5-lts", 'export const CLICKHOUSE_VERSION = "26.8.15.10";')).toBe(
415
+ 'export const CLICKHOUSE_VERSION = "26.8.20.5";',
416
+ );
417
+ });
418
+
419
+ test("k3s and cedar declare a pin and no companion note", async () => {
420
+ for (const name of ["k3s", "cedar"]) {
421
+ const dir = join(repoLexicons, name);
422
+ const pin = await loadUpstreamPin(lexiconNameOf(dir), dir);
423
+ expect(pin, name).not.toBeNull();
424
+ expect(pin?.alsoMoves, name).toBeUndefined();
425
+ }
426
+ });
427
+
428
+ test("lexiconNameOf reads the package name, then the directory name", () => {
429
+ expect(lexiconNameOf(join(repoLexicons, "sql"))).toBe("sql");
430
+ const root = mkdtempSync(join(tmpdir(), "chant-name-"));
431
+ try {
432
+ expect(lexiconNameOf(root)).toBe(root.split("/").pop());
433
+ } finally {
434
+ rmSync(root, { recursive: true, force: true });
435
+ }
436
+ });
437
+
438
+ test("a directory whose plugin has no upstreamPin gets a clear message", async () => {
439
+ const result = await runPinnedUpgrade({ lexiconDir: join(repoLexicons, "aws") });
440
+ expect(result.hasUpgrade).toBe(false);
441
+ expect(result.fetchError).toMatch(/declares no upstreamPin/);
442
+ });
443
+ });
444
+
445
+ describe("pinned-upgrade for a pin that moves with a digest (sql shape, network mocked)", () => {
446
+ function sqlShaped(root: string): { dir: string; pin: string } {
447
+ const dir = makeWorkingLexicon(root, "sql", "src/spec/pin.ts", [
448
+ 'export const CLICKHOUSE_VERSION = "26.8.15.10";',
449
+ 'export const CLICKHOUSE_IMAGE_DIGEST = "sha256:aaaa";',
450
+ "",
451
+ ].join("\n"));
452
+ return { dir, pin: join(dir, "src/spec/pin.ts") };
453
+ }
454
+
455
+ test("reports the newer -lts version with instructions and edits nothing", async () => {
456
+ const root = mkdtempSync(join(tmpdir(), "chant-up-"));
457
+ try {
458
+ const { dir, pin } = sqlShaped(root);
459
+ const before = readFileSync(pin, "utf-8");
460
+ const result = await checkPinnedUpgrade({
461
+ lexiconDir: dir,
462
+ lexicon: "sql",
463
+ resolverOverride: async () => "v26.8.20.5-lts",
464
+ });
465
+ expect(result.hasUpgrade).toBe(true);
466
+ expect(result.from).toBe("26.8.15.10");
467
+ expect(result.to).toBe("v26.8.20.5-lts");
468
+ expect(result.validation).toBeNull();
469
+ expect(result.manualPin?.file).toBe("src/spec/pin.ts");
470
+ expect(result.manualPin?.instructions).toMatch(/digest/);
471
+ expect(readFileSync(pin, "utf-8")).toBe(before);
472
+ } finally {
473
+ rmSync(root, { recursive: true, force: true });
474
+ }
475
+ });
476
+
477
+ test("the -lts tag compares equal to the bare pinned version", async () => {
478
+ const root = mkdtempSync(join(tmpdir(), "chant-up-"));
479
+ try {
480
+ const { dir } = sqlShaped(root);
481
+ const result = await checkPinnedUpgrade({
482
+ lexiconDir: dir,
483
+ lexicon: "sql",
484
+ resolverOverride: async () => "v26.8.15.10-lts",
485
+ });
486
+ expect(result.hasUpgrade).toBe(false);
487
+ } finally {
488
+ rmSync(root, { recursive: true, force: true });
489
+ }
490
+ });
491
+
492
+ test("applyPinnedVersionBump refuses a pin it cannot rewrite generically", async () => {
493
+ const root = mkdtempSync(join(tmpdir(), "chant-up-"));
494
+ try {
495
+ const { dir, pin } = sqlShaped(root);
496
+ const before = readFileSync(pin, "utf-8");
497
+ await expect(applyPinnedVersionBump("sql", dir, "v26.8.20.5-lts")).rejects.toThrow(/generically/);
498
+ expect(readFileSync(pin, "utf-8")).toBe(before);
499
+ } finally {
500
+ rmSync(root, { recursive: true, force: true });
501
+ }
502
+ });
503
+ });