@intentius/chant 0.102.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 (464) 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/workspace/box-cli.d.ts +12 -0
  114. package/dist/workspace/box-cli.d.ts.map +1 -0
  115. package/dist/workspace/box-factory.d.ts +27 -3
  116. package/dist/workspace/box-factory.d.ts.map +1 -1
  117. package/dist/workspace/box-listing.d.ts +85 -0
  118. package/dist/workspace/box-listing.d.ts.map +1 -0
  119. package/dist/workspace/box-publish.d.ts +147 -0
  120. package/dist/workspace/box-publish.d.ts.map +1 -0
  121. package/dist/workspace/broker-protocol.d.ts +190 -0
  122. package/dist/workspace/broker-protocol.d.ts.map +1 -0
  123. package/dist/workspace/checks.d.ts.map +1 -1
  124. package/dist/workspace/composites.d.ts +2 -2
  125. package/dist/workspace/composites.d.ts.map +1 -1
  126. package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
  127. package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
  128. package/dist/workspace/conformance/broker.d.ts +202 -0
  129. package/dist/workspace/conformance/broker.d.ts.map +1 -0
  130. package/dist/workspace/conformance/index.d.ts +2 -1
  131. package/dist/workspace/conformance/index.d.ts.map +1 -1
  132. package/dist/workspace/conformance/vitest.d.ts +9 -2
  133. package/dist/workspace/conformance/vitest.d.ts.map +1 -1
  134. package/dist/workspace/conformance/writer.d.ts +108 -14
  135. package/dist/workspace/conformance/writer.d.ts.map +1 -1
  136. package/dist/workspace/decide.d.ts +126 -12
  137. package/dist/workspace/decide.d.ts.map +1 -1
  138. package/dist/workspace/decision-points.schema.json +11 -4
  139. package/dist/workspace/declaration.d.ts +65 -0
  140. package/dist/workspace/declaration.d.ts.map +1 -1
  141. package/dist/workspace/declaration.schema.json +153 -4
  142. package/dist/workspace/environments.d.ts +36 -10
  143. package/dist/workspace/environments.d.ts.map +1 -1
  144. package/dist/workspace/factory-rules.d.ts +180 -0
  145. package/dist/workspace/factory-rules.d.ts.map +1 -0
  146. package/dist/workspace/init.d.ts +21 -0
  147. package/dist/workspace/init.d.ts.map +1 -1
  148. package/dist/workspace/intent-cli.d.ts +1 -1
  149. package/dist/workspace/intent-cli.d.ts.map +1 -1
  150. package/dist/workspace/intent-record.d.ts +28 -1
  151. package/dist/workspace/intent-record.d.ts.map +1 -1
  152. package/dist/workspace/intent.d.ts +102 -5
  153. package/dist/workspace/intent.d.ts.map +1 -1
  154. package/dist/workspace/json-edit.d.ts +24 -0
  155. package/dist/workspace/json-edit.d.ts.map +1 -0
  156. package/dist/workspace/jsonc.d.ts +11 -0
  157. package/dist/workspace/jsonc.d.ts.map +1 -1
  158. package/dist/workspace/kinds.d.ts +48 -0
  159. package/dist/workspace/kinds.d.ts.map +1 -1
  160. package/dist/workspace/lexicon-symbols.d.ts +29 -0
  161. package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
  162. package/dist/workspace/lineage-upgrade.d.ts +31 -2
  163. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  164. package/dist/workspace/point-answer.schema.json +42 -2
  165. package/dist/workspace/points-cli.d.ts +10 -3
  166. package/dist/workspace/points-cli.d.ts.map +1 -1
  167. package/dist/workspace/points.d.ts +66 -5
  168. package/dist/workspace/points.d.ts.map +1 -1
  169. package/dist/workspace/reason-codes.d.ts +33 -4
  170. package/dist/workspace/reason-codes.d.ts.map +1 -1
  171. package/dist/workspace/record-sessions.d.ts +5 -7
  172. package/dist/workspace/record-sessions.d.ts.map +1 -1
  173. package/dist/workspace/records-cli.d.ts +7 -0
  174. package/dist/workspace/records-cli.d.ts.map +1 -1
  175. package/dist/workspace/records-close.d.ts +7 -3
  176. package/dist/workspace/records-close.d.ts.map +1 -1
  177. package/dist/workspace/records-write.d.ts +66 -6
  178. package/dist/workspace/records-write.d.ts.map +1 -1
  179. package/dist/workspace/records.d.ts +28 -9
  180. package/dist/workspace/records.d.ts.map +1 -1
  181. package/dist/workspace/runs-cli.d.ts +138 -6
  182. package/dist/workspace/runs-cli.d.ts.map +1 -1
  183. package/dist/workspace/runs.d.ts +132 -11
  184. package/dist/workspace/runs.d.ts.map +1 -1
  185. package/dist/workspace/session-kinds.d.ts +1 -1
  186. package/dist/workspace/session-kinds.d.ts.map +1 -1
  187. package/dist/workspace/squash.d.ts +80 -0
  188. package/dist/workspace/squash.d.ts.map +1 -0
  189. package/dist/workspace/status-gates.d.ts +2 -0
  190. package/dist/workspace/status-gates.d.ts.map +1 -1
  191. package/dist/workspace/status.d.ts +54 -0
  192. package/dist/workspace/status.d.ts.map +1 -1
  193. package/dist/workspace/symbols.d.ts +16 -5
  194. package/dist/workspace/symbols.d.ts.map +1 -1
  195. package/dist/workspace/trust/run-commits.d.ts +46 -0
  196. package/dist/workspace/trust/run-commits.d.ts.map +1 -0
  197. package/dist/workspace/trust/run-statement.d.ts +128 -0
  198. package/dist/workspace/trust/run-statement.d.ts.map +1 -0
  199. package/dist/workspace/trust/seal.d.ts +6 -1
  200. package/dist/workspace/trust/seal.d.ts.map +1 -1
  201. package/dist/workspace/trust/verify-cli.d.ts +1 -1
  202. package/dist/workspace/trust/verify.d.ts +16 -2
  203. package/dist/workspace/trust/verify.d.ts.map +1 -1
  204. package/dist/workspace/wip-cli.d.ts +21 -0
  205. package/dist/workspace/wip-cli.d.ts.map +1 -0
  206. package/dist/workspace/wip.d.ts +268 -0
  207. package/dist/workspace/wip.d.ts.map +1 -0
  208. package/dist/workspace/work-cli.d.ts.map +1 -1
  209. package/dist/workspace/work-evidence.d.ts +1 -1
  210. package/dist/workspace/work-evidence.d.ts.map +1 -1
  211. package/dist/workspace/work-size.d.ts +55 -0
  212. package/dist/workspace/work-size.d.ts.map +1 -0
  213. package/dist/workspace/workspace-kinds.schema.json +122 -0
  214. package/dist/workspace/write-lock-cli.d.ts +60 -0
  215. package/dist/workspace/write-lock-cli.d.ts.map +1 -0
  216. package/dist/workspace/write-lock.d.ts +152 -0
  217. package/dist/workspace/write-lock.d.ts.map +1 -0
  218. package/dist/workspace/write-scope.d.ts +6 -2
  219. package/dist/workspace/write-scope.d.ts.map +1 -1
  220. package/package.json +6 -1
  221. package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
  222. package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
  223. package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
  224. package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
  225. package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
  226. package/src/__fixtures__/change-set/warden.plan.json +44 -0
  227. package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
  228. package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
  229. package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
  230. package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
  231. package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
  232. package/src/audit/core.test.ts +15 -0
  233. package/src/audit/core.ts +8 -2
  234. package/src/audit/discover.test.ts +11 -0
  235. package/src/audit/discover.ts +7 -2
  236. package/src/change-set-bundle.test.ts +57 -0
  237. package/src/change-set.test.ts +215 -0
  238. package/src/change-set.ts +445 -0
  239. package/src/cli/commands/audit-opt-in.test.ts +54 -0
  240. package/src/cli/commands/audit.ts +29 -2
  241. package/src/cli/commands/build.test.ts +19 -0
  242. package/src/cli/commands/build.ts +3 -2
  243. package/src/cli/handlers/build.ts +13 -1
  244. package/src/cli/handlers/change-set.test.ts +56 -0
  245. package/src/cli/handlers/change-set.ts +44 -0
  246. package/src/cli/handlers/fan-out.test.ts +221 -2
  247. package/src/cli/handlers/fan-out.ts +165 -75
  248. package/src/cli/handlers/graph.ts +3 -0
  249. package/src/cli/handlers/operator.test.ts +21 -0
  250. package/src/cli/handlers/operator.ts +34 -3
  251. package/src/cli/handlers/pr.ts +373 -0
  252. package/src/cli/handlers/run.ts +1 -0
  253. package/src/cli/main.test.ts +20 -0
  254. package/src/cli/main.ts +185 -23
  255. package/src/cli/mcp/never-over-mcp.test.ts +101 -0
  256. package/src/cli/mcp/op-tools.ts +24 -2
  257. package/src/cli/mcp/workspace-tools.test.ts +1 -1
  258. package/src/cli/mcp/workspace-tools.ts +34 -6
  259. package/src/cli/registry.ts +63 -1
  260. package/src/components/auto-release.ts +1 -1
  261. package/src/components/capability.ts +55 -0
  262. package/src/components/changed-files.ts +66 -0
  263. package/src/components/cli-support.ts +28 -5
  264. package/src/components/component.schema.json +17 -0
  265. package/src/components/component.ts +25 -0
  266. package/src/components/deploy-units.ts +3 -0
  267. package/src/components/driver.test.ts +52 -0
  268. package/src/components/driver.ts +31 -13
  269. package/src/components/fan-out-output.ts +42 -1
  270. package/src/components/fan-out-record.ts +69 -0
  271. package/src/components/fan-out-run.test.ts +17 -0
  272. package/src/components/fan-out-run.ts +304 -1
  273. package/src/components/fan-out-support.ts +3 -0
  274. package/src/components/fan-out-waves.test.ts +375 -0
  275. package/src/components/fan-out.ts +18 -17
  276. package/src/components/gated-wave-pipeline.ts +82 -0
  277. package/src/components/index.ts +1 -0
  278. package/src/components/layers.ts +30 -0
  279. package/src/components/pr-pipeline.ts +91 -0
  280. package/src/components/pr-run.test.ts +205 -0
  281. package/src/components/pr-run.ts +280 -0
  282. package/src/components/promote.ts +5 -0
  283. package/src/components/verbs/shell.test.ts +11 -0
  284. package/src/components/verbs/shell.ts +7 -3
  285. package/src/components/wave-plan.ts +124 -0
  286. package/src/discovery/sandbox/bundle.ts +1 -1
  287. package/src/gated-waves-bundle.test.ts +62 -0
  288. package/src/gated-waves.test.ts +118 -0
  289. package/src/gated-waves.ts +240 -0
  290. package/src/index.ts +1 -0
  291. package/src/lexicon.ts +51 -0
  292. package/src/lifecycle/gate-ledger.ts +7 -0
  293. package/src/lifecycle/git.ts +102 -16
  294. package/src/lint/post-synth.test.ts +19 -0
  295. package/src/lint/post-synth.ts +19 -1
  296. package/src/meta/declared-imports.test.ts +1 -1
  297. package/src/op/activities/activity-contracts.ts +84 -0
  298. package/src/op/activities/change-set.ts +114 -0
  299. package/src/op/activities/decide.ts +3 -0
  300. package/src/op/activities/factory.ts +675 -0
  301. package/src/op/activities/index.ts +6 -0
  302. package/src/op/activity-contract.test.ts +21 -1
  303. package/src/op/activity-contract.ts +19 -9
  304. package/src/op/builders.ts +23 -0
  305. package/src/op/decide-backend.ts +5 -1
  306. package/src/op/decide-read-inputs.ts +33 -5
  307. package/src/op/factory.e2e.test.ts +232 -0
  308. package/src/op/factory.ts +118 -0
  309. package/src/op/index.ts +9 -1
  310. package/src/op/op-ir.test.ts +9 -0
  311. package/src/op/op-ir.ts +4 -0
  312. package/src/op/op-verb-class.ts +3 -0
  313. package/src/op/types.ts +8 -0
  314. package/src/op/work-lease-run.ts +3 -0
  315. package/src/plan-summary.test.ts +263 -0
  316. package/src/plan-summary.ts +845 -0
  317. package/src/pr-forge.test.ts +237 -0
  318. package/src/pr-forge.ts +332 -0
  319. package/src/pr-loop-bundle.test.ts +46 -0
  320. package/src/pr-loop.test.ts +171 -0
  321. package/src/pr-loop.ts +324 -0
  322. package/src/telemetry-attribution.test.ts +23 -1
  323. package/src/telemetry-attribution.ts +51 -0
  324. package/src/terraform/hcl2json.test.ts +21 -0
  325. package/src/terraform/hcl2json.ts +81 -0
  326. package/src/terraform/parse.ts +11 -74
  327. package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
  328. package/src/workspace/app-kind.test.ts +196 -0
  329. package/src/workspace/box-cli.ts +113 -0
  330. package/src/workspace/box-factory.test.ts +4 -1
  331. package/src/workspace/box-factory.ts +37 -4
  332. package/src/workspace/box-listing-write.schema.json +204 -0
  333. package/src/workspace/box-listing.test.ts +234 -0
  334. package/src/workspace/box-listing.ts +324 -0
  335. package/src/workspace/box-publish.schema.json +498 -0
  336. package/src/workspace/box-publish.test.ts +204 -0
  337. package/src/workspace/box-publish.ts +420 -0
  338. package/src/workspace/box-ship.test.ts +96 -0
  339. package/src/workspace/broker-protocol.schema.json +186 -0
  340. package/src/workspace/broker-protocol.test.ts +122 -0
  341. package/src/workspace/broker-protocol.ts +317 -0
  342. package/src/workspace/builder-tiers.test.ts +146 -0
  343. package/src/workspace/change-set.schema.json +460 -0
  344. package/src/workspace/chant-migrations.e2e.test.ts +17 -5
  345. package/src/workspace/checks/boxes.test.ts +3 -0
  346. package/src/workspace/checks.ts +10 -3
  347. package/src/workspace/component-environments.test.ts +105 -0
  348. package/src/workspace/composites.schema.json +23 -4
  349. package/src/workspace/composites.test.ts +8 -8
  350. package/src/workspace/composites.ts +13 -2
  351. package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
  352. package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
  353. package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +7 -2
  354. package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +42 -2
  355. package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  356. package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  357. package/src/workspace/conformance/__writer_fixture__/decisions/points.json +96 -0
  358. package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  359. package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  360. package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +14 -8
  361. package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +187 -6
  362. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +25 -0
  363. package/src/workspace/conformance/broker.test.ts +122 -0
  364. package/src/workspace/conformance/broker.ts +792 -0
  365. package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
  366. package/src/workspace/conformance/index.mjs +22 -1
  367. package/src/workspace/conformance/index.ts +5 -1
  368. package/src/workspace/conformance/vitest.ts +33 -1
  369. package/src/workspace/conformance/writer-conformance.e2e.test.ts +49 -3
  370. package/src/workspace/conformance/writer.test.ts +32 -2
  371. package/src/workspace/conformance/writer.ts +339 -28
  372. package/src/workspace/decide.test.ts +208 -4
  373. package/src/workspace/decide.ts +427 -73
  374. package/src/workspace/decision-points.schema.json +11 -4
  375. package/src/workspace/declaration.schema.json +153 -4
  376. package/src/workspace/declaration.ts +141 -0
  377. package/src/workspace/environments.ts +66 -14
  378. package/src/workspace/factory-rules.test.ts +62 -0
  379. package/src/workspace/factory-rules.ts +218 -0
  380. package/src/workspace/graph-cli.ts +2 -2
  381. package/src/workspace/graph.schema.json +67 -0
  382. package/src/workspace/identity.test.ts +23 -0
  383. package/src/workspace/init.ts +82 -2
  384. package/src/workspace/intent-cli.ts +26 -9
  385. package/src/workspace/intent-patch-id.test.ts +162 -0
  386. package/src/workspace/intent-record.schema.json +130 -3
  387. package/src/workspace/intent-record.ts +74 -28
  388. package/src/workspace/intent-reviews.test.ts +76 -0
  389. package/src/workspace/intent-squash.test.ts +213 -0
  390. package/src/workspace/intent-why.test.ts +5 -5
  391. package/src/workspace/intent.schema.json +234 -4
  392. package/src/workspace/intent.ts +260 -66
  393. package/src/workspace/json-edit.test.ts +121 -0
  394. package/src/workspace/json-edit.ts +142 -0
  395. package/src/workspace/jsonc.ts +20 -0
  396. package/src/workspace/kinds.ts +157 -2
  397. package/src/workspace/lexicon-symbols.test.ts +148 -0
  398. package/src/workspace/lexicon-symbols.ts +125 -0
  399. package/src/workspace/lineage-upgrade.test.ts +63 -0
  400. package/src/workspace/lineage-upgrade.ts +146 -5
  401. package/src/workspace/plan-summary.schema.json +155 -0
  402. package/src/workspace/point-answer.schema.json +42 -2
  403. package/src/workspace/points-cli.ts +42 -16
  404. package/src/workspace/points-write.schema.json +162 -4
  405. package/src/workspace/points.schema.json +157 -2
  406. package/src/workspace/points.test.ts +13 -1
  407. package/src/workspace/points.ts +118 -12
  408. package/src/workspace/pr-report.schema.json +95 -0
  409. package/src/workspace/profiles.test.ts +159 -0
  410. package/src/workspace/read-contract.test.ts +2 -2
  411. package/src/workspace/reason-codes.test.ts +13 -1
  412. package/src/workspace/reason-codes.ts +38 -4
  413. package/src/workspace/record-sessions.ts +9 -8
  414. package/src/workspace/records-amend.schema.json +78 -0
  415. package/src/workspace/records-cli.ts +20 -6
  416. package/src/workspace/records-close.schema.json +78 -0
  417. package/src/workspace/records-close.ts +31 -7
  418. package/src/workspace/records-concurrent.e2e.test.ts +135 -0
  419. package/src/workspace/records-concurrent.test.ts +145 -0
  420. package/src/workspace/records-formats.test.ts +46 -10
  421. package/src/workspace/records-new.schema.json +7 -0
  422. package/src/workspace/records-review.schema.json +78 -0
  423. package/src/workspace/records-sessions-write.test.ts +69 -0
  424. package/src/workspace/records-sessions.test.ts +22 -0
  425. package/src/workspace/records-write.ts +192 -25
  426. package/src/workspace/records.schema.json +16 -0
  427. package/src/workspace/records.ts +50 -9
  428. package/src/workspace/reference-kinds/app/package.json +10 -0
  429. package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  430. package/src/workspace/run-statement.schema.json +622 -0
  431. package/src/workspace/runs-cli.ts +343 -14
  432. package/src/workspace/runs-statement.test.ts +239 -0
  433. package/src/workspace/runs-write.schema.json +416 -5
  434. package/src/workspace/runs.schema.json +451 -4
  435. package/src/workspace/runs.test.ts +39 -0
  436. package/src/workspace/runs.ts +296 -35
  437. package/src/workspace/session-kinds.ts +3 -3
  438. package/src/workspace/squash.ts +198 -0
  439. package/src/workspace/status-contract.test.ts +5 -2
  440. package/src/workspace/status-gates.ts +3 -1
  441. package/src/workspace/status.schema.json +126 -3
  442. package/src/workspace/status.ts +90 -1
  443. package/src/workspace/symbols.ts +20 -9
  444. package/src/workspace/trust/run-commits.ts +115 -0
  445. package/src/workspace/trust/run-statement.ts +226 -0
  446. package/src/workspace/trust/seal.ts +8 -2
  447. package/src/workspace/trust/verify-cli.ts +6 -5
  448. package/src/workspace/trust/verify.ts +39 -6
  449. package/src/workspace/wip-cli.ts +97 -0
  450. package/src/workspace/wip-write.schema.json +504 -0
  451. package/src/workspace/wip.schema.json +334 -0
  452. package/src/workspace/wip.test.ts +294 -0
  453. package/src/workspace/wip.ts +753 -0
  454. package/src/workspace/work-cli.ts +3 -0
  455. package/src/workspace/work-evidence.schema.json +3 -0
  456. package/src/workspace/work-size.test.ts +77 -0
  457. package/src/workspace/work-size.ts +93 -0
  458. package/src/workspace/workspace-kinds.schema.json +122 -0
  459. package/src/workspace/write-lock-cli.ts +131 -0
  460. package/src/workspace/write-lock.schema.json +172 -0
  461. package/src/workspace/write-lock.test.ts +189 -0
  462. package/src/workspace/write-lock.ts +474 -0
  463. package/src/workspace/write-scope.test.ts +16 -1
  464. package/src/workspace/write-scope.ts +33 -11
@@ -10,12 +10,12 @@ import { join } from "node:path";
10
10
  import { afterAll, beforeAll, describe, expect, test } from "vitest";
11
11
  import { runDeclarationChecks } from "./checks";
12
12
  import { cleanScratch, commitAll, contract, REPO, repo } from "./__fixtures__/contract-repo";
13
- import { answerPoint, askPoint, type PointsWriteDocument } from "./decide";
13
+ import { answerFields, answerPoint, askPoint, reasonFields, retractAnswer, type PointsWriteDocument } from "./decide";
14
14
  import pointAnswerSchema from "./point-answer.schema.json";
15
- import { workspacePoints } from "./points-cli";
15
+ import { responseAsk, workspacePoints } from "./points-cli";
16
16
  import pointsSchema from "./points.schema.json";
17
17
  import pointsWriteSchema from "./points-write.schema.json";
18
- import type { ModelAsk, WireAnswer } from "./points";
18
+ import { parsePoints, type ModelAsk, type WireAnswer } from "./points";
19
19
  import { queryRecords } from "./records-cli";
20
20
 
21
21
  const REF = join(REPO, "reference-workspace");
@@ -134,7 +134,7 @@ describe("points ask (#2739)", () => {
134
134
  expect(q).toMatchObject({ state: "escalated", open: true, current: true, model: { answer: "medium", confidence: 0.175, threshold: 0.8, model: "bosun-v3.1-1.7b", observed: false } });
135
135
  expect(q.escalations.map((e) => e.reason)).toEqual(["no row matches these inputs", "not observed: confidence 0.175 is below the threshold 0.8"]);
136
136
  expect(listed.questions.every((x) => x.open)).toBe(true);
137
- expect(listed.points.map((p) => p.name)).toEqual(["slice-tier", "ship-skip", "finding-triage", "needs-a-decision", "needs-decision"]);
137
+ expect(listed.points.map((p) => p.name)).toEqual(["slice-tier", "understand", "ship-skip", "finding-triage", "needs-a-decision", "intent-origin", "intent-judgment", "intent-disposition", "agent-question", "needs-decision"]);
138
138
  expect(listed.points[0].inputs[0]).toEqual({ name: "work-item.criteria", output: "work-item", description: "acceptance criteria in the work item" });
139
139
 
140
140
  // A later ask still escalating keeps the standing record; one a model answers rewrites it, as proposed.
@@ -195,6 +195,210 @@ describe("points answer (#2739)", () => {
195
195
  });
196
196
  });
197
197
 
198
+ describe("the model's reason (#3345)", () => {
199
+ const why = "Nine acceptance criteria across three services: more than a medium slice holds.";
200
+
201
+ test("a proposal keeps the model's reason, from --response too; points --json returns it, and confirming keeps it", async () => {
202
+ const response = { model: "bosun-v3.1-1.7b", answers: { "slice-tier": { ...confident, reason: why } } };
203
+ const asked = ok(await askPoint({ cwd: root, point: "slice-tier", inputs: { ...big, "work-item.criteria": 20 }, ask: responseAsk(response), on }));
204
+ expect(asked.question).toMatchObject({ state: "proposed", reason: why, model: { answer: "large", observed: true, reason: why } });
205
+ expect(fm(asked.path)).toContain(`reason: ${JSON.stringify(why)}`);
206
+ const listed = await workspacePoints({ cwd: root });
207
+ read.expectValid(listed);
208
+ if ("error" in listed) throw new Error(listed.error.message);
209
+ expect(listed.questions.find((q) => q.id === asked.id)).toMatchObject({ reason: why, model: { reason: why } });
210
+ const confirmed = ok(await answerPoint({ cwd: root, id: asked.id, answer: "large", by: ["alice"], on }));
211
+ expect(confirmed.question).toMatchObject({ state: "answered", decider: { kind: "model" }, reason: why });
212
+ });
213
+
214
+ test("people answering otherwise move the reason into the escalation, as model_reason", async () => {
215
+ const asked = ok(await askPoint({ cwd: root, point: "slice-tier", inputs: { ...big, "work-item.criteria": 21 }, ask: stub({ ...confident, reason: why }), on }));
216
+ const doc = ok(await answerPoint({ cwd: root, id: asked.id, answer: "medium", by: ["bob"], on }));
217
+ expect(doc.question).toMatchObject({ decider: { kind: "quorum" }, reason: null });
218
+ expect(doc.question.escalations.at(-1)).toMatchObject({ kind: "model", answer: "large", reason: "proposed large, and people answered medium", model_reason: why });
219
+ expect(fm(doc.path)).not.toMatch(/^reason:/m);
220
+ });
221
+
222
+ test("an answer below the threshold keeps its reason in the escalation, and points --json shows it on the model's answer", async () => {
223
+ const asked = ok(await askPoint({ cwd: root, point: "slice-tier", inputs: { ...big, "work-item.criteria": 22 }, ask: stub({ ...unsure, reason: "Could be either." }), on }));
224
+ expect(asked.question).toMatchObject({ state: "escalated", reason: null, model: { answer: "medium", observed: false, reason: "Could be either." } });
225
+ expect(asked.question.escalations[1]).toMatchObject({ kind: "model", model_reason: "Could be either." });
226
+ expect(ok(await askPoint({ cwd: root, point: "slice-tier", inputs: { ...big, "work-item.criteria": 23 }, ask: stub(unsure), on })).question.model).toMatchObject({ reason: null });
227
+ });
228
+
229
+ test("a workspace whose answer schema predates the reason keeps none, rather than failing the write", () => {
230
+ expect(reasonFields(pointAnswerSchema)).toEqual({ top: true, escalation: true });
231
+ const old = JSON.parse(JSON.stringify(pointAnswerSchema));
232
+ delete old.properties.reason;
233
+ delete old.definitions.escalation.properties.model_reason;
234
+ expect(reasonFields(old)).toEqual({ top: false, escalation: false });
235
+ });
236
+ });
237
+
238
+ describe("the intent walk's points, a note on an answer, and retracting it (#3351)", () => {
239
+ const walk = (node: string) => ({ "region.id": "region:app/server.mjs:1-1", "node.id": node });
240
+
241
+ test("the reference workspace declares the walk's three questions, each answered by the person walking", async () => {
242
+ const listed = await workspacePoints({ cwd: root });
243
+ read.expectValid(listed);
244
+ if ("error" in listed) throw new Error(listed.error.message);
245
+ const byName = Object.fromEntries(listed.points.map((p) => [p.name, p]));
246
+ expect(byName["intent-origin"]).toMatchObject({ candidates: ["carried-out-decision", "incidental", "unknown"], quorum: { count: 1 } });
247
+ expect(byName["intent-judgment"]).toMatchObject({ candidates: ["drift", "unwritten-supersession", "decision-wrong", "no-gap", "not-decidable"] });
248
+ expect(byName["intent-disposition"]).toMatchObject({ candidates: ["handled", "skipped", "needs-discussion"] });
249
+ for (const name of ["intent-origin", "intent-judgment", "intent-disposition"]) {
250
+ expect(byName[name].inputs.map((i: { name: string; output: string }) => [i.name, i.output])).toEqual([["region.id", "region"], ["node.id", "node"]]);
251
+ expect(byName[name].deciders.map((d: { kind: string }) => d.kind)).toEqual(["quorum"]);
252
+ }
253
+ });
254
+
255
+ test("an answer keeps its note; retracting it escalates the question again and keeps the answer, its note and why", async () => {
256
+ const asked = ok(await askPoint({ cwd: root, point: "intent-judgment", inputs: walk("decision:ref-001"), subject: "decision:ref-001", on }));
257
+ expect(asked.question).toMatchObject({ state: "escalated", open: true, note: null, retractions: [] });
258
+ expect(refused(await retractAnswer({ cwd: root, id: asked.id, by: ["alice"] }))).toBe("answer-not-answered");
259
+ const answered = ok(await answerPoint({ cwd: root, id: asked.id, answer: "drift", by: ["alice"], note: " The port moved off 8080. ", on }));
260
+ expect(answered.question).toMatchObject({ state: "answered", answer: "drift", note: "The port moved off 8080." });
261
+ expect(fm(answered.path)).toContain('note: "The port moved off 8080."');
262
+ expect(refused(await retractAnswer({ cwd: root, id: asked.id, by: ["bot"] }))).toBe("quorum-not-met");
263
+
264
+ const retracted = ok(await retractAnswer({ cwd: root, id: asked.id, by: ["alice"], note: "Wrong decision.", on: "2026-09-26" }));
265
+ expect(retracted.verb).toBe("retract");
266
+ expect(retracted.question).toMatchObject({ state: "escalated", open: true, answer: null, note: null, answeredBy: [], answeredOn: null, decider: { kind: "quorum", count: 1 } });
267
+ expect(retracted.question.retractions).toEqual([
268
+ { answer: "drift", decider: { kind: "quorum", count: 1, by: ["alice"] }, answeredBy: ["alice"], answeredOn: on, answerNote: "The port moved off 8080.", answerRelayedBy: null, by: ["alice"], on: "2026-09-26", note: "Wrong decision." },
269
+ ]);
270
+ expect(retracted.question.title).toMatch(/: open for people$/);
271
+ // Asking again leaves it with people.
272
+ expect(ok(await askPoint({ cwd: root, point: "intent-judgment", inputs: walk("decision:ref-001"), on }))).toMatchObject({ reused: true, question: { state: "escalated" } });
273
+
274
+ const again = ok(await answerPoint({ cwd: root, id: asked.id, answer: "no-gap", by: ["bob"], on: "2026-09-27" }));
275
+ expect(again.question).toMatchObject({ state: "answered", answer: "no-gap", note: null, answeredBy: ["bob"] });
276
+ expect(again.question.retractions).toHaveLength(1);
277
+ const listed = await workspacePoints({ cwd: root });
278
+ read.expectValid(listed);
279
+ if ("error" in listed) throw new Error(listed.error.message);
280
+ expect(listed.questions.find((q) => q.id === asked.id)).toMatchObject({ answer: "no-gap", retractions: [{ answer: "drift", note: "Wrong decision." }] });
281
+ });
282
+
283
+ test("retracting a confirmed proposal puts the model's answer back among the escalations", async () => {
284
+ const asked = ok(await askPoint({ cwd: root, point: "slice-tier", inputs: { ...big, "work-item.criteria": 30 }, ask: stub({ ...confident, reason: "Many criteria." }), on }));
285
+ ok(await answerPoint({ cwd: root, id: asked.id, answer: "large", by: ["alice"], on }));
286
+ const dry = ok(await retractAnswer({ cwd: root, id: asked.id, by: ["alice"], dryRun: true }));
287
+ expect(dry).toMatchObject({ dryRun: true, written: false, question: { state: "escalated" } });
288
+ expect(fm(asked.path)).toMatch(/^state: "answered"$/m);
289
+ const doc = ok(await retractAnswer({ cwd: root, id: asked.id, by: ["alice"], on }));
290
+ expect(doc.question).toMatchObject({ state: "escalated", decider: { kind: "quorum" }, probabilities: null, confidence: null, reason: null });
291
+ expect(doc.question.retractions[0]).toMatchObject({ answer: "large", decider: { kind: "model", model: "bosun-v3.1-1.7b" } });
292
+ expect(doc.question.escalations.at(-1)).toMatchObject({ kind: "model", answer: "large", reason: "proposed large, which people confirmed and then retracted", model_reason: "Many criteria." });
293
+ });
294
+
295
+ test("a workspace whose answer schema predates notes and retractions refuses them, rather than dropping them", () => {
296
+ expect(answerFields(pointAnswerSchema)).toEqual({ note: true, retractions: true, relayedBy: true, asked: true });
297
+ const old = JSON.parse(JSON.stringify(pointAnswerSchema));
298
+ delete old.properties.note;
299
+ delete old.properties.retractions;
300
+ delete old.properties.relayed_by;
301
+ delete old.properties.asked;
302
+ expect(answerFields(old)).toEqual({ note: false, retractions: false, relayedBy: false, asked: false });
303
+ });
304
+
305
+ test("an answer relayed for a person records who relayed it, and a retraction keeps it (#3402)", async () => {
306
+ const asked = ok(await askPoint({ cwd: root, point: "intent-origin", inputs: walk("decision:ref-002"), on }));
307
+ expect(asked.question).toMatchObject({ relayedBy: null });
308
+ const answered = ok(await answerPoint({ cwd: root, id: asked.id, answer: "incidental", by: ["alice"], relayedBy: " follower:hud-player-7 ", on }));
309
+ expect(answered.question).toMatchObject({ state: "answered", answeredBy: ["alice"], relayedBy: "follower:hud-player-7" });
310
+ expect(fm(answered.path)).toContain('relayed_by: "follower:hud-player-7"');
311
+ const retracted = ok(await retractAnswer({ cwd: root, id: asked.id, by: ["alice"], on: "2026-09-26" }));
312
+ expect(retracted.question).toMatchObject({ relayedBy: null, retractions: [{ answer: "incidental", answeredBy: ["alice"], answerRelayedBy: "follower:hud-player-7" }] });
313
+ expect(fm(asked.path)).toContain('answer_relayed_by: "follower:hud-player-7"');
314
+ });
315
+ });
316
+
317
+ describe("an ad-hoc question whose candidates come with the ask (#3403)", () => {
318
+ const room = {
319
+ question: "Which language should the importer be written in?",
320
+ criteria: { ts: "TypeScript: matches the rest of the repo.", py: "Python: the parser library is better." },
321
+ };
322
+
323
+ test("the reference workspace declares agent-question, ad hoc and decided by one person", async () => {
324
+ const listed = await workspacePoints({ cwd: root });
325
+ read.expectValid(listed);
326
+ if ("error" in listed) throw new Error(listed.error.message);
327
+ const p = listed.points.find((x) => x.name === "agent-question")!;
328
+ expect(p).toMatchObject({ adhoc: true, questionType: "choice", candidates: [], criteria: {}, quorum: { count: 1 } });
329
+ expect(p.inputs.map((i) => [i.name, i.output])).toEqual([["ask.id", "ask"], ["ask.by", "ask"]]);
330
+ expect(listed.points.find((x) => x.name === "slice-tier")).toMatchObject({ adhoc: false });
331
+ });
332
+
333
+ test("the ask keeps the question and candidates; the answer is checked against them, noted, retracted and answered again", async () => {
334
+ const inputs = { "ask.id": "req-1", "ask.by": "hud:session-7" };
335
+ const asked = ok(await askPoint({ cwd: root, point: "agent-question", inputs, candidates: room, subject: "hud:session-7", on }));
336
+ expect(asked.question).toMatchObject({
337
+ state: "escalated",
338
+ open: true,
339
+ point: "agent-question",
340
+ title: "Which language should the importer be written in? (hud:session-7): open for people",
341
+ candidates: ["ts", "py"],
342
+ asked: room,
343
+ decider: { kind: "quorum", count: 1 },
344
+ });
345
+ const text = fm(asked.path);
346
+ expect(text).toContain('asked:\n question: "Which language should the importer be written in?"');
347
+ expect(text).toContain("- ts: TypeScript: matches the rest of the repo.");
348
+
349
+ // The same ask returns the same question; other options are another question.
350
+ expect(ok(await askPoint({ cwd: root, point: "agent-question", inputs, candidates: room, on }))).toMatchObject({ reused: true, id: asked.id });
351
+ const other = ok(await askPoint({ cwd: root, point: "agent-question", inputs, candidates: { ...room, criteria: { ...room.criteria, go: "Go." } }, on, dryRun: true }));
352
+ expect(other.id).not.toBe(asked.id);
353
+
354
+ expect(refused(await answerPoint({ cwd: root, id: asked.id, answer: "rust", by: ["alice"] }))).toBe("answer-not-candidate");
355
+ const answered = ok(await answerPoint({ cwd: root, id: asked.id, answer: "py", by: ["alice"], note: "The parser decides it.", on }));
356
+ expect(answered.question).toMatchObject({ state: "answered", answer: "py", answeredBy: ["alice"], note: "The parser decides it.", asked: room, title: "Which language should the importer be written in? (hud:session-7): py" });
357
+ const retracted = ok(await retractAnswer({ cwd: root, id: asked.id, by: ["alice"], note: "Asked too early.", on }));
358
+ expect(retracted.question).toMatchObject({ state: "escalated", asked: room, retractions: [{ answer: "py" }] });
359
+ ok(await answerPoint({ cwd: root, id: asked.id, answer: "ts", by: ["bob"], on }));
360
+
361
+ const listed = await workspacePoints({ cwd: root });
362
+ read.expectValid(listed);
363
+ if ("error" in listed) throw new Error(listed.error.message);
364
+ expect(listed.questions.find((q) => q.id === asked.id)).toMatchObject({ state: "answered", answer: "ts", answeredBy: ["bob"], asked: room, candidates: ["ts", "py"] });
365
+ expect(listed.questions.find((q) => q.point === "slice-tier")).toMatchObject({ asked: null });
366
+ });
367
+
368
+ test("refusals: no candidates for an ad-hoc point, candidates for a declared one, candidates that don't fit", async () => {
369
+ const inputs = { "ask.id": "req-2" };
370
+ expect(refused(await askPoint({ cwd: root, point: "agent-question", inputs }))).toBe("point-candidates-invalid");
371
+ expect(refused(await askPoint({ cwd: root, point: "slice-tier", inputs: { "work-item.fits_small": true }, candidates: room }))).toBe("point-candidates-invalid");
372
+ for (const bad of [[], { question: "Which?", criteria: { only: "One option." } }, { question: "", criteria: room.criteria }, { ...room, extra: 1 }, { question: "Which?", criteria: ["a", "b"] }]) {
373
+ const doc = await askPoint({ cwd: root, point: "agent-question", inputs, candidates: bad });
374
+ expect(refused(doc)).toBe("point-candidates-invalid");
375
+ }
376
+ });
377
+
378
+ test("an ad-hoc point leaves out criteria and is decided by one quorum", () => {
379
+ const base = { title: "Ad hoc", adhoc: true, question: { type: "choice", instructions: "Asked at runtime." }, inputs: { "ask.id": "the ask" } };
380
+ expect(() => parsePoints(JSON.stringify({ points: { a: { ...base, deciders: [{ kind: "quorum", count: 1 }] } } }), "points.json")).not.toThrow();
381
+ expect(() => parsePoints(JSON.stringify({ points: { a: { ...base, question: { ...base.question, criteria: { x: "X", y: "Y" } }, deciders: [{ kind: "quorum", count: 1 }] } } }), "points.json")).toThrow(/leave criteria out/);
382
+ expect(() =>
383
+ parsePoints(JSON.stringify({ points: { a: { ...base, deciders: [{ kind: "model", backend: "systemone", model: "jev-1.13.0", threshold: 0.8 }, { kind: "quorum", count: 1 }] } } }), "points.json"),
384
+ ).toThrow(/decided by people alone/);
385
+ expect(() => parsePoints(JSON.stringify({ points: { a: { ...base, adhoc: false, deciders: [{ kind: "quorum", count: 1 }] } } }), "points.json")).toThrow(/criteria/);
386
+ });
387
+
388
+ test("a workspace whose answer schema predates asked refuses an ad-hoc ask, rather than dropping the question", async () => {
389
+ const schemaFile = join(root, "answers", "answer.schema.json");
390
+ const original = readFileSync(schemaFile, "utf-8");
391
+ const old = JSON.parse(original);
392
+ delete old.properties.asked;
393
+ writeFileSync(schemaFile, JSON.stringify(old, null, 2));
394
+ try {
395
+ expect(refused(await askPoint({ cwd: root, point: "agent-question", inputs: { "ask.id": "req-3" }, candidates: room }))).toBe("answer-field-unsupported");
396
+ } finally {
397
+ writeFileSync(schemaFile, original);
398
+ }
399
+ });
400
+ });
401
+
198
402
  describe("the points file in check and on read (#2738)", () => {
199
403
  test("a changed point warns on its answers, and an invalid points file is WSP116 and a points-invalid source", async () => {
200
404
  const file = join(root, "decisions", "points.json");