@intentius/chant 0.102.0 → 0.104.1

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 (471) hide show
  1. package/dist/audit/core.d.ts +2 -0
  2. package/dist/audit/core.d.ts.map +1 -1
  3. package/dist/audit/discover.d.ts.map +1 -1
  4. package/dist/change-set.d.ts +232 -0
  5. package/dist/change-set.d.ts.map +1 -0
  6. package/dist/cli/commands/audit.d.ts +7 -0
  7. package/dist/cli/commands/audit.d.ts.map +1 -1
  8. package/dist/cli/commands/build.d.ts.map +1 -1
  9. package/dist/cli/handlers/build.d.ts.map +1 -1
  10. package/dist/cli/handlers/change-set.d.ts +11 -0
  11. package/dist/cli/handlers/change-set.d.ts.map +1 -0
  12. package/dist/cli/handlers/fan-out.d.ts +33 -0
  13. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  14. package/dist/cli/handlers/operator.d.ts +7 -0
  15. package/dist/cli/handlers/operator.d.ts.map +1 -1
  16. package/dist/cli/handlers/pr.d.ts +31 -0
  17. package/dist/cli/handlers/pr.d.ts.map +1 -0
  18. package/dist/cli/handlers/run.d.ts.map +1 -1
  19. package/dist/cli/main.d.ts.map +1 -1
  20. package/dist/cli/mcp/op-tools.d.ts.map +1 -1
  21. package/dist/cli/mcp/workspace-tools.d.ts +3 -2
  22. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  23. package/dist/cli/registry.d.ts +63 -1
  24. package/dist/cli/registry.d.ts.map +1 -1
  25. package/dist/components/auto-release.d.ts +16 -0
  26. package/dist/components/auto-release.d.ts.map +1 -1
  27. package/dist/components/capability.d.ts +53 -0
  28. package/dist/components/capability.d.ts.map +1 -1
  29. package/dist/components/changed-files.d.ts +31 -0
  30. package/dist/components/changed-files.d.ts.map +1 -0
  31. package/dist/components/cli-support.d.ts +9 -1
  32. package/dist/components/cli-support.d.ts.map +1 -1
  33. package/dist/components/component.d.ts +24 -0
  34. package/dist/components/component.d.ts.map +1 -1
  35. package/dist/components/deploy-units.d.ts.map +1 -1
  36. package/dist/components/driver.d.ts +13 -0
  37. package/dist/components/driver.d.ts.map +1 -1
  38. package/dist/components/fan-out-output.d.ts +6 -0
  39. package/dist/components/fan-out-output.d.ts.map +1 -1
  40. package/dist/components/fan-out-record.d.ts +41 -0
  41. package/dist/components/fan-out-record.d.ts.map +1 -0
  42. package/dist/components/fan-out-run.d.ts +65 -0
  43. package/dist/components/fan-out-run.d.ts.map +1 -1
  44. package/dist/components/fan-out-support.d.ts +2 -0
  45. package/dist/components/fan-out-support.d.ts.map +1 -1
  46. package/dist/components/fan-out.d.ts +6 -0
  47. package/dist/components/fan-out.d.ts.map +1 -1
  48. package/dist/components/gated-wave-pipeline.d.ts +50 -0
  49. package/dist/components/gated-wave-pipeline.d.ts.map +1 -0
  50. package/dist/components/index.d.ts +1 -1
  51. package/dist/components/index.d.ts.map +1 -1
  52. package/dist/components/layers.d.ts +25 -0
  53. package/dist/components/layers.d.ts.map +1 -0
  54. package/dist/components/pr-pipeline.d.ts +61 -0
  55. package/dist/components/pr-pipeline.d.ts.map +1 -0
  56. package/dist/components/pr-run.d.ts +119 -0
  57. package/dist/components/pr-run.d.ts.map +1 -0
  58. package/dist/components/promote.d.ts.map +1 -1
  59. package/dist/components/verbs/shell.d.ts.map +1 -1
  60. package/dist/components/wave-plan.d.ts +49 -0
  61. package/dist/components/wave-plan.d.ts.map +1 -0
  62. package/dist/gated-waves.d.ts +147 -0
  63. package/dist/gated-waves.d.ts.map +1 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/lexicon.d.ts +48 -0
  67. package/dist/lexicon.d.ts.map +1 -1
  68. package/dist/lifecycle/gate-ledger.d.ts +7 -0
  69. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  70. package/dist/lifecycle/git.d.ts +46 -1
  71. package/dist/lifecycle/git.d.ts.map +1 -1
  72. package/dist/lint/post-synth.d.ts +18 -0
  73. package/dist/lint/post-synth.d.ts.map +1 -1
  74. package/dist/op/activities/activity-contracts.d.ts +126 -0
  75. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  76. package/dist/op/activities/change-set.d.ts +62 -0
  77. package/dist/op/activities/change-set.d.ts.map +1 -0
  78. package/dist/op/activities/decide.d.ts +2 -0
  79. package/dist/op/activities/decide.d.ts.map +1 -1
  80. package/dist/op/activities/factory.d.ts +137 -0
  81. package/dist/op/activities/factory.d.ts.map +1 -0
  82. package/dist/op/activities/index.d.ts +4 -0
  83. package/dist/op/activities/index.d.ts.map +1 -1
  84. package/dist/op/activity-contract.d.ts.map +1 -1
  85. package/dist/op/builders.d.ts +11 -0
  86. package/dist/op/builders.d.ts.map +1 -1
  87. package/dist/op/decide-backend.d.ts +5 -1
  88. package/dist/op/decide-backend.d.ts.map +1 -1
  89. package/dist/op/decide-read-inputs.d.ts +4 -2
  90. package/dist/op/decide-read-inputs.d.ts.map +1 -1
  91. package/dist/op/factory.d.ts +83 -0
  92. package/dist/op/factory.d.ts.map +1 -0
  93. package/dist/op/index.d.ts +4 -1
  94. package/dist/op/index.d.ts.map +1 -1
  95. package/dist/op/op-ir.d.ts +2 -0
  96. package/dist/op/op-ir.d.ts.map +1 -1
  97. package/dist/op/op-verb-class.d.ts.map +1 -1
  98. package/dist/op/types.d.ts +8 -0
  99. package/dist/op/types.d.ts.map +1 -1
  100. package/dist/op/work-lease-run.d.ts.map +1 -1
  101. package/dist/plan-summary.d.ts +207 -0
  102. package/dist/plan-summary.d.ts.map +1 -0
  103. package/dist/pr-forge.d.ts +105 -0
  104. package/dist/pr-forge.d.ts.map +1 -0
  105. package/dist/pr-loop.d.ts +178 -0
  106. package/dist/pr-loop.d.ts.map +1 -0
  107. package/dist/telemetry-attribution.d.ts +31 -0
  108. package/dist/telemetry-attribution.d.ts.map +1 -1
  109. package/dist/terraform/hcl2json.d.ts +45 -0
  110. package/dist/terraform/hcl2json.d.ts.map +1 -0
  111. package/dist/terraform/parse.d.ts +4 -40
  112. package/dist/terraform/parse.d.ts.map +1 -1
  113. package/dist/vendor/js-yaml-load.d.ts +56 -0
  114. package/dist/vendor/js-yaml-load.d.ts.map +1 -0
  115. package/dist/workspace/box-cli.d.ts +12 -0
  116. package/dist/workspace/box-cli.d.ts.map +1 -0
  117. package/dist/workspace/box-factory.d.ts +27 -3
  118. package/dist/workspace/box-factory.d.ts.map +1 -1
  119. package/dist/workspace/box-listing.d.ts +85 -0
  120. package/dist/workspace/box-listing.d.ts.map +1 -0
  121. package/dist/workspace/box-publish.d.ts +147 -0
  122. package/dist/workspace/box-publish.d.ts.map +1 -0
  123. package/dist/workspace/broker-protocol.d.ts +190 -0
  124. package/dist/workspace/broker-protocol.d.ts.map +1 -0
  125. package/dist/workspace/checks.d.ts.map +1 -1
  126. package/dist/workspace/composites.d.ts +2 -2
  127. package/dist/workspace/composites.d.ts.map +1 -1
  128. package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
  129. package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
  130. package/dist/workspace/conformance/broker.d.ts +202 -0
  131. package/dist/workspace/conformance/broker.d.ts.map +1 -0
  132. package/dist/workspace/conformance/index.d.ts +2 -1
  133. package/dist/workspace/conformance/index.d.ts.map +1 -1
  134. package/dist/workspace/conformance/vitest.d.ts +9 -2
  135. package/dist/workspace/conformance/vitest.d.ts.map +1 -1
  136. package/dist/workspace/conformance/writer.d.ts +108 -14
  137. package/dist/workspace/conformance/writer.d.ts.map +1 -1
  138. package/dist/workspace/decide.d.ts +126 -12
  139. package/dist/workspace/decide.d.ts.map +1 -1
  140. package/dist/workspace/decision-points.schema.json +11 -4
  141. package/dist/workspace/declaration.d.ts +65 -0
  142. package/dist/workspace/declaration.d.ts.map +1 -1
  143. package/dist/workspace/declaration.schema.json +153 -4
  144. package/dist/workspace/environments.d.ts +36 -10
  145. package/dist/workspace/environments.d.ts.map +1 -1
  146. package/dist/workspace/factory-rules.d.ts +180 -0
  147. package/dist/workspace/factory-rules.d.ts.map +1 -0
  148. package/dist/workspace/init.d.ts +21 -0
  149. package/dist/workspace/init.d.ts.map +1 -1
  150. package/dist/workspace/intent-cli.d.ts +1 -1
  151. package/dist/workspace/intent-cli.d.ts.map +1 -1
  152. package/dist/workspace/intent-record.d.ts +28 -1
  153. package/dist/workspace/intent-record.d.ts.map +1 -1
  154. package/dist/workspace/intent.d.ts +102 -5
  155. package/dist/workspace/intent.d.ts.map +1 -1
  156. package/dist/workspace/json-edit.d.ts +24 -0
  157. package/dist/workspace/json-edit.d.ts.map +1 -0
  158. package/dist/workspace/jsonc.d.ts +11 -0
  159. package/dist/workspace/jsonc.d.ts.map +1 -1
  160. package/dist/workspace/kinds.d.ts +48 -0
  161. package/dist/workspace/kinds.d.ts.map +1 -1
  162. package/dist/workspace/lexicon-symbols.d.ts +29 -0
  163. package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
  164. package/dist/workspace/lineage-upgrade.d.ts +31 -2
  165. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  166. package/dist/workspace/point-answer.schema.json +42 -2
  167. package/dist/workspace/points-cli.d.ts +10 -3
  168. package/dist/workspace/points-cli.d.ts.map +1 -1
  169. package/dist/workspace/points.d.ts +66 -5
  170. package/dist/workspace/points.d.ts.map +1 -1
  171. package/dist/workspace/reason-codes.d.ts +33 -4
  172. package/dist/workspace/reason-codes.d.ts.map +1 -1
  173. package/dist/workspace/record-sessions.d.ts +5 -7
  174. package/dist/workspace/record-sessions.d.ts.map +1 -1
  175. package/dist/workspace/records-cli.d.ts +7 -0
  176. package/dist/workspace/records-cli.d.ts.map +1 -1
  177. package/dist/workspace/records-close.d.ts +7 -3
  178. package/dist/workspace/records-close.d.ts.map +1 -1
  179. package/dist/workspace/records-write.d.ts +66 -6
  180. package/dist/workspace/records-write.d.ts.map +1 -1
  181. package/dist/workspace/records.d.ts +28 -9
  182. package/dist/workspace/records.d.ts.map +1 -1
  183. package/dist/workspace/runs-cli.d.ts +138 -6
  184. package/dist/workspace/runs-cli.d.ts.map +1 -1
  185. package/dist/workspace/runs.d.ts +132 -11
  186. package/dist/workspace/runs.d.ts.map +1 -1
  187. package/dist/workspace/session-kinds.d.ts +1 -1
  188. package/dist/workspace/session-kinds.d.ts.map +1 -1
  189. package/dist/workspace/squash.d.ts +80 -0
  190. package/dist/workspace/squash.d.ts.map +1 -0
  191. package/dist/workspace/status-gates.d.ts +2 -0
  192. package/dist/workspace/status-gates.d.ts.map +1 -1
  193. package/dist/workspace/status.d.ts +54 -0
  194. package/dist/workspace/status.d.ts.map +1 -1
  195. package/dist/workspace/symbols.d.ts +16 -5
  196. package/dist/workspace/symbols.d.ts.map +1 -1
  197. package/dist/workspace/trust/run-commits.d.ts +46 -0
  198. package/dist/workspace/trust/run-commits.d.ts.map +1 -0
  199. package/dist/workspace/trust/run-statement.d.ts +128 -0
  200. package/dist/workspace/trust/run-statement.d.ts.map +1 -0
  201. package/dist/workspace/trust/seal.d.ts +6 -1
  202. package/dist/workspace/trust/seal.d.ts.map +1 -1
  203. package/dist/workspace/trust/verify-cli.d.ts +1 -1
  204. package/dist/workspace/trust/verify.d.ts +16 -2
  205. package/dist/workspace/trust/verify.d.ts.map +1 -1
  206. package/dist/workspace/wip-cli.d.ts +21 -0
  207. package/dist/workspace/wip-cli.d.ts.map +1 -0
  208. package/dist/workspace/wip.d.ts +268 -0
  209. package/dist/workspace/wip.d.ts.map +1 -0
  210. package/dist/workspace/work-cli.d.ts.map +1 -1
  211. package/dist/workspace/work-evidence.d.ts +1 -1
  212. package/dist/workspace/work-evidence.d.ts.map +1 -1
  213. package/dist/workspace/work-size.d.ts +55 -0
  214. package/dist/workspace/work-size.d.ts.map +1 -0
  215. package/dist/workspace/workspace-kinds.schema.json +122 -0
  216. package/dist/workspace/write-lock-cli.d.ts +60 -0
  217. package/dist/workspace/write-lock-cli.d.ts.map +1 -0
  218. package/dist/workspace/write-lock.d.ts +152 -0
  219. package/dist/workspace/write-lock.d.ts.map +1 -0
  220. package/dist/workspace/write-scope.d.ts +6 -2
  221. package/dist/workspace/write-scope.d.ts.map +1 -1
  222. package/dist/yaml.d.ts +1 -1
  223. package/dist/yaml.d.ts.map +1 -1
  224. package/package.json +6 -1
  225. package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
  226. package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
  227. package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
  228. package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
  229. package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
  230. package/src/__fixtures__/change-set/warden.plan.json +44 -0
  231. package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
  232. package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
  233. package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
  234. package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
  235. package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
  236. package/src/audit/core.test.ts +15 -0
  237. package/src/audit/core.ts +8 -2
  238. package/src/audit/discover.test.ts +11 -0
  239. package/src/audit/discover.ts +7 -2
  240. package/src/change-set-bundle.test.ts +57 -0
  241. package/src/change-set.test.ts +215 -0
  242. package/src/change-set.ts +445 -0
  243. package/src/cli/commands/audit-opt-in.test.ts +54 -0
  244. package/src/cli/commands/audit.ts +29 -2
  245. package/src/cli/commands/build.test.ts +19 -0
  246. package/src/cli/commands/build.ts +3 -2
  247. package/src/cli/handlers/build.ts +13 -1
  248. package/src/cli/handlers/change-set.test.ts +56 -0
  249. package/src/cli/handlers/change-set.ts +44 -0
  250. package/src/cli/handlers/fan-out.test.ts +221 -2
  251. package/src/cli/handlers/fan-out.ts +165 -75
  252. package/src/cli/handlers/graph.ts +3 -0
  253. package/src/cli/handlers/operator.test.ts +21 -0
  254. package/src/cli/handlers/operator.ts +34 -3
  255. package/src/cli/handlers/pr.ts +373 -0
  256. package/src/cli/handlers/run.ts +1 -0
  257. package/src/cli/main.test.ts +20 -0
  258. package/src/cli/main.ts +185 -23
  259. package/src/cli/mcp/never-over-mcp.test.ts +101 -0
  260. package/src/cli/mcp/op-tools.ts +24 -2
  261. package/src/cli/mcp/workspace-tools.test.ts +1 -1
  262. package/src/cli/mcp/workspace-tools.ts +34 -6
  263. package/src/cli/registry.ts +63 -1
  264. package/src/components/auto-release.ts +1 -1
  265. package/src/components/capability.ts +55 -0
  266. package/src/components/changed-files.ts +66 -0
  267. package/src/components/cli-support.ts +28 -5
  268. package/src/components/component.schema.json +17 -0
  269. package/src/components/component.ts +25 -0
  270. package/src/components/deploy-units.ts +3 -0
  271. package/src/components/driver.test.ts +52 -0
  272. package/src/components/driver.ts +31 -13
  273. package/src/components/fan-out-output.ts +42 -1
  274. package/src/components/fan-out-record.ts +69 -0
  275. package/src/components/fan-out-run.test.ts +17 -0
  276. package/src/components/fan-out-run.ts +304 -1
  277. package/src/components/fan-out-support.ts +3 -0
  278. package/src/components/fan-out-waves.test.ts +375 -0
  279. package/src/components/fan-out.ts +18 -17
  280. package/src/components/gated-wave-pipeline.ts +82 -0
  281. package/src/components/index.ts +1 -0
  282. package/src/components/layers.ts +30 -0
  283. package/src/components/pr-pipeline.ts +91 -0
  284. package/src/components/pr-run.test.ts +205 -0
  285. package/src/components/pr-run.ts +280 -0
  286. package/src/components/promote.ts +5 -0
  287. package/src/components/verbs/shell.test.ts +11 -0
  288. package/src/components/verbs/shell.ts +7 -3
  289. package/src/components/wave-plan.ts +124 -0
  290. package/src/discovery/sandbox/bundle.ts +1 -1
  291. package/src/gated-waves-bundle.test.ts +62 -0
  292. package/src/gated-waves.test.ts +118 -0
  293. package/src/gated-waves.ts +240 -0
  294. package/src/index.ts +1 -0
  295. package/src/lexicon.ts +51 -0
  296. package/src/lifecycle/gate-ledger.ts +7 -0
  297. package/src/lifecycle/git.ts +102 -16
  298. package/src/lint/post-synth.test.ts +19 -0
  299. package/src/lint/post-synth.ts +19 -1
  300. package/src/meta/declared-imports.test.ts +1 -1
  301. package/src/op/activities/activity-contracts.ts +84 -0
  302. package/src/op/activities/change-set.ts +114 -0
  303. package/src/op/activities/decide.ts +3 -0
  304. package/src/op/activities/factory.ts +675 -0
  305. package/src/op/activities/index.ts +6 -0
  306. package/src/op/activity-contract.test.ts +21 -1
  307. package/src/op/activity-contract.ts +19 -9
  308. package/src/op/builders.ts +23 -0
  309. package/src/op/decide-backend.ts +5 -1
  310. package/src/op/decide-read-inputs.ts +33 -5
  311. package/src/op/factory.e2e.test.ts +232 -0
  312. package/src/op/factory.ts +118 -0
  313. package/src/op/index.ts +9 -1
  314. package/src/op/op-ir.test.ts +9 -0
  315. package/src/op/op-ir.ts +4 -0
  316. package/src/op/op-verb-class.ts +3 -0
  317. package/src/op/types.ts +8 -0
  318. package/src/op/work-lease-run.ts +3 -0
  319. package/src/plan-summary.test.ts +263 -0
  320. package/src/plan-summary.ts +845 -0
  321. package/src/pr-forge.test.ts +237 -0
  322. package/src/pr-forge.ts +332 -0
  323. package/src/pr-loop-bundle.test.ts +46 -0
  324. package/src/pr-loop.test.ts +171 -0
  325. package/src/pr-loop.ts +324 -0
  326. package/src/telemetry-attribution.test.ts +23 -1
  327. package/src/telemetry-attribution.ts +51 -0
  328. package/src/terraform/hcl2json.test.ts +21 -0
  329. package/src/terraform/hcl2json.ts +81 -0
  330. package/src/terraform/parse.ts +11 -74
  331. package/src/vendor/js-yaml-load.test.ts +115 -0
  332. package/src/vendor/js-yaml-load.ts +1939 -0
  333. package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
  334. package/src/workspace/app-kind.test.ts +196 -0
  335. package/src/workspace/box-cli.ts +113 -0
  336. package/src/workspace/box-factory.test.ts +4 -1
  337. package/src/workspace/box-factory.ts +37 -4
  338. package/src/workspace/box-listing-write.schema.json +204 -0
  339. package/src/workspace/box-listing.test.ts +234 -0
  340. package/src/workspace/box-listing.ts +324 -0
  341. package/src/workspace/box-publish.schema.json +498 -0
  342. package/src/workspace/box-publish.test.ts +204 -0
  343. package/src/workspace/box-publish.ts +420 -0
  344. package/src/workspace/box-ship.test.ts +96 -0
  345. package/src/workspace/broker-protocol.schema.json +186 -0
  346. package/src/workspace/broker-protocol.test.ts +122 -0
  347. package/src/workspace/broker-protocol.ts +317 -0
  348. package/src/workspace/builder-tiers.test.ts +146 -0
  349. package/src/workspace/change-set.schema.json +460 -0
  350. package/src/workspace/chant-migrations.e2e.test.ts +17 -5
  351. package/src/workspace/checks/boxes.test.ts +3 -0
  352. package/src/workspace/checks.ts +10 -3
  353. package/src/workspace/component-environments.test.ts +105 -0
  354. package/src/workspace/composites.schema.json +23 -4
  355. package/src/workspace/composites.test.ts +8 -8
  356. package/src/workspace/composites.ts +13 -2
  357. package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
  358. package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
  359. package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +7 -2
  360. package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +42 -2
  361. package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  362. package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  363. package/src/workspace/conformance/__writer_fixture__/decisions/points.json +96 -0
  364. package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  365. package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  366. package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +14 -8
  367. package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +187 -6
  368. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +25 -0
  369. package/src/workspace/conformance/broker.test.ts +122 -0
  370. package/src/workspace/conformance/broker.ts +792 -0
  371. package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
  372. package/src/workspace/conformance/index.mjs +22 -1
  373. package/src/workspace/conformance/index.ts +5 -1
  374. package/src/workspace/conformance/vitest.ts +33 -1
  375. package/src/workspace/conformance/writer-conformance.e2e.test.ts +49 -3
  376. package/src/workspace/conformance/writer.test.ts +32 -2
  377. package/src/workspace/conformance/writer.ts +339 -28
  378. package/src/workspace/decide.test.ts +208 -4
  379. package/src/workspace/decide.ts +427 -73
  380. package/src/workspace/decision-points.schema.json +11 -4
  381. package/src/workspace/declaration.schema.json +153 -4
  382. package/src/workspace/declaration.ts +141 -0
  383. package/src/workspace/environments.ts +66 -14
  384. package/src/workspace/factory-rules.test.ts +62 -0
  385. package/src/workspace/factory-rules.ts +218 -0
  386. package/src/workspace/graph-cli.ts +2 -2
  387. package/src/workspace/graph.schema.json +67 -0
  388. package/src/workspace/identity.test.ts +23 -0
  389. package/src/workspace/init.ts +82 -2
  390. package/src/workspace/intent-cli.ts +26 -9
  391. package/src/workspace/intent-patch-id.test.ts +162 -0
  392. package/src/workspace/intent-record.schema.json +130 -3
  393. package/src/workspace/intent-record.ts +74 -28
  394. package/src/workspace/intent-reviews.test.ts +76 -0
  395. package/src/workspace/intent-squash.test.ts +213 -0
  396. package/src/workspace/intent-why.test.ts +5 -5
  397. package/src/workspace/intent.schema.json +234 -4
  398. package/src/workspace/intent.ts +260 -66
  399. package/src/workspace/json-edit.test.ts +121 -0
  400. package/src/workspace/json-edit.ts +142 -0
  401. package/src/workspace/jsonc.ts +20 -0
  402. package/src/workspace/kinds.ts +157 -2
  403. package/src/workspace/lexicon-symbols.test.ts +148 -0
  404. package/src/workspace/lexicon-symbols.ts +125 -0
  405. package/src/workspace/lineage-upgrade.test.ts +63 -0
  406. package/src/workspace/lineage-upgrade.ts +146 -5
  407. package/src/workspace/plan-summary.schema.json +155 -0
  408. package/src/workspace/point-answer.schema.json +42 -2
  409. package/src/workspace/points-cli.ts +42 -16
  410. package/src/workspace/points-write.schema.json +162 -4
  411. package/src/workspace/points.schema.json +157 -2
  412. package/src/workspace/points.test.ts +13 -1
  413. package/src/workspace/points.ts +118 -12
  414. package/src/workspace/pr-report.schema.json +95 -0
  415. package/src/workspace/profiles.test.ts +159 -0
  416. package/src/workspace/read-contract.test.ts +2 -2
  417. package/src/workspace/reason-codes.test.ts +13 -1
  418. package/src/workspace/reason-codes.ts +38 -4
  419. package/src/workspace/record-sessions.ts +9 -8
  420. package/src/workspace/records-amend.schema.json +78 -0
  421. package/src/workspace/records-cli.ts +20 -6
  422. package/src/workspace/records-close.schema.json +78 -0
  423. package/src/workspace/records-close.ts +31 -7
  424. package/src/workspace/records-concurrent.e2e.test.ts +135 -0
  425. package/src/workspace/records-concurrent.test.ts +145 -0
  426. package/src/workspace/records-formats.test.ts +46 -10
  427. package/src/workspace/records-new.schema.json +7 -0
  428. package/src/workspace/records-review.schema.json +78 -0
  429. package/src/workspace/records-sessions-write.test.ts +69 -0
  430. package/src/workspace/records-sessions.test.ts +22 -0
  431. package/src/workspace/records-write.ts +192 -25
  432. package/src/workspace/records.schema.json +16 -0
  433. package/src/workspace/records.ts +50 -9
  434. package/src/workspace/reference-kinds/app/package.json +10 -0
  435. package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  436. package/src/workspace/run-statement.schema.json +622 -0
  437. package/src/workspace/runs-cli.ts +343 -14
  438. package/src/workspace/runs-statement.test.ts +239 -0
  439. package/src/workspace/runs-write.schema.json +416 -5
  440. package/src/workspace/runs.schema.json +451 -4
  441. package/src/workspace/runs.test.ts +39 -0
  442. package/src/workspace/runs.ts +296 -35
  443. package/src/workspace/session-kinds.ts +3 -3
  444. package/src/workspace/squash.ts +198 -0
  445. package/src/workspace/status-contract.test.ts +5 -2
  446. package/src/workspace/status-gates.ts +3 -1
  447. package/src/workspace/status.schema.json +126 -3
  448. package/src/workspace/status.ts +90 -1
  449. package/src/workspace/symbols.ts +20 -9
  450. package/src/workspace/trust/run-commits.ts +115 -0
  451. package/src/workspace/trust/run-statement.ts +226 -0
  452. package/src/workspace/trust/seal.ts +8 -2
  453. package/src/workspace/trust/verify-cli.ts +6 -5
  454. package/src/workspace/trust/verify.ts +39 -6
  455. package/src/workspace/wip-cli.ts +97 -0
  456. package/src/workspace/wip-write.schema.json +504 -0
  457. package/src/workspace/wip.schema.json +334 -0
  458. package/src/workspace/wip.test.ts +294 -0
  459. package/src/workspace/wip.ts +753 -0
  460. package/src/workspace/work-cli.ts +3 -0
  461. package/src/workspace/work-evidence.schema.json +3 -0
  462. package/src/workspace/work-size.test.ts +77 -0
  463. package/src/workspace/work-size.ts +93 -0
  464. package/src/workspace/workspace-kinds.schema.json +122 -0
  465. package/src/workspace/write-lock-cli.ts +131 -0
  466. package/src/workspace/write-lock.schema.json +172 -0
  467. package/src/workspace/write-lock.test.ts +189 -0
  468. package/src/workspace/write-lock.ts +474 -0
  469. package/src/workspace/write-scope.test.ts +16 -1
  470. package/src/workspace/write-scope.ts +33 -11
  471. package/src/yaml.ts +31 -21
@@ -38,6 +38,7 @@ const JSON_FLAG: Record<ReadContractCommand, string[]> = {
38
38
  "graph --intent": ["--json"],
39
39
  "graph --composites": ["--json"],
40
40
  runs: ["--json"],
41
+ wip: ["--json"],
41
42
  };
42
43
 
43
44
  /** The smallest reader that conforms, with a hook to misbehave. */
@@ -119,7 +120,7 @@ describe("commands (#2679)", () => {
119
120
  expect(report.problems).toEqual([]);
120
121
  expect(read).toEqual(["ls", "status", "graph --composites"]);
121
122
  expect(report.checked).toEqual(["ls", "status", "graph --composites"]);
122
- expect(report.skipped).toEqual(["graph", "check", "records", "records --uncommitted", "graph --intent", "runs"]);
123
+ expect(report.skipped).toEqual(["graph", "check", "records", "records --uncommitted", "graph --intent", "runs", "wip"]);
123
124
  }, 300_000);
124
125
 
125
126
  test("a name that is not a contract command, or an empty list, is refused", () => {
@@ -1,5 +1,5 @@
1
1
  // The entry of `@intentius/chant/workspace/conformance` for plain Node
2
- // (#2679): the reader suite, and the writer suite (#3159). The suites are
2
+ // (#2679): the reader suite, the writer suite (#3159), and the broker suite (#3164). The suites are
3
3
  // written in TypeScript like the rest of the package, and Node does not
4
4
  // strip types under node_modules, so this file loads them through tsx, a
5
5
  // dependency of this package. `node --test` runs a reader's or a writer's
@@ -42,6 +42,11 @@ export const {
42
42
  WRITER_PRINCIPALS,
43
43
  WRITER_SCRIPT,
44
44
  WRITER_FIXTURE_DIR,
45
+ WRITER_BOX,
46
+ WRITER_INPUTS,
47
+ writeWriterInputs,
48
+ readListing,
49
+ readWip,
45
50
  PRIVATE_STATE_CATEGORIES,
46
51
  writeArgv,
47
52
  writeContractSchema,
@@ -59,4 +64,20 @@ export const {
59
64
  selectActions,
60
65
  undeclaredState,
61
66
  runWorkspaceWriterConformance,
67
+ CONCURRENT_AMENDS,
68
+ concurrentAmendStep,
69
+ concurrentAmends,
70
+ BROKER_CONFORMANCE_CAPABILITIES,
71
+ LOBBY_CAPABILITIES,
72
+ CONFORMANCE_BOXES,
73
+ CONFORMANCE_SECRET,
74
+ CONFORMANCE_UNHELD_SECRET,
75
+ BROKER_CHECKS,
76
+ brokerChecks,
77
+ brokerSchemaValidator,
78
+ schemaInstance,
79
+ startBrokerConformance,
80
+ runBrokerCheck,
81
+ runBrokerConformance,
82
+ upstreamHandlers,
62
83
  } = suite;
@@ -56,7 +56,7 @@ import { isDeepStrictEqual } from "node:util";
56
56
  import { READ_CONTRACT_VERSION } from "../reason-codes";
57
57
 
58
58
  /** The read-contract commands, as a reader names them. */
59
- export const READ_CONTRACT_COMMANDS = ["ls", "graph", "check", "status", "records", "records --uncommitted", "graph --intent", "graph --composites", "runs"] as const;
59
+ export const READ_CONTRACT_COMMANDS = ["ls", "graph", "check", "status", "records", "records --uncommitted", "graph --intent", "graph --composites", "runs", "wip"] as const;
60
60
  export type ReadContractCommand = (typeof READ_CONTRACT_COMMANDS)[number];
61
61
 
62
62
  /**
@@ -74,6 +74,7 @@ export const READ_CONTRACT_SCHEMAS: Record<ReadContractCommand, string> = {
74
74
  "graph --intent": "intent.schema.json",
75
75
  "graph --composites": "composites.schema.json",
76
76
  runs: "runs.schema.json",
77
+ wip: "wip.schema.json",
77
78
  };
78
79
 
79
80
  /** The flags that ask each command for its JSON document. A reader adds one of these and nothing else. */
@@ -87,6 +88,7 @@ export const READ_CONTRACT_JSON_FLAGS: Record<ReadContractCommand, readonly (rea
87
88
  "graph --intent": [["--json"]],
88
89
  "graph --composites": [[], ["--json"]],
89
90
  runs: [["--json"]],
91
+ wip: [["--json"]],
90
92
  };
91
93
 
92
94
  /** The arguments the suite passes each read, on the reference workspace or the generated one. */
@@ -100,6 +102,7 @@ export const REFERENCE_READS: Record<ReadContractCommand, string[]> = {
100
102
  "graph --intent": ["app/src/server.mjs:19", "--kind", "decisions/decision.kind.mjs"],
101
103
  "graph --composites": [],
102
104
  runs: [],
105
+ wip: [],
103
106
  };
104
107
 
105
108
  /** One chant run: the arguments after `chant`, what it was given on stdin, and what it printed. */
@@ -744,3 +747,4 @@ export async function runWorkspaceReaderConformance(reader: WorkspaceReaderFacto
744
747
 
745
748
  // The writer suite (#3159), published from this same entry.
746
749
  export * from "./writer";
750
+ export * from "./broker";
@@ -6,7 +6,8 @@
6
6
  * (#3159) does the same for the writer suite: one test per step of the
7
7
  * script, and one per check after it. This is the only module of the suite
8
8
  * that imports vitest; `@intentius/chant/workspace/conformance` imports no
9
- * runner.
9
+ * runner. {@link describeBrokerConformance} (#3164) makes one test per check
10
+ * of the broker suite.
10
11
  */
11
12
 
12
13
  import { afterAll, beforeAll, describe, expect, it } from "vitest";
@@ -26,6 +27,10 @@ import {
26
27
  type WorkspaceReaderConformanceConfig,
27
28
  type WorkspaceWriterConformanceConfig,
28
29
  type WorkspaceWriterConformanceReport,
30
+ brokerChecks,
31
+ runBrokerCheck,
32
+ startBrokerConformance,
33
+ type BrokerConformanceConfig,
29
34
  } from "./index";
30
35
 
31
36
  export function describeWorkspaceReaderConformance(config: WorkspaceReaderConformanceConfig): void {
@@ -110,4 +115,31 @@ export function describeWorkspaceWriterConformance(config: WorkspaceWriterConfor
110
115
  });
111
116
  }
112
117
 
118
+ /**
119
+ * The broker suite in vitest (#3164): the upstreams and the broker start
120
+ * before the tests, and each check is one test, run in order. A check of a
121
+ * capability the broker does not serve is skipped.
122
+ */
123
+ export function describeBrokerConformance(config: BrokerConformanceConfig): void {
124
+ describe(`broker conformance (#3164): ${config.name}`, () => {
125
+ let run: Awaited<ReturnType<typeof startBrokerConformance>> | undefined;
126
+ beforeAll(async () => {
127
+ run = await startBrokerConformance(config);
128
+ }, 120_000);
129
+ afterAll(async () => {
130
+ await run?.close();
131
+ });
132
+ for (const { check, skipped } of brokerChecks(config)) {
133
+ if (skipped) {
134
+ it.skip(`${check.id}: not applicable, ${skipped}`, () => {});
135
+ continue;
136
+ }
137
+ it(`${check.id}: ${check.title}`, async () => {
138
+ expect(run, "the broker did not start").toBeDefined();
139
+ expect(await runBrokerCheck(run!.ctx, check)).toEqual([]);
140
+ }, 60_000);
141
+ }
142
+ });
143
+ }
144
+
113
145
  export * from "./index";
@@ -5,6 +5,7 @@
5
5
  * run on a workspace generated from the shipped fixtures, at the same time.
6
6
  */
7
7
 
8
+ import { createHash } from "node:crypto";
8
9
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
9
10
  import { join } from "node:path";
10
11
  import { describe, expect, test } from "vitest";
@@ -13,6 +14,7 @@ import {
13
14
  runWorkspaceWriterConformance,
14
15
  WRITE_CONTRACT_ACTIONS,
15
16
  WRITE_CONTRACT_JSON_FLAGS,
17
+ WRITER_INPUTS,
16
18
  WRITER_KINDS,
17
19
  WRITER_SCRIPT,
18
20
  type ChantTransport,
@@ -69,7 +71,7 @@ const leakyWriter: WorkspaceWriterFactory = (chant, { stateDir }) => {
69
71
  writeFileSync(join(stateDir, "notes.txt"), "kept and not declared");
70
72
  return doc;
71
73
  }
72
- if (step.id === "answer") return perform(chant, step, ["--dry-run"]);
74
+ if (step.id === "reanswer") return perform(chant, step, ["--dry-run"]);
73
75
  return perform(chant, step);
74
76
  },
75
77
  async facts() {
@@ -92,12 +94,29 @@ describe("the writer conformance suite (#3159)", () => {
92
94
  expect(report.skipped).toEqual([]);
93
95
  expect(report.results.map((r) => [r.id, r.by])).toEqual(WRITER_SCRIPT.map((s) => [s.id, "writer"]));
94
96
  expect(report.facts.after).toEqual(report.facts.before);
97
+ // #3173: three amendments of one record at once, one written, two refused with record-conflict and written on retry.
98
+ expect(report.after.concurrent).toEqual([]);
95
99
  expect(report.facts.before).toMatchObject({
96
100
  decision: [["fix-001", "decided"], ["fix-002", "proposed"]],
97
101
  session: [["S-0001", "closed"]],
98
- answer: [[expect.stringMatching(/^slice-tier-/), "answered"]],
102
+ // #3403: the ad-hoc question an agent asked, answered from the options it offered.
103
+ answer: [
104
+ [expect.stringMatching(/^agent-question-/), "answered"],
105
+ [expect.stringMatching(/^slice-tier-/), "answered"],
106
+ ],
99
107
  work: [["W-001", "open"]],
100
108
  runs: [["conformance-run", "ended"], ["writer-run-1", "ended"], ["writer-run-2", "ended"]],
109
+ // #3308: the box's listing, set through chant with its cover copied in, survives amnesia.
110
+ listing: {
111
+ app: {
112
+ published: true,
113
+ title: "The writer suite's box",
114
+ line: "Listed through chant, read back after amnesia.",
115
+ cover: { path: "app/listing/cover.png", sha256: createHash("sha256").update(WRITER_INPUTS.cover.bytes).digest("hex") },
116
+ },
117
+ },
118
+ // #3172: the checkpoint of the uncommitted work; restoring it to the same tree takes no second one.
119
+ wip: { main: [["save", "turn:1"]] },
101
120
  });
102
121
  }, 900_000);
103
122
 
@@ -109,13 +128,19 @@ describe("the writer conformance suite (#3159)", () => {
109
128
  expect(report.checked).toEqual(["records new", "records amend", "records review", "points answer"]);
110
129
  const by = Object.fromEntries(report.results.map((r) => [r.id, r]));
111
130
  expect(by.claim.by).toBe("suite");
131
+ expect(by.listing).toMatchObject({ by: "suite", problems: [] });
132
+ expect(by.checkpoint).toMatchObject({ by: "suite", problems: [] });
133
+ expect(by.undo).toMatchObject({ by: "suite", problems: [] });
112
134
  expect(by.session.problems).toEqual([]);
113
135
  expect(by.decision.problems).toEqual(["decision (records new): the writer must return the document chant printed, unchanged, and it returned something else"]);
114
136
  expect(by.amend.problems).toHaveLength(2);
115
137
  expect(by.amend.problems[0]).toMatch(/^amend \(records amend\): made 2 chant calls .* expected exactly one$/);
116
138
  expect(by.amend.problems[1]).toMatch(/^amend \(records amend\): files changed that chant did not report writing: decisions\/fix-003-a-decision-nobody-asked-for\.md \(added\)$/);
117
139
  expect(by.review.problems).toEqual([]);
118
- expect(by.answer.problems).toEqual([expect.stringMatching(/^answer \(points answer\): .* it may add only nothing or --json, and it added --dry-run$/)]);
140
+ expect(by.answer.problems).toEqual([]);
141
+ expect(by.retract.by).toBe("suite");
142
+ expect(by.retract.problems).toEqual([]);
143
+ expect(by.reanswer.problems).toEqual([expect.stringMatching(/^reanswer \(points answer\): .* it may add only nothing or --json, and it added --dry-run$/)]);
119
144
  expect(report.after.facts).toEqual([
120
145
  "facts: before amnesia, facts() made calls outside the read contract: workspace runs start --from -",
121
146
  "facts: after amnesia, facts() made calls outside the read contract: workspace runs start --from -",
@@ -127,5 +152,26 @@ describe("the writer conformance suite (#3159)", () => {
127
152
  'holds: events is held as "database"; outside the repo a tool keeps only cache, telemetry, secret, runtime (ws-074)',
128
153
  ]);
129
154
  expect(report.after.readBack).toEqual([]);
155
+ expect(report.after.concurrent).toEqual([]);
156
+ }, 900_000);
157
+
158
+ test.concurrent("a writer that hides a conflict by writing again without --expect is caught (#3173)", async () => {
159
+ const blindRetry: WorkspaceWriterFactory = (chant, ctx) => {
160
+ const inner = referenceWriter(chant, ctx);
161
+ return {
162
+ async write(step) {
163
+ const doc = (await inner.write(step)) as { error?: { code: string } };
164
+ if (doc.error?.code !== "record-conflict" || step.action !== "records amend") return doc;
165
+ // Overwrites whatever the other writer wrote, and reports success.
166
+ const args = step.args.filter((a, i, all) => a !== "--expect" && all[i - 1] !== "--expect");
167
+ return JSON.parse((await chant.run(["workspace", "records", "amend", ...args], { input: step.input })).stdout);
168
+ },
169
+ facts: () => inner.facts(),
170
+ };
171
+ };
172
+ const report = await runWorkspaceWriterConformance(blindRetry, { actions: ["records amend"] });
173
+ expect(report.after.concurrent.length).toBeGreaterThan(0);
174
+ expect(report.after.concurrent.every((p) => p.startsWith("concurrent: "))).toBe(true);
175
+ expect(report.after.concurrent.join("\n")).toMatch(/made 2 chant calls/);
130
176
  }, 900_000);
131
177
  });
@@ -49,6 +49,25 @@ describe("the script (#3159)", () => {
49
49
  input: '{"criterion":"AC-1"}',
50
50
  });
51
51
  expect(writeArgv("runs end", { id: "r", fields: {} })).toEqual({ args: ["r", "--from", "-"], input: "{}" });
52
+ expect(writeArgv("box listing set", { member: "app", fields: { title: "T" }, cover: "/in/cover.png" })).toEqual({
53
+ args: ["app", "--from", "-", "--cover", "/in/cover.png"],
54
+ input: '{"title":"T"}',
55
+ });
56
+ const listing = buildStep(WRITER_SCRIPT.find((s) => s.id === "listing")!, {}, { dir: "/in" });
57
+ expect(listing.args).toEqual(["app", "--from", "-", "--cover", "/in/cover.png"]);
58
+ expect(buildStep(WRITER_SCRIPT.find((s) => s.id === "listing")!, {}).args).toEqual(["app", "--from", "-"]);
59
+ // #3403: an ad-hoc ask reads its question and candidates on stdin, and takes the inputs as JSON.
60
+ const adhoc = buildStep(WRITER_SCRIPT.find((s) => s.id === "adhoc")!, {});
61
+ expect(adhoc.args).toEqual(["agent-question", "--inputs", '{"ask.id":"conformance-ask-1","ask.by":"conformance-writer"}', "--candidates", "-", "--subject", "W-001", "--kind", "answers/answer.kind.mjs"]);
62
+ expect(JSON.parse(adhoc.input!)).toMatchObject({ question: expect.any(String), criteria: { flag: expect.any(String), now: expect.any(String) } });
63
+ // The inputs may be spelled with other key order or spacing.
64
+ const respelled = ["workspace", "points", "ask", "agent-question", "--inputs", '{ "ask.by": "conformance-writer", "ask.id": "conformance-ask-1" }', "--candidates", "-", "--subject", "W-001", "--kind", "answers/answer.kind.mjs"];
65
+ expect(writerCallProblems(adhoc, [run(respelled, adhoc.input)])).toEqual([]);
66
+ expect(writerCallProblems(adhoc, [run(respelled.map((a) => (a.includes("ask.id") ? '{"ask.id":"other"}' : a)), adhoc.input)])).toHaveLength(1);
67
+ // #3172: a snapshot takes no stdin, and the restore names the snapshot the save took.
68
+ expect(writeArgv("wip save", { label: "turn:1", by: "p" })).toEqual({ args: ["--label", "turn:1", "--by", "p"] });
69
+ expect(writeArgv("wip save", {})).toEqual({ args: [] });
70
+ expect(buildStep(WRITER_SCRIPT.find((s) => s.id === "undo")!, { checkpoint: { snapshot: { commit: "c0ffee" } } }).args).toEqual(["c0ffee", "--by", "conformance"]);
52
71
  });
53
72
 
54
73
  test("a later step's params come from the documents of the steps before it", () => {
@@ -110,6 +129,12 @@ describe("unreportedChanges (#3159)", () => {
110
129
  const claim = buildStep(WRITER_SCRIPT.find((s) => s.id === "claim")!, {});
111
130
  const doc = { ref: "refs/chant/lease/work/W-001", history: { commit: "c2" } };
112
131
  expect(reportedWrites("work claim", doc)).toEqual({ paths: [], refs: { "refs/heads/chant/lifecycle": "c2", "refs/chant/lease/work/W-001": "*" } });
132
+ expect(reportedWrites("wip save", { ref: "refs/chant/wip/main", snapshot: { commit: "s1" }, replication: { remote: "origin", pushed: [{ ref: "refs/chant/wip/main", commit: "s1" }] } })).toEqual({
133
+ paths: [],
134
+ refs: { "refs/chant/wip/main": "s1", "refs/chant/replica/origin/chant/wip/main": "s1" },
135
+ });
136
+ expect(reportedWrites("wip restore", { ref: "refs/chant/wip/main", checkpoint: { snapshot: { commit: "s2" } }, paths: ["a.txt"] })).toEqual({ paths: ["a.txt"], refs: { "refs/chant/wip/main": "s2" } });
137
+ expect(reportedWrites("box listing set", { paths: ["app/listing/cover.png", "chant.workspace.json"], declaration: { path: "chant.workspace.json" } })).toEqual({ paths: ["app/listing/cover.png", "chant.workspace.json"], refs: {} });
113
138
  const before = { "refs/heads/chant/lifecycle": "c1", HEAD: "m 1" };
114
139
  expect(unreportedChanges(claim, doc, { before: {}, after: {} }, { before, after: { ...before, "refs/heads/chant/lifecycle": "c2", "refs/chant/lease/work/W-001": "b" } })).toEqual([]);
115
140
  expect(unreportedChanges(claim, doc, { before: {}, after: {} }, { before, after: { ...before, "refs/heads/chant/lifecycle": "c3" } })[0]).toMatch(/git refs changed that chant did not report writing: refs\/heads\/chant\/lifecycle/);
@@ -128,10 +153,10 @@ describe("state and reads (#3159)", () => {
128
153
  });
129
154
 
130
155
  test("isReadCall: the read contract, never a write verb", () => {
131
- for (const argv of [["workspace", "records", "--kind", "k", "--json"], ["workspace", "records", "--uncommitted", "--json"], ["workspace", "runs", "--json"], ["workspace", "points", "--open", "--json"], ["workspace", "work", "history", "W-001"], ["workspace", "ls", "--json"]]) {
156
+ for (const argv of [["workspace", "wip", "--json"], ["workspace", "records", "--kind", "k", "--json"], ["workspace", "records", "--uncommitted", "--json"], ["workspace", "runs", "--json"], ["workspace", "points", "--open", "--json"], ["workspace", "work", "history", "W-001"], ["workspace", "ls", "--json"]]) {
132
157
  expect(isReadCall(argv), argv.join(" ")).toBe(true);
133
158
  }
134
- for (const argv of [["workspace", "records", "new"], ["workspace", "runs", "start"], ["workspace", "points", "answer"], ["workspace", "work", "claim"], ["workspace", "work", "evidence"], ["build"]]) {
159
+ for (const argv of [["workspace", "wip", "save"], ["workspace", "wip", "restore"], ["workspace", "wip", "push"], ["workspace", "wip", "fetch"], ["workspace", "records", "new"], ["workspace", "runs", "start"], ["workspace", "points", "answer"], ["workspace", "points", "retract"], ["workspace", "work", "claim"], ["workspace", "work", "evidence"], ["build"]]) {
135
160
  expect(isReadCall(argv), argv.join(" ")).toBe(false);
136
161
  }
137
162
  });
@@ -146,6 +171,11 @@ describe("the writer fixture (#3159)", () => {
146
171
  ["answers/answer.schema.json", "answers/answer.schema.json"],
147
172
  ["decisions/points.json", "decisions/points.json"],
148
173
  ["sessions/session.schema.json", "design/sessions/session.schema.json"],
174
+ // The session kind's other subject kinds (#3148).
175
+ ["contracts/contract.kind.mjs", "design/contracts/contract.kind.mjs"],
176
+ ["contracts/contract.schema.json", "design/contracts/contract.schema.json"],
177
+ ["drivers/driver.kind.mjs", "design/drivers/driver.kind.mjs"],
178
+ ["drivers/driver.schema.json", "design/drivers/driver.schema.json"],
149
179
  ];
150
180
  for (const [ours, theirs] of same) expect(readFileSync(join(WRITER_FIXTURE_DIR, ours), "utf-8"), ours).toBe(readFileSync(join(repoRoot, "reference-workspace", theirs), "utf-8"));
151
181
  // The session kind sits one directory higher here than in the reference