@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
@@ -7,6 +7,7 @@ import {
7
7
  patchDockerfile,
8
8
  patchRootTsconfigPaths,
9
9
  insertPrepackAfterEach,
10
+ patchLexiconList,
10
11
  } from "./onboard";
11
12
 
12
13
  function makeTempDir(): string {
@@ -184,6 +185,8 @@ function writeFixtureRepo(root: string): void {
184
185
  writeFileSync(join(root, ".github/workflows/publish.yml"), publishContent);
185
186
  writeFileSync(join(root, "test/Dockerfile.smoke"), dockerLoopContent);
186
187
  writeFileSync(join(root, "test/Dockerfile.smoke-npm"), dockerNpmContent);
188
+ writeFileSync(join(root, "test/smoke-npm-lexicons.txt"), "aws\ngitlab\nk8s\n");
189
+ writeFileSync(join(root, "test/smoke-e2e-lexicons.txt"), "aws\nk8s\n");
187
190
  }
188
191
 
189
192
  const TRACKED = [
@@ -193,6 +196,8 @@ const TRACKED = [
193
196
  ".github/workflows/publish.yml",
194
197
  "test/Dockerfile.smoke",
195
198
  "test/Dockerfile.smoke-npm",
199
+ "test/smoke-npm-lexicons.txt",
200
+ "test/smoke-e2e-lexicons.txt",
196
201
  ];
197
202
 
198
203
  function snapshot(root: string): Record<string, string> {
@@ -223,8 +228,12 @@ describe("onboardCommand", () => {
223
228
  "publish.yml (prepack)",
224
229
  "Dockerfile.smoke (lexicon list)",
225
230
  "Dockerfile.smoke-npm (lexicon list)",
231
+ "smoke-npm-lexicons.txt (lexicon list)",
226
232
  ]);
227
- expect(result.skipped).toEqual([]);
233
+ expect(result.skipped).toHaveLength(1);
234
+ expect(result.skipped[0]).toContain("smoke-e2e-lexicons.txt: not patched");
235
+ expect(readFileSync(join(root, "test/smoke-npm-lexicons.txt"), "utf-8")).toBe("aws\ngitlab\nk8s\nterraform\n");
236
+ expect(readFileSync(join(root, "test/smoke-e2e-lexicons.txt"), "utf-8")).toBe("aws\nk8s\n");
228
237
 
229
238
  const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf-8"));
230
239
  expect(pkg.dependencies["@intentius/chant-lexicon-terraform"]).toBe("workspace:*");
@@ -254,6 +263,8 @@ describe("onboardCommand", () => {
254
263
  "publish.yml: prepack for terraform already present",
255
264
  "Dockerfile.smoke: already covers terraform",
256
265
  "Dockerfile.smoke-npm: already covers terraform",
266
+ "smoke-npm-lexicons.txt: terraform already in test/smoke-npm-lexicons.txt",
267
+ expect.stringContaining("smoke-e2e-lexicons.txt: not patched"),
257
268
  ]);
258
269
  });
259
270
 
@@ -312,9 +323,9 @@ describe("root tsconfig.json paths (#1614)", () => {
312
323
 
313
324
  const cfg = JSON.parse(readFileSync(join(root, "tsconfig.json"), "utf-8"));
314
325
  expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-terraform"]).toEqual([
315
- "lexicons/terraform/src/index.ts",
326
+ "./lexicons/terraform/src/index.ts",
316
327
  ]);
317
- expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-terraform/*"]).toEqual(["lexicons/terraform/src/*"]);
328
+ expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-terraform/*"]).toEqual(["./lexicons/terraform/src/*"]);
318
329
  // Existing entries untouched
319
330
  expect(cfg.compilerOptions.paths["@intentius/chant-lexicon-aws"]).toEqual(["lexicons/aws/src/index.ts"]);
320
331
  expect(cfg.compilerOptions.moduleResolution).toBe("node");
@@ -462,3 +473,42 @@ describe("insertPrepackAfterEach", () => {
462
473
  ]);
463
474
  });
464
475
  });
476
+
477
+ describe("smoke lists and publish.yml reporting (#3227)", () => {
478
+ let root: string;
479
+
480
+ beforeEach(() => {
481
+ root = makeTempDir();
482
+ writeFixtureRepo(root);
483
+ });
484
+
485
+ afterEach(() => {
486
+ rmSync(root, { recursive: true, force: true });
487
+ });
488
+
489
+ test("patchLexiconList appends once and keeps the trailing newline", () => {
490
+ const file = join(root, "test/smoke-npm-lexicons.txt");
491
+ writeFileSync(file, "aws\nk8s");
492
+ expect(patchLexiconList(file, "sql").patched).toBe(true);
493
+ expect(readFileSync(file, "utf-8")).toBe("aws\nk8s\nsql\n");
494
+ expect(patchLexiconList(file, "sql").patched).toBe(false);
495
+ expect(readFileSync(file, "utf-8")).toBe("aws\nk8s\nsql\n");
496
+ });
497
+
498
+ test("a Dockerfile that reads the list file points at it instead of claiming coverage", () => {
499
+ const file = join(root, "test/Dockerfile.smoke-npm");
500
+ writeFileSync(file, "RUN LEXICONS=$(cat /app/test/smoke-npm-lexicons.txt) && \\\n for lex in $LEXICONS; do :; done\n");
501
+ const result = patchDockerfile(file, "sql");
502
+ expect(result.patched).toBe(false);
503
+ expect(result.reason).toContain("test/smoke-npm-lexicons.txt");
504
+ expect(result.reason).not.toContain("already covers");
505
+ });
506
+
507
+ test("publish.yml with no per-lexicon prepack lines says nothing needs patching", () => {
508
+ writeFileSync(join(root, ".github/workflows/publish.yml"), "name: publish\njobs:\n test:\n steps:\n - run: bash scripts/publish-verify-ci.sh\n");
509
+ const result = onboardCommand({ name: "sql", root });
510
+ const line = result.skipped.find((s) => s.startsWith("publish.yml:"));
511
+ expect(line).toContain("nothing to patch");
512
+ expect(line).toContain("scripts/ci-lexicon-artifacts.sh");
513
+ });
514
+ });
@@ -117,6 +117,10 @@ function patchRootPackageJson(root: string, name: string): PatchResult {
117
117
  * The whole-repo typecheck runs with `moduleResolution: node`, which never
118
118
  * reads package exports maps, so every lexicon needs a bare + subpath
119
119
  * mapping here or an example importing the package fails to resolve.
120
+ *
121
+ * Entries are `./`-prefixed like every other entry (#3227): with no `baseUrl`
122
+ * (removed in #3205) a bare `lexicons/...` path is invalid and tsx's tsconfig
123
+ * loader throws on it for every run in the repo.
120
124
  */
121
125
  export function patchRootTsconfigPaths(root: string, name: string): PatchResult {
122
126
  const tsconfigPath = join(root, "tsconfig.json");
@@ -128,8 +132,8 @@ export function patchRootTsconfigPaths(root: string, name: string): PatchResult
128
132
 
129
133
  const bare = `@intentius/chant-lexicon-${name}`;
130
134
  const wanted: Record<string, string[]> = {
131
- [bare]: [`lexicons/${name}/src/index.ts`],
132
- [`${bare}/*`]: [`lexicons/${name}/src/*`],
135
+ [bare]: [`./lexicons/${name}/src/index.ts`],
136
+ [`${bare}/*`]: [`./lexicons/${name}/src/*`],
133
137
  };
134
138
 
135
139
  let changed = false;
@@ -297,7 +301,15 @@ function patchPublishWorkflow(root: string, name: string): PatchResult {
297
301
  }
298
302
 
299
303
  if (!insertPrepackAfterEach(lines, name)) {
300
- return { patched: false, reason: "no prepack line found to anchor on" };
304
+ // #3227 — not a failure and not "covered by a prepack line": publish.yml
305
+ // carries no per-lexicon lines. The run builds every lexicon through
306
+ // scripts/ci-lexicon-artifacts.sh and publishes through
307
+ // scripts/publish-packages.sh, both of which enumerate the workspace.
308
+ return {
309
+ patched: false,
310
+ reason:
311
+ "nothing to patch: it has no per-lexicon prepack lines; scripts/ci-lexicon-artifacts.sh and scripts/publish-packages.sh enumerate the workspace",
312
+ };
301
313
  }
302
314
  writeFileSync(filePath, lines.join("\n"));
303
315
  return { patched: true };
@@ -321,6 +333,12 @@ export function patchDockerfile(filePath: string, name: string): PatchResult {
321
333
 
322
334
  const changed = addToLexiconLoops(lines, name) || insertPrepackAfterEach(lines, name);
323
335
  if (!changed) {
336
+ // #3227 — the smoke-npm and smoke-e2e images read their lexicon list from
337
+ // a file. Point at it instead of reporting a missing anchor.
338
+ const listFile = lines.join("\n").match(/test\/(smoke-[\w-]+-lexicons\.txt)/)?.[1];
339
+ if (listFile) {
340
+ return { patched: false, reason: `reads its lexicon list from test/${listFile}, not from the Dockerfile` };
341
+ }
324
342
  return { patched: false, reason: "no lexicon loop or prepack line found to anchor on" };
325
343
  }
326
344
 
@@ -328,6 +346,22 @@ export function patchDockerfile(filePath: string, name: string): PatchResult {
328
346
  return { patched: true };
329
347
  }
330
348
 
349
+ /**
350
+ * Append a lexicon to a one-name-per-line list file (test/smoke-npm-lexicons.txt).
351
+ * Idempotent; keeps the file's trailing newline.
352
+ */
353
+ export function patchLexiconList(filePath: string, name: string): PatchResult {
354
+ const rel = filePath.split("/").slice(-2).join("/");
355
+ if (!existsSync(filePath)) return { patched: false, reason: `${rel} not found` };
356
+ const content = readFileSync(filePath, "utf-8");
357
+ if (content.split("\n").some((l) => l.trim() === name)) {
358
+ return { patched: false, reason: `${name} already in ${rel}` };
359
+ }
360
+ const sep = content === "" || content.endsWith("\n") ? "" : "\n";
361
+ writeFileSync(filePath, `${content}${sep}${name}\n`);
362
+ return { patched: true };
363
+ }
364
+
331
365
  /**
332
366
  * Execute the onboard command — patches monorepo infrastructure for a new lexicon.
333
367
  */
@@ -375,6 +409,20 @@ export function onboardCommand(options: OnboardOptions): OnboardResult {
375
409
  patchDockerfile(join(root, "test/Dockerfile.smoke-npm"), options.name),
376
410
  );
377
411
 
412
+ // 6. Smoke image lexicon lists (#3227). The npm smoke packs every lexicon.
413
+ // The e2e list is opt-in: it names the lexicons an example uses plus
414
+ // their dependencies, so onboard leaves it alone and says so.
415
+ record(
416
+ "smoke-npm-lexicons.txt",
417
+ "lexicon list",
418
+ patchLexiconList(join(root, "test/smoke-npm-lexicons.txt"), options.name),
419
+ );
420
+ if (existsSync(join(root, "test/smoke-e2e-lexicons.txt"))) {
421
+ skipped.push(
422
+ `smoke-e2e-lexicons.txt: not patched; it lists only lexicons an e2e example uses (and their dependencies). Add ${options.name} to test/smoke-e2e-lexicons.txt when an example needs it`,
423
+ );
424
+ }
425
+
378
426
  return { success: true, patched, skipped, verbose: options.verbose };
379
427
  }
380
428
 
@@ -396,7 +444,7 @@ export async function printOnboardResult(result: OnboardResult, name: string): P
396
444
 
397
445
  if (result.skipped.length > 0) {
398
446
  console.log("");
399
- console.log("Skipped (already covered):");
447
+ console.log("Not patched (already covered, or nothing to patch):");
400
448
  for (const s of result.skipped) {
401
449
  console.log(` ${s}`);
402
450
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `chant dev pinned-upgrade <lexicon-dir>` command implementation.
3
3
  *
4
- * Detects whether a pinned-version lexicon (k8s, gcp, docker, gitlab) has a
4
+ * Detects whether a lexicon that declares `upstreamPin` has a
5
5
  * newer stable upstream release. When it does, it dry-run bumps the pinned
6
6
  * version constant, regenerates + surface-diffs (via #524's regenLexicon), then
7
7
  * reverts the bump — leaving the working tree unchanged.
@@ -10,20 +10,21 @@
10
10
  */
11
11
 
12
12
  import { existsSync } from "fs";
13
- import { basename, resolve } from "path";
13
+ import { resolve } from "path";
14
14
  import {
15
- checkPinnedUpgrade,
15
+ checkPinnedUpgrades,
16
+ lexiconNameOf,
16
17
  type LexiconId,
17
18
  type UpgradeCheckResult,
18
19
  } from "../../codegen/pinned-upgrade";
19
20
 
20
- const PINNED_LEXICONS: readonly LexiconId[] = ["k8s", "gcp", "docker", "gitlab"];
21
-
22
21
  export interface PinnedUpgradeOptions {
23
22
  /** Resolved path to the lexicon directory. */
24
23
  lexiconDir: string;
25
24
  /** Explicit lexicon id; inferred from the directory name when omitted. */
26
25
  lexicon?: LexiconId;
26
+ /** Label of one pin to check, for a lexicon that declares several. Omitted: all of them. */
27
+ pin?: string;
27
28
  /** Force re-fetch of the upstream spec during regen. */
28
29
  force?: boolean;
29
30
  /** Print subprocess output while running. */
@@ -31,12 +32,13 @@ export interface PinnedUpgradeOptions {
31
32
  }
32
33
 
33
34
  /**
34
- * Infer the lexicon id from a directory name. Returns null when the directory
35
- * basename is not one of the pinned lexicons.
35
+ * Infer the lexicon id from a directory: its package name
36
+ * (`@intentius/chant-lexicon-<name>`), else the directory name. Whether the
37
+ * lexicon is pinned is the plugin's `upstreamPin`, checked by
38
+ * `checkPinnedUpgrade`, not a list here.
36
39
  */
37
- export function inferLexicon(lexiconDir: string): LexiconId | null {
38
- const name = basename(lexiconDir);
39
- return (PINNED_LEXICONS as readonly string[]).includes(name) ? (name as LexiconId) : null;
40
+ export function inferLexicon(lexiconDir: string): LexiconId {
41
+ return lexiconNameOf(lexiconDir);
40
42
  }
41
43
 
42
44
  /**
@@ -52,37 +54,38 @@ export function semverLabel(result: UpgradeCheckResult): "minor" | "major" | "no
52
54
 
53
55
  /**
54
56
  * Run the pinned-upgrade check and return the structured result.
55
- * Never throws — a missing dir or an unrecognised lexicon becomes a fetchError.
57
+ * Never throws — a missing dir or a lexicon with no `upstreamPin` becomes a fetchError.
56
58
  */
57
59
  export async function runPinnedUpgrade(opts: PinnedUpgradeOptions): Promise<UpgradeCheckResult> {
60
+ return (await runPinnedUpgrades(opts))[0]!;
61
+ }
62
+
63
+ /**
64
+ * Run the check for every pin the plugin declares (or the one in `opts.pin`),
65
+ * one result each. A lexicon with one pin gives one result.
66
+ */
67
+ export async function runPinnedUpgrades(opts: PinnedUpgradeOptions): Promise<UpgradeCheckResult[]> {
58
68
  const dir = resolve(opts.lexiconDir);
59
69
 
60
70
  const lexicon = opts.lexicon ?? inferLexicon(dir);
61
- if (!lexicon) {
62
- return {
63
- lexicon: "k8s",
64
- hasUpgrade: false,
65
- from: "(unknown)",
66
- to: null,
67
- validation: null,
68
- fetchError: `Not a pinned lexicon directory: ${dir}. Expected one of: ${PINNED_LEXICONS.join(", ")}.`,
69
- };
70
- }
71
71
 
72
72
  if (!existsSync(dir)) {
73
- return {
74
- lexicon,
75
- hasUpgrade: false,
76
- from: "(unknown)",
77
- to: null,
78
- validation: null,
79
- fetchError: `Lexicon directory not found: ${dir}`,
80
- };
73
+ return [
74
+ {
75
+ lexicon,
76
+ hasUpgrade: false,
77
+ from: "(unknown)",
78
+ to: null,
79
+ validation: null,
80
+ fetchError: `Lexicon directory not found: ${dir}`,
81
+ },
82
+ ];
81
83
  }
82
84
 
83
- return checkPinnedUpgrade({
85
+ return checkPinnedUpgrades({
84
86
  lexiconDir: dir,
85
87
  lexicon,
88
+ pin: opts.pin,
86
89
  force: opts.force,
87
90
  verbose: opts.verbose,
88
91
  });
@@ -112,12 +115,14 @@ function c(text: string, code: string): string {
112
115
  */
113
116
  export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boolean): void {
114
117
  const label = semverLabel(result);
118
+ const name = result.pin ? `${result.lexicon}/${result.pin}` : result.lexicon;
115
119
 
116
120
  if (json) {
117
121
  console.log(
118
122
  JSON.stringify(
119
123
  {
120
124
  lexicon: result.lexicon,
125
+ ...(result.pin ? { pin: result.pin } : {}),
121
126
  hasUpgrade: result.hasUpgrade,
122
127
  from: result.from,
123
128
  to: result.to,
@@ -128,6 +133,7 @@ export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boole
128
133
  validationOk: result.validation?.ok ?? null,
129
134
  failures: result.validation?.failures ?? [],
130
135
  fetchError: result.fetchError,
136
+ manualPin: result.manualPin ?? null,
131
137
  },
132
138
  null,
133
139
  2,
@@ -137,22 +143,31 @@ export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boole
137
143
  }
138
144
 
139
145
  if (result.fetchError) {
140
- console.log(c(`[${result.lexicon}] error: ${result.fetchError}`, COLORS.red));
146
+ console.log(c(`[${name}] error: ${result.fetchError}`, COLORS.red));
141
147
  return;
142
148
  }
143
149
 
144
150
  if (!result.hasUpgrade) {
145
151
  console.log(
146
- c(`[${result.lexicon}] up to date`, COLORS.green) +
152
+ c(`[${name}] up to date`, COLORS.green) +
147
153
  ` pinned=${result.from}` +
148
154
  (result.to ? ` latest=${result.to}` : ""),
149
155
  );
150
156
  return;
151
157
  }
152
158
 
159
+ if (result.manualPin) {
160
+ console.log(
161
+ c(`[${name}] upgrade available`, COLORS.bold) + ` ${result.from} -> ${result.to}`,
162
+ );
163
+ console.log(` The pin in ${result.manualPin.file} cannot be rewritten generically, so nothing was edited or regenerated.`);
164
+ console.log(` ${result.manualPin.instructions}`);
165
+ return;
166
+ }
167
+
153
168
  // Upgrade available
154
169
  console.log(
155
- c(`[${result.lexicon}] upgrade available`, COLORS.bold) +
170
+ c(`[${name}] upgrade available`, COLORS.bold) +
156
171
  ` ${result.from} -> ${result.to}`,
157
172
  );
158
173
 
@@ -202,3 +217,28 @@ export function printPinnedUpgradeResult(result: UpgradeCheckResult, json: boole
202
217
  `Validation: ${validationLabel} Semver: ${c(label, labelColor)} ${result.from} -> ${result.to}`,
203
218
  );
204
219
  }
220
+
221
+ /**
222
+ * Print one result per pin. One result prints exactly as `printPinnedUpgradeResult`;
223
+ * several print in turn, and `json` emits an array of the same objects.
224
+ */
225
+ export function printPinnedUpgradeResults(results: UpgradeCheckResult[], json: boolean): void {
226
+ if (results.length === 1) {
227
+ printPinnedUpgradeResult(results[0]!, json);
228
+ return;
229
+ }
230
+ if (json) {
231
+ // Each result prints as its own JSON object; collect them into one array.
232
+ const lines: string[] = [];
233
+ const log = console.log;
234
+ console.log = (...a: unknown[]) => void lines.push(a.join(" "));
235
+ try {
236
+ for (const r of results) printPinnedUpgradeResult(r, true);
237
+ } finally {
238
+ console.log = log;
239
+ }
240
+ console.log(`[${lines.join(",\n")}]`);
241
+ return;
242
+ }
243
+ for (const r of results) printPinnedUpgradeResult(r, false);
244
+ }
@@ -14,7 +14,7 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
  container: node:22-slim
16
16
  steps:
17
- - uses: actions/checkout@v4
17
+ - uses: actions/checkout@v7
18
18
  - run: chant run --components shared-alb --env staging --dump-outputs shared-alb.outputs.json
19
19
  - name: Upload shared-alb outputs
20
20
  uses: actions/upload-artifact@v4
@@ -27,7 +27,7 @@ jobs:
27
27
  - shared-alb
28
28
  container: node:22-slim
29
29
  steps:
30
- - uses: actions/checkout@v4
30
+ - uses: actions/checkout@v7
31
31
  - name: Download shared-alb outputs
32
32
  uses: actions/download-artifact@v4
33
33
  with:
@@ -48,7 +48,7 @@ import type { ComponentBomSummary } from "../../lifecycle/build-ledger";
48
48
  import type { BuildArchiveManifest } from "../../components/verbs/build-archive";
49
49
  import { loadChantConfig } from "../../config";
50
50
  import { applyLiveEndpoint } from "../../live-endpoint";
51
- import { isResourceDeclarable } from "../../declarable";
51
+ import { isObservableDeclarable } from "../../declarable";
52
52
  import { build } from "../../build";
53
53
  import { discoverComponents } from "../../components/discover";
54
54
  import { formatError, formatWarning, formatSuccess, formatBold } from "../format";
@@ -643,7 +643,7 @@ export async function runComponentsStatus(ctx: CommandContext): Promise<number>
643
643
  const entities = new Map<string, { entityType: string; props: Record<string, unknown> }>();
644
644
  for (const [name, entity] of buildResult.entities) {
645
645
  // Resource declarables only (see lifecycle/observe.ts).
646
- if (entity.lexicon === plugin.name && isResourceDeclarable(entity)) {
646
+ if (entity.lexicon === plugin.name && isObservableDeclarable(entity)) {
647
647
  declared.add(name);
648
648
  entities.set(name, {
649
649
  entityType: entity.entityType,
@@ -85,16 +85,18 @@ export async function runDevSurfaceDiff(ctx: CommandContext): Promise<number> {
85
85
 
86
86
  export async function runDevPinnedUpgrade(ctx: CommandContext): Promise<number> {
87
87
  const dir = ctx.args.extraPositional ?? ".";
88
- const { runPinnedUpgrade, printPinnedUpgradeResult } = await import("../commands/pinned-upgrade");
89
- const result = await runPinnedUpgrade({
88
+ const { runPinnedUpgrades, printPinnedUpgradeResults } = await import("../commands/pinned-upgrade");
89
+ // The optional second positional is a pin label, for a lexicon that declares several pins.
90
+ const results = await runPinnedUpgrades({
90
91
  lexiconDir: resolve(dir),
92
+ pin: ctx.args.extraPositional2,
91
93
  force: ctx.args.force,
92
94
  verbose: ctx.args.verbose,
93
95
  });
94
- printPinnedUpgradeResult(result, ctx.args.format === "json");
95
- // Exit non-zero when the upstream query failed or the regen validation broke.
96
- if (result.fetchError) return 1;
97
- if (result.validation && !result.validation.ok) return 1;
96
+ printPinnedUpgradeResults(results, ctx.args.format === "json");
97
+ // Exit non-zero when an upstream query failed or a regen validation broke.
98
+ if (results.some((r) => r.fetchError)) return 1;
99
+ if (results.some((r) => r.validation && !r.validation.ok)) return 1;
98
100
  return 0;
99
101
  }
100
102
 
@@ -204,8 +204,8 @@ describe("proof: a plan-only invocation prints the derivation and dispatches not
204
204
  expect(out).toContain("wave 1: cluster-a");
205
205
  expect(out).toContain("seeded from an earlier run: net");
206
206
  expect(out).toMatch(/billing +unaffected/);
207
- expect(out).toMatch(/plan: sha256:[0-9a-f]{64}/);
208
- expect(out).toMatch(/approve: chant approve fan-out release --plan sha256:[0-9a-f]{64}/);
207
+ expect(out).toMatch(/plan: jcs1-sha256:[0-9a-f]{64}/);
208
+ expect(out).toMatch(/approve: chant approve fan-out release --plan jcs1-sha256:[0-9a-f]{64}/);
209
209
  });
210
210
 
211
211
  test("--dry-run with --resume shows what is left, at the digest that approves it", async () => {
@@ -214,7 +214,7 @@ describe("proof: a plan-only invocation prints the derivation and dispatches not
214
214
  const resume = join(dir, "attempt.json");
215
215
  failing = ["cluster-a"];
216
216
  await runComponentsFanOut(ctx({ base: "main", env: "test", resume }));
217
- const digest = /plan: (sha256:[0-9a-f]{64})/.exec(stderr())?.[1];
217
+ const digest = /plan: (jcs1-sha256:[0-9a-f]{64})/.exec(stderr())?.[1];
218
218
 
219
219
  ran = [];
220
220
  stderrLines = [];
@@ -236,7 +236,7 @@ describe("proof: a plan-only invocation prints the derivation and dispatches not
236
236
  expect(exit).toBe(0);
237
237
  const parsed = JSON.parse(stdout());
238
238
  expect(parsed.order).toEqual(["net", "cluster-a", "cluster-b", "app-one", "app-three", "app-two"]);
239
- expect(parsed.digest).toMatch(/^sha256:[0-9a-f]{64}$/);
239
+ expect(parsed.digest).toMatch(/^jcs1-sha256:[0-9a-f]{64}$/);
240
240
  });
241
241
  });
242
242
 
@@ -334,10 +334,10 @@ describe("proof: one approval covers the set, and the printed digest is what app
334
334
  expect(ran).toEqual([]);
335
335
  const out = stderr();
336
336
  expect(out).toContain("gated: nothing ran.");
337
- expect(out).toMatch(/approve : chant approve fan-out release --plan sha256:[0-9a-f]{64}/);
337
+ expect(out).toMatch(/approve : chant approve fan-out release --plan jcs1-sha256:[0-9a-f]{64}/);
338
338
  // One pending fact for the whole set, not one per component.
339
339
  expect(gateLedger.appended).toHaveLength(1);
340
- expect(gateLedger.appended[0].planDigest).toBe(/plan: (sha256:[0-9a-f]{64})/.exec(out)?.[1]);
340
+ expect(gateLedger.appended[0].planDigest).toBe(/plan: (jcs1-sha256:[0-9a-f]{64})/.exec(out)?.[1]);
341
341
  });
342
342
 
343
343
  test("the resolution for that digest lets the whole set through", async () => {
@@ -38,6 +38,7 @@
38
38
  import { resolve, dirname } from "node:path";
39
39
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
40
40
  import { loadChantConfig, resolveAutoReleaseDisabled, type ChantConfig } from "../../config";
41
+ import { samePlanDigest } from "../../lifecycle/plan-digest";
41
42
  import { affectedStacks } from "../../lifecycle/affected";
42
43
  import { deriveFanOut, fanOutRegistry } from "../../components/fan-out-support";
43
44
  import { runFanOut } from "../../components/fan-out-run";
@@ -242,7 +243,7 @@ export async function runComponentsFanOut(ctx: CommandContext): Promise<number>
242
243
  console.error(formatError({ message: `--resume: could not read "${args.resume}": ${err instanceof Error ? err.message : String(err)}` }));
243
244
  return 1;
244
245
  }
245
- if (attempt && attempt.digest !== derived.plan.digest) {
246
+ if (attempt && !samePlanDigest(attempt.digest, derived.plan.digest)) {
246
247
  console.error(formatWarning({
247
248
  message: `--resume: "${args.resume}" records a different fan-out (${attempt.digest || "no digest"}), so its progress does not apply here`,
248
249
  hint: "The derivation changed, which makes this a different change. Everything selected will run.",
@@ -161,6 +161,7 @@ describe("runGraph", () => {
161
161
  observeMock.mockReset();
162
162
  buildMock.mockReset();
163
163
  loadPluginsMock.mockReset();
164
+ loadPluginsMock.mockResolvedValue([]);
164
165
  resolveLexMock.mockReset();
165
166
  loadChantConfigMock.mockReset();
166
167
  loadChantConfigMock.mockResolvedValue({ config: {} });
@@ -228,6 +229,47 @@ describe("runGraph", () => {
228
229
  expect(ir.edges).toContainEqual({ from: "subnet", to: "vpc", kind: "ref", viaAttr: "network" });
229
230
  });
230
231
 
232
+ // #2559 — a lexicon's graphMeta answer lands in the IR meta, so the
233
+ // workspace graph can list collector pipelines without core importing otel.
234
+ test("--format ir carries what a lexicon's graphMeta reports under meta", async () => {
235
+ lintClean(); discovered();
236
+ const seen: string[][] = [];
237
+ loadPluginsMock.mockResolvedValue([{
238
+ name: "gcp",
239
+ serializer: {},
240
+ graphMeta: (entities: Map<string, unknown>) => {
241
+ seen.push([...entities.keys()].sort());
242
+ return { collector: { pipelines: [] } };
243
+ },
244
+ }]);
245
+ resolveLexMock.mockResolvedValue(["gcp"]);
246
+ const exit = await runGraph({ args: makeArgs({ format: "ir" }), plugins: [], serializers: [] });
247
+ expect(exit).toBe(0);
248
+ expect(seen).toEqual([["pod", "subnet", "vpc"]]);
249
+ expect(JSON.parse(stdoutBuf.join("\n")).meta).toEqual({ collector: { pipelines: [] } });
250
+ });
251
+
252
+ test("--format ir has no meta when no lexicon reports anything", async () => {
253
+ lintClean(); discovered();
254
+ loadPluginsMock.mockResolvedValue([{ name: "gcp", serializer: {}, graphMeta: () => undefined }, { name: "k8s", serializer: {} }]);
255
+ resolveLexMock.mockResolvedValue(["gcp", "k8s"]);
256
+ const exit = await runGraph({ args: makeArgs({ format: "ir" }), plugins: [], serializers: [] });
257
+ expect(exit).toBe(0);
258
+ expect("meta" in JSON.parse(stdoutBuf.join("\n"))).toBe(false);
259
+ });
260
+
261
+ test("--format ir keeps the first answer when two lexicons report one key", async () => {
262
+ lintClean(); discovered();
263
+ loadPluginsMock.mockResolvedValue([
264
+ { name: "a", serializer: {}, graphMeta: () => ({ collector: 1 }) },
265
+ { name: "b", serializer: {}, graphMeta: () => ({ collector: 2 }) },
266
+ ]);
267
+ resolveLexMock.mockResolvedValue(["a", "b"]);
268
+ const exit = await runGraph({ args: makeArgs({ format: "ir" }), plugins: [], serializers: [] });
269
+ expect(exit).toBe(0);
270
+ expect(JSON.parse(stdoutBuf.join("\n")).meta).toEqual({ collector: 1 });
271
+ });
272
+
231
273
  // #2529 — the IR carries its version, as the first key, so a reader can
232
274
  // decide how to read the rest before it reads anything else.
233
275
  test("--format ir leads with the IR version", async () => {
@@ -702,6 +702,27 @@ async function buildPipelineProjection(
702
702
  * Lint-gated: the IR represents valid infra, so we refuse to emit for source that
703
703
  * does not pass lint. Non-zero on discovery errors or a layout-engine failure.
704
704
  */
705
+ /**
706
+ * Add what the lexicons' `graphMeta` hooks report to `ir.meta` (#2559). A
707
+ * lexicon with nothing to report leaves the IR as it was, so a project that
708
+ * declares none of their entities prints what it did before. Two lexicons
709
+ * that answer the same key keep the first and say so on stderr.
710
+ */
711
+ function withGraphMeta(ir: GraphIR, plugins: LexiconPlugin[], entities: Map<string, import("../../declarable").Declarable>): GraphIR {
712
+ const added: Record<string, unknown> = {};
713
+ for (const p of plugins) {
714
+ if (!p.graphMeta) continue;
715
+ for (const [key, value] of Object.entries(p.graphMeta(entities) ?? {})) {
716
+ if (key in added || (ir.meta && key in ir.meta)) {
717
+ console.error(formatWarning({ message: `the ${p.name} lexicon reports graph meta "${key}", which another source already set; its value is dropped` }));
718
+ continue;
719
+ }
720
+ added[key] = value;
721
+ }
722
+ }
723
+ return Object.keys(added).length === 0 ? ir : { ...ir, meta: { ...(ir.meta ?? {}), ...added } };
724
+ }
725
+
705
726
  /** Returned instead of a graph when the prediction cannot be attempted honestly. */
706
727
  const REFUSED = Symbol("behaviour-refused");
707
728
 
@@ -855,6 +876,7 @@ async function runGraphView(
855
876
  });
856
877
  if (predicted === REFUSED) return 1;
857
878
  ir = predicted;
879
+ ir = withGraphMeta(ir, plugins as LexiconPlugin[], result.entities);
858
880
  }
859
881
 
860
882
  if (ctx.args.lens) {