@intentius/chant 0.101.0 → 0.102.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. package/dist/agents/checks.d.ts.map +1 -1
  2. package/dist/attrref.d.ts.map +1 -1
  3. package/dist/audit/discover.d.ts.map +1 -1
  4. package/dist/audit/nginx.d.ts.map +1 -1
  5. package/dist/audit/prior-art.d.ts +48 -0
  6. package/dist/audit/prior-art.d.ts.map +1 -1
  7. package/dist/behaviour-kinds.d.ts.map +1 -1
  8. package/dist/builder.d.ts.map +1 -1
  9. package/dist/cli/commands/carve-emit.d.ts.map +1 -1
  10. package/dist/cli/commands/check-lexicon.d.ts +16 -0
  11. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  12. package/dist/cli/commands/import.d.ts +8 -0
  13. package/dist/cli/commands/import.d.ts.map +1 -1
  14. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  15. package/dist/cli/commands/init.d.ts +19 -0
  16. package/dist/cli/commands/init.d.ts.map +1 -1
  17. package/dist/cli/commands/onboard.d.ts +9 -0
  18. package/dist/cli/commands/onboard.d.ts.map +1 -1
  19. package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
  20. package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
  21. package/dist/cli/handlers/dev.d.ts.map +1 -1
  22. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  23. package/dist/cli/handlers/misc.d.ts.map +1 -1
  24. package/dist/cli/handlers/operator.d.ts +9 -0
  25. package/dist/cli/handlers/operator.d.ts.map +1 -1
  26. package/dist/cli/handlers/run.d.ts.map +1 -1
  27. package/dist/cli/lsp/server.d.ts.map +1 -1
  28. package/dist/cli/main.d.ts.map +1 -1
  29. package/dist/cli/mcp/server.d.ts.map +1 -1
  30. package/dist/cli/mcp/tools/build.d.ts.map +1 -1
  31. package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
  32. package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
  33. package/dist/cli/mcp/tools/import.d.ts.map +1 -1
  34. package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
  35. package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
  36. package/dist/cli/mcp/tools/search.d.ts.map +1 -1
  37. package/dist/cli/mcp/workspace-tools.d.ts +1 -1
  38. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  39. package/dist/cli/registry.d.ts +11 -2
  40. package/dist/cli/registry.d.ts.map +1 -1
  41. package/dist/codegen/fetch.d.ts.map +1 -1
  42. package/dist/codegen/naming.d.ts.map +1 -1
  43. package/dist/codegen/pinned-upgrade.d.ts +67 -3
  44. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  45. package/dist/codegen/registry.d.ts.map +1 -1
  46. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  47. package/dist/components/capability.d.ts.map +1 -1
  48. package/dist/components/driver.d.ts.map +1 -1
  49. package/dist/components/fan-out.d.ts.map +1 -1
  50. package/dist/components/starter-plugin.d.ts.map +1 -1
  51. package/dist/components/verbs/process-runner.d.ts.map +1 -1
  52. package/dist/components/verbs/r2-sync.d.ts.map +1 -1
  53. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  54. package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
  55. package/dist/components/verbs/sign.d.ts.map +1 -1
  56. package/dist/components/verbs/verify.d.ts.map +1 -1
  57. package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
  58. package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
  59. package/dist/components/verbs/wrangler.d.ts.map +1 -1
  60. package/dist/composite.d.ts.map +1 -1
  61. package/dist/config.d.ts +19 -7
  62. package/dist/config.d.ts.map +1 -1
  63. package/dist/declarable.d.ts +16 -0
  64. package/dist/declarable.d.ts.map +1 -1
  65. package/dist/discovery/cache.d.ts.map +1 -1
  66. package/dist/discovery/fold-import.d.ts +15 -5
  67. package/dist/discovery/fold-import.d.ts.map +1 -1
  68. package/dist/discovery/param-deps.d.ts +16 -0
  69. package/dist/discovery/param-deps.d.ts.map +1 -1
  70. package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
  71. package/dist/discovery/specifier-resolve.d.ts +37 -0
  72. package/dist/discovery/specifier-resolve.d.ts.map +1 -0
  73. package/dist/errors.d.ts.map +1 -1
  74. package/dist/fold/fold.d.ts +3 -1
  75. package/dist/fold/fold.d.ts.map +1 -1
  76. package/dist/graph-detail.d.ts.map +1 -1
  77. package/dist/graph-ir.d.ts.map +1 -1
  78. package/dist/graph-layout.d.ts.map +1 -1
  79. package/dist/import/base-parser.d.ts.map +1 -1
  80. package/dist/import/embedded.d.ts +7 -0
  81. package/dist/import/embedded.d.ts.map +1 -1
  82. package/dist/import/parser-options.d.ts +14 -0
  83. package/dist/import/parser-options.d.ts.map +1 -0
  84. package/dist/import/parser.d.ts +17 -0
  85. package/dist/import/parser.d.ts.map +1 -1
  86. package/dist/kubectl-context.d.ts.map +1 -1
  87. package/dist/lexicon-output.d.ts.map +1 -1
  88. package/dist/lexicon-schema.d.ts +3 -3
  89. package/dist/lexicon.d.ts +55 -3
  90. package/dist/lexicon.d.ts.map +1 -1
  91. package/dist/lifecycle/assert-live.d.ts.map +1 -1
  92. package/dist/lifecycle/gate-ledger.d.ts +15 -0
  93. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  94. package/dist/lifecycle/git.d.ts.map +1 -1
  95. package/dist/lifecycle/member-ledger.d.ts.map +1 -1
  96. package/dist/lifecycle/observe.d.ts.map +1 -1
  97. package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
  98. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  99. package/dist/lifecycle/scenario.d.ts.map +1 -1
  100. package/dist/lifecycle/status.d.ts.map +1 -1
  101. package/dist/lifecycle/work-lease.d.ts +61 -2
  102. package/dist/lifecycle/work-lease.d.ts.map +1 -1
  103. package/dist/lint/config.d.ts +8 -8
  104. package/dist/lint/engine.d.ts +6 -0
  105. package/dist/lint/engine.d.ts.map +1 -1
  106. package/dist/lsp/lexicon-providers.d.ts.map +1 -1
  107. package/dist/op/activities/activity-contracts.d.ts +11 -11
  108. package/dist/op/activities/apply.d.ts +79 -9
  109. package/dist/op/activities/apply.d.ts.map +1 -1
  110. package/dist/op/activities/decide.d.ts.map +1 -1
  111. package/dist/op/activities/index.d.ts +1 -1
  112. package/dist/op/activities/index.d.ts.map +1 -1
  113. package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
  114. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
  115. package/dist/op/activity-contract.d.ts +1 -1
  116. package/dist/op/activity-failure.d.ts.map +1 -1
  117. package/dist/op/activity-profiles.d.ts.map +1 -1
  118. package/dist/op/builders.d.ts.map +1 -1
  119. package/dist/op/composites/apply-op.d.ts +12 -5
  120. package/dist/op/composites/apply-op.d.ts.map +1 -1
  121. package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
  122. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
  123. package/dist/op/decide-backend.d.ts.map +1 -1
  124. package/dist/op/decide-read-inputs.d.ts.map +1 -1
  125. package/dist/op/emulator-lifecycle.d.ts +21 -2
  126. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  127. package/dist/op/gate-approval.d.ts +5 -1
  128. package/dist/op/gate-approval.d.ts.map +1 -1
  129. package/dist/op/gate-wait.d.ts.map +1 -1
  130. package/dist/op/gate.d.ts +19 -3
  131. package/dist/op/gate.d.ts.map +1 -1
  132. package/dist/op/index.d.ts +2 -0
  133. package/dist/op/index.d.ts.map +1 -1
  134. package/dist/op/local-executor.d.ts +6 -0
  135. package/dist/op/local-executor.d.ts.map +1 -1
  136. package/dist/op/operator.d.ts.map +1 -1
  137. package/dist/op/run-context.d.ts +39 -0
  138. package/dist/op/run-context.d.ts.map +1 -0
  139. package/dist/op/run-live.d.ts.map +1 -1
  140. package/dist/op/runtimes/local.d.ts.map +1 -1
  141. package/dist/op/source-archive.d.ts.map +1 -1
  142. package/dist/op/steward-beside.d.ts.map +1 -1
  143. package/dist/op/steward-points.d.ts.map +1 -1
  144. package/dist/op/steward.d.ts.map +1 -1
  145. package/dist/op/types.d.ts +8 -3
  146. package/dist/op/types.d.ts.map +1 -1
  147. package/dist/op/work-lease-run.d.ts +24 -4
  148. package/dist/op/work-lease-run.d.ts.map +1 -1
  149. package/dist/project-root.d.ts.map +1 -1
  150. package/dist/provenance.d.ts +21 -0
  151. package/dist/provenance.d.ts.map +1 -1
  152. package/dist/pseudo-parameter.d.ts.map +1 -1
  153. package/dist/reconcile.d.ts.map +1 -1
  154. package/dist/secret-materialization.d.ts.map +1 -1
  155. package/dist/terraform/emit-source.d.ts.map +1 -1
  156. package/dist/terraform/parse.d.ts.map +1 -1
  157. package/dist/testing.d.ts.map +1 -1
  158. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  159. package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
  160. package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
  161. package/dist/workspace/agent-cli.d.ts +5 -0
  162. package/dist/workspace/agent-cli.d.ts.map +1 -1
  163. package/dist/workspace/box-factory.d.ts +73 -0
  164. package/dist/workspace/box-factory.d.ts.map +1 -0
  165. package/dist/workspace/changes.d.ts.map +1 -1
  166. package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
  167. package/dist/workspace/checks/boxes.d.ts.map +1 -1
  168. package/dist/workspace/checks.d.ts +5 -0
  169. package/dist/workspace/checks.d.ts.map +1 -1
  170. package/dist/workspace/compose-graph.d.ts +10 -0
  171. package/dist/workspace/compose-graph.d.ts.map +1 -1
  172. package/dist/workspace/conformance/index.d.ts +67 -6
  173. package/dist/workspace/conformance/index.d.ts.map +1 -1
  174. package/dist/workspace/conformance/vitest.d.ts +12 -3
  175. package/dist/workspace/conformance/vitest.d.ts.map +1 -1
  176. package/dist/workspace/conformance/writer.d.ts +368 -0
  177. package/dist/workspace/conformance/writer.d.ts.map +1 -0
  178. package/dist/workspace/decide.d.ts +1 -1
  179. package/dist/workspace/decide.d.ts.map +1 -1
  180. package/dist/workspace/declaration.d.ts +91 -4
  181. package/dist/workspace/declaration.d.ts.map +1 -1
  182. package/dist/workspace/declaration.schema.json +234 -5
  183. package/dist/workspace/generated-files.d.ts.map +1 -1
  184. package/dist/workspace/graph-cache.d.ts.map +1 -1
  185. package/dist/workspace/graph-cli.d.ts +2 -0
  186. package/dist/workspace/graph-cli.d.ts.map +1 -1
  187. package/dist/workspace/identity.d.ts +111 -0
  188. package/dist/workspace/identity.d.ts.map +1 -0
  189. package/dist/workspace/intent-cli.d.ts +7 -4
  190. package/dist/workspace/intent-cli.d.ts.map +1 -1
  191. package/dist/workspace/intent-record.d.ts +8 -1
  192. package/dist/workspace/intent-record.d.ts.map +1 -1
  193. package/dist/workspace/intent.d.ts +149 -5
  194. package/dist/workspace/intent.d.ts.map +1 -1
  195. package/dist/workspace/kinds.d.ts +18 -4
  196. package/dist/workspace/kinds.d.ts.map +1 -1
  197. package/dist/workspace/lineage-hash-index.d.ts.map +1 -1
  198. package/dist/workspace/lineage-lock.d.ts +2 -2
  199. package/dist/workspace/lineage-lock.d.ts.map +1 -1
  200. package/dist/workspace/links.d.ts.map +1 -1
  201. package/dist/workspace/points.d.ts.map +1 -1
  202. package/dist/workspace/principal-classes.d.ts +114 -0
  203. package/dist/workspace/principal-classes.d.ts.map +1 -0
  204. package/dist/workspace/reason-codes.d.ts +21 -1
  205. package/dist/workspace/reason-codes.d.ts.map +1 -1
  206. package/dist/workspace/record-assets.d.ts.map +1 -1
  207. package/dist/workspace/records-checkout.d.ts +54 -0
  208. package/dist/workspace/records-checkout.d.ts.map +1 -0
  209. package/dist/workspace/records-cli.d.ts +27 -1
  210. package/dist/workspace/records-cli.d.ts.map +1 -1
  211. package/dist/workspace/records-close.d.ts +1 -1
  212. package/dist/workspace/records-close.d.ts.map +1 -1
  213. package/dist/workspace/records-since.d.ts.map +1 -1
  214. package/dist/workspace/records-write.d.ts +5 -4
  215. package/dist/workspace/records-write.d.ts.map +1 -1
  216. package/dist/workspace/records.d.ts +15 -0
  217. package/dist/workspace/records.d.ts.map +1 -1
  218. package/dist/workspace/runs-cli.d.ts +164 -0
  219. package/dist/workspace/runs-cli.d.ts.map +1 -0
  220. package/dist/workspace/runs.d.ts +423 -0
  221. package/dist/workspace/runs.d.ts.map +1 -0
  222. package/dist/workspace/source-block.d.ts +1 -1
  223. package/dist/workspace/source-block.d.ts.map +1 -1
  224. package/dist/workspace/status-gates.d.ts +15 -3
  225. package/dist/workspace/status-gates.d.ts.map +1 -1
  226. package/dist/workspace/status.d.ts +10 -0
  227. package/dist/workspace/status.d.ts.map +1 -1
  228. package/dist/workspace/symbols.d.ts +52 -0
  229. package/dist/workspace/symbols.d.ts.map +1 -0
  230. package/dist/workspace/trailer-joins.d.ts +46 -0
  231. package/dist/workspace/trailer-joins.d.ts.map +1 -0
  232. package/dist/workspace/trailers.d.ts +89 -0
  233. package/dist/workspace/trailers.d.ts.map +1 -0
  234. package/dist/workspace/trust/attestor.d.ts.map +1 -1
  235. package/dist/workspace/trust/rotation.d.ts.map +1 -1
  236. package/dist/workspace/trust/seal.d.ts +33 -0
  237. package/dist/workspace/trust/seal.d.ts.map +1 -1
  238. package/dist/workspace/trust/test-repo.d.ts.map +1 -1
  239. package/dist/workspace/work-cli.d.ts +39 -3
  240. package/dist/workspace/work-cli.d.ts.map +1 -1
  241. package/dist/workspace/work-evidence.d.ts +1 -1
  242. package/dist/workspace/work-evidence.d.ts.map +1 -1
  243. package/dist/workspace/work.d.ts +26 -1
  244. package/dist/workspace/work.d.ts.map +1 -1
  245. package/dist/workspace/workspace-principals.schema.json +60 -0
  246. package/dist/workspace/write-scope.d.ts +79 -19
  247. package/dist/workspace/write-scope.d.ts.map +1 -1
  248. package/dist/yaml.d.ts +21 -39
  249. package/dist/yaml.d.ts.map +1 -1
  250. package/package.json +2 -2
  251. package/src/audit/prior-art.ts +15 -0
  252. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
  253. package/src/cli/commands/carve-emit-state.test.ts +4 -0
  254. package/src/cli/commands/carve-emit.ts +5 -19
  255. package/src/cli/commands/check-lexicon.test.ts +62 -1
  256. package/src/cli/commands/check-lexicon.ts +36 -6
  257. package/src/cli/commands/import-live.test.ts +18 -0
  258. package/src/cli/commands/import-parser-options.test.ts +133 -0
  259. package/src/cli/commands/import.ts +21 -3
  260. package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
  261. package/src/cli/commands/init.test.ts +8 -1
  262. package/src/cli/commands/init.ts +23 -8
  263. package/src/cli/commands/lint.test.ts +37 -0
  264. package/src/cli/commands/onboard.test.ts +53 -3
  265. package/src/cli/commands/onboard.ts +52 -4
  266. package/src/cli/commands/pinned-upgrade.ts +73 -33
  267. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
  268. package/src/cli/handlers/components.ts +2 -2
  269. package/src/cli/handlers/dev.ts +8 -6
  270. package/src/cli/handlers/lifecycle.test.ts +67 -0
  271. package/src/cli/handlers/lifecycle.ts +6 -5
  272. package/src/cli/handlers/misc.ts +2 -0
  273. package/src/cli/handlers/operator.ts +87 -3
  274. package/src/cli/handlers/run.test.ts +111 -0
  275. package/src/cli/handlers/run.ts +85 -24
  276. package/src/cli/handlers/scenario.ts +2 -2
  277. package/src/cli/main.test.ts +1 -0
  278. package/src/cli/main.ts +65 -11
  279. package/src/cli/mcp/workspace-tools.test.ts +5 -2
  280. package/src/cli/mcp/workspace-tools.ts +29 -2
  281. package/src/cli/registry.ts +11 -2
  282. package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
  283. package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
  284. package/src/codegen/pinned-upgrade.test.ts +104 -0
  285. package/src/codegen/pinned-upgrade.ts +250 -56
  286. package/src/codegen/testdata/postgres-tags.json +242 -0
  287. package/src/config.test.ts +21 -0
  288. package/src/config.ts +15 -0
  289. package/src/declarable.test.ts +21 -0
  290. package/src/declarable.ts +19 -0
  291. package/src/discovery/fold-composite.test.ts +41 -5
  292. package/src/discovery/fold-import.test.ts +129 -0
  293. package/src/discovery/fold-import.ts +643 -131
  294. package/src/discovery/fold-package-composite.test.ts +264 -0
  295. package/src/discovery/fold-specifiers.test.ts +191 -0
  296. package/src/discovery/param-deps.test.ts +66 -1
  297. package/src/discovery/param-deps.ts +45 -0
  298. package/src/discovery/specifier-resolve.ts +344 -0
  299. package/src/fold/fold.test.ts +39 -1
  300. package/src/fold/fold.ts +83 -9
  301. package/src/fold-provenance.test.ts +140 -0
  302. package/src/graph-ir.test.ts +83 -0
  303. package/src/graph-ir.ts +29 -0
  304. package/src/import/embedded.test.ts +20 -0
  305. package/src/import/embedded.ts +13 -0
  306. package/src/import/parser-options.ts +46 -0
  307. package/src/import/parser.ts +20 -0
  308. package/src/lexicon.ts +55 -3
  309. package/src/lifecycle/gate-ledger.ts +16 -0
  310. package/src/lifecycle/observe.test.ts +18 -0
  311. package/src/lifecycle/observe.ts +6 -4
  312. package/src/lifecycle/snapshot.ts +2 -2
  313. package/src/lifecycle/work-lease.test.ts +1 -1
  314. package/src/lifecycle/work-lease.ts +93 -2
  315. package/src/lint/engine.test.ts +55 -0
  316. package/src/lint/engine.ts +30 -4
  317. package/src/lint/output-docs.test.ts +59 -56
  318. package/src/op/activities/apply.test.ts +189 -5
  319. package/src/op/activities/apply.ts +230 -8
  320. package/src/op/activities/index.ts +3 -0
  321. package/src/op/activities/lexicon-upgrade.test.ts +160 -6
  322. package/src/op/activities/lexicon-upgrade.ts +154 -51
  323. package/src/op/composites/apply-op.ts +12 -5
  324. package/src/op/composites/composites.test.ts +30 -3
  325. package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
  326. package/src/op/composites/lexicon-upgrade-op.ts +29 -8
  327. package/src/op/emulator-lifecycle.test.ts +23 -0
  328. package/src/op/emulator-lifecycle.ts +52 -14
  329. package/src/op/gate-approval.test.ts +74 -0
  330. package/src/op/gate-approval.ts +5 -1
  331. package/src/op/gate.ts +31 -5
  332. package/src/op/index.ts +2 -0
  333. package/src/op/local-executor.test.ts +15 -0
  334. package/src/op/local-executor.ts +40 -12
  335. package/src/op/local-output.ts +1 -1
  336. package/src/op/operator.ts +4 -0
  337. package/src/op/run-context.test.ts +141 -0
  338. package/src/op/run-context.ts +51 -0
  339. package/src/op/runtimes/local.test.ts +14 -0
  340. package/src/op/runtimes/local.ts +2 -0
  341. package/src/op/steward-beside.ts +2 -0
  342. package/src/op/types.ts +8 -3
  343. package/src/op/work-lease-run.test.ts +47 -0
  344. package/src/op/work-lease-run.ts +73 -11
  345. package/src/provenance.ts +35 -0
  346. package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
  347. package/src/workspace/agent-cli.ts +7 -3
  348. package/src/workspace/agent.schema.json +22 -0
  349. package/src/workspace/box-factory.test.ts +320 -0
  350. package/src/workspace/box-factory.ts +103 -0
  351. package/src/workspace/changes.schema.json +12 -20
  352. package/src/workspace/changes.ts +4 -1
  353. package/src/workspace/checks/boxes.test.ts +2 -0
  354. package/src/workspace/checks.ts +29 -5
  355. package/src/workspace/compose-graph.ts +7 -0
  356. package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +27 -0
  357. package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +95 -0
  358. package/src/workspace/conformance/__writer_fixture__/decisions/points.json +132 -0
  359. package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +48 -0
  360. package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +108 -0
  361. package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  362. package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  363. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +578 -0
  364. package/src/workspace/conformance/conformance.e2e.test.ts +35 -3
  365. package/src/workspace/conformance/index.mjs +30 -3
  366. package/src/workspace/conformance/index.ts +103 -15
  367. package/src/workspace/conformance/vitest.ts +44 -2
  368. package/src/workspace/conformance/writer-conformance.e2e.test.ts +131 -0
  369. package/src/workspace/conformance/writer.test.ts +156 -0
  370. package/src/workspace/conformance/writer.ts +880 -0
  371. package/src/workspace/decide.ts +7 -1
  372. package/src/workspace/declaration.schema.json +234 -5
  373. package/src/workspace/declaration.ts +174 -10
  374. package/src/workspace/graph-cli.ts +5 -2
  375. package/src/workspace/graph.schema.json +247 -0
  376. package/src/workspace/identity.test.ts +196 -0
  377. package/src/workspace/identity.ts +186 -0
  378. package/src/workspace/intent-cli.ts +64 -10
  379. package/src/workspace/intent-record.schema.json +208 -0
  380. package/src/workspace/intent-record.ts +35 -1
  381. package/src/workspace/intent-why.test.ts +274 -0
  382. package/src/workspace/intent.schema.json +718 -7
  383. package/src/workspace/intent.test.ts +11 -2
  384. package/src/workspace/intent.ts +495 -32
  385. package/src/workspace/kinds.ts +44 -37
  386. package/src/workspace/points-write.schema.json +1 -0
  387. package/src/workspace/principal-classes.test.ts +175 -0
  388. package/src/workspace/principal-classes.ts +307 -0
  389. package/src/workspace/reason-codes.test.ts +11 -3
  390. package/src/workspace/reason-codes.ts +24 -1
  391. package/src/workspace/records-amend.schema.json +2 -0
  392. package/src/workspace/records-checkout.ts +106 -0
  393. package/src/workspace/records-cli.ts +103 -11
  394. package/src/workspace/records-close.schema.json +1 -0
  395. package/src/workspace/records-new.schema.json +2 -0
  396. package/src/workspace/records-review.schema.json +2 -0
  397. package/src/workspace/records-uncommitted.test.ts +171 -0
  398. package/src/workspace/records-write.ts +28 -6
  399. package/src/workspace/records.schema.json +72 -1
  400. package/src/workspace/records.ts +27 -0
  401. package/src/workspace/runs-cli.ts +381 -0
  402. package/src/workspace/runs-write.schema.json +583 -0
  403. package/src/workspace/runs.schema.json +810 -0
  404. package/src/workspace/runs.test.ts +242 -0
  405. package/src/workspace/runs.ts +709 -0
  406. package/src/workspace/status-contract.test.ts +5 -0
  407. package/src/workspace/status-gates.ts +22 -8
  408. package/src/workspace/status.schema.json +127 -2
  409. package/src/workspace/status.ts +21 -1
  410. package/src/workspace/symbols.ts +180 -0
  411. package/src/workspace/trailer-joins.test.ts +171 -0
  412. package/src/workspace/trailer-joins.ts +82 -0
  413. package/src/workspace/trailers.ts +148 -0
  414. package/src/workspace/trust/seal.ts +52 -1
  415. package/src/workspace/work-cli.e2e.test.ts +28 -1
  416. package/src/workspace/work-cli.ts +133 -8
  417. package/src/workspace/work-evidence.schema.json +2 -0
  418. package/src/workspace/work-history.schema.json +73 -1
  419. package/src/workspace/work-history.test.ts +48 -5
  420. package/src/workspace/work-kind-fields.test.ts +154 -0
  421. package/src/workspace/work-lease.schema.json +14 -1
  422. package/src/workspace/work.ts +82 -0
  423. package/src/workspace/workspace-principals.schema.json +60 -0
  424. package/src/workspace/write-scope.test.ts +128 -2
  425. package/src/workspace/write-scope.ts +170 -45
  426. package/src/yaml.test.ts +111 -1
  427. package/src/yaml.ts +141 -549
@@ -17,6 +17,9 @@
17
17
  * - `implements`: each decision it names, with that decision's state;
18
18
  * - `acceptance`, for a kind with acceptance criteria (#2772): how many of the
19
19
  * record's criteria passing evidence of the expected verification meets;
20
+ * - `contract`, for a kind with a contract link (#3147): the contract record
21
+ * the item builds, with its state, read from the contract kind at the same
22
+ * revision;
20
23
  *
21
24
  * and each decision `implementedBy`, the work records naming it. The
22
25
  * warnings are closed codes. `work-done-gap-open` is not raised here: it
@@ -48,6 +51,12 @@ export const WORK_WARNING_CODES = [
48
51
  "work-acceptance-unmet",
49
52
  /** A passing `manual` verdict on a criterion names the record's implementer, so it does not count: a manual verdict comes from someone else (#2772). */
50
53
  "work-acceptance-self-verified",
54
+ /** The record names a contract no record of the kind's contract kind has (#3147). */
55
+ "work-contract-unknown",
56
+ /** The record names a contract whose state is not approved, such as a draft (#3147). */
57
+ "work-contract-undecided",
58
+ /** The record names a builder tier its kind's `work.tier.tiers` does not list (#3147). */
59
+ "work-tier-unknown",
51
60
  ] as const satisfies readonly ReasonCode[];
52
61
  export type WorkWarningCode = (typeof WORK_WARNING_CODES)[number];
53
62
 
@@ -58,6 +67,49 @@ export interface WorkLink {
58
67
  state: string | null;
59
68
  }
60
69
 
70
+ /**
71
+ * One decision-point answer about a work item (#3147), as `records --json`
72
+ * joins it from the answer kind the work kind names: the answer records whose
73
+ * `constrains` names the item's id. The item never copies them.
74
+ */
75
+ export interface WorkAnswer {
76
+ /** The answer record's id, such as understand-0123456789ab. */
77
+ id: string;
78
+ /** The decision point it answers. */
79
+ point: string | null;
80
+ /** escalated, proposed or answered. */
81
+ state: string | null;
82
+ /** The answer, or null while there is none. */
83
+ answer: string | boolean | null;
84
+ /** The people who answered or confirmed it, empty when a table or model did. */
85
+ answeredBy: string[];
86
+ }
87
+
88
+ /**
89
+ * The answers about each work item: every answer record whose `constrains`
90
+ * names the item's id, in path order, by item id.
91
+ */
92
+ export function workAnswers(answerRecords: readonly RecordEntry[], ids: Iterable<string>): Map<string, WorkAnswer[]> {
93
+ const out = new Map<string, WorkAnswer[]>();
94
+ for (const id of ids) out.set(id, []);
95
+ for (const a of answerRecords) {
96
+ if (a.id === null || a.data === null) continue;
97
+ for (const target of idList(a.data, "constrains")) {
98
+ const list = out.get(target);
99
+ if (!list || list.some((x) => x.id === a.id)) continue;
100
+ const answer = a.data.answer;
101
+ list.push({
102
+ id: a.id,
103
+ point: typeof a.data.point === "string" ? a.data.point : null,
104
+ state: a.state,
105
+ answer: typeof answer === "string" || typeof answer === "boolean" ? answer : null,
106
+ answeredBy: idList(a.data, "answered_by"),
107
+ });
108
+ }
109
+ }
110
+ return out;
111
+ }
112
+
61
113
  /** A decision as a work read lists it: its state and the work records implementing it. */
62
114
  export interface DecisionWork {
63
115
  id: string;
@@ -174,6 +226,16 @@ export async function applyWork(loaded: LoadedRecordKind, entries: RecordEntry[]
174
226
  for (const e of entries) if (e.id !== null && !byId.has(e.id)) byId.set(e.id, e);
175
227
  const closed = new Set(kind.closedStates);
176
228
 
229
+ // The contract kind a work item names its contract in (#3147), read at the same revision.
230
+ let contracts: { kind: LoadedRecordKind; byId: Map<string, RecordEntry> } | undefined;
231
+ if (work.contract) {
232
+ const contractKind = await loadRecordKind(work.contract.kind, dirname(loaded.file));
233
+ const contractRead = await readRecords(contractKind, { root: options.root, source: options.source });
234
+ const contractById = new Map<string, RecordEntry>();
235
+ for (const c of contractRead.records) if (c.id !== null && !contractById.has(c.id)) contractById.set(c.id, c);
236
+ contracts = { kind: contractKind, byId: contractById };
237
+ }
238
+
177
239
  // Records in a needs cycle: those that reach themselves.
178
240
  const inCycle = new Set<string>();
179
241
  for (const start of byId.keys()) {
@@ -242,6 +304,26 @@ export async function applyWork(loaded: LoadedRecordKind, entries: RecordEntry[]
242
304
  });
243
305
  }
244
306
  }
307
+ if (contracts && work.contract) {
308
+ const named = e.data[work.contract.field];
309
+ if (typeof named === "string" && named !== "") {
310
+ const c = contracts.byId.get(named);
311
+ e.contract = { id: named, state: c?.state ?? null };
312
+ if (!c) {
313
+ e.warnings.push({ code: "work-contract-unknown", message: `names the contract ${named}, which no record in ${work.contract.kind} has` });
314
+ } else if (!isDecided(contracts.kind.kind, c.state)) {
315
+ e.warnings.push({ code: "work-contract-undecided", message: `names the contract ${named}, which is ${c.state ?? "in no state"}: the work may build a contract nobody approved` });
316
+ }
317
+ } else {
318
+ e.contract = null;
319
+ }
320
+ }
321
+ if (work.tier) {
322
+ const tier = e.data[work.tier.field];
323
+ if (typeof tier === "string" && !work.tier.tiers.includes(tier)) {
324
+ e.warnings.push({ code: "work-tier-unknown", message: `names the builder tier ${tier}, which the kind's tiers (${work.tier.tiers.join(", ")}) do not list` });
325
+ }
326
+ }
245
327
  if (e.state !== null && closed.has(e.state) && typeof e.data[work.closedOn] !== "string") {
246
328
  e.warnings.push({ code: "work-closed-without-date", message: `${e.id ?? e.path} is ${e.state} and has no ${work.closedOn}` });
247
329
  }
@@ -0,0 +1,60 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://intentius.io/chant/schemas/workspace/principals/v1/workspace-principals.schema.json",
4
+ "title": "workspace-principals.json",
5
+ "description": "Principal classes a plugin supplies (#2524 D5, #3080, ws-079). A package publishes this file as data at its ./workspace-principals subpath, beside ./workspace-kinds. chant reads it with the file system and never imports the package. A class is a name for the principals holding one role in the trust policy at base; the declaration's writeScope may then give it an entry.",
6
+ "type": "object",
7
+ "required": ["schema", "classes"],
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string",
11
+ "description": "An editor hint. chant ignores it."
12
+ },
13
+ "$comment": {
14
+ "type": "string",
15
+ "description": "A note for people. chant ignores it."
16
+ },
17
+ "schema": {
18
+ "const": 1,
19
+ "description": "The principal classes format version."
20
+ },
21
+ "classes": {
22
+ "type": "array",
23
+ "minItems": 1,
24
+ "items": {
25
+ "$ref": "#/$defs/class"
26
+ }
27
+ }
28
+ },
29
+ "patternProperties": {
30
+ "^x-": true
31
+ },
32
+ "additionalProperties": false,
33
+ "$defs": {
34
+ "class": {
35
+ "type": "object",
36
+ "required": ["name", "description", "role"],
37
+ "properties": {
38
+ "name": {
39
+ "type": "string",
40
+ "pattern": "^(?!x-)[a-z][a-z0-9-]{0,39}$",
41
+ "description": "The class's name, as a key of the declaration's writeScope names it. human, agent, runner and service are the core classes and can't be supplied."
42
+ },
43
+ "description": {
44
+ "type": "string",
45
+ "minLength": 1,
46
+ "description": "One line saying who is in the class, for listings and error messages."
47
+ },
48
+ "role": {
49
+ "type": "string",
50
+ "pattern": "^[a-z][a-z0-9-]*$",
51
+ "description": "The role whose grant in the trust policy at base (.chant/trust.json roles) puts a principal in this class. The agent, runner and service roles belong to the core classes and can't be named here. One role puts a principal in one class."
52
+ }
53
+ },
54
+ "patternProperties": {
55
+ "^x-": true
56
+ },
57
+ "additionalProperties": false
58
+ }
59
+ }
60
+ }
@@ -21,6 +21,7 @@ import { cleanScratch, contract, git, REPO, repo, writeFiles } from "./__fixture
21
21
  import { agentSession } from "./agent-cli";
22
22
  import agentSchema from "./agent.schema.json";
23
23
  import { checkChanges, type ChangesDocument } from "./changes";
24
+ import { runDeclarationChecks } from "./checks";
24
25
  import changesSchema from "./changes.schema.json";
25
26
  import { formatChanges } from "./changes-cli";
26
27
  import { parseDeclaration, WorkspaceReadError } from "./declaration";
@@ -109,8 +110,8 @@ describe("the declaration's writeScope and agents (#2548)", () => {
109
110
  test("are read with their defaults", () => {
110
111
  const d = parseDeclaration(declaration(), "chant.workspace.json");
111
112
  expect(d.writeScope).toEqual({
112
- agent: { members: null, records: { decision: ["new", "review"] }, pointer: "/writeScope/agent" },
113
- runner: { members: ["app"], records: { decision: ["review"] }, pointer: "/writeScope/runner" },
113
+ agent: { members: null, records: { decision: ["new", "review"] }, protected: [], pointer: "/writeScope/agent" },
114
+ runner: { members: ["app"], records: { decision: ["review"] }, protected: [], pointer: "/writeScope/runner" },
114
115
  });
115
116
  expect(d.agents.map((a) => [a.name, a.member, a.principals])).toEqual([
116
117
  ["app-agent", "app", ["bot@example.com"]],
@@ -326,6 +327,7 @@ describe("chant workspace agent: what a session reloads from (#2548)", () => {
326
327
  { path: KIND, kind: "decision", name: null, member: null, verbs: ["new", "review"] },
327
328
  { path: DESIGN_KIND, kind: "decision", name: "screen", member: "design", verbs: ["new", "review"] },
328
329
  ],
330
+ protected: [],
329
331
  });
330
332
  expect(doc.spec.kinds.map((k) => k.path)).toEqual([KIND, DESIGN_KIND]);
331
333
  expect(doc.spec.records.map((r) => `${r.kind}/${r.id}`)).toContain("decision/ws-001");
@@ -338,3 +340,127 @@ describe("chant workspace agent: what a session reloads from (#2548)", () => {
338
340
  expect(code(doc)).toBe("agent-unknown");
339
341
  });
340
342
  });
343
+
344
+ describe("principal classes a plugin defines (#3080)", () => {
345
+ const PLUGIN = "plugins/review";
346
+ const PRINCIPALS = JSON.stringify({ schema: 1, classes: [{ name: "reviewer", description: "people who review decisions", role: "reviewer" }] });
347
+ const REVIEWER_SCOPE = { reviewer: { members: ["design"], records: { decision: ["review"] } } };
348
+ let dom: string;
349
+ const at: Record<string, string> = {};
350
+
351
+ function domainDeclaration(scope: unknown): string {
352
+ return JSON.stringify({ ...JSON.parse(declaration(scope, [])), pins: [{ path: PLUGIN }] }, null, 2);
353
+ }
354
+ function commitIn(message: string, email?: string): string {
355
+ git(dom, "add", "-A");
356
+ git(dom, ...(email ? ["-c", `user.email=${email}`] : []), "commit", "-q", "-m", message);
357
+ return git(dom, "rev-parse", "HEAD");
358
+ }
359
+
360
+ beforeAll(() => {
361
+ const kind = readFileSync(join(DECISIONS, "decision.kind.mjs"), "utf-8");
362
+ const schema = readFileSync(join(DECISIONS, "decision.schema.json"), "utf-8");
363
+ dom = repo({
364
+ "chant.workspace.json": domainDeclaration(REVIEWER_SCOPE),
365
+ ".chant/trust.json": JSON.stringify({ schema: 1, roles: { reviewer: ["rev@example.com"] } }),
366
+ [`${PLUGIN}/package.json`]: JSON.stringify({ name: "review-classes", version: "1.0.0", exports: { "./workspace-principals": "./workspace-principals.json" } }),
367
+ [`${PLUGIN}/workspace-principals.json`]: PRINCIPALS,
368
+ [KIND]: kind,
369
+ "decisions/decision.schema.json": schema,
370
+ "decisions/ws-001-one.md": record(decided({ id: "ws-001", title: "One" })),
371
+ [DESIGN_KIND]: kind,
372
+ "design/decisions/decision.schema.json": schema,
373
+ "design/decisions/ws-001-screen.md": record(decided({ id: "ws-001", title: "Screen" })),
374
+ "app/server.mjs": "export const port = 8080;\n",
375
+ "design/spec.md": "# Spec\n",
376
+ });
377
+ at.base = commitIn("the workspace");
378
+ git(dom, "branch", "-M", "main");
379
+ });
380
+
381
+ test("writeScope takes a domain class's name as a key, in file order", () => {
382
+ const d = parseDeclaration(domainDeclaration({ reviewer: { records: { decision: ["review"] } }, human: {} }), "chant.workspace.json");
383
+ expect(Object.keys(d.writeScope!)).toEqual(["reviewer", "human"]);
384
+ expect(() => parseDeclaration(domainDeclaration({ "x-reviewer": {} }), "chant.workspace.json")).toThrow(WorkspaceReadError);
385
+ expect(() => parseDeclaration(domainDeclaration({ Reviewer: {} }), "chant.workspace.json")).toThrow(WorkspaceReadError);
386
+ });
387
+
388
+ test("a principal holding the class's role at base is held to its entry; anyone else is a human", async () => {
389
+ expect(code(await reviewRecord({ kind: KIND, id: "ws-001", verdict: "agree", by: "rev@example.com", cwd: dom, dryRun: true }))).toBeNull();
390
+ const proposed = await newRecord({ kind: KIND, fields: newDecision("Logs"), by: "rev@example.com", cwd: dom, dryRun: true });
391
+ expect(proposed).toMatchObject({ error: { code: "write-scope-kind", message: expect.stringContaining("rev@example.com (reviewer) may review decision records, and not new") } });
392
+ expect(code(await newRecord({ kind: KIND, fields: newDecision("Logs"), by: "lex00", cwd: dom, dryRun: true }))).toBeNull();
393
+ });
394
+
395
+ test("a path-pinned plugin's classes are read at base: remapping the class in the working tree changes nothing", async () => {
396
+ writeFiles(dom, { [`${PLUGIN}/workspace-principals.json`]: JSON.stringify({ schema: 1, classes: [{ name: "reviewer", description: "d", role: "nobody" }] }) });
397
+ try {
398
+ expect(code(await newRecord({ kind: KIND, fields: newDecision("Logs"), by: "rev@example.com", cwd: dom, dryRun: true }))).toBe("write-scope-kind");
399
+ } finally {
400
+ writeFiles(dom, { [`${PLUGIN}/workspace-principals.json`]: PRINCIPALS });
401
+ }
402
+ });
403
+
404
+ test("check --changes judges a commit by its author's domain class", async () => {
405
+ git(dom, "checkout", "-q", "-b", "work");
406
+ writeFiles(dom, { "app/server.mjs": "export const port = 9090;\n" });
407
+ at.outside = commitIn("app: a port", "rev@example.com");
408
+ writeFiles(dom, { "design/spec.md": "# Spec, reviewed\n" });
409
+ at.inside = commitIn("design: a note", "rev@example.com");
410
+ const { doc } = (await checkChanges({ cwd: dom, range: "main..work" })) as { doc: Exclude<ChangesDocument, { error: unknown }> };
411
+ contract(changesSchema).expectValid(doc);
412
+ expect(doc.scope).toMatchObject({ restricted: ["reviewer"] });
413
+ expect(doc.scope!.commits.map((c) => [c.commit, c.class])).toEqual([
414
+ [at.outside, "reviewer"],
415
+ [at.inside, "reviewer"],
416
+ ]);
417
+ expect(doc.scope!.findings.map((f) => [f.commit, f.code, f.path, f.class])).toEqual([[at.outside, "write-scope-member", "app/server.mjs", "reviewer"]]);
418
+ git(dom, "checkout", "-q", "main");
419
+ });
420
+
421
+ describe("a class no pinned package supplies fails closed", () => {
422
+ beforeAll(() => {
423
+ writeFiles(dom, { "chant.workspace.json": domainDeclaration({ ...REVIEWER_SCOPE, auditor: { members: ["design"] } }) });
424
+ at.unknown = commitIn("an auditor class no plugin supplies");
425
+ });
426
+
427
+ test("a writer judged human is refused; one in a known class is judged by it", async () => {
428
+ const refused = await newRecord({ kind: KIND, fields: newDecision("Logs"), by: "lex00", cwd: dom, dryRun: true });
429
+ expect(refused).toMatchObject({ error: { code: "write-scope-class-unknown", message: expect.stringContaining("writeScope.auditor") } });
430
+ expect(code(await newRecord({ kind: KIND, fields: newDecision("Logs"), cwd: dom, dryRun: true }))).toBe("write-scope-class-unknown");
431
+ expect(code(await reviewRecord({ kind: KIND, id: "ws-001", verdict: "agree", by: "rev@example.com", cwd: dom, dryRun: true }))).toBeNull();
432
+ });
433
+
434
+ test("check --changes reports the human's commit as a whole", async () => {
435
+ git(dom, "checkout", "-q", "-b", "audit");
436
+ writeFiles(dom, { "design/spec.md": "# Spec, by a person\n" });
437
+ const human = commitIn("a person's edit");
438
+ const { doc } = (await checkChanges({ cwd: dom, range: "main..audit" })) as { doc: Exclude<ChangesDocument, { error: unknown }> };
439
+ contract(changesSchema).expectValid(doc);
440
+ expect(doc.scope).toMatchObject({ restricted: ["reviewer", "auditor"] });
441
+ expect(doc.scope!.findings.map((f) => [f.id, f.path, f.class])).toEqual([[`finding:write-scope-class-unknown:${human}`, null, "human"]]);
442
+ git(dom, "checkout", "-q", "main");
443
+ });
444
+
445
+ test("workspace check reports the unknown class with WSP003", async () => {
446
+ const report = await runDeclarationChecks(dom, undefined, { gather: false });
447
+ const found = report.diagnostics.filter((d) => d.ruleId === "WSP003");
448
+ expect(found).toHaveLength(1);
449
+ expect(found[0].message).toMatch(/writeScope names the principal class auditor, which no core class or pinned package supplies/);
450
+ expect(found[0].message).toMatch(/known classes: human, agent, runner, service, reviewer/);
451
+ });
452
+ });
453
+
454
+ test("workspace check reports an unreadable principals file with WSP002", async () => {
455
+ const root = repo({
456
+ "chant.workspace.json": domainDeclaration(REVIEWER_SCOPE),
457
+ [`${PLUGIN}/package.json`]: JSON.stringify({ exports: { "./workspace-principals": "./workspace-principals.json" } }),
458
+ [`${PLUGIN}/workspace-principals.json`]: JSON.stringify({ schema: 1, classes: [{ name: "human", description: "d", role: "people" }] }),
459
+ "app/server.mjs": "",
460
+ "design/spec.md": "",
461
+ });
462
+ const report = await runDeclarationChecks(root, undefined, { gather: false });
463
+ expect(report.diagnostics.filter((d) => d.ruleId === "WSP002").map((d) => d.message)).toEqual([`${PLUGIN}: class human is a core class and can't be supplied by a package`]);
464
+ expect(report.diagnostics.filter((d) => d.ruleId === "WSP003").map((d) => d.message)).toEqual([expect.stringContaining("principal class reviewer")]);
465
+ });
466
+ });