@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
@@ -45,7 +45,8 @@ import type { PostSynthDiagnostic } from "../lint/post-synth";
45
45
  import { readDeclaration, resolveGroups, WorkspaceReadError, type Declaration, type Entry, type ErrorLocation, type ResolvedGroup } from "./declaration";
46
46
  import type { ReasonCode } from "./reason-codes";
47
47
  import { parseJsonText, pointerToken, type TextLocation } from "./jsonc";
48
- import { loadKindRegistry, probeKind, resolveKind, type KindLoadProblem, type KindRegistry } from "./kinds";
48
+ import { loadKindRegistry, probeKind, resolveKind, resolveMemberFields, type KindLoadProblem, type KindRegistry } from "./kinds";
49
+ import { coreClassRegistry, loadClassRegistry, unknownScopeClasses, type ClassRegistry } from "./principal-classes";
49
50
  import { gitTop, workingTree, type WorkspaceTree } from "./tree";
50
51
  import { LINK_CHECKS, linkTable } from "./checks/links";
51
52
  import type { LinkRow, LinkTableRow } from "./links";
@@ -89,6 +90,10 @@ export interface WorkspaceCheckContext {
89
90
  kinds: KindRegistry;
90
91
  /** Why some pinned kinds could not be read. */
91
92
  kindProblems: KindLoadProblem[];
93
+ /** The principal classes: the core four and those the pins supply (#3080). Without it, the core four. */
94
+ classes?: ClassRegistry;
95
+ /** Why some pinned principal classes could not be read (#3080). */
96
+ classProblems?: KindLoadProblem[];
92
97
  /** The facts gathered before the checks ran. */
93
98
  facts?: WorkspaceFacts;
94
99
  }
@@ -182,23 +187,41 @@ export const WORKSPACE_CHECKS: readonly WorkspaceCheck[] = [
182
187
  {
183
188
  id: "WSP002",
184
189
  name: "kinds-unreadable",
185
- description: "Every pinned package's kinds can be read: it is installed at the pinned version, and its ./workspace-kinds file is valid kind data.",
190
+ description: "Every pinned package's kinds and principal classes can be read: it is installed at the pinned version, its ./workspace-kinds file is valid kind data, and its ./workspace-principals file is valid class data.",
186
191
  severity: "error",
187
192
  configurable: false,
188
193
  check(ctx) {
189
- return ctx.kindProblems.map((p) => ({ checkId: this.id, severity: this.severity, message: p.message, pointer: `/pins/${p.pin}` }));
194
+ // A pin that can't be read is a problem for both loaders; report it once.
195
+ const seen = new Set<string>();
196
+ return [...ctx.kindProblems, ...(ctx.classProblems ?? [])]
197
+ .filter((p) => {
198
+ const key = `${p.pin}\0${p.message}`;
199
+ if (seen.has(key)) return false;
200
+ seen.add(key);
201
+ return true;
202
+ })
203
+ .map((p) => ({ checkId: this.id, severity: this.severity, message: p.message, pointer: `/pins/${p.pin}` }));
190
204
  },
191
205
  },
192
206
  {
193
207
  id: "WSP003",
194
208
  name: "kind-unknown",
195
- description: "Every member's kind is built in or supplied by a pinned package. Unknown kinds fail closed.",
209
+ description: "Every member's kind is built in or supplied by a pinned package, and so is every principal class writeScope names (#3080). Unknown kinds and classes fail closed.",
196
210
  severity: "error",
197
211
  configurable: false,
198
212
  check(ctx) {
199
- return ctx.declaration.members
213
+ const members = ctx.declaration.members
200
214
  .filter((m) => ctx.kinds.get(m.kind) === undefined)
201
215
  .map((m) => entryFinding(this, m, "kind", `member ${m.name} has kind ${m.kind}, which no built-in kind or pinned package supplies; known kinds: ${ctx.kinds.names().join(", ")}`));
216
+ const classes = ctx.classes ?? coreClassRegistry();
217
+ const scope = unknownScopeClasses(ctx.declaration.writeScope, classes).map((c) => ({
218
+ checkId: this.id,
219
+ severity: this.severity,
220
+ message: `writeScope names the principal class ${c}, which no core class or pinned package supplies, so a writer judged human is refused with write-scope-class-unknown; known classes: ${classes.names().join(", ")}`,
221
+ entity: c,
222
+ pointer: `/writeScope/${pointerToken(c)}`,
223
+ }));
224
+ return [...members, ...scope];
202
225
  },
203
226
  },
204
227
  {
@@ -216,13 +239,20 @@ export const WORKSPACE_CHECKS: readonly WorkspaceCheck[] = [
216
239
  {
217
240
  id: "WSP005",
218
241
  name: "kind-probe-failed",
219
- description: "Every member's directory is what its kind reads, such as a chant config for a chant member.",
242
+ description: "Every member's directory is what its kind reads, such as a chant config for a chant member, and its fields are ones its kind declares, of the declared types (#3151).",
220
243
  severity: "error",
221
244
  configurable: true,
222
245
  check(ctx) {
223
- return readableMembers(ctx)
246
+ const probes = readableMembers(ctx)
224
247
  .filter((m) => !probeKind(ctx.kinds.get(m.kind)!, ctx.tree, memberDir(m.dir)))
225
248
  .map((m) => entryFinding(this, m, "kind", `member ${m.name} (${m.dir}) is not ${ctx.kinds.get(m.kind)!.description}`));
249
+ // A member's fields (#3151): checked whether or not its directory exists, since they are the entry's own.
250
+ const fields = ctx.declaration.members.flatMap((m) =>
251
+ resolveMemberFields(ctx.kinds.get(m.kind), m.fields).problems.map((p) =>
252
+ entryFinding(this, m, p.path === "" ? "fields" : `fields/${p.path.split("/").map(pointerToken).join("/")}`, `member ${m.name}: ${p.message}`),
253
+ ),
254
+ );
255
+ return [...probes, ...fields];
226
256
  },
227
257
  },
228
258
  {
@@ -484,6 +514,7 @@ export async function runDeclarationChecks(
484
514
  return { file: display(location.file), diagnostics: [diagnostic], suppressed: [], links: [], ok: false };
485
515
  }
486
516
  const { registry, problems } = loadKindRegistry(declaration.pins, root);
517
+ const classes = loadClassRegistry(declaration.pins, root, { tree });
487
518
  const gathered = options.gather === false || options.tree ? {} : await gatherWorkspaceFacts(root, declaration, options);
488
519
  // The declared record kinds load from the working tree; under --at only whether each exists at the revision is checked (#2680).
489
520
  // A declared work kind's acceptance criteria are counted in the working tree too (#2772).
@@ -497,7 +528,7 @@ export async function runDeclarationChecks(
497
528
  ...(boxIntents ? { boxIntents } : {}),
498
529
  ...(options.live && !options.tree ? { live: await gatherLiveLinkFacts(root, declaration, registry, options.live.env, options.live.onStderr) } : {}),
499
530
  };
500
- const ctx: WorkspaceCheckContext = { declaration, tree, groups, kinds: registry, kindProblems: problems, facts };
531
+ const ctx: WorkspaceCheckContext = { declaration, tree, groups, kinds: registry, kindProblems: problems, classes: classes.registry, classProblems: classes.problems, facts };
501
532
  const findings = runWorkspaceChecks(ctx);
502
533
  const { active, suppressed } = applyCheckSettings(declaration, findings);
503
534
 
@@ -0,0 +1,105 @@
1
+ /**
2
+ * #3153, ws-095: a component declares where each release goes, by
3
+ * environment (the runtime that hosts it, its URL, a custom domain and the
4
+ * git remote its lifecycle records go to), replacing studio's
5
+ * `studio.sites` key in delivery's chant.config.ts. The contract validates
6
+ * it, `chant graph --components` carries it, and `graph --composites` lists
7
+ * each environment with its site.
8
+ */
9
+
10
+ import { mkdir, rm, writeFile } from "node:fs/promises";
11
+ import { tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+ import Ajv2020 from "ajv/dist/2020";
14
+ import { afterEach, beforeEach, describe, expect, test } from "vitest";
15
+ import { computeComponentGraph } from "../components/cli-support";
16
+ import componentSchema from "../components/component.schema.json";
17
+ import { componentEnvironments, memberEnvironments, type EnvironmentReason } from "./environments";
18
+ import type { MemberRuntimes } from "./runtimes";
19
+
20
+ const runtimes = (environments: MemberRuntimes["environments"], lexicons: string[] = []): MemberRuntimes => ({ lexicons, default: "local", reasons: [], environments });
21
+
22
+ const SITES = [
23
+ { name: "prod", runtime: "local" },
24
+ { name: "fly", runtime: "fly", lifecycle: "origin", url: "https://shop.fly.dev", domain: "shop.example.com" },
25
+ ];
26
+
27
+ describe("a component's environments in the contract (#3153)", () => {
28
+ const validate = new Ajv2020({ strict: false }).compile(componentSchema);
29
+ const base = { name: "app", dependsOn: [], deploy: [{ phase: "Apply", steps: [{ kind: "cfn-deploy" }] }] };
30
+
31
+ test("are optional, each a name with an optional runtime, url, domain and lifecycle", () => {
32
+ expect(validate(base)).toBe(true);
33
+ expect(validate({ ...base, environments: SITES })).toBe(true);
34
+ });
35
+
36
+ test("refuse an empty list, an entry with no name, a url that isn't http and a field nobody reads", () => {
37
+ expect(validate({ ...base, environments: [] })).toBe(false);
38
+ expect(validate({ ...base, environments: [{ runtime: "fly" }] })).toBe(false);
39
+ expect(validate({ ...base, environments: [{ name: "fly", url: "shop.fly.dev" }] })).toBe(false);
40
+ expect(validate({ ...base, environments: [{ name: "fly", region: "ams" }] })).toBe(false);
41
+ });
42
+ });
43
+
44
+ describe("chant graph --components carries them (#3153)", () => {
45
+ let dir: string;
46
+ beforeEach(async () => {
47
+ dir = join(tmpdir(), `chant-3153-${Date.now()}-${Math.random()}`);
48
+ await mkdir(dir, { recursive: true });
49
+ });
50
+ afterEach(async () => {
51
+ await rm(dir, { recursive: true, force: true });
52
+ });
53
+
54
+ test("for a component that declares them, and not for one that doesn't", async () => {
55
+ await writeFile(
56
+ join(dir, "app.component.ts"),
57
+ `export const app = { name: "app", dependsOn: [], environments: ${JSON.stringify(SITES)}, deploy: [{ phase: "Apply", steps: [{ kind: "cfn-deploy" }] }] };\n` +
58
+ `export const db = { name: "db", dependsOn: [], deploy: [{ phase: "Apply", steps: [{ kind: "cfn-deploy" }] }] };\n`,
59
+ );
60
+ const graph = await computeComponentGraph(dir);
61
+ expect(graph.success, graph.error).toBe(true);
62
+ expect(graph.environments).toEqual({ app: SITES });
63
+ });
64
+ });
65
+
66
+ describe("graph --composites lists each environment with the component's site (#3153)", () => {
67
+ test("an environment the config names takes the site, and the command runs on the site's runtime when the member hosts it", () => {
68
+ const member = memberEnvironments(runtimes(["prod", "fly"], ["fly"]), { envs: [], reason: null });
69
+ const envs = componentEnvironments("app", member, "local", SITES, ["fly"]);
70
+ expect(envs).toEqual([
71
+ { name: "local", default: true, source: "builtin", site: null, command: "chant run --components app" },
72
+ { name: "prod", default: false, source: "config", site: { runtime: "local", url: null, domain: null, lifecycle: null }, command: "chant run --components app --env prod" },
73
+ {
74
+ name: "fly",
75
+ default: false,
76
+ source: "config",
77
+ site: { runtime: "fly", url: "https://shop.fly.dev", domain: "shop.example.com", lifecycle: "origin" },
78
+ command: "chant run --components app --on fly --env fly",
79
+ },
80
+ ]);
81
+ });
82
+
83
+ test("a site whose runtime the member doesn't host runs on the default runtime", () => {
84
+ const member = memberEnvironments(runtimes(["fly"]), { envs: [], reason: null });
85
+ const fly = componentEnvironments("app", member, "local", SITES, []).find((e) => e.name === "fly")!;
86
+ expect(fly.command).toBe("chant run --components app --env fly");
87
+ expect(fly.site?.runtime).toBe("fly");
88
+ });
89
+
90
+ test("an environment only the component names is added when the config declares none, and left out with a reason when the config doesn't cover it", () => {
91
+ const open = memberEnvironments(runtimes([]), { envs: [], reason: null });
92
+ expect(componentEnvironments("app", open, "local", SITES).map((e) => `${e.name}:${e.source}`)).toEqual(["local:builtin", "prod:component", "fly:component"]);
93
+
94
+ const reasons: EnvironmentReason[] = [];
95
+ const closed = memberEnvironments(runtimes(["prod"]), { envs: [], reason: null });
96
+ expect(componentEnvironments("app", closed, "local", SITES, [], reasons).map((e) => e.name)).toEqual(["local", "prod"]);
97
+ expect(reasons).toEqual([{ code: "environments-component-undeclared", message: expect.stringMatching(/component app declares environment fly/) }]);
98
+ });
99
+
100
+ test("a pattern in the config covers a declared name", () => {
101
+ const member = memberEnvironments(runtimes(["pr-*"]), { envs: [], reason: null });
102
+ const envs = componentEnvironments("app", member, "local", [{ name: "pr-7", url: "https://pr-7.example.com" }]);
103
+ expect(envs.find((e) => e.name === "pr-7")).toMatchObject({ source: "component", site: { url: "https://pr-7.example.com" } });
104
+ });
105
+ });
@@ -29,6 +29,7 @@
29
29
  * `chant graph` itself is untouched: this is the only place members compose.
30
30
  */
31
31
 
32
+ import type { FactoryView, ListingView } from "./box-factory";
32
33
  import type { Declaration } from "./declaration";
33
34
  import type { KindRegistry } from "./kinds";
34
35
  import { graphLinks, type LinkTableRow } from "./links";
@@ -93,6 +94,12 @@ export interface ComposedMember {
93
94
  * the outer `nodes` with `outer/inner/id` ids.
94
95
  */
95
96
  nested?: NestedWorkspace;
97
+ /**
98
+ * The factory and listing the member's box block declares (#3146, ws-077),
99
+ * read from the declaration at the revision read. Set by
100
+ * `chant workspace graph` on every member; null when the box declares neither.
101
+ */
102
+ box?: { factory: FactoryView | null; listing: ListingView | null } | null;
96
103
  /** Whole-read facts the member's IR carried (`meta`, `pipeline`), kept apart from the composed sections. */
97
104
  meta?: Record<string, unknown>;
98
105
  pipeline?: unknown;
@@ -227,7 +227,8 @@
227
227
  "runtimes-config-unreadable",
228
228
  "environments-none-declared",
229
229
  "environments-ledger-undeclared",
230
- "environments-ledger-unreadable"
230
+ "environments-ledger-unreadable",
231
+ "environments-component-undeclared"
231
232
  ]
232
233
  },
233
234
  "message": {
@@ -428,7 +429,7 @@
428
429
  }
429
430
  },
430
431
  "environments": {
431
- "description": "The environments the component may deploy to with chant run --components --env in its member: local first, the default, then each name the member's chant.config.ts declares in environments (patterns left out), in config order, then each environment with a release ledger for the member on chant/lifecycle that the config covers, sorted. The component contract declares no environments.",
432
+ "description": "The environments the component may deploy to with chant run --components --env in its member: local first, the default, then each name the member's chant.config.ts declares in environments (patterns left out), in config order, then each environment with a release ledger for the member on chant/lifecycle that the config covers, sorted, then each environment only the component's own environments declare (#3153) that the config covers, in contract order. An environment the component declares carries its site.",
432
433
  "type": "array",
433
434
  "minItems": 1,
434
435
  "items": {
@@ -569,6 +570,7 @@
569
570
  "name",
570
571
  "default",
571
572
  "source",
573
+ "site",
572
574
  "command"
573
575
  ],
574
576
  "properties": {
@@ -584,9 +586,26 @@
584
586
  "enum": [
585
587
  "config",
586
588
  "ledger",
587
- "builtin"
589
+ "builtin",
590
+ "component"
588
591
  ],
589
- "description": "Where the name came from, the first of these that names it: config for the member's chant.config.ts environments, ledger for a release ledger on chant/lifecycle, builtin for local when neither names it."
592
+ "description": "Where the name came from, the first of these that names it: config for the member's chant.config.ts environments, ledger for a release ledger on chant/lifecycle, builtin for local when neither names it, and component for an environment only the component's own environments declare (#3153, added by chant 0.103.0)."
593
+ },
594
+ "site": {
595
+ "description": "Where a release of the component goes in this environment, as the component's environments declare it (#3153): the runtime that hosts it, the URL it answers on, a custom domain and the git remote its lifecycle records are pushed to, each null when not declared. Null when the component declares nothing for this environment. Added by chant 0.103.0.",
596
+ "oneOf": [
597
+ { "type": "null" },
598
+ {
599
+ "type": "object",
600
+ "required": ["runtime", "url", "domain", "lifecycle"],
601
+ "properties": {
602
+ "runtime": { "type": ["string", "null"] },
603
+ "url": { "type": ["string", "null"] },
604
+ "domain": { "type": ["string", "null"] },
605
+ "lifecycle": { "type": ["string", "null"] }
606
+ }
607
+ }
608
+ ]
590
609
  },
591
610
  "command": {
592
611
  "type": "string",
@@ -61,7 +61,7 @@ const componentIr = (components: { name: string; composites?: string[]; archetyp
61
61
  const local = (name: string) => ({ name: "local", lexicon: null, default: true, command: `chant run --components ${name}` });
62
62
 
63
63
  /** The default environment, named by nothing but chant itself. */
64
- const localEnv = (name: string) => ({ name: "local", default: true, source: "builtin", command: `chant run --components ${name}` });
64
+ const localEnv = (name: string) => ({ name: "local", default: true, source: "builtin", site: null, command: `chant run --components ${name}` });
65
65
 
66
66
  /**
67
67
  * app declares three instances and exports ImageUri; delivery links to it and
@@ -381,11 +381,11 @@ describe("the environments each component may deploy to (#2695)", () => {
381
381
  const g = result((await workspaceComposites({ cwd: declared() })).doc);
382
382
  expectValid(g);
383
383
  expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments).toEqual([
384
- { name: "local", default: true, source: "builtin", command: "chant run --components queue-runner" },
385
- { name: "staging", default: false, source: "config", command: "chant run --components queue-runner --env staging" },
386
- { name: "prod", default: false, source: "config", command: "chant run --components queue-runner --env prod" },
384
+ { name: "local", default: true, source: "builtin", site: null, command: "chant run --components queue-runner" },
385
+ { name: "staging", default: false, source: "config", site: null, command: "chant run --components queue-runner --env staging" },
386
+ { name: "prod", default: false, source: "config", site: null, command: "chant run --components queue-runner --env prod" },
387
387
  // The pattern pr-* is no environment by itself, and it covers the ledger's pr-42.
388
- { name: "pr-42", default: false, source: "ledger", command: "chant run --components queue-runner --env pr-42" },
388
+ { name: "pr-42", default: false, source: "ledger", site: null, command: "chant run --components queue-runner --env pr-42" },
389
389
  ]);
390
390
  const jobs = g.members.find((m) => m.name === "jobs")!;
391
391
  expect(jobs.environmentReasons).toEqual([{ code: "environments-ledger-undeclared", message: expect.stringContaining("retired") }]);
@@ -397,7 +397,7 @@ describe("the environments each component may deploy to (#2695)", () => {
397
397
  // delivery has no _members/delivery, so the flat staging ledger is its; its config declares nothing, so anything goes.
398
398
  expect(g.components.find((c) => c.id === "delivery/edge")!.environments).toEqual([
399
399
  localEnv("edge"),
400
- { name: "staging", default: false, source: "ledger", command: "chant run --components edge --env staging" },
400
+ { name: "staging", default: false, source: "ledger", site: null, command: "chant run --components edge --env staging" },
401
401
  ]);
402
402
  expect(g.members.find((m) => m.name === "delivery")!.environmentReasons.map((r) => r.code)).toEqual(["environments-none-declared"]);
403
403
  expect(g.members.find((m) => m.name === "docs")!.environmentReasons).toEqual([]);
@@ -409,8 +409,8 @@ describe("the environments each component may deploy to (#2695)", () => {
409
409
  const g = result((await workspaceComposites({ cwd: root })).doc);
410
410
  expectValid(g);
411
411
  expect(g.components.find((c) => c.id === "jobs/queue-runner")!.environments).toEqual([
412
- { name: "local", default: true, source: "config", command: "chant run --components queue-runner" },
413
- { name: "prod", default: false, source: "config", command: "chant run --components queue-runner --env prod" },
412
+ { name: "local", default: true, source: "config", site: null, command: "chant run --components queue-runner" },
413
+ { name: "prod", default: false, source: "config", site: null, command: "chant run --components queue-runner --env prod" },
414
414
  ]);
415
415
  expect(g.members.find((m) => m.name === "jobs")!.environmentReasons).toEqual([]);
416
416
  });
@@ -49,6 +49,7 @@ import type { LinkRow } from "./links";
49
49
  import { emitDocument, type UnitResult } from "./member-commands";
50
50
  import { readerVersion, WORKSPACE_ERROR_CODES, type ErrorLocation, type WorkspaceErrorCode } from "./declaration";
51
51
  import type { ReasonCode } from "./reason-codes";
52
+ import type { ComponentEnvironmentDeclaration } from "../components/component";
52
53
  import { componentEnvironments, ENVIRONMENT_REASON_CODES, memberEnvironments, readLedgerEnvironments, type ComponentEnvironment, type EnvironmentReason, type LedgerEnvironmentReader, type MemberEnvironments } from "./environments";
53
54
  import { componentRuntimes, readRuntimesIn, RUNTIME_REASON_CODES, type ComponentRuntime, type MemberRuntimes, type PluginLoader, type RuntimeReason } from "./runtimes";
54
55
 
@@ -109,7 +110,7 @@ export interface ComponentEntry {
109
110
  file: string | null;
110
111
  /** The runtimes it can deploy on: `local` first, then each hosting lexicon its member configures. */
111
112
  runtimes: ComponentRuntime[];
112
- /** The environments it may deploy to: `local` first, then the config's, then the ledger's. */
113
+ /** The environments it may deploy to: `local` first, then the config's, then the ledger's, then the ones only the component declares, each with the site the component declares for it. */
113
114
  environments: ComponentEnvironment[];
114
115
  }
115
116
 
@@ -183,12 +184,22 @@ function readComponents(member: string, dir: string, run: UnitResult, runtimes:
183
184
  composites: composites && composites.length > 0 ? composites : null,
184
185
  file: file ? (dir === "." ? file : `${dir}/${file}`) : null,
185
186
  runtimes: componentRuntimes(n.id, runtimes),
186
- environments: componentEnvironments(n.id, environments, runtimes?.default),
187
+ // The component's own environments (#3153): their sites, and any the member doesn't list; a reason lands on the member.
188
+ environments: componentEnvironments(n.id, environments, runtimes?.default, declaredEnvironments(attrs.environments), runtimes?.lexicons ?? [], environments?.reasons ?? []),
187
189
  });
188
190
  }
189
191
  return { components };
190
192
  }
191
193
 
194
+ /** A component's declared environments from its IR attrs (#3153), keeping only well-formed entries. */
195
+ function declaredEnvironments(raw: unknown): ComponentEnvironmentDeclaration[] {
196
+ if (!Array.isArray(raw)) return [];
197
+ const text = (v: unknown) => (typeof v === "string" && v.length > 0 ? v : undefined);
198
+ return raw
199
+ .filter((e): e is Record<string, unknown> => e !== null && typeof e === "object" && typeof (e as Record<string, unknown>).name === "string")
200
+ .map((e) => ({ name: e.name as string, runtime: text(e.runtime), url: text(e.url), domain: text(e.domain), lifecycle: text(e.lifecycle) }));
201
+ }
202
+
192
203
  /** The composite instances in a composed graph, without their components. */
193
204
  export function compositeInstances(graph: Pick<WorkspaceGraph, "nodes">): CompositeInstanceRow[] {
194
205
  const byId = new Map<string, { member: string; kinds: Set<string>; lexicons: Set<string>; nodes: string[] }>();
@@ -233,12 +233,12 @@
233
233
  "pattern": "^sha256:[0-9a-f]{64}$"
234
234
  },
235
235
  "constrains": {
236
- "description": "What this decision governs: issues (owner/repo#n), other decisions (their ids), workspace members (member:<name>) or files and directories in the workspace (path:<path>, the grammar of an evidence path, #2549). At least one entry: a decision that governs nothing is refused.",
236
+ "description": "What this decision governs: issues (owner/repo#n), other decisions (their ids), workspace members (member:<name>), contracts (contract:<id>, #3148) or files and directories in the workspace (path:<path>, the grammar of an evidence path, #2549). At least one entry: a decision that governs nothing is refused.",
237
237
  "type": "array",
238
238
  "minItems": 1,
239
239
  "items": {
240
240
  "type": "string",
241
- "pattern": "^([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+#[0-9]+|[a-z][a-z0-9]{0,15}-[0-9]{3,}|member:[a-z0-9][a-z0-9-]{0,39}|path:(?!/)(?!(?:[^/]*/)*\\.{1,2}(?:/|$))(?!.*//)[^\\\\\\u0000-\\u001f]*[^/\\\\\\u0000-\\u001f])$"
241
+ "pattern": "^([A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+#[0-9]+|[a-z][a-z0-9]{0,15}-[0-9]{3,}|member:[a-z0-9][a-z0-9-]{0,39}|contract:[A-Za-z0-9][A-Za-z0-9._-]{0,99}|path:(?!/)(?!(?:[^/]*/)*\\.{1,2}(?:/|$))(?!.*//)[^\\\\\\u0000-\\u001f]*[^/\\\\\\u0000-\\u001f])$"
242
242
  }
243
243
  },
244
244
  "out_of_scope": {
@@ -0,0 +1,207 @@
1
+ /**
2
+ * The reference broker (#3164, ws-097): the smallest broker of the broker
3
+ * protocol (`../broker-protocol.ts`) that passes the conformance suite
4
+ * (`./broker.ts`), serving all four standard capabilities. It keeps every
5
+ * report in memory and buffers each request, which a real broker should not;
6
+ * it exists to show the suite can be passed and what passing takes, and for
7
+ * a test to run a box against without studio's lobby.
8
+ *
9
+ * It is a test fixture and the package does not export it: chant never runs
10
+ * a broker or listens on a port (ws-052, ws-086), so it lives under
11
+ * `__fixtures__`, which test/no-listener.test.ts leaves out like a test file.
12
+ * `startReferenceBroker(env)` has the shape of the suite's `start`.
13
+ */
14
+
15
+ import { randomBytes } from "node:crypto";
16
+ import { createServer, type IncomingMessage, type ServerResponse } from "node:http";
17
+ import type { AddressInfo } from "node:net";
18
+ import {
19
+ BROKER_ROUTES,
20
+ DECLARATION_LIMITS,
21
+ declaredRefusal,
22
+ EGRESS_CAPABILITY,
23
+ FEEDBACK_CAPABILITY,
24
+ FOUNTAIN_CAPABILITY,
25
+ INFERENCE_CAPABILITY,
26
+ parseDeclarationReport,
27
+ formatPayerHeader,
28
+ PAYER_HEADER,
29
+ type BrokerPayer,
30
+ type KeptDeclaration,
31
+ } from "../../broker-protocol";
32
+ import type { BrokerConformanceEnv, StartedBroker } from "../broker";
33
+
34
+ const MAX_BODY = 1024 * 1024;
35
+ /** Request headers that describe the hop or carry the caller's credential. */
36
+ const DROP = new Set(["host", "connection", "keep-alive", "content-length", "transfer-encoding", "authorization", "x-api-key", "cookie", "proxy-authorization", "te", "upgrade", "forwarded", "x-forwarded-for", "x-forwarded-host", "x-forwarded-proto", "x-real-ip"]);
37
+ /** Response headers fetch has already undone. */
38
+ const HOP = new Set(["connection", "keep-alive", "content-length", "content-encoding", "transfer-encoding"]);
39
+
40
+ function send(res: ServerResponse, status: number, value: unknown, extra: Record<string, string> = {}): void {
41
+ res.writeHead(status, { "content-type": "application/json", "cache-control": "no-store", ...extra });
42
+ res.end(JSON.stringify(value));
43
+ }
44
+
45
+ const refuse = (res: ServerResponse, status: number, message: string) => send(res, status, { error: { type: status === 403 ? "permission_error" : "invalid_request", message } });
46
+
47
+ async function readBody(req: IncomingMessage): Promise<string | null> {
48
+ let raw = "";
49
+ for await (const chunk of req) {
50
+ raw += chunk;
51
+ if (raw.length > MAX_BODY) return null;
52
+ }
53
+ return raw;
54
+ }
55
+
56
+ /** The headers to forward, without the box's credential, plus `extra`. */
57
+ function forwarded(req: IncomingMessage, extra: Record<string, string>): Record<string, string> {
58
+ const headers: Record<string, string> = {};
59
+ for (const [k, v] of Object.entries(req.headers)) if (!DROP.has(k) && v !== undefined) headers[k] = [v].flat().join(", ");
60
+ return { ...headers, ...extra };
61
+ }
62
+
63
+ async function relay(res: ServerResponse, answer: Response, swap?: [string, string], extra: Record<string, string> = {}): Promise<void> {
64
+ const headers: Record<string, string> = {};
65
+ answer.headers.forEach((v, k) => {
66
+ if (!HOP.has(k)) headers[k] = swap ? v.split(swap[0]).join(swap[1]) : v;
67
+ });
68
+ Object.assign(headers, extra);
69
+ res.writeHead(answer.status, headers);
70
+ res.end(Buffer.from(await answer.arrayBuffer()));
71
+ }
72
+
73
+ /** Start the reference broker for `env`, with a fresh token per box. */
74
+ export async function startReferenceBroker(env: BrokerConformanceEnv): Promise<StartedBroker> {
75
+ const tokens: Record<string, string> = Object.fromEntries(env.boxes.map((b) => [b, `box_${randomBytes(32).toString("hex")}`]));
76
+ const boxOf = new Map(Object.entries(tokens).map(([box, token]) => [token, box]));
77
+ const reports = new Map<string, KeptDeclaration>();
78
+ const anthropic = new URL(env.anthropic.url);
79
+ // It spends the operator's one credential for every box, so the payer is shared (#3474), said on the report's answer and on each inference and decide answer.
80
+ const payer: BrokerPayer = { kind: "shared", principal: null };
81
+ const paid = { [PAYER_HEADER]: formatPayerHeader(payer) };
82
+ const fountain = new URL(env.fountain.url);
83
+
84
+ const tokenOf = (req: IncomingMessage): string | undefined => {
85
+ const bearer = /^Bearer\s+(\S+)$/i.exec(String(req.headers.authorization ?? ""))?.[1];
86
+ return bearer ?? (typeof req.headers["x-api-key"] === "string" ? req.headers["x-api-key"] : undefined);
87
+ };
88
+
89
+ const server = createServer(async (req, res) => {
90
+ try {
91
+ const url = new URL(req.url ?? "/", "http://broker");
92
+ const path = url.pathname;
93
+ const method = req.method ?? "GET";
94
+ const token = tokenOf(req);
95
+ const box = token ? boxOf.get(token) : undefined;
96
+ const raw = await readBody(req);
97
+ if (raw === null) return refuse(res, 413, "The request is larger than 1 MB.");
98
+
99
+ if (path === BROKER_ROUTES.declaration) {
100
+ if (method !== "POST") return refuse(res, 405, `POST ${BROKER_ROUTES.declaration}`);
101
+ if (!box) return refuse(res, 403, "This token is no box this broker knows.");
102
+ if (raw.length > DECLARATION_LIMITS.bytes) return refuse(res, 413, "The declaration is larger than 32 KB.");
103
+ let body: unknown;
104
+ try {
105
+ body = JSON.parse(raw);
106
+ } catch {
107
+ return refuse(res, 400, "The body is not JSON.");
108
+ }
109
+ const parsed = parseDeclarationReport(body, env.broker);
110
+ if ("error" in parsed) return refuse(res, 400, parsed.error);
111
+ const kept: KeptDeclaration = { capabilities: parsed.capabilities, at: new Date().toISOString() };
112
+ reports.set(box, kept);
113
+ return send(res, 200, { ...kept, payer });
114
+ }
115
+
116
+ let body: unknown;
117
+ try {
118
+ body = raw ? JSON.parse(raw) : undefined;
119
+ } catch {
120
+ body = undefined;
121
+ }
122
+ const request = { method, path, body };
123
+ for (const spec of [INFERENCE_CAPABILITY, EGRESS_CAPABILITY, FEEDBACK_CAPABILITY, FOUNTAIN_CAPABILITY]) {
124
+ if (!spec.routes.some((r) => path === r || path.startsWith(`${r}/`))) continue;
125
+ const words = spec.scopes(request);
126
+ if (words === null) return refuse(res, 404, `This broker does not serve ${method} ${path}.`);
127
+ if (words.length === 0 && spec !== FEEDBACK_CAPABILITY) return send(res, 200, {});
128
+ if (!box) return refuse(res, spec === INFERENCE_CAPABILITY && path === BROKER_ROUTES.decide ? 401 : 403, "This request carried no token of a box this broker knows.");
129
+ if (words.length === 0) return refuse(res, 400, "A batch carries entries (scope agent), counts (scope passive), or both.");
130
+ for (const word of words) {
131
+ const refused = declaredRefusal(reports.get(box), env.broker, spec.name, word);
132
+ if (refused) return refuse(res, 403, refused);
133
+ }
134
+
135
+ if (spec === INFERENCE_CAPABILITY && path === BROKER_ROUTES.decide) return decide(res, body);
136
+ if (spec === INFERENCE_CAPABILITY) {
137
+ const rest = path.slice(BROKER_ROUTES.inference.length);
138
+ const answer = await fetch(new URL(`${rest}${url.search}`, anthropic), { method, headers: forwarded(req, { "x-api-key": env.anthropic.credential }), body: raw || undefined });
139
+ return relay(res, answer, undefined, paid);
140
+ }
141
+ if (spec === EGRESS_CAPABILITY) {
142
+ const [name] = words;
143
+ const secret = env.secrets.find((s) => s.box === box && s.name === name);
144
+ if (!secret) return refuse(res, 403, `This broker holds no value for ${name}.`);
145
+ const rest = path.slice(BROKER_ROUTES.egress.length + 1 + name.length) || "/";
146
+ // The box's token stands in for the value wherever the API expects its key, so it is swapped in every header.
147
+ const headers: Record<string, string> = {};
148
+ for (const [k, v] of Object.entries(req.headers)) if (v !== undefined && !HOP.has(k) && k !== "host") headers[k] = [v].flat().join(", ").split(token!).join(secret.value);
149
+ const search = url.search.split(token!).join(secret.value);
150
+ const answer = await fetch(new URL(`${rest}${search}`, secret.host), { method, headers, body: raw || undefined });
151
+ return relay(res, answer, [secret.value, token!]);
152
+ }
153
+ if (spec === FEEDBACK_CAPABILITY) return send(res, 202, { taken: true });
154
+ if (spec === FOUNTAIN_CAPABILITY) {
155
+ const rest = path.slice(BROKER_ROUTES.fountain.length);
156
+ const answer = await fetch(new URL(`${rest}${url.search}`, fountain), { method, headers: forwarded(req, { authorization: `Bearer ${env.fountain.credential}` }), body: raw || undefined });
157
+ return relay(res, answer);
158
+ }
159
+ }
160
+ if (path === BROKER_ROUTES.feedback) return refuse(res, 400, "A batch carries entries (scope agent), counts (scope passive), or both.");
161
+ return refuse(res, 404, "not found");
162
+ } catch (err) {
163
+ if (!res.headersSent) refuse(res, 502, `The broker could not answer: ${err instanceof Error ? err.message : String(err)}`);
164
+ }
165
+ });
166
+
167
+ /** One Messages call per question, asking for JSON in a schema made from it, as studio's lobby does. */
168
+ async function decide(res: ServerResponse, body: unknown): Promise<void> {
169
+ const b = body as { model?: unknown; state?: unknown; questions?: Record<string, { type?: string; instructions?: string; criteria?: Record<string, string> }> } | undefined;
170
+ if (!b || typeof b.model !== "string" || b.state === undefined || !b.questions || typeof b.questions !== "object" || Object.keys(b.questions).length === 0) {
171
+ return refuse(res, 422, "The body is { model, state, questions } with at least one question.");
172
+ }
173
+ const answers: Record<string, unknown> = {};
174
+ for (const [name, q] of Object.entries(b.questions)) {
175
+ if (q.type !== "choice" && q.type !== "noul") {
176
+ answers[name] = { type: "unsupported" };
177
+ continue;
178
+ }
179
+ const options = q.type === "noul" ? ["true", "false"] : Object.keys(q.criteria ?? {});
180
+ const schema = {
181
+ type: "object",
182
+ properties: { reason: { type: "string" }, choice: { type: "string", enum: options }, probabilities: { type: "object", properties: Object.fromEntries(options.map((o) => [o, { type: "number" }])) } },
183
+ required: ["reason", "choice", "probabilities"],
184
+ };
185
+ const asked = await fetch(new URL("/v1/messages", anthropic), {
186
+ method: "POST",
187
+ headers: { "content-type": "application/json", "anthropic-version": "2023-06-01", "x-api-key": env.anthropic.credential },
188
+ body: JSON.stringify({ model: b.model, max_tokens: 1024, messages: [{ role: "user", content: `${name}: ${q.instructions}\n${JSON.stringify(b.state)}` }], output_config: { format: { type: "json_schema", schema } } }),
189
+ });
190
+ if (!asked.ok) return refuse(res, 502, `The model answered ${asked.status}.`);
191
+ const message = (await asked.json()) as { content?: { type: string; text?: string }[] };
192
+ const out = JSON.parse(message.content?.find((c) => c.type === "text")?.text ?? "{}") as { reason?: string; choice?: string; probabilities?: Record<string, number> };
193
+ const total = options.reduce((t, o) => t + Number(out.probabilities?.[o] ?? 0), 0) || 1;
194
+ const p = Object.fromEntries(options.map((o) => [o, Number(out.probabilities?.[o] ?? 0) / total]));
195
+ const reason = typeof out.reason === "string" ? { reason: out.reason } : {};
196
+ answers[name] = q.type === "noul" ? { type: "noul", noul: p.true, ...reason } : { type: "choice", choice: out.choice, probabilities: p, confidence: p[out.choice ?? ""] ?? 0, ...reason };
197
+ }
198
+ send(res, 200, { model: b.model, answers }, paid);
199
+ }
200
+
201
+ await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", () => resolve()));
202
+ return {
203
+ url: `http://127.0.0.1:${(server.address() as AddressInfo).port}`,
204
+ tokens,
205
+ close: () => new Promise<void>((resolve) => server.close(() => resolve())),
206
+ };
207
+ }
@@ -0,0 +1,32 @@
1
+ // The answers to the workspace's decision points (ws-058, #2739), data only:
2
+ // no imports, no code.
3
+ //
4
+ // chant workspace points --open --json
5
+ // chant workspace points ask slice-tier --inputs inputs.json --subject W-002
6
+ // chant workspace points answer <id> --answer medium --by <name> --note <text>
7
+ // chant workspace points retract <id> --by <name> --note <why>
8
+ // chant workspace points ask agent-question --inputs '{"ask.id":"req-1"}' --candidates question.json
9
+ //
10
+ // The points are declared in ../decisions/points.json: typed questions, the
11
+ // read-contract outputs they read, and a table, model and quorum chain. Each
12
+ // answer is one record here, named for the point and its inputs' hash, so the
13
+ // same question is answered once. A table's answer is answered, a model's is
14
+ // proposed until a person confirms it, and a question nobody before the
15
+ // quorum answered is escalated to people. An answer never changes in place:
16
+ // retracting it escalates the question again and keeps the answer in the
17
+ // record's retractions (#3351). An ad-hoc point's question and candidates
18
+ // come with each ask and stay in the record as asked (#3403). answer.schema.json is a copy of the
19
+ // one @intentius/chant ships as workspace/point-answer.schema.json.
20
+ export const recordKind = {
21
+ name: "answer",
22
+ location: { dir: ".", match: "^[a-z][a-z0-9-]*-[0-9a-f]{12}\\.md$" },
23
+ format: "markdown-front-matter",
24
+ schema: { id: "urn:intentius:chant:point-answer:1", path: "answer.schema.json" },
25
+ idField: "id",
26
+ stateField: "state",
27
+ states: ["escalated", "proposed", "answered"],
28
+ closedStates: ["answered"],
29
+ constrains: { field: "constrains" },
30
+ source: { field: "source" },
31
+ answers: { points: "../decisions/points.json" },
32
+ };