@intentius/chant 0.101.0 → 0.104.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 (739) 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/core.d.ts +2 -0
  4. package/dist/audit/core.d.ts.map +1 -1
  5. package/dist/audit/discover.d.ts.map +1 -1
  6. package/dist/audit/nginx.d.ts.map +1 -1
  7. package/dist/audit/prior-art.d.ts +48 -0
  8. package/dist/audit/prior-art.d.ts.map +1 -1
  9. package/dist/behaviour-kinds.d.ts.map +1 -1
  10. package/dist/builder.d.ts.map +1 -1
  11. package/dist/change-set.d.ts +232 -0
  12. package/dist/change-set.d.ts.map +1 -0
  13. package/dist/cli/commands/audit.d.ts +7 -0
  14. package/dist/cli/commands/audit.d.ts.map +1 -1
  15. package/dist/cli/commands/build.d.ts.map +1 -1
  16. package/dist/cli/commands/carve-emit.d.ts.map +1 -1
  17. package/dist/cli/commands/check-lexicon.d.ts +16 -0
  18. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  19. package/dist/cli/commands/import.d.ts +8 -0
  20. package/dist/cli/commands/import.d.ts.map +1 -1
  21. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  22. package/dist/cli/commands/init.d.ts +19 -0
  23. package/dist/cli/commands/init.d.ts.map +1 -1
  24. package/dist/cli/commands/onboard.d.ts +9 -0
  25. package/dist/cli/commands/onboard.d.ts.map +1 -1
  26. package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
  27. package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
  28. package/dist/cli/handlers/build.d.ts.map +1 -1
  29. package/dist/cli/handlers/change-set.d.ts +11 -0
  30. package/dist/cli/handlers/change-set.d.ts.map +1 -0
  31. package/dist/cli/handlers/dev.d.ts.map +1 -1
  32. package/dist/cli/handlers/fan-out.d.ts +33 -0
  33. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  34. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  35. package/dist/cli/handlers/misc.d.ts.map +1 -1
  36. package/dist/cli/handlers/operator.d.ts +16 -0
  37. package/dist/cli/handlers/operator.d.ts.map +1 -1
  38. package/dist/cli/handlers/pr.d.ts +31 -0
  39. package/dist/cli/handlers/pr.d.ts.map +1 -0
  40. package/dist/cli/handlers/run.d.ts.map +1 -1
  41. package/dist/cli/lsp/server.d.ts.map +1 -1
  42. package/dist/cli/main.d.ts.map +1 -1
  43. package/dist/cli/mcp/op-tools.d.ts.map +1 -1
  44. package/dist/cli/mcp/server.d.ts.map +1 -1
  45. package/dist/cli/mcp/tools/build.d.ts.map +1 -1
  46. package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
  47. package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
  48. package/dist/cli/mcp/tools/import.d.ts.map +1 -1
  49. package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
  50. package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
  51. package/dist/cli/mcp/tools/search.d.ts.map +1 -1
  52. package/dist/cli/mcp/workspace-tools.d.ts +4 -3
  53. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  54. package/dist/cli/registry.d.ts +74 -3
  55. package/dist/cli/registry.d.ts.map +1 -1
  56. package/dist/codegen/fetch.d.ts.map +1 -1
  57. package/dist/codegen/naming.d.ts.map +1 -1
  58. package/dist/codegen/pinned-upgrade.d.ts +67 -3
  59. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  60. package/dist/codegen/registry.d.ts.map +1 -1
  61. package/dist/components/auto-release.d.ts +16 -0
  62. package/dist/components/auto-release.d.ts.map +1 -1
  63. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  64. package/dist/components/capability.d.ts +53 -0
  65. package/dist/components/capability.d.ts.map +1 -1
  66. package/dist/components/changed-files.d.ts +31 -0
  67. package/dist/components/changed-files.d.ts.map +1 -0
  68. package/dist/components/cli-support.d.ts +9 -1
  69. package/dist/components/cli-support.d.ts.map +1 -1
  70. package/dist/components/component.d.ts +24 -0
  71. package/dist/components/component.d.ts.map +1 -1
  72. package/dist/components/deploy-units.d.ts.map +1 -1
  73. package/dist/components/driver.d.ts +13 -0
  74. package/dist/components/driver.d.ts.map +1 -1
  75. package/dist/components/fan-out-output.d.ts +6 -0
  76. package/dist/components/fan-out-output.d.ts.map +1 -1
  77. package/dist/components/fan-out-record.d.ts +41 -0
  78. package/dist/components/fan-out-record.d.ts.map +1 -0
  79. package/dist/components/fan-out-run.d.ts +65 -0
  80. package/dist/components/fan-out-run.d.ts.map +1 -1
  81. package/dist/components/fan-out-support.d.ts +2 -0
  82. package/dist/components/fan-out-support.d.ts.map +1 -1
  83. package/dist/components/fan-out.d.ts +6 -0
  84. package/dist/components/fan-out.d.ts.map +1 -1
  85. package/dist/components/gated-wave-pipeline.d.ts +50 -0
  86. package/dist/components/gated-wave-pipeline.d.ts.map +1 -0
  87. package/dist/components/index.d.ts +1 -1
  88. package/dist/components/index.d.ts.map +1 -1
  89. package/dist/components/layers.d.ts +25 -0
  90. package/dist/components/layers.d.ts.map +1 -0
  91. package/dist/components/pr-pipeline.d.ts +61 -0
  92. package/dist/components/pr-pipeline.d.ts.map +1 -0
  93. package/dist/components/pr-run.d.ts +119 -0
  94. package/dist/components/pr-run.d.ts.map +1 -0
  95. package/dist/components/promote.d.ts.map +1 -1
  96. package/dist/components/starter-plugin.d.ts.map +1 -1
  97. package/dist/components/verbs/process-runner.d.ts.map +1 -1
  98. package/dist/components/verbs/r2-sync.d.ts.map +1 -1
  99. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  100. package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
  101. package/dist/components/verbs/shell.d.ts.map +1 -1
  102. package/dist/components/verbs/sign.d.ts.map +1 -1
  103. package/dist/components/verbs/verify.d.ts.map +1 -1
  104. package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
  105. package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
  106. package/dist/components/verbs/wrangler.d.ts.map +1 -1
  107. package/dist/components/wave-plan.d.ts +49 -0
  108. package/dist/components/wave-plan.d.ts.map +1 -0
  109. package/dist/composite.d.ts.map +1 -1
  110. package/dist/config.d.ts +19 -7
  111. package/dist/config.d.ts.map +1 -1
  112. package/dist/declarable.d.ts +16 -0
  113. package/dist/declarable.d.ts.map +1 -1
  114. package/dist/discovery/cache.d.ts.map +1 -1
  115. package/dist/discovery/fold-import.d.ts +15 -5
  116. package/dist/discovery/fold-import.d.ts.map +1 -1
  117. package/dist/discovery/param-deps.d.ts +16 -0
  118. package/dist/discovery/param-deps.d.ts.map +1 -1
  119. package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
  120. package/dist/discovery/specifier-resolve.d.ts +37 -0
  121. package/dist/discovery/specifier-resolve.d.ts.map +1 -0
  122. package/dist/errors.d.ts.map +1 -1
  123. package/dist/fold/fold.d.ts +3 -1
  124. package/dist/fold/fold.d.ts.map +1 -1
  125. package/dist/gated-waves.d.ts +147 -0
  126. package/dist/gated-waves.d.ts.map +1 -0
  127. package/dist/graph-detail.d.ts.map +1 -1
  128. package/dist/graph-ir.d.ts.map +1 -1
  129. package/dist/graph-layout.d.ts.map +1 -1
  130. package/dist/import/base-parser.d.ts.map +1 -1
  131. package/dist/import/embedded.d.ts +7 -0
  132. package/dist/import/embedded.d.ts.map +1 -1
  133. package/dist/import/parser-options.d.ts +14 -0
  134. package/dist/import/parser-options.d.ts.map +1 -0
  135. package/dist/import/parser.d.ts +17 -0
  136. package/dist/import/parser.d.ts.map +1 -1
  137. package/dist/index.d.ts +1 -0
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/kubectl-context.d.ts.map +1 -1
  140. package/dist/lexicon-output.d.ts.map +1 -1
  141. package/dist/lexicon-schema.d.ts +3 -3
  142. package/dist/lexicon.d.ts +103 -3
  143. package/dist/lexicon.d.ts.map +1 -1
  144. package/dist/lifecycle/assert-live.d.ts.map +1 -1
  145. package/dist/lifecycle/gate-ledger.d.ts +22 -0
  146. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  147. package/dist/lifecycle/git.d.ts +46 -1
  148. package/dist/lifecycle/git.d.ts.map +1 -1
  149. package/dist/lifecycle/member-ledger.d.ts.map +1 -1
  150. package/dist/lifecycle/observe.d.ts.map +1 -1
  151. package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
  152. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  153. package/dist/lifecycle/scenario.d.ts.map +1 -1
  154. package/dist/lifecycle/status.d.ts.map +1 -1
  155. package/dist/lifecycle/work-lease.d.ts +61 -2
  156. package/dist/lifecycle/work-lease.d.ts.map +1 -1
  157. package/dist/lint/config.d.ts +8 -8
  158. package/dist/lint/engine.d.ts +6 -0
  159. package/dist/lint/engine.d.ts.map +1 -1
  160. package/dist/lint/post-synth.d.ts +18 -0
  161. package/dist/lint/post-synth.d.ts.map +1 -1
  162. package/dist/lsp/lexicon-providers.d.ts.map +1 -1
  163. package/dist/op/activities/activity-contracts.d.ts +137 -11
  164. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  165. package/dist/op/activities/apply.d.ts +79 -9
  166. package/dist/op/activities/apply.d.ts.map +1 -1
  167. package/dist/op/activities/change-set.d.ts +62 -0
  168. package/dist/op/activities/change-set.d.ts.map +1 -0
  169. package/dist/op/activities/decide.d.ts +2 -0
  170. package/dist/op/activities/decide.d.ts.map +1 -1
  171. package/dist/op/activities/factory.d.ts +137 -0
  172. package/dist/op/activities/factory.d.ts.map +1 -0
  173. package/dist/op/activities/index.d.ts +5 -1
  174. package/dist/op/activities/index.d.ts.map +1 -1
  175. package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
  176. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
  177. package/dist/op/activity-contract.d.ts +1 -1
  178. package/dist/op/activity-contract.d.ts.map +1 -1
  179. package/dist/op/activity-failure.d.ts.map +1 -1
  180. package/dist/op/activity-profiles.d.ts.map +1 -1
  181. package/dist/op/builders.d.ts +11 -0
  182. package/dist/op/builders.d.ts.map +1 -1
  183. package/dist/op/composites/apply-op.d.ts +12 -5
  184. package/dist/op/composites/apply-op.d.ts.map +1 -1
  185. package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
  186. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
  187. package/dist/op/decide-backend.d.ts +5 -1
  188. package/dist/op/decide-backend.d.ts.map +1 -1
  189. package/dist/op/decide-read-inputs.d.ts +4 -2
  190. package/dist/op/decide-read-inputs.d.ts.map +1 -1
  191. package/dist/op/emulator-lifecycle.d.ts +21 -2
  192. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  193. package/dist/op/factory.d.ts +83 -0
  194. package/dist/op/factory.d.ts.map +1 -0
  195. package/dist/op/gate-approval.d.ts +5 -1
  196. package/dist/op/gate-approval.d.ts.map +1 -1
  197. package/dist/op/gate-wait.d.ts.map +1 -1
  198. package/dist/op/gate.d.ts +19 -3
  199. package/dist/op/gate.d.ts.map +1 -1
  200. package/dist/op/index.d.ts +6 -1
  201. package/dist/op/index.d.ts.map +1 -1
  202. package/dist/op/local-executor.d.ts +6 -0
  203. package/dist/op/local-executor.d.ts.map +1 -1
  204. package/dist/op/op-ir.d.ts +2 -0
  205. package/dist/op/op-ir.d.ts.map +1 -1
  206. package/dist/op/op-verb-class.d.ts.map +1 -1
  207. package/dist/op/operator.d.ts.map +1 -1
  208. package/dist/op/run-context.d.ts +39 -0
  209. package/dist/op/run-context.d.ts.map +1 -0
  210. package/dist/op/run-live.d.ts.map +1 -1
  211. package/dist/op/runtimes/local.d.ts.map +1 -1
  212. package/dist/op/source-archive.d.ts.map +1 -1
  213. package/dist/op/steward-beside.d.ts.map +1 -1
  214. package/dist/op/steward-points.d.ts.map +1 -1
  215. package/dist/op/steward.d.ts.map +1 -1
  216. package/dist/op/types.d.ts +16 -3
  217. package/dist/op/types.d.ts.map +1 -1
  218. package/dist/op/work-lease-run.d.ts +24 -4
  219. package/dist/op/work-lease-run.d.ts.map +1 -1
  220. package/dist/plan-summary.d.ts +207 -0
  221. package/dist/plan-summary.d.ts.map +1 -0
  222. package/dist/pr-forge.d.ts +105 -0
  223. package/dist/pr-forge.d.ts.map +1 -0
  224. package/dist/pr-loop.d.ts +178 -0
  225. package/dist/pr-loop.d.ts.map +1 -0
  226. package/dist/project-root.d.ts.map +1 -1
  227. package/dist/provenance.d.ts +21 -0
  228. package/dist/provenance.d.ts.map +1 -1
  229. package/dist/pseudo-parameter.d.ts.map +1 -1
  230. package/dist/reconcile.d.ts.map +1 -1
  231. package/dist/secret-materialization.d.ts.map +1 -1
  232. package/dist/telemetry-attribution.d.ts +31 -0
  233. package/dist/telemetry-attribution.d.ts.map +1 -1
  234. package/dist/terraform/emit-source.d.ts.map +1 -1
  235. package/dist/terraform/hcl2json.d.ts +45 -0
  236. package/dist/terraform/hcl2json.d.ts.map +1 -0
  237. package/dist/terraform/parse.d.ts +4 -40
  238. package/dist/terraform/parse.d.ts.map +1 -1
  239. package/dist/testing.d.ts.map +1 -1
  240. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  241. package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
  242. package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
  243. package/dist/workspace/agent-cli.d.ts +5 -0
  244. package/dist/workspace/agent-cli.d.ts.map +1 -1
  245. package/dist/workspace/box-cli.d.ts +12 -0
  246. package/dist/workspace/box-cli.d.ts.map +1 -0
  247. package/dist/workspace/box-factory.d.ts +97 -0
  248. package/dist/workspace/box-factory.d.ts.map +1 -0
  249. package/dist/workspace/box-listing.d.ts +85 -0
  250. package/dist/workspace/box-listing.d.ts.map +1 -0
  251. package/dist/workspace/box-publish.d.ts +147 -0
  252. package/dist/workspace/box-publish.d.ts.map +1 -0
  253. package/dist/workspace/broker-protocol.d.ts +190 -0
  254. package/dist/workspace/broker-protocol.d.ts.map +1 -0
  255. package/dist/workspace/changes.d.ts.map +1 -1
  256. package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
  257. package/dist/workspace/checks/boxes.d.ts.map +1 -1
  258. package/dist/workspace/checks.d.ts +5 -0
  259. package/dist/workspace/checks.d.ts.map +1 -1
  260. package/dist/workspace/compose-graph.d.ts +10 -0
  261. package/dist/workspace/compose-graph.d.ts.map +1 -1
  262. package/dist/workspace/composites.d.ts +2 -2
  263. package/dist/workspace/composites.d.ts.map +1 -1
  264. package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
  265. package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
  266. package/dist/workspace/conformance/broker.d.ts +202 -0
  267. package/dist/workspace/conformance/broker.d.ts.map +1 -0
  268. package/dist/workspace/conformance/index.d.ts +68 -6
  269. package/dist/workspace/conformance/index.d.ts.map +1 -1
  270. package/dist/workspace/conformance/vitest.d.ts +19 -3
  271. package/dist/workspace/conformance/vitest.d.ts.map +1 -1
  272. package/dist/workspace/conformance/writer.d.ts +462 -0
  273. package/dist/workspace/conformance/writer.d.ts.map +1 -0
  274. package/dist/workspace/decide.d.ts +126 -12
  275. package/dist/workspace/decide.d.ts.map +1 -1
  276. package/dist/workspace/decision-points.schema.json +11 -4
  277. package/dist/workspace/declaration.d.ts +156 -4
  278. package/dist/workspace/declaration.d.ts.map +1 -1
  279. package/dist/workspace/declaration.schema.json +383 -5
  280. package/dist/workspace/environments.d.ts +36 -10
  281. package/dist/workspace/environments.d.ts.map +1 -1
  282. package/dist/workspace/factory-rules.d.ts +180 -0
  283. package/dist/workspace/factory-rules.d.ts.map +1 -0
  284. package/dist/workspace/generated-files.d.ts.map +1 -1
  285. package/dist/workspace/graph-cache.d.ts.map +1 -1
  286. package/dist/workspace/graph-cli.d.ts +2 -0
  287. package/dist/workspace/graph-cli.d.ts.map +1 -1
  288. package/dist/workspace/identity.d.ts +111 -0
  289. package/dist/workspace/identity.d.ts.map +1 -0
  290. package/dist/workspace/init.d.ts +21 -0
  291. package/dist/workspace/init.d.ts.map +1 -1
  292. package/dist/workspace/intent-cli.d.ts +7 -4
  293. package/dist/workspace/intent-cli.d.ts.map +1 -1
  294. package/dist/workspace/intent-record.d.ts +36 -2
  295. package/dist/workspace/intent-record.d.ts.map +1 -1
  296. package/dist/workspace/intent.d.ts +249 -8
  297. package/dist/workspace/intent.d.ts.map +1 -1
  298. package/dist/workspace/json-edit.d.ts +24 -0
  299. package/dist/workspace/json-edit.d.ts.map +1 -0
  300. package/dist/workspace/jsonc.d.ts +11 -0
  301. package/dist/workspace/jsonc.d.ts.map +1 -1
  302. package/dist/workspace/kinds.d.ts +66 -4
  303. package/dist/workspace/kinds.d.ts.map +1 -1
  304. package/dist/workspace/lexicon-symbols.d.ts +29 -0
  305. package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
  306. package/dist/workspace/lineage-hash-index.d.ts.map +1 -1
  307. package/dist/workspace/lineage-lock.d.ts +2 -2
  308. package/dist/workspace/lineage-lock.d.ts.map +1 -1
  309. package/dist/workspace/lineage-upgrade.d.ts +31 -2
  310. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  311. package/dist/workspace/links.d.ts.map +1 -1
  312. package/dist/workspace/point-answer.schema.json +42 -2
  313. package/dist/workspace/points-cli.d.ts +10 -3
  314. package/dist/workspace/points-cli.d.ts.map +1 -1
  315. package/dist/workspace/points.d.ts +66 -5
  316. package/dist/workspace/points.d.ts.map +1 -1
  317. package/dist/workspace/principal-classes.d.ts +114 -0
  318. package/dist/workspace/principal-classes.d.ts.map +1 -0
  319. package/dist/workspace/reason-codes.d.ts +53 -4
  320. package/dist/workspace/reason-codes.d.ts.map +1 -1
  321. package/dist/workspace/record-assets.d.ts.map +1 -1
  322. package/dist/workspace/record-sessions.d.ts +5 -7
  323. package/dist/workspace/record-sessions.d.ts.map +1 -1
  324. package/dist/workspace/records-checkout.d.ts +54 -0
  325. package/dist/workspace/records-checkout.d.ts.map +1 -0
  326. package/dist/workspace/records-cli.d.ts +34 -1
  327. package/dist/workspace/records-cli.d.ts.map +1 -1
  328. package/dist/workspace/records-close.d.ts +7 -3
  329. package/dist/workspace/records-close.d.ts.map +1 -1
  330. package/dist/workspace/records-since.d.ts.map +1 -1
  331. package/dist/workspace/records-write.d.ts +68 -7
  332. package/dist/workspace/records-write.d.ts.map +1 -1
  333. package/dist/workspace/records.d.ts +43 -9
  334. package/dist/workspace/records.d.ts.map +1 -1
  335. package/dist/workspace/runs-cli.d.ts +296 -0
  336. package/dist/workspace/runs-cli.d.ts.map +1 -0
  337. package/dist/workspace/runs.d.ts +544 -0
  338. package/dist/workspace/runs.d.ts.map +1 -0
  339. package/dist/workspace/session-kinds.d.ts +1 -1
  340. package/dist/workspace/session-kinds.d.ts.map +1 -1
  341. package/dist/workspace/source-block.d.ts +1 -1
  342. package/dist/workspace/source-block.d.ts.map +1 -1
  343. package/dist/workspace/squash.d.ts +80 -0
  344. package/dist/workspace/squash.d.ts.map +1 -0
  345. package/dist/workspace/status-gates.d.ts +17 -3
  346. package/dist/workspace/status-gates.d.ts.map +1 -1
  347. package/dist/workspace/status.d.ts +64 -0
  348. package/dist/workspace/status.d.ts.map +1 -1
  349. package/dist/workspace/symbols.d.ts +63 -0
  350. package/dist/workspace/symbols.d.ts.map +1 -0
  351. package/dist/workspace/trailer-joins.d.ts +46 -0
  352. package/dist/workspace/trailer-joins.d.ts.map +1 -0
  353. package/dist/workspace/trailers.d.ts +89 -0
  354. package/dist/workspace/trailers.d.ts.map +1 -0
  355. package/dist/workspace/trust/attestor.d.ts.map +1 -1
  356. package/dist/workspace/trust/rotation.d.ts.map +1 -1
  357. package/dist/workspace/trust/run-commits.d.ts +46 -0
  358. package/dist/workspace/trust/run-commits.d.ts.map +1 -0
  359. package/dist/workspace/trust/run-statement.d.ts +128 -0
  360. package/dist/workspace/trust/run-statement.d.ts.map +1 -0
  361. package/dist/workspace/trust/seal.d.ts +38 -0
  362. package/dist/workspace/trust/seal.d.ts.map +1 -1
  363. package/dist/workspace/trust/test-repo.d.ts.map +1 -1
  364. package/dist/workspace/trust/verify-cli.d.ts +1 -1
  365. package/dist/workspace/trust/verify.d.ts +16 -2
  366. package/dist/workspace/trust/verify.d.ts.map +1 -1
  367. package/dist/workspace/wip-cli.d.ts +21 -0
  368. package/dist/workspace/wip-cli.d.ts.map +1 -0
  369. package/dist/workspace/wip.d.ts +268 -0
  370. package/dist/workspace/wip.d.ts.map +1 -0
  371. package/dist/workspace/work-cli.d.ts +39 -3
  372. package/dist/workspace/work-cli.d.ts.map +1 -1
  373. package/dist/workspace/work-evidence.d.ts +1 -1
  374. package/dist/workspace/work-evidence.d.ts.map +1 -1
  375. package/dist/workspace/work-size.d.ts +55 -0
  376. package/dist/workspace/work-size.d.ts.map +1 -0
  377. package/dist/workspace/work.d.ts +26 -1
  378. package/dist/workspace/work.d.ts.map +1 -1
  379. package/dist/workspace/workspace-kinds.schema.json +122 -0
  380. package/dist/workspace/workspace-principals.schema.json +60 -0
  381. package/dist/workspace/write-lock-cli.d.ts +60 -0
  382. package/dist/workspace/write-lock-cli.d.ts.map +1 -0
  383. package/dist/workspace/write-lock.d.ts +152 -0
  384. package/dist/workspace/write-lock.d.ts.map +1 -0
  385. package/dist/workspace/write-scope.d.ts +83 -19
  386. package/dist/workspace/write-scope.d.ts.map +1 -1
  387. package/dist/yaml.d.ts +21 -39
  388. package/dist/yaml.d.ts.map +1 -1
  389. package/package.json +7 -2
  390. package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
  391. package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
  392. package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
  393. package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
  394. package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
  395. package/src/__fixtures__/change-set/warden.plan.json +44 -0
  396. package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
  397. package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
  398. package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
  399. package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
  400. package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
  401. package/src/audit/core.test.ts +15 -0
  402. package/src/audit/core.ts +8 -2
  403. package/src/audit/discover.test.ts +11 -0
  404. package/src/audit/discover.ts +7 -2
  405. package/src/audit/prior-art.ts +15 -0
  406. package/src/change-set-bundle.test.ts +57 -0
  407. package/src/change-set.test.ts +215 -0
  408. package/src/change-set.ts +445 -0
  409. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
  410. package/src/cli/commands/audit-opt-in.test.ts +54 -0
  411. package/src/cli/commands/audit.ts +29 -2
  412. package/src/cli/commands/build.test.ts +19 -0
  413. package/src/cli/commands/build.ts +3 -2
  414. package/src/cli/commands/carve-emit-state.test.ts +4 -0
  415. package/src/cli/commands/carve-emit.ts +5 -19
  416. package/src/cli/commands/check-lexicon.test.ts +62 -1
  417. package/src/cli/commands/check-lexicon.ts +36 -6
  418. package/src/cli/commands/import-live.test.ts +18 -0
  419. package/src/cli/commands/import-parser-options.test.ts +133 -0
  420. package/src/cli/commands/import.ts +21 -3
  421. package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
  422. package/src/cli/commands/init.test.ts +8 -1
  423. package/src/cli/commands/init.ts +23 -8
  424. package/src/cli/commands/lint.test.ts +37 -0
  425. package/src/cli/commands/onboard.test.ts +53 -3
  426. package/src/cli/commands/onboard.ts +52 -4
  427. package/src/cli/commands/pinned-upgrade.ts +73 -33
  428. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
  429. package/src/cli/handlers/build.ts +13 -1
  430. package/src/cli/handlers/change-set.test.ts +56 -0
  431. package/src/cli/handlers/change-set.ts +44 -0
  432. package/src/cli/handlers/components.ts +2 -2
  433. package/src/cli/handlers/dev.ts +8 -6
  434. package/src/cli/handlers/fan-out.test.ts +221 -2
  435. package/src/cli/handlers/fan-out.ts +165 -75
  436. package/src/cli/handlers/graph.ts +3 -0
  437. package/src/cli/handlers/lifecycle.test.ts +67 -0
  438. package/src/cli/handlers/lifecycle.ts +6 -5
  439. package/src/cli/handlers/misc.ts +2 -0
  440. package/src/cli/handlers/operator.test.ts +21 -0
  441. package/src/cli/handlers/operator.ts +121 -6
  442. package/src/cli/handlers/pr.ts +373 -0
  443. package/src/cli/handlers/run.test.ts +111 -0
  444. package/src/cli/handlers/run.ts +86 -24
  445. package/src/cli/handlers/scenario.ts +2 -2
  446. package/src/cli/main.test.ts +21 -0
  447. package/src/cli/main.ts +246 -30
  448. package/src/cli/mcp/never-over-mcp.test.ts +101 -0
  449. package/src/cli/mcp/op-tools.ts +24 -2
  450. package/src/cli/mcp/workspace-tools.test.ts +5 -2
  451. package/src/cli/mcp/workspace-tools.ts +62 -7
  452. package/src/cli/registry.ts +74 -3
  453. package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
  454. package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
  455. package/src/codegen/pinned-upgrade.test.ts +104 -0
  456. package/src/codegen/pinned-upgrade.ts +250 -56
  457. package/src/codegen/testdata/postgres-tags.json +242 -0
  458. package/src/components/auto-release.ts +1 -1
  459. package/src/components/capability.ts +55 -0
  460. package/src/components/changed-files.ts +66 -0
  461. package/src/components/cli-support.ts +28 -5
  462. package/src/components/component.schema.json +17 -0
  463. package/src/components/component.ts +25 -0
  464. package/src/components/deploy-units.ts +3 -0
  465. package/src/components/driver.test.ts +52 -0
  466. package/src/components/driver.ts +31 -13
  467. package/src/components/fan-out-output.ts +42 -1
  468. package/src/components/fan-out-record.ts +69 -0
  469. package/src/components/fan-out-run.test.ts +17 -0
  470. package/src/components/fan-out-run.ts +304 -1
  471. package/src/components/fan-out-support.ts +3 -0
  472. package/src/components/fan-out-waves.test.ts +375 -0
  473. package/src/components/fan-out.ts +18 -17
  474. package/src/components/gated-wave-pipeline.ts +82 -0
  475. package/src/components/index.ts +1 -0
  476. package/src/components/layers.ts +30 -0
  477. package/src/components/pr-pipeline.ts +91 -0
  478. package/src/components/pr-run.test.ts +205 -0
  479. package/src/components/pr-run.ts +280 -0
  480. package/src/components/promote.ts +5 -0
  481. package/src/components/verbs/shell.test.ts +11 -0
  482. package/src/components/verbs/shell.ts +7 -3
  483. package/src/components/wave-plan.ts +124 -0
  484. package/src/config.test.ts +21 -0
  485. package/src/config.ts +15 -0
  486. package/src/declarable.test.ts +21 -0
  487. package/src/declarable.ts +19 -0
  488. package/src/discovery/fold-composite.test.ts +41 -5
  489. package/src/discovery/fold-import.test.ts +129 -0
  490. package/src/discovery/fold-import.ts +643 -131
  491. package/src/discovery/fold-package-composite.test.ts +264 -0
  492. package/src/discovery/fold-specifiers.test.ts +191 -0
  493. package/src/discovery/param-deps.test.ts +66 -1
  494. package/src/discovery/param-deps.ts +45 -0
  495. package/src/discovery/sandbox/bundle.ts +1 -1
  496. package/src/discovery/specifier-resolve.ts +344 -0
  497. package/src/fold/fold.test.ts +39 -1
  498. package/src/fold/fold.ts +83 -9
  499. package/src/fold-provenance.test.ts +140 -0
  500. package/src/gated-waves-bundle.test.ts +62 -0
  501. package/src/gated-waves.test.ts +118 -0
  502. package/src/gated-waves.ts +240 -0
  503. package/src/graph-ir.test.ts +83 -0
  504. package/src/graph-ir.ts +29 -0
  505. package/src/import/embedded.test.ts +20 -0
  506. package/src/import/embedded.ts +13 -0
  507. package/src/import/parser-options.ts +46 -0
  508. package/src/import/parser.ts +20 -0
  509. package/src/index.ts +1 -0
  510. package/src/lexicon.ts +106 -3
  511. package/src/lifecycle/gate-ledger.ts +23 -0
  512. package/src/lifecycle/git.ts +102 -16
  513. package/src/lifecycle/observe.test.ts +18 -0
  514. package/src/lifecycle/observe.ts +6 -4
  515. package/src/lifecycle/snapshot.ts +2 -2
  516. package/src/lifecycle/work-lease.test.ts +1 -1
  517. package/src/lifecycle/work-lease.ts +93 -2
  518. package/src/lint/engine.test.ts +55 -0
  519. package/src/lint/engine.ts +30 -4
  520. package/src/lint/output-docs.test.ts +59 -56
  521. package/src/lint/post-synth.test.ts +19 -0
  522. package/src/lint/post-synth.ts +19 -1
  523. package/src/meta/declared-imports.test.ts +1 -1
  524. package/src/op/activities/activity-contracts.ts +84 -0
  525. package/src/op/activities/apply.test.ts +189 -5
  526. package/src/op/activities/apply.ts +230 -8
  527. package/src/op/activities/change-set.ts +114 -0
  528. package/src/op/activities/decide.ts +3 -0
  529. package/src/op/activities/factory.ts +675 -0
  530. package/src/op/activities/index.ts +9 -0
  531. package/src/op/activities/lexicon-upgrade.test.ts +160 -6
  532. package/src/op/activities/lexicon-upgrade.ts +154 -51
  533. package/src/op/activity-contract.test.ts +21 -1
  534. package/src/op/activity-contract.ts +19 -9
  535. package/src/op/builders.ts +23 -0
  536. package/src/op/composites/apply-op.ts +12 -5
  537. package/src/op/composites/composites.test.ts +30 -3
  538. package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
  539. package/src/op/composites/lexicon-upgrade-op.ts +29 -8
  540. package/src/op/decide-backend.ts +5 -1
  541. package/src/op/decide-read-inputs.ts +33 -5
  542. package/src/op/emulator-lifecycle.test.ts +23 -0
  543. package/src/op/emulator-lifecycle.ts +52 -14
  544. package/src/op/factory.e2e.test.ts +232 -0
  545. package/src/op/factory.ts +118 -0
  546. package/src/op/gate-approval.test.ts +74 -0
  547. package/src/op/gate-approval.ts +5 -1
  548. package/src/op/gate.ts +31 -5
  549. package/src/op/index.ts +11 -1
  550. package/src/op/local-executor.test.ts +15 -0
  551. package/src/op/local-executor.ts +40 -12
  552. package/src/op/local-output.ts +1 -1
  553. package/src/op/op-ir.test.ts +9 -0
  554. package/src/op/op-ir.ts +4 -0
  555. package/src/op/op-verb-class.ts +3 -0
  556. package/src/op/operator.ts +4 -0
  557. package/src/op/run-context.test.ts +141 -0
  558. package/src/op/run-context.ts +51 -0
  559. package/src/op/runtimes/local.test.ts +14 -0
  560. package/src/op/runtimes/local.ts +2 -0
  561. package/src/op/steward-beside.ts +2 -0
  562. package/src/op/types.ts +16 -3
  563. package/src/op/work-lease-run.test.ts +47 -0
  564. package/src/op/work-lease-run.ts +76 -11
  565. package/src/plan-summary.test.ts +263 -0
  566. package/src/plan-summary.ts +845 -0
  567. package/src/pr-forge.test.ts +237 -0
  568. package/src/pr-forge.ts +332 -0
  569. package/src/pr-loop-bundle.test.ts +46 -0
  570. package/src/pr-loop.test.ts +171 -0
  571. package/src/pr-loop.ts +324 -0
  572. package/src/provenance.ts +35 -0
  573. package/src/telemetry-attribution.test.ts +23 -1
  574. package/src/telemetry-attribution.ts +51 -0
  575. package/src/terraform/hcl2json.test.ts +21 -0
  576. package/src/terraform/hcl2json.ts +81 -0
  577. package/src/terraform/parse.ts +11 -74
  578. package/src/workspace/agent-cli.ts +7 -3
  579. package/src/workspace/agent.schema.json +22 -0
  580. package/src/workspace/app-kind.test.ts +196 -0
  581. package/src/workspace/box-cli.ts +113 -0
  582. package/src/workspace/box-factory.test.ts +323 -0
  583. package/src/workspace/box-factory.ts +136 -0
  584. package/src/workspace/box-listing-write.schema.json +204 -0
  585. package/src/workspace/box-listing.test.ts +234 -0
  586. package/src/workspace/box-listing.ts +324 -0
  587. package/src/workspace/box-publish.schema.json +498 -0
  588. package/src/workspace/box-publish.test.ts +204 -0
  589. package/src/workspace/box-publish.ts +420 -0
  590. package/src/workspace/box-ship.test.ts +96 -0
  591. package/src/workspace/broker-protocol.schema.json +186 -0
  592. package/src/workspace/broker-protocol.test.ts +122 -0
  593. package/src/workspace/broker-protocol.ts +317 -0
  594. package/src/workspace/builder-tiers.test.ts +146 -0
  595. package/src/workspace/change-set.schema.json +460 -0
  596. package/src/workspace/changes.schema.json +12 -20
  597. package/src/workspace/changes.ts +4 -1
  598. package/src/workspace/chant-migrations.e2e.test.ts +17 -5
  599. package/src/workspace/checks/boxes.test.ts +5 -0
  600. package/src/workspace/checks.ts +39 -8
  601. package/src/workspace/component-environments.test.ts +105 -0
  602. package/src/workspace/compose-graph.ts +7 -0
  603. package/src/workspace/composites.schema.json +23 -4
  604. package/src/workspace/composites.test.ts +8 -8
  605. package/src/workspace/composites.ts +13 -2
  606. package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
  607. package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
  608. package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
  609. package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
  610. package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  611. package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  612. package/src/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
  613. package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  614. package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  615. package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
  616. package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
  617. package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  618. package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  619. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
  620. package/src/workspace/conformance/broker.test.ts +122 -0
  621. package/src/workspace/conformance/broker.ts +792 -0
  622. package/src/workspace/conformance/conformance.e2e.test.ts +36 -3
  623. package/src/workspace/conformance/index.mjs +51 -3
  624. package/src/workspace/conformance/index.ts +107 -15
  625. package/src/workspace/conformance/vitest.ts +76 -2
  626. package/src/workspace/conformance/writer-conformance.e2e.test.ts +177 -0
  627. package/src/workspace/conformance/writer.test.ts +186 -0
  628. package/src/workspace/conformance/writer.ts +1191 -0
  629. package/src/workspace/decide.test.ts +208 -4
  630. package/src/workspace/decide.ts +433 -73
  631. package/src/workspace/decision-points.schema.json +11 -4
  632. package/src/workspace/declaration.schema.json +383 -5
  633. package/src/workspace/declaration.ts +315 -10
  634. package/src/workspace/environments.ts +66 -14
  635. package/src/workspace/factory-rules.test.ts +62 -0
  636. package/src/workspace/factory-rules.ts +218 -0
  637. package/src/workspace/graph-cli.ts +6 -3
  638. package/src/workspace/graph.schema.json +314 -0
  639. package/src/workspace/identity.test.ts +219 -0
  640. package/src/workspace/identity.ts +186 -0
  641. package/src/workspace/init.ts +82 -2
  642. package/src/workspace/intent-cli.ts +84 -13
  643. package/src/workspace/intent-patch-id.test.ts +162 -0
  644. package/src/workspace/intent-record.schema.json +336 -1
  645. package/src/workspace/intent-record.ts +96 -16
  646. package/src/workspace/intent-reviews.test.ts +76 -0
  647. package/src/workspace/intent-squash.test.ts +213 -0
  648. package/src/workspace/intent-why.test.ts +274 -0
  649. package/src/workspace/intent.schema.json +950 -9
  650. package/src/workspace/intent.test.ts +11 -2
  651. package/src/workspace/intent.ts +722 -65
  652. package/src/workspace/json-edit.test.ts +121 -0
  653. package/src/workspace/json-edit.ts +142 -0
  654. package/src/workspace/jsonc.ts +20 -0
  655. package/src/workspace/kinds.ts +201 -39
  656. package/src/workspace/lexicon-symbols.test.ts +148 -0
  657. package/src/workspace/lexicon-symbols.ts +125 -0
  658. package/src/workspace/lineage-upgrade.test.ts +63 -0
  659. package/src/workspace/lineage-upgrade.ts +146 -5
  660. package/src/workspace/plan-summary.schema.json +155 -0
  661. package/src/workspace/point-answer.schema.json +42 -2
  662. package/src/workspace/points-cli.ts +42 -16
  663. package/src/workspace/points-write.schema.json +163 -4
  664. package/src/workspace/points.schema.json +157 -2
  665. package/src/workspace/points.test.ts +13 -1
  666. package/src/workspace/points.ts +118 -12
  667. package/src/workspace/pr-report.schema.json +95 -0
  668. package/src/workspace/principal-classes.test.ts +175 -0
  669. package/src/workspace/principal-classes.ts +307 -0
  670. package/src/workspace/profiles.test.ts +159 -0
  671. package/src/workspace/read-contract.test.ts +2 -2
  672. package/src/workspace/reason-codes.test.ts +23 -3
  673. package/src/workspace/reason-codes.ts +61 -4
  674. package/src/workspace/record-sessions.ts +9 -8
  675. package/src/workspace/records-amend.schema.json +80 -0
  676. package/src/workspace/records-checkout.ts +106 -0
  677. package/src/workspace/records-cli.ts +123 -17
  678. package/src/workspace/records-close.schema.json +79 -0
  679. package/src/workspace/records-close.ts +31 -7
  680. package/src/workspace/records-concurrent.e2e.test.ts +135 -0
  681. package/src/workspace/records-concurrent.test.ts +145 -0
  682. package/src/workspace/records-formats.test.ts +46 -10
  683. package/src/workspace/records-new.schema.json +9 -0
  684. package/src/workspace/records-review.schema.json +80 -0
  685. package/src/workspace/records-sessions-write.test.ts +69 -0
  686. package/src/workspace/records-sessions.test.ts +22 -0
  687. package/src/workspace/records-uncommitted.test.ts +171 -0
  688. package/src/workspace/records-write.ts +219 -30
  689. package/src/workspace/records.schema.json +88 -1
  690. package/src/workspace/records.ts +76 -8
  691. package/src/workspace/reference-kinds/app/package.json +10 -0
  692. package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  693. package/src/workspace/run-statement.schema.json +622 -0
  694. package/src/workspace/runs-cli.ts +710 -0
  695. package/src/workspace/runs-statement.test.ts +239 -0
  696. package/src/workspace/runs-write.schema.json +994 -0
  697. package/src/workspace/runs.schema.json +1257 -0
  698. package/src/workspace/runs.test.ts +281 -0
  699. package/src/workspace/runs.ts +970 -0
  700. package/src/workspace/session-kinds.ts +3 -3
  701. package/src/workspace/squash.ts +198 -0
  702. package/src/workspace/status-contract.test.ts +10 -2
  703. package/src/workspace/status-gates.ts +25 -9
  704. package/src/workspace/status.schema.json +252 -4
  705. package/src/workspace/status.ts +110 -1
  706. package/src/workspace/symbols.ts +191 -0
  707. package/src/workspace/trailer-joins.test.ts +171 -0
  708. package/src/workspace/trailer-joins.ts +82 -0
  709. package/src/workspace/trailers.ts +148 -0
  710. package/src/workspace/trust/run-commits.ts +115 -0
  711. package/src/workspace/trust/run-statement.ts +226 -0
  712. package/src/workspace/trust/seal.ts +58 -1
  713. package/src/workspace/trust/verify-cli.ts +6 -5
  714. package/src/workspace/trust/verify.ts +39 -6
  715. package/src/workspace/wip-cli.ts +97 -0
  716. package/src/workspace/wip-write.schema.json +504 -0
  717. package/src/workspace/wip.schema.json +334 -0
  718. package/src/workspace/wip.test.ts +294 -0
  719. package/src/workspace/wip.ts +753 -0
  720. package/src/workspace/work-cli.e2e.test.ts +28 -1
  721. package/src/workspace/work-cli.ts +136 -8
  722. package/src/workspace/work-evidence.schema.json +5 -0
  723. package/src/workspace/work-history.schema.json +73 -1
  724. package/src/workspace/work-history.test.ts +48 -5
  725. package/src/workspace/work-kind-fields.test.ts +154 -0
  726. package/src/workspace/work-lease.schema.json +14 -1
  727. package/src/workspace/work-size.test.ts +77 -0
  728. package/src/workspace/work-size.ts +93 -0
  729. package/src/workspace/work.ts +82 -0
  730. package/src/workspace/workspace-kinds.schema.json +122 -0
  731. package/src/workspace/workspace-principals.schema.json +60 -0
  732. package/src/workspace/write-lock-cli.ts +131 -0
  733. package/src/workspace/write-lock.schema.json +172 -0
  734. package/src/workspace/write-lock.test.ts +189 -0
  735. package/src/workspace/write-lock.ts +474 -0
  736. package/src/workspace/write-scope.test.ts +144 -3
  737. package/src/workspace/write-scope.ts +192 -45
  738. package/src/yaml.test.ts +111 -1
  739. package/src/yaml.ts +141 -549
@@ -107,9 +107,11 @@ export interface ChangesPolicy {
107
107
  ignore: string[];
108
108
  }
109
109
 
110
- /** The core principal classes (#2524 D5). */
110
+ /** The core principal classes (#2524 D5). A pinned package may supply domain classes too (#3080, `principal-classes.ts`). */
111
111
  export const PRINCIPAL_CLASSES = ["human", "agent", "runner", "service"] as const;
112
- export type PrincipalClass = (typeof PRINCIPAL_CLASSES)[number];
112
+ export type CorePrincipalClass = (typeof PRINCIPAL_CLASSES)[number];
113
+ /** A class name: a core class, or a domain class a pinned package supplies (#3080). */
114
+ export type PrincipalClass = string;
113
115
 
114
116
  /** How a record is written, as the records commands name it (#2548). */
115
117
  export const WRITE_VERBS = ["new", "amend", "review", "close"] as const;
@@ -121,11 +123,46 @@ export interface ClassScope {
121
123
  members: string[] | null;
122
124
  /** Kind name to the verbs the class may write it with, or null for every kind in reach with every verb. */
123
125
  records: Record<string, WriteVerb[]> | null;
126
+ /** Paths the class may not write even inside a member it may (#3146, ws-077), in file order. Empty when the entry lists none. */
127
+ protected: ProtectedPath[];
124
128
  pointer: string;
125
129
  }
126
130
 
127
- /** The declaration's `writeScope` block: an entry per restricted class. A class with no entry is not restricted. */
128
- export type WriteScope = Partial<Record<PrincipalClass, ClassScope>>;
131
+ /**
132
+ * A protected path in a write scope (#3146, ws-077): a glob from the
133
+ * workspace root. It protects the files it matches and everything under a
134
+ * directory it matches. `except` names top-level keys of a JSON file a write
135
+ * may still change; empty when the entry allows none.
136
+ */
137
+ export interface ProtectedPath {
138
+ path: string;
139
+ except: string[];
140
+ }
141
+
142
+ /**
143
+ * The declaration's `writeScope` block: an entry per restricted class, in
144
+ * file order. A class with no entry is not restricted. A key may name a
145
+ * domain class a pinned package supplies (#3080); whether one does is known
146
+ * only once the pins are read, so an unknown key is judged where the scope
147
+ * is applied, not here.
148
+ */
149
+ export type WriteScope = Record<PrincipalClass, ClassScope>;
150
+
151
+ /** A gate the declaration's `identity.gates` names (#3163, ws-080): it passes only on a signed approval. */
152
+ export interface SignedGate {
153
+ gate: string;
154
+ /** The class the signer must be in, or null for any signer the signers file at base lists. */
155
+ class: PrincipalClass | null;
156
+ pointer: string;
157
+ }
158
+
159
+ /** The declaration's `identity` block (#3163, ws-080), read at base. */
160
+ export interface IdentityPolicy {
161
+ /** `identified`: a person-attributed write must name a forge identity, a signer at base, or an agent, runner or service principal. */
162
+ attribution: "any" | "identified";
163
+ /** By gate name. */
164
+ gates: Record<string, SignedGate>;
165
+ }
129
166
 
130
167
  /** An agent session the declaration names (#2524 D20, #2548): bound to one member. */
131
168
  export interface AgentDeclaration {
@@ -254,10 +291,133 @@ export interface BoxDeclaration {
254
291
  * `spriteApplyServices` read them with `box: true`.
255
292
  */
256
293
  services: BoxService[];
294
+ /** What the box builds and how (#3146, ws-077), or null when the block declares no factory. */
295
+ factory: BoxFactory | null;
296
+ /** What the box shows of itself on a home site (#3146), or null when the block declares no listing. */
297
+ listing: BoxListing | null;
298
+ /**
299
+ * The command that publishes the box's work (#3165, ws-088), as declared,
300
+ * or null when the block names none. `chant workspace box publish` runs it
301
+ * (`box-publish.ts`).
302
+ */
303
+ publisher: string | null;
304
+ /** Where the box's work in progress is replicated (#3172, ws-085), or null when the block declares no policy. */
305
+ replicate: BoxReplicate | null;
306
+ /** How the box ships its staged work to its own site (ws-100), or null when the block declares none. */
307
+ ship: BoxShip | null;
308
+ /** The block's JSON Pointer in the file, for messages. */
309
+ pointer: string;
310
+ }
311
+
312
+ /** The gate a ship Op stops at when the block names none (ws-100). */
313
+ export const DEFAULT_SHIP_GATE = "ship";
314
+ /** The environment a ship Op records its releases in when the block names none (ws-100). */
315
+ export const DEFAULT_SHIP_ENV = "box";
316
+
317
+ /**
318
+ * How a box ships its staged work (ws-100): the Op in the box member that
319
+ * commits the staged tree and releases it to the box's own site, the gate
320
+ * it stops at, the environment whose release ledger it records each
321
+ * release in, and the paths that are bookkeeping rather than the app (left
322
+ * out of what is pending). Defaults are filled in.
323
+ */
324
+ export interface BoxShip {
325
+ op: string;
326
+ gate: string;
327
+ env: string;
328
+ /** Path prefixes from the workspace root, in file order, whose changes never count as waiting to ship. */
329
+ bookkeeping: string[];
257
330
  /** The block's JSON Pointer in the file, for messages. */
258
331
  pointer: string;
259
332
  }
260
333
 
334
+ /** What a replicate policy pushes (#3172): work branches, kept attempts, work-in-progress snapshots and the ledger branch. */
335
+ export const REPLICATE_REF_CLASSES = ["work", "kept", "wip", "ledger"] as const;
336
+ export type ReplicateRefClass = (typeof REPLICATE_REF_CLASSES)[number];
337
+
338
+ /** When chant pushes on its own under a replicate policy (#3172). */
339
+ export const REPLICATE_TRIGGERS = ["save", "release"] as const;
340
+ export type ReplicateTrigger = (typeof REPLICATE_TRIGGERS)[number];
341
+
342
+ /** The remote a replicate policy pushes to when it names none. */
343
+ export const DEFAULT_REPLICATE_REMOTE = "origin";
344
+
345
+ /**
346
+ * Where a box's work in progress is replicated (#3172, ws-085), with the
347
+ * defaults filled in: the git remote, which refs, and when chant pushes on
348
+ * its own. `every` is an interval for the host's own scheduler.
349
+ */
350
+ export interface BoxReplicate {
351
+ remote: string;
352
+ refs: ReplicateRefClass[];
353
+ on: ReplicateTrigger[];
354
+ every: string | null;
355
+ /** The block's JSON Pointer in the file, for messages. */
356
+ pointer: string;
357
+ }
358
+
359
+ /** What a check command is (#3146). */
360
+ export const FACTORY_CHECK_KINDS = ["test", "build", "lint", "plan", "conformance"] as const;
361
+ export type FactoryCheckKind = (typeof FACTORY_CHECK_KINDS)[number];
362
+
363
+ /**
364
+ * A box's factory (#3146, ws-077): what it builds, how a build is checked,
365
+ * which member declares the builder agents and where a finished build is
366
+ * published. Defaults are filled in, so a reader never guesses one.
367
+ */
368
+ export interface BoxFactory {
369
+ /** The members the factory builds, in file order; at least one. */
370
+ builds: string[];
371
+ /** The verdict command, run from the workspace root, or null when none is declared. */
372
+ check: { run: string; kind: FactoryCheckKind } | null;
373
+ /** Where a work item's builder writes its check, from the workspace root, or null for the orchestrator's choice. */
374
+ checks: string | null;
375
+ /** The member that declares the builder agents, or null when none is named. */
376
+ builders: string | null;
377
+ /** Which builder agent builds at which tier, and for which member kinds (#3152, ws-094), in file order; empty when none is declared. */
378
+ tiers: FactoryTier[];
379
+ /** Where a finished build is published, or null when the factory doesn't publish past the box. */
380
+ publish: FactoryPublish | null;
381
+ /** The block's JSON Pointer in the file, for messages. */
382
+ pointer: string;
383
+ }
384
+
385
+ /** One builder agent at one tier (#3152): `kinds` null means every kind no other entry of the tier names. */
386
+ export interface FactoryTier {
387
+ tier: string;
388
+ /** The agent's name, as the builders member declares it. */
389
+ agent: string;
390
+ /** The member kinds it builds at this tier, or null for the tier's default. */
391
+ kinds: string[] | null;
392
+ /** The declared agent session it writes as, or null for the orchestrator's choice. */
393
+ session: string | null;
394
+ }
395
+
396
+ /** Where a finished build goes (#3146): its branch is pushed and a pull request opened against `repo`'s `base`. */
397
+ export interface FactoryPublish {
398
+ forge: "github";
399
+ /** owner/name. */
400
+ repo: string;
401
+ /** The branch the pull request targets, or null for the repository's default branch. */
402
+ base: string | null;
403
+ /** What the published branch's name starts with, before the work item's id. */
404
+ branchPrefix: string;
405
+ /** The repository the branch is pushed to when it isn't `repo` (a fork), as owner/name, or null. */
406
+ head: string | null;
407
+ }
408
+
409
+ /** The branch prefix a publish target uses when it names none: the work lease's own branch. */
410
+ export const DEFAULT_PUBLISH_BRANCH_PREFIX = "chant/work/";
411
+
412
+ /** What a box shows of itself (#3146, #3154). */
413
+ export interface BoxListing {
414
+ published: boolean;
415
+ title: string;
416
+ line: string;
417
+ /** The cover image, from the workspace root, or null. */
418
+ cover: string | null;
419
+ }
420
+
261
421
  /** A service a box runs under its supervisor (#2880). */
262
422
  export interface BoxService {
263
423
  /** Unique in the box. */
@@ -313,6 +473,8 @@ export interface Member {
313
473
  generated: GeneratedFile[];
314
474
  /** Outputs the entry lists as link targets, or null when it lists none (#2539). */
315
475
  outputs: string[] | null;
476
+ /** The values the entry sets for its kind's fields (#3151), as written, or null when it sets none. Checked against the kind by `resolveMemberFields`. */
477
+ fields: Record<string, unknown> | null;
316
478
  /** The links this member states as a consumer, in file order (#2539). */
317
479
  links: LinkDeclaration[];
318
480
  /** The record kinds this member declares, in file order (#2680). */
@@ -375,6 +537,8 @@ export interface Declaration {
375
537
  writeScope: WriteScope | null;
376
538
  /** The agent sessions, in file order (#2548). */
377
539
  agents: AgentDeclaration[];
540
+ /** Who a person-attributed write may name, and which gates need a signed approval (#3163), or null when the declaration has no `identity` block. */
541
+ identity: IdentityPolicy | null;
378
542
  /** The file, relative to the workspace root's tree (`chant.workspace.json` or `.jsonc`). */
379
543
  file: string;
380
544
  }
@@ -598,6 +762,7 @@ export function parseDeclaration(text: string, file: string, reader: string = re
598
762
  roles,
599
763
  generated,
600
764
  outputs: e.outputs === undefined ? null : [...(e.outputs as string[])],
765
+ fields: e.fields === undefined ? null : structuredClone(e.fields as Record<string, unknown>),
601
766
  links,
602
767
  records,
603
768
  diagrams,
@@ -699,6 +864,18 @@ export function parseDeclaration(text: string, file: string, reader: string = re
699
864
  const problem = m.box ? boxServicesProblem(m.name, m.box.services) : null;
700
865
  if (problem) throw new WorkspaceReadError("declaration-invalid", problem.message, at(problem.pointer));
701
866
  }
867
+ // One factory, building and naming declared members (#3146).
868
+ const factory = factoryProblem(members);
869
+ if (factory) throw new WorkspaceReadError("declaration-invalid", factory.message, at(factory.pointer));
870
+ // One replicate policy (#3172): the checkout is the whole repository's, so one remote takes its work in progress.
871
+ const replicating = members.filter((m) => m.box?.replicate);
872
+ if (replicating.length > 1) {
873
+ throw new WorkspaceReadError(
874
+ "declaration-invalid",
875
+ `members ${replicating[0].name} and ${replicating[1].name} both declare replicate in their box block; a checkout's work in progress goes to one remote, so a workspace has one replicate policy`,
876
+ at(replicating[1].box!.replicate!.pointer),
877
+ );
878
+ }
702
879
 
703
880
  // A diagram name is given once across the declaration (#2764): a reader keys diagrams by name.
704
881
  const ownDiagrams = diagramsOf(obj.diagrams, null, "/diagrams");
@@ -714,6 +891,8 @@ export function parseDeclaration(text: string, file: string, reader: string = re
714
891
  const hosts = hostsOf(obj, members, at);
715
892
  const writeScope = writeScopeOf(obj.writeScope, members, at);
716
893
  const agents = agentsOf(obj.agents, members, at);
894
+ const tierSession = factoryTierSessionProblem(members, agents);
895
+ if (tierSession) throw new WorkspaceReadError("declaration-invalid", tierSession.message, at(tierSession.pointer));
717
896
 
718
897
  const pins = ((obj.pins as Record<string, string>[] | undefined) ?? []).map((p) => ({
719
898
  package: p.package ?? null,
@@ -738,21 +917,21 @@ export function parseDeclaration(text: string, file: string, reader: string = re
738
917
  changes: changesOf(obj.changes as Record<string, unknown> | undefined),
739
918
  writeScope,
740
919
  agents,
920
+ identity: identityOf(obj.identity),
741
921
  file,
742
922
  };
743
923
  }
744
924
 
745
925
  /**
746
926
  * The `writeScope` block, already validated, with the rule the schema can't
747
- * say (#2548): a member it names is a declared member.
927
+ * say (#2548): a member it names is a declared member. Its keys are kept in
928
+ * file order: the core classes and any domain class (#3080).
748
929
  */
749
930
  function writeScopeOf(raw: unknown, members: Member[], at: (pointer: string, key?: boolean) => ErrorLocation): WriteScope | null {
750
931
  if (raw === undefined) return null;
751
- const block = raw as Partial<Record<PrincipalClass, { members?: "*" | string[]; records?: Record<string, WriteVerb[]> }>>;
932
+ const block = raw as Record<PrincipalClass, { members?: "*" | string[]; records?: Record<string, WriteVerb[]>; protected?: (string | { path: string; except?: string[] })[] }>;
752
933
  const out: WriteScope = {};
753
- for (const cls of PRINCIPAL_CLASSES) {
754
- const entry = block[cls];
755
- if (entry === undefined) continue;
934
+ for (const [cls, entry] of Object.entries(block)) {
756
935
  const pointer = `/writeScope/${cls}`;
757
936
  const list = entry.members === undefined || entry.members === "*" ? null : [...entry.members];
758
937
  for (const [i, name] of (list ?? []).entries()) {
@@ -765,7 +944,8 @@ function writeScopeOf(raw: unknown, members: Member[], at: (pointer: string, key
765
944
  }
766
945
  }
767
946
  const records = entry.records === undefined ? null : Object.fromEntries(Object.entries(entry.records).map(([k, v]) => [k, [...v]]));
768
- out[cls] = { members: list, records, pointer };
947
+ const guarded = (entry.protected ?? []).map((p) => (typeof p === "string" ? { path: p, except: [] } : { path: p.path, except: [...(p.except ?? [])] }));
948
+ out[cls] = { members: list, records, protected: guarded, pointer };
769
949
  }
770
950
  return out;
771
951
  }
@@ -775,6 +955,17 @@ function writeScopeOf(raw: unknown, members: Member[], at: (pointer: string, key
775
955
  * (#2548): names are unique, each names a declared member, and a principal
776
956
  * is listed by one session at most.
777
957
  */
958
+ /** The `identity` block, already validated by the schema (#3163). */
959
+ function identityOf(raw: unknown): IdentityPolicy | null {
960
+ if (raw === undefined) return null;
961
+ const block = raw as { attribution?: "any" | "identified"; gates?: Record<string, { class?: string }> };
962
+ const gates: Record<string, SignedGate> = {};
963
+ for (const [gate, entry] of Object.entries(block.gates ?? {})) {
964
+ gates[gate] = { gate, class: entry.class ?? null, pointer: `/identity/gates/${gate.replace(/~/g, "~0").replace(/\//g, "~1")}` };
965
+ }
966
+ return { attribution: block.attribution ?? "any", gates };
967
+ }
968
+
778
969
  function agentsOf(raw: unknown, members: Member[], at: (pointer: string, key?: boolean) => ErrorLocation): AgentDeclaration[] {
779
970
  const agents = ((raw as { name: string; member: string; principals?: string[] }[] | undefined) ?? []).map((a, i) => ({
780
971
  name: a.name,
@@ -856,7 +1047,22 @@ function boxOf(raw: unknown, pointer: string): BoxDeclaration | null {
856
1047
  cookies?: string[];
857
1048
  intent?: string;
858
1049
  services?: { name: string; cmd: string; needs?: string[]; httpPort?: number; duration?: string; health?: string; optional?: boolean }[];
1050
+ factory?: {
1051
+ builds: string[];
1052
+ check?: string | { run: string; kind?: FactoryCheckKind };
1053
+ checks?: string;
1054
+ builders?: string;
1055
+ tiers?: { tier: string; agent: string; kinds?: string[]; session?: string }[];
1056
+ publish?: { forge?: "github"; repo: string; base?: string; branchPrefix?: string; head?: string };
1057
+ };
1058
+ listing?: { published?: boolean; title?: string; line?: string; cover?: string };
1059
+ publisher?: string;
1060
+ replicate?: { remote?: string; refs?: ReplicateRefClass[]; on?: ReplicateTrigger[]; every?: string };
1061
+ ship?: { op: string; gate?: string; env?: string; bookkeeping?: string[] };
859
1062
  };
1063
+ const f = b.factory;
1064
+ const l = b.listing;
1065
+ const r = b.replicate;
860
1066
  return {
861
1067
  capabilities: (b.capabilities ?? []).map((c, i) => ({ name: c.name, broker: c.broker ?? null, scope: [...(c.scope ?? [])], pointer: `${pointer}/capabilities/${i}` })),
862
1068
  // The schema requires host and slot together, and host for ports, state and cookies.
@@ -875,10 +1081,109 @@ function boxOf(raw: unknown, pointer: string): BoxDeclaration | null {
875
1081
  optional: s.optional ?? false,
876
1082
  pointer: `${pointer}/services/${i}`,
877
1083
  })),
1084
+ factory:
1085
+ f === undefined
1086
+ ? null
1087
+ : {
1088
+ builds: [...f.builds],
1089
+ check: f.check === undefined ? null : typeof f.check === "string" ? { run: f.check, kind: "test" } : { run: f.check.run, kind: f.check.kind ?? "test" },
1090
+ checks: f.checks ?? null,
1091
+ builders: f.builders ?? null,
1092
+ tiers: (f.tiers ?? []).map((t) => ({ tier: t.tier, agent: t.agent, kinds: t.kinds === undefined ? null : [...t.kinds], session: t.session ?? null })),
1093
+ publish:
1094
+ f.publish === undefined
1095
+ ? null
1096
+ : {
1097
+ forge: f.publish.forge ?? "github",
1098
+ repo: f.publish.repo,
1099
+ base: f.publish.base ?? null,
1100
+ branchPrefix: f.publish.branchPrefix ?? DEFAULT_PUBLISH_BRANCH_PREFIX,
1101
+ head: f.publish.head ?? null,
1102
+ },
1103
+ pointer: `${pointer}/factory`,
1104
+ },
1105
+ listing: l === undefined ? null : { published: l.published ?? true, title: l.title ?? "", line: l.line ?? "", cover: l.cover ?? null },
1106
+ publisher: b.publisher ?? null,
1107
+ ship:
1108
+ b.ship === undefined
1109
+ ? null
1110
+ : {
1111
+ op: b.ship.op,
1112
+ gate: b.ship.gate ?? DEFAULT_SHIP_GATE,
1113
+ env: b.ship.env ?? DEFAULT_SHIP_ENV,
1114
+ bookkeeping: (b.ship.bookkeeping ?? []).map((p) => p.replace(/^\.\//, "").replace(/\/+$/, "")),
1115
+ pointer: `${pointer}/ship`,
1116
+ },
1117
+ replicate:
1118
+ r === undefined
1119
+ ? null
1120
+ : {
1121
+ remote: r.remote ?? DEFAULT_REPLICATE_REMOTE,
1122
+ // In the order the closed lists give, so a reader compares them without sorting.
1123
+ refs: REPLICATE_REF_CLASSES.filter((c) => (r.refs ?? REPLICATE_REF_CLASSES).includes(c)),
1124
+ on: REPLICATE_TRIGGERS.filter((t) => (r.on ?? REPLICATE_TRIGGERS).includes(t)),
1125
+ every: r.every ?? null,
1126
+ pointer: `${pointer}/replicate`,
1127
+ },
878
1128
  pointer,
879
1129
  };
880
1130
  }
881
1131
 
1132
+ /**
1133
+ * The rules the schema can't say about the factories (#3146, ws-077): at most
1134
+ * one box block declares one, and the members its builds and builders name
1135
+ * are declared members.
1136
+ */
1137
+ function factoryProblem(members: readonly Member[]): { message: string; pointer: string } | null {
1138
+ const declaring = members.filter((m) => m.box?.factory);
1139
+ if (declaring.length > 1) {
1140
+ return {
1141
+ message: `members ${declaring[0].name} and ${declaring[1].name} both declare a factory in their box block; a workspace has one factory, so an orchestrator reads one`,
1142
+ pointer: declaring[1].box!.factory!.pointer,
1143
+ };
1144
+ }
1145
+ const factory = declaring[0]?.box?.factory;
1146
+ if (!factory) return null;
1147
+ const known = () => members.map((m) => m.name).join(", ");
1148
+ const j = factory.builds.findIndex((name) => !members.some((m) => m.name === name));
1149
+ if (j >= 0) {
1150
+ return { message: `the factory builds ${JSON.stringify(factory.builds[j])}, which is not a declared member; declared members: ${known()}`, pointer: `${factory.pointer}/builds/${j}` };
1151
+ }
1152
+ if (factory.builders !== null && !members.some((m) => m.name === factory.builders)) {
1153
+ return { message: `the factory's builders names ${JSON.stringify(factory.builders)}, which is not a declared member; declared members: ${known()}`, pointer: `${factory.pointer}/builders` };
1154
+ }
1155
+ // Builder tiers (#3152): their agents are the builders member's, and one entry answers each tier and kind.
1156
+ if (factory.tiers.length > 0 && factory.builders === null) {
1157
+ return { message: "the factory declares tiers and no builders; tiers name agents the builders member declares, so name it", pointer: `${factory.pointer}/tiers` };
1158
+ }
1159
+ const answered = new Map<string, number>();
1160
+ for (const [i, t] of factory.tiers.entries()) {
1161
+ for (const kind of t.kinds ?? [null]) {
1162
+ const key = `${t.tier}\0${kind ?? ""}`;
1163
+ const first = answered.get(key);
1164
+ if (first !== undefined) {
1165
+ const which = kind === null ? "with no kinds" : `for kind ${kind}`;
1166
+ return { message: `tiers/${first} and tiers/${i} both name a builder at tier ${t.tier} ${which}; a tier has one builder per kind, so one entry answers it`, pointer: `${factory.pointer}/tiers/${i}` };
1167
+ }
1168
+ answered.set(key, i);
1169
+ }
1170
+ }
1171
+ return null;
1172
+ }
1173
+
1174
+ /** The rule the schema can't say about the factory's tiers once the sessions are read (#3152): a session is a declared agent session. */
1175
+ function factoryTierSessionProblem(members: readonly Member[], agents: readonly AgentDeclaration[]): { message: string; pointer: string } | null {
1176
+ const factory = members.find((m) => m.box?.factory)?.box?.factory;
1177
+ if (!factory) return null;
1178
+ for (const [i, t] of factory.tiers.entries()) {
1179
+ if (t.session !== null && !agents.some((a) => a.name === t.session)) {
1180
+ const known = agents.map((a) => a.name).join(", ") || "none";
1181
+ return { message: `tiers/${i} names the session ${JSON.stringify(t.session)}, which is not a declared agent session; declared sessions: ${known}`, pointer: `${factory.pointer}/tiers/${i}/session` };
1182
+ }
1183
+ }
1184
+ return null;
1185
+ }
1186
+
882
1187
  /**
883
1188
  * The rules the schema can't say about a box's services (#2880), as a
884
1189
  * message and the pointer to show, or null when they hold: each name is
@@ -15,8 +15,13 @@
15
15
  * (`../cli/handlers/run.ts`), when neither the config nor the ledger names
16
16
  * it.
17
17
  *
18
- * The component contract declares no environments, so every component of a
19
- * member lists the member's environments.
18
+ * A component may also declare environments of its own (#3153, ws-095),
19
+ * each with the site a release goes to there: the runtime that hosts it, its
20
+ * URL, a custom domain and the git remote its lifecycle records are pushed
21
+ * to. Each declared environment the member already lists carries that site,
22
+ * and one it doesn't is added with source `component` when `chant run --env`
23
+ * would take it, or left out with `environments-component-undeclared` when
24
+ * the config's environments don't cover it.
20
25
  *
21
26
  * `chant run --env` refuses a name the config's `environments` doesn't cover
22
27
  * whenever it declares any (`unknownEnvError` in `../env.ts`), so a ledger
@@ -31,7 +36,8 @@
31
36
  */
32
37
 
33
38
  import { execFileSync } from "node:child_process";
34
- import { environmentName, isEnvironmentPattern, matchesDeclaredEnvironment } from "../config";
39
+ import { environmentName, isEnvironmentPattern, matchesDeclaredEnvironment, type EnvironmentDeclaration } from "../config";
40
+ import type { ComponentEnvironmentDeclaration } from "../components/component";
35
41
  import type { ReasonCode } from "./reason-codes";
36
42
  import { LOCAL_RUNTIME, type MemberRuntimes } from "./runtimes";
37
43
  import { ENV_PATTERN, LIFECYCLE_REF, MEMBERS_DIR } from "./status";
@@ -49,6 +55,8 @@ export const ENVIRONMENT_REASON_CODES = [
49
55
  "environments-ledger-undeclared",
50
56
  /** The chant/lifecycle branch exists and the member's ledger directories could not be listed. */
51
57
  "environments-ledger-unreadable",
58
+ /** A component declares an environment the config's environments don't cover, so chant run --env would refuse it (#3153). */
59
+ "environments-component-undeclared",
52
60
  ] as const satisfies readonly ReasonCode[];
53
61
  export type EnvironmentReasonCode = (typeof ENVIRONMENT_REASON_CODES)[number];
54
62
 
@@ -63,12 +71,22 @@ export interface ComponentEnvironment {
63
71
  name: string;
64
72
  /** True for the environment `chant run --components` deploys to without `--env`. */
65
73
  default: boolean;
66
- /** Where the name came from; the first of config, ledger and builtin that names it. */
67
- source: "config" | "ledger" | "builtin";
68
- /** The command that deploys the component there on the default runtime, run in the member's directory. */
74
+ /** Where the name came from; the first of config, ledger, builtin and the component's own environments that names it. */
75
+ source: "config" | "ledger" | "builtin" | "component";
76
+ /** Where a release of the component goes in this environment, as the component declares it (#3153), or null when it declares nothing for it. */
77
+ site: ComponentSite | null;
78
+ /** The command that deploys the component there, on the site's runtime when the member hosts it and else the default runtime, run in the member's directory. */
69
79
  command: string;
70
80
  }
71
81
 
82
+ /** A component's declared site in one environment (#3153): every field present, null when not declared. */
83
+ export interface ComponentSite {
84
+ runtime: string | null;
85
+ url: string | null;
86
+ domain: string | null;
87
+ lifecycle: string | null;
88
+ }
89
+
72
90
  /** The environments a member's ledger has, or why they couldn't be listed. */
73
91
  export interface LedgerEnvironments {
74
92
  envs: string[];
@@ -80,9 +98,11 @@ export type LedgerEnvironmentReader = (member: { name: string; dir: string }, cw
80
98
 
81
99
  /** What one member's config and ledger say about environments. */
82
100
  export interface MemberEnvironments {
83
- /** Each environment in list order, without the per-component command. */
84
- environments: Omit<ComponentEnvironment, "command">[];
101
+ /** Each environment in list order, without the per-component site and command. */
102
+ environments: Omit<ComponentEnvironment, "command" | "site">[];
85
103
  reasons: EnvironmentReason[];
104
+ /** The config's environments, for whether `chant run --env` takes a name: null when the config couldn't be read, `[]` when it declares none. */
105
+ declared?: EnvironmentDeclaration[] | null;
86
106
  }
87
107
 
88
108
  function git(cwd: string, args: string[], input?: string): string {
@@ -154,12 +174,44 @@ export function memberEnvironments(runtimes: MemberRuntimes | undefined, ledger:
154
174
  add(LOCAL_ENVIRONMENT, literals.includes(LOCAL_ENVIRONMENT) ? "config" : ledgerEnvs.includes(LOCAL_ENVIRONMENT) ? "ledger" : "builtin");
155
175
  for (const name of literals) add(name, "config");
156
176
  for (const name of ledgerEnvs) if (covered(name)) add(name, "ledger");
157
- return { environments: out, reasons };
177
+ return { environments: out, reasons, declared };
158
178
  }
159
179
 
160
- /** The environments one component may deploy to, each with its command line on the member's default runtime. */
161
- export function componentEnvironments(component: string, member: MemberEnvironments | undefined, runtime = LOCAL_RUNTIME): ComponentEnvironment[] {
162
- const list = member?.environments ?? [{ name: LOCAL_ENVIRONMENT, default: true, source: "builtin" as const }];
163
- const on = runtime === LOCAL_RUNTIME ? "" : ` --on ${runtime}`;
164
- return list.map((e) => ({ ...e, command: `chant run --components ${component}${on}${e.default ? "" : ` --env ${e.name}`}` }));
180
+ /**
181
+ * The environments one component may deploy to, each with its command line.
182
+ * `declared` is what the component's contract says (#3153): an environment
183
+ * the member lists takes its site, and one it doesn't is added after the
184
+ * member's when `chant run --env` takes it. `reasons` collects the declared
185
+ * environments left out because the config's environments don't cover them.
186
+ * `hosts` are the runtimes the member configures; a site's runtime is used
187
+ * for the command only when it is one of them.
188
+ */
189
+ export function componentEnvironments(
190
+ component: string,
191
+ member: MemberEnvironments | undefined,
192
+ runtime = LOCAL_RUNTIME,
193
+ declared: readonly ComponentEnvironmentDeclaration[] = [],
194
+ hosts: readonly string[] = [],
195
+ reasons: EnvironmentReason[] = [],
196
+ ): ComponentEnvironment[] {
197
+ const list: Omit<ComponentEnvironment, "command" | "site">[] = [...(member?.environments ?? [{ name: LOCAL_ENVIRONMENT, default: true, source: "builtin" as const }])];
198
+ const config = member?.declared;
199
+ const takes = (env: string): boolean => !config || config.length === 0 || matchesDeclaredEnvironment(config, env);
200
+ const sites = new Map<string, ComponentSite>();
201
+ for (const d of declared) {
202
+ sites.set(d.name, { runtime: d.runtime ?? null, url: d.url ?? null, domain: d.domain ?? null, lifecycle: d.lifecycle ?? null });
203
+ if (list.some((e) => e.name === d.name)) continue;
204
+ if (takes(d.name)) list.push({ name: d.name, default: false, source: "component" });
205
+ else {
206
+ reasons.push({
207
+ code: "environments-component-undeclared",
208
+ message: `component ${component} declares environment ${d.name}, which chant.config.ts's environments don't cover, so chant run --env refuses it`,
209
+ });
210
+ }
211
+ }
212
+ return list.map((e) => {
213
+ const site = sites.get(e.name) ?? null;
214
+ const on = site?.runtime && (site.runtime === LOCAL_RUNTIME || hosts.includes(site.runtime)) ? site.runtime : runtime;
215
+ return { ...e, site, command: `chant run --components ${component}${on === LOCAL_RUNTIME ? "" : ` --on ${on}`}${e.default ? "" : ` --env ${e.name}`}` };
216
+ });
165
217
  }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The factory's rules (#3406, ws-087): readiness, understand, retry, done
3
+ * and the implements proposals, as pure functions. The Op that runs them is
4
+ * tested in ../op/factory.e2e.test.ts.
5
+ */
6
+
7
+ import { describe, expect, test } from "vitest";
8
+ import { isAsk, pickable, retryState, doneVerdict, proposeImplements, understandOutcome, type FactoryContext, type FactoryItem } from "./factory-rules";
9
+
10
+ describe("the factory's rules", () => {
11
+ const base: FactoryItem = { id: "W-1", state: "open", openState: "open", proposedState: "proposed", ready: true, data: {}, tier: null, contract: null, warnings: [], answers: [], leased: false };
12
+ const ctx: FactoryContext = { intentDecided: null, claims: [], attempts: { exhausted: false }, branch: null, questions: { tier: null, understand: null } };
13
+ const hold = (i: Partial<FactoryItem>, c: Partial<FactoryContext> = {}) => {
14
+ const v = pickable({ ...base, ...i }, { ...ctx, ...c });
15
+ return v.ok ? "ok" : v.hold;
16
+ };
17
+
18
+ test("readiness", () => {
19
+ expect(hold({})).toBe("ok");
20
+ expect(hold({}, { intentDecided: false })).toBe("intent-undecided");
21
+ expect(hold({ ready: false })).toBe("not-ready");
22
+ expect(hold({ ready: false, state: "proposed", data: { source: { ask: { said: "x", by: "a" } } } })).toBe("ok");
23
+ expect(hold({ contract: { id: "C-1", state: "draft" }, warnings: ["work-contract-undecided"] })).toBe("contract-not-approved");
24
+ expect(hold({}, { branch: { state: "done", applied: false } })).toBe("built-not-applied");
25
+ expect(hold({}, { branch: { state: "done", applied: true } })).toBe("ok");
26
+ expect(hold({}, { branch: { state: "dropped", applied: false } })).toBe("dropped-on-branch");
27
+ expect(hold({}, { attempts: { exhausted: true } })).toBe("attempts-exhausted");
28
+ const failed = { claims: [{ token: "t1", ended: "released", outcome: "not_done", attempt: true }] };
29
+ expect(hold({}, failed)).toBe("awaiting-retry");
30
+ expect(hold({ data: { retry: { after: "t1", by: "alice" } } }, failed)).toBe("ok");
31
+ expect(hold({ data: { retry: { after: "t0", by: "alice" } } }, failed)).toBe("awaiting-retry");
32
+ expect(hold({}, { questions: { tier: { state: "escalated", answer: null }, understand: null } })).toBe("question-open");
33
+ expect(hold({ tier: "large" }, { questions: { tier: { state: "escalated", answer: null }, understand: null } })).toBe("ok");
34
+ const ask = { data: { source: { ask: { said: "x", by: "a" } } } };
35
+ expect(hold(ask, { questions: { tier: null, understand: { state: "answered", answer: "redraft" } } })).toBe("redraft-or-ask");
36
+ expect(hold({ leased: true })).toBe("leased");
37
+ });
38
+
39
+ test("understand, retry, done and implements", () => {
40
+ expect(isAsk({ source: { intent: { answer: "x" } } })).toBe(true);
41
+ expect([understandOutcome("proceed"), understandOutcome("refuse"), understandOutcome("redraft"), understandOutcome("ask")]).toEqual([null, "dropped", "redraft", "ask"]);
42
+ const claims = [{ token: "t1", ended: "released", outcome: "not_done", attempt: true }];
43
+ expect(retryState({}, claims, { exhausted: false }, false)).toEqual({ possible: true, after: "t1", asked: false });
44
+ expect(retryState({ retry: { after: "t1", by: "a" } }, claims, { exhausted: false }, false)).toMatchObject({ asked: true });
45
+ expect(retryState({}, claims, { exhausted: true }, false)).toMatchObject({ possible: false, reason: "attempts-exhausted" });
46
+ expect(retryState({}, [], { exhausted: false }, false)).toMatchObject({ possible: false, reason: "no-failed-build" });
47
+ const unit = { id: "AC-1", verification: "unit", met: true };
48
+ expect(doneVerdict({ finished: true, reverted: [] }, { ran: true, ok: true }, [unit])).toEqual({ done: true });
49
+ expect(doneVerdict({ finished: true, reverted: [] }, { ran: true, ok: true }, [unit, { id: "AC-2", verification: "manual", met: false }])).toMatchObject({ done: false });
50
+ expect(doneVerdict({ finished: true, reverted: ["x"] }, { ran: true, ok: true }, [unit])).toMatchObject({ done: false });
51
+ expect(doneVerdict({ finished: true, reverted: [] }, { ran: true, ok: false }, [unit])).toMatchObject({ done: false });
52
+ expect(
53
+ proposeImplements(
54
+ [
55
+ { path: "a.ts", decisions: [{ id: "d-1", state: "decided", granularity: "path" }, { id: "d-2", state: "decided", granularity: "member" }, { id: "d-3", state: "proposed", granularity: "path" }] },
56
+ { path: "b.ts", decisions: [{ id: "d-1", state: "decided", granularity: "path" }, { id: "d-4", state: "ratified", granularity: "path" }] },
57
+ ],
58
+ ["d-4"],
59
+ ),
60
+ ).toEqual([{ decision: "d-1", paths: ["a.ts", "b.ts"] }]);
61
+ });
62
+ });