@intentius/chant 0.100.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 (608) 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/build.d.ts +6 -0
  9. package/dist/build.d.ts.map +1 -1
  10. package/dist/builder.d.ts.map +1 -1
  11. package/dist/cli/build-options.d.ts +2 -0
  12. package/dist/cli/build-options.d.ts.map +1 -1
  13. package/dist/cli/commands/build.d.ts.map +1 -1
  14. package/dist/cli/commands/carve-emit.d.ts.map +1 -1
  15. package/dist/cli/commands/check-lexicon.d.ts +16 -0
  16. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  17. package/dist/cli/commands/import.d.ts +8 -0
  18. package/dist/cli/commands/import.d.ts.map +1 -1
  19. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  20. package/dist/cli/commands/init.d.ts +19 -0
  21. package/dist/cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/commands/onboard.d.ts +9 -0
  23. package/dist/cli/commands/onboard.d.ts.map +1 -1
  24. package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
  25. package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
  26. package/dist/cli/handlers/dev.d.ts.map +1 -1
  27. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  28. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  29. package/dist/cli/handlers/misc.d.ts.map +1 -1
  30. package/dist/cli/handlers/operator.d.ts +9 -0
  31. package/dist/cli/handlers/operator.d.ts.map +1 -1
  32. package/dist/cli/handlers/run.d.ts.map +1 -1
  33. package/dist/cli/lsp/server.d.ts.map +1 -1
  34. package/dist/cli/main.d.ts.map +1 -1
  35. package/dist/cli/mcp/server.d.ts.map +1 -1
  36. package/dist/cli/mcp/tools/build.d.ts.map +1 -1
  37. package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
  38. package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
  39. package/dist/cli/mcp/tools/import.d.ts.map +1 -1
  40. package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
  41. package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
  42. package/dist/cli/mcp/tools/search.d.ts.map +1 -1
  43. package/dist/cli/mcp/workspace-tools.d.ts +9 -1
  44. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  45. package/dist/cli/registry.d.ts +33 -2
  46. package/dist/cli/registry.d.ts.map +1 -1
  47. package/dist/codegen/fetch.d.ts.map +1 -1
  48. package/dist/codegen/naming.d.ts.map +1 -1
  49. package/dist/codegen/pinned-upgrade.d.ts +67 -3
  50. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  51. package/dist/codegen/registry.d.ts.map +1 -1
  52. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  53. package/dist/components/capability.d.ts.map +1 -1
  54. package/dist/components/driver.d.ts.map +1 -1
  55. package/dist/components/fan-out.d.ts.map +1 -1
  56. package/dist/components/starter-plugin.d.ts.map +1 -1
  57. package/dist/components/verbs/process-runner.d.ts.map +1 -1
  58. package/dist/components/verbs/r2-sync.d.ts.map +1 -1
  59. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  60. package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
  61. package/dist/components/verbs/sign.d.ts.map +1 -1
  62. package/dist/components/verbs/verify.d.ts.map +1 -1
  63. package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
  64. package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
  65. package/dist/components/verbs/wrangler.d.ts.map +1 -1
  66. package/dist/composite.d.ts.map +1 -1
  67. package/dist/config.d.ts +30 -7
  68. package/dist/config.d.ts.map +1 -1
  69. package/dist/declarable.d.ts +16 -0
  70. package/dist/declarable.d.ts.map +1 -1
  71. package/dist/discovery/cache.d.ts.map +1 -1
  72. package/dist/discovery/fold-import.d.ts +15 -5
  73. package/dist/discovery/fold-import.d.ts.map +1 -1
  74. package/dist/discovery/param-deps.d.ts +16 -0
  75. package/dist/discovery/param-deps.d.ts.map +1 -1
  76. package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
  77. package/dist/discovery/specifier-resolve.d.ts +37 -0
  78. package/dist/discovery/specifier-resolve.d.ts.map +1 -0
  79. package/dist/errors.d.ts.map +1 -1
  80. package/dist/fold/fold.d.ts +3 -1
  81. package/dist/fold/fold.d.ts.map +1 -1
  82. package/dist/graph-detail.d.ts.map +1 -1
  83. package/dist/graph-ir.d.ts.map +1 -1
  84. package/dist/graph-layout.d.ts.map +1 -1
  85. package/dist/import/base-parser.d.ts.map +1 -1
  86. package/dist/import/embedded.d.ts +7 -0
  87. package/dist/import/embedded.d.ts.map +1 -1
  88. package/dist/import/parser-options.d.ts +14 -0
  89. package/dist/import/parser-options.d.ts.map +1 -0
  90. package/dist/import/parser.d.ts +17 -0
  91. package/dist/import/parser.d.ts.map +1 -1
  92. package/dist/kubectl-context.d.ts.map +1 -1
  93. package/dist/lexicon-output.d.ts.map +1 -1
  94. package/dist/lexicon-schema.d.ts +3 -3
  95. package/dist/lexicon.d.ts +78 -3
  96. package/dist/lexicon.d.ts.map +1 -1
  97. package/dist/lifecycle/assert-live.d.ts.map +1 -1
  98. package/dist/lifecycle/gate-ledger.d.ts +15 -0
  99. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  100. package/dist/lifecycle/git.d.ts.map +1 -1
  101. package/dist/lifecycle/member-ledger.d.ts.map +1 -1
  102. package/dist/lifecycle/observe.d.ts.map +1 -1
  103. package/dist/lifecycle/plan-digest.d.ts +26 -5
  104. package/dist/lifecycle/plan-digest.d.ts.map +1 -1
  105. package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
  106. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  107. package/dist/lifecycle/scenario.d.ts.map +1 -1
  108. package/dist/lifecycle/status.d.ts.map +1 -1
  109. package/dist/lifecycle/work-lease.d.ts +61 -2
  110. package/dist/lifecycle/work-lease.d.ts.map +1 -1
  111. package/dist/lint/config.d.ts +4 -4
  112. package/dist/lint/engine.d.ts +6 -0
  113. package/dist/lint/engine.d.ts.map +1 -1
  114. package/dist/lsp/lexicon-providers.d.ts.map +1 -1
  115. package/dist/op/activities/activity-contracts.d.ts +12 -11
  116. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  117. package/dist/op/activities/apply.d.ts +79 -9
  118. package/dist/op/activities/apply.d.ts.map +1 -1
  119. package/dist/op/activities/decide.d.ts.map +1 -1
  120. package/dist/op/activities/index.d.ts +1 -1
  121. package/dist/op/activities/index.d.ts.map +1 -1
  122. package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
  123. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
  124. package/dist/op/activities/propose-upgrade.d.ts +2 -0
  125. package/dist/op/activities/propose-upgrade.d.ts.map +1 -1
  126. package/dist/op/activity-contract.d.ts +1 -1
  127. package/dist/op/activity-failure.d.ts.map +1 -1
  128. package/dist/op/activity-profiles.d.ts.map +1 -1
  129. package/dist/op/builders.d.ts.map +1 -1
  130. package/dist/op/composites/apply-op.d.ts +12 -5
  131. package/dist/op/composites/apply-op.d.ts.map +1 -1
  132. package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
  133. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
  134. package/dist/op/decide-backend.d.ts.map +1 -1
  135. package/dist/op/decide-read-inputs.d.ts.map +1 -1
  136. package/dist/op/emulator-lifecycle.d.ts +21 -2
  137. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  138. package/dist/op/gate-approval.d.ts +5 -1
  139. package/dist/op/gate-approval.d.ts.map +1 -1
  140. package/dist/op/gate-wait.d.ts.map +1 -1
  141. package/dist/op/gate.d.ts +19 -3
  142. package/dist/op/gate.d.ts.map +1 -1
  143. package/dist/op/index.d.ts +3 -1
  144. package/dist/op/index.d.ts.map +1 -1
  145. package/dist/op/local-executor.d.ts +6 -0
  146. package/dist/op/local-executor.d.ts.map +1 -1
  147. package/dist/op/operator.d.ts.map +1 -1
  148. package/dist/op/run-context.d.ts +39 -0
  149. package/dist/op/run-context.d.ts.map +1 -0
  150. package/dist/op/run-live.d.ts.map +1 -1
  151. package/dist/op/runtimes/local.d.ts.map +1 -1
  152. package/dist/op/source-archive.d.ts.map +1 -1
  153. package/dist/op/steward-beside.d.ts.map +1 -1
  154. package/dist/op/steward-points.d.ts.map +1 -1
  155. package/dist/op/steward.d.ts.map +1 -1
  156. package/dist/op/types.d.ts +8 -3
  157. package/dist/op/types.d.ts.map +1 -1
  158. package/dist/op/work-lease-run.d.ts +24 -4
  159. package/dist/op/work-lease-run.d.ts.map +1 -1
  160. package/dist/project-root.d.ts.map +1 -1
  161. package/dist/provenance.d.ts +21 -0
  162. package/dist/provenance.d.ts.map +1 -1
  163. package/dist/pseudo-parameter.d.ts.map +1 -1
  164. package/dist/reconcile.d.ts.map +1 -1
  165. package/dist/secret-materialization.d.ts.map +1 -1
  166. package/dist/serializer.d.ts +8 -0
  167. package/dist/serializer.d.ts.map +1 -1
  168. package/dist/telemetry-attribution.d.ts +77 -0
  169. package/dist/telemetry-attribution.d.ts.map +1 -0
  170. package/dist/terraform/emit-source.d.ts.map +1 -1
  171. package/dist/terraform/parse.d.ts.map +1 -1
  172. package/dist/testing.d.ts.map +1 -1
  173. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  174. package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
  175. package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
  176. package/dist/workspace/agent-cli.d.ts +88 -0
  177. package/dist/workspace/agent-cli.d.ts.map +1 -0
  178. package/dist/workspace/box-factory.d.ts +73 -0
  179. package/dist/workspace/box-factory.d.ts.map +1 -0
  180. package/dist/workspace/changes-cli.d.ts.map +1 -1
  181. package/dist/workspace/changes.d.ts +8 -1
  182. package/dist/workspace/changes.d.ts.map +1 -1
  183. package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
  184. package/dist/workspace/checks/boxes.d.ts.map +1 -1
  185. package/dist/workspace/checks/links.d.ts +1 -0
  186. package/dist/workspace/checks/links.d.ts.map +1 -1
  187. package/dist/workspace/checks/live.d.ts +40 -0
  188. package/dist/workspace/checks/live.d.ts.map +1 -0
  189. package/dist/workspace/checks.d.ts +26 -2
  190. package/dist/workspace/checks.d.ts.map +1 -1
  191. package/dist/workspace/compose-graph.d.ts +73 -0
  192. package/dist/workspace/compose-graph.d.ts.map +1 -1
  193. package/dist/workspace/conformance/index.d.ts +67 -6
  194. package/dist/workspace/conformance/index.d.ts.map +1 -1
  195. package/dist/workspace/conformance/vitest.d.ts +12 -3
  196. package/dist/workspace/conformance/vitest.d.ts.map +1 -1
  197. package/dist/workspace/conformance/writer.d.ts +368 -0
  198. package/dist/workspace/conformance/writer.d.ts.map +1 -0
  199. package/dist/workspace/decide.d.ts +1 -1
  200. package/dist/workspace/decide.d.ts.map +1 -1
  201. package/dist/workspace/declaration.d.ts +119 -0
  202. package/dist/workspace/declaration.d.ts.map +1 -1
  203. package/dist/workspace/declaration.schema.json +368 -4
  204. package/dist/workspace/export-cli.d.ts +12 -0
  205. package/dist/workspace/export-cli.d.ts.map +1 -0
  206. package/dist/workspace/export.d.ts +145 -0
  207. package/dist/workspace/export.d.ts.map +1 -0
  208. package/dist/workspace/generated-files.d.ts.map +1 -1
  209. package/dist/workspace/graph-cache.d.ts.map +1 -1
  210. package/dist/workspace/graph-cli.d.ts +2 -0
  211. package/dist/workspace/graph-cli.d.ts.map +1 -1
  212. package/dist/workspace/identity.d.ts +111 -0
  213. package/dist/workspace/identity.d.ts.map +1 -0
  214. package/dist/workspace/import.d.ts +73 -0
  215. package/dist/workspace/import.d.ts.map +1 -0
  216. package/dist/workspace/intent-cli.d.ts +7 -4
  217. package/dist/workspace/intent-cli.d.ts.map +1 -1
  218. package/dist/workspace/intent-record.d.ts +8 -1
  219. package/dist/workspace/intent-record.d.ts.map +1 -1
  220. package/dist/workspace/intent.d.ts +149 -5
  221. package/dist/workspace/intent.d.ts.map +1 -1
  222. package/dist/workspace/kinds.d.ts +24 -6
  223. package/dist/workspace/kinds.d.ts.map +1 -1
  224. package/dist/workspace/lineage-adopt-cli.d.ts +15 -0
  225. package/dist/workspace/lineage-adopt-cli.d.ts.map +1 -0
  226. package/dist/workspace/lineage-adopt.d.ts +106 -0
  227. package/dist/workspace/lineage-adopt.d.ts.map +1 -0
  228. package/dist/workspace/lineage-check.d.ts +9 -2
  229. package/dist/workspace/lineage-check.d.ts.map +1 -1
  230. package/dist/workspace/lineage-cli.d.ts +6 -1
  231. package/dist/workspace/lineage-cli.d.ts.map +1 -1
  232. package/dist/workspace/lineage-hash-index.d.ts +110 -0
  233. package/dist/workspace/lineage-hash-index.d.ts.map +1 -0
  234. package/dist/workspace/lineage-init.d.ts +10 -0
  235. package/dist/workspace/lineage-init.d.ts.map +1 -1
  236. package/dist/workspace/lineage-lock.d.ts +149 -2
  237. package/dist/workspace/lineage-lock.d.ts.map +1 -1
  238. package/dist/workspace/lineage-migrations.d.ts +15 -3
  239. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  240. package/dist/workspace/lineage-provenance.d.ts +18 -0
  241. package/dist/workspace/lineage-provenance.d.ts.map +1 -0
  242. package/dist/workspace/lineage-upgrade-cli.d.ts +2 -0
  243. package/dist/workspace/lineage-upgrade-cli.d.ts.map +1 -1
  244. package/dist/workspace/lineage-upgrade.d.ts +30 -1
  245. package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
  246. package/dist/workspace/lineage-versions.d.ts +116 -0
  247. package/dist/workspace/lineage-versions.d.ts.map +1 -0
  248. package/dist/workspace/links.d.ts +31 -5
  249. package/dist/workspace/links.d.ts.map +1 -1
  250. package/dist/workspace/ls-generated.d.ts +37 -0
  251. package/dist/workspace/ls-generated.d.ts.map +1 -0
  252. package/dist/workspace/ls.d.ts +4 -0
  253. package/dist/workspace/ls.d.ts.map +1 -1
  254. package/dist/workspace/member-commands.d.ts.map +1 -1
  255. package/dist/workspace/nested-graph.d.ts +56 -0
  256. package/dist/workspace/nested-graph.d.ts.map +1 -0
  257. package/dist/workspace/nesting.d.ts +21 -0
  258. package/dist/workspace/nesting.d.ts.map +1 -0
  259. package/dist/workspace/pin-cli.d.ts +10 -0
  260. package/dist/workspace/pin-cli.d.ts.map +1 -0
  261. package/dist/workspace/pin-integrity.d.ts +51 -0
  262. package/dist/workspace/pin-integrity.d.ts.map +1 -0
  263. package/dist/workspace/points.d.ts.map +1 -1
  264. package/dist/workspace/principal-classes.d.ts +114 -0
  265. package/dist/workspace/principal-classes.d.ts.map +1 -0
  266. package/dist/workspace/reason-codes.d.ts +47 -3
  267. package/dist/workspace/reason-codes.d.ts.map +1 -1
  268. package/dist/workspace/record-assets.d.ts.map +1 -1
  269. package/dist/workspace/record-sessions.d.ts +7 -11
  270. package/dist/workspace/record-sessions.d.ts.map +1 -1
  271. package/dist/workspace/records-checkout.d.ts +54 -0
  272. package/dist/workspace/records-checkout.d.ts.map +1 -0
  273. package/dist/workspace/records-cli.d.ts +57 -2
  274. package/dist/workspace/records-cli.d.ts.map +1 -1
  275. package/dist/workspace/records-close.d.ts +5 -2
  276. package/dist/workspace/records-close.d.ts.map +1 -1
  277. package/dist/workspace/records-since.d.ts.map +1 -1
  278. package/dist/workspace/records-write.d.ts +23 -4
  279. package/dist/workspace/records-write.d.ts.map +1 -1
  280. package/dist/workspace/records.d.ts +58 -5
  281. package/dist/workspace/records.d.ts.map +1 -1
  282. package/dist/workspace/returns.d.ts +129 -0
  283. package/dist/workspace/returns.d.ts.map +1 -0
  284. package/dist/workspace/runs-cli.d.ts +164 -0
  285. package/dist/workspace/runs-cli.d.ts.map +1 -0
  286. package/dist/workspace/runs.d.ts +423 -0
  287. package/dist/workspace/runs.d.ts.map +1 -0
  288. package/dist/workspace/source-block.d.ts +1 -1
  289. package/dist/workspace/source-block.d.ts.map +1 -1
  290. package/dist/workspace/status-gates.d.ts +15 -3
  291. package/dist/workspace/status-gates.d.ts.map +1 -1
  292. package/dist/workspace/status.d.ts +10 -0
  293. package/dist/workspace/status.d.ts.map +1 -1
  294. package/dist/workspace/symbols.d.ts +52 -0
  295. package/dist/workspace/symbols.d.ts.map +1 -0
  296. package/dist/workspace/template-manifest.d.ts +11 -3
  297. package/dist/workspace/template-manifest.d.ts.map +1 -1
  298. package/dist/workspace/trailer-joins.d.ts +46 -0
  299. package/dist/workspace/trailer-joins.d.ts.map +1 -0
  300. package/dist/workspace/trailers.d.ts +89 -0
  301. package/dist/workspace/trailers.d.ts.map +1 -0
  302. package/dist/workspace/trust/attestor.d.ts +8 -0
  303. package/dist/workspace/trust/attestor.d.ts.map +1 -1
  304. package/dist/workspace/trust/dsse.d.ts +58 -0
  305. package/dist/workspace/trust/dsse.d.ts.map +1 -0
  306. package/dist/workspace/trust/evidence-cli.d.ts +66 -0
  307. package/dist/workspace/trust/evidence-cli.d.ts.map +1 -0
  308. package/dist/workspace/trust/evidence.d.ts +93 -0
  309. package/dist/workspace/trust/evidence.d.ts.map +1 -0
  310. package/dist/workspace/trust/policy.d.ts +54 -1
  311. package/dist/workspace/trust/policy.d.ts.map +1 -1
  312. package/dist/workspace/trust/provenance.d.ts +21 -1
  313. package/dist/workspace/trust/provenance.d.ts.map +1 -1
  314. package/dist/workspace/trust/rotation.d.ts +132 -0
  315. package/dist/workspace/trust/rotation.d.ts.map +1 -0
  316. package/dist/workspace/trust/seal.d.ts +33 -0
  317. package/dist/workspace/trust/seal.d.ts.map +1 -1
  318. package/dist/workspace/trust/signers-cli.d.ts +49 -0
  319. package/dist/workspace/trust/signers-cli.d.ts.map +1 -0
  320. package/dist/workspace/trust/ssh-commit.d.ts +12 -0
  321. package/dist/workspace/trust/ssh-commit.d.ts.map +1 -1
  322. package/dist/workspace/trust/test-repo.d.ts +13 -0
  323. package/dist/workspace/trust/test-repo.d.ts.map +1 -1
  324. package/dist/workspace/trust/verify.d.ts +15 -0
  325. package/dist/workspace/trust/verify.d.ts.map +1 -1
  326. package/dist/workspace/work-cli.d.ts +39 -3
  327. package/dist/workspace/work-cli.d.ts.map +1 -1
  328. package/dist/workspace/work-evidence.d.ts +1 -1
  329. package/dist/workspace/work-evidence.d.ts.map +1 -1
  330. package/dist/workspace/work.d.ts +26 -1
  331. package/dist/workspace/work.d.ts.map +1 -1
  332. package/dist/workspace/workspace-principals.schema.json +60 -0
  333. package/dist/workspace/write-scope.d.ts +259 -0
  334. package/dist/workspace/write-scope.d.ts.map +1 -0
  335. package/dist/yaml.d.ts +21 -39
  336. package/dist/yaml.d.ts.map +1 -1
  337. package/package.json +2 -2
  338. package/src/audit/prior-art.ts +15 -0
  339. package/src/build.ts +8 -0
  340. package/src/cli/build-options.ts +4 -1
  341. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
  342. package/src/cli/commands/build.ts +2 -0
  343. package/src/cli/commands/carve-emit-state.test.ts +4 -0
  344. package/src/cli/commands/carve-emit.ts +5 -19
  345. package/src/cli/commands/check-lexicon.test.ts +62 -1
  346. package/src/cli/commands/check-lexicon.ts +36 -6
  347. package/src/cli/commands/import-live.test.ts +87 -1
  348. package/src/cli/commands/import-parser-options.test.ts +133 -0
  349. package/src/cli/commands/import.ts +69 -25
  350. package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
  351. package/src/cli/commands/init.test.ts +8 -1
  352. package/src/cli/commands/init.ts +23 -8
  353. package/src/cli/commands/lint.test.ts +37 -0
  354. package/src/cli/commands/onboard.test.ts +53 -3
  355. package/src/cli/commands/onboard.ts +52 -4
  356. package/src/cli/commands/pinned-upgrade.ts +73 -33
  357. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
  358. package/src/cli/handlers/components.ts +2 -2
  359. package/src/cli/handlers/dev.ts +8 -6
  360. package/src/cli/handlers/fan-out.test.ts +6 -6
  361. package/src/cli/handlers/fan-out.ts +2 -1
  362. package/src/cli/handlers/graph.test.ts +42 -0
  363. package/src/cli/handlers/graph.ts +22 -0
  364. package/src/cli/handlers/lifecycle.test.ts +67 -0
  365. package/src/cli/handlers/lifecycle.ts +6 -5
  366. package/src/cli/handlers/misc.ts +2 -0
  367. package/src/cli/handlers/operator.ts +88 -4
  368. package/src/cli/handlers/run.test.ts +111 -0
  369. package/src/cli/handlers/run.ts +85 -24
  370. package/src/cli/handlers/scenario.ts +2 -2
  371. package/src/cli/main.test.ts +33 -0
  372. package/src/cli/main.ts +168 -17
  373. package/src/cli/mcp/workspace-tools.test.ts +5 -2
  374. package/src/cli/mcp/workspace-tools.ts +62 -4
  375. package/src/cli/registry.ts +33 -2
  376. package/src/cli/serve-mcp-workspace.test.ts +1 -1
  377. package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
  378. package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
  379. package/src/codegen/pinned-upgrade.test.ts +104 -0
  380. package/src/codegen/pinned-upgrade.ts +250 -56
  381. package/src/codegen/release-wiring.test.ts +5 -1
  382. package/src/codegen/testdata/postgres-tags.json +242 -0
  383. package/src/components/fan-out-output.test.ts +1 -1
  384. package/src/components/fan-out.test.ts +1 -1
  385. package/src/components/promote.test.ts +1 -1
  386. package/src/config.test.ts +21 -0
  387. package/src/config.ts +27 -0
  388. package/src/content-digest.test.ts +2 -2
  389. package/src/declarable.test.ts +21 -0
  390. package/src/declarable.ts +19 -0
  391. package/src/discovery/fold-composite.test.ts +41 -5
  392. package/src/discovery/fold-import.test.ts +129 -0
  393. package/src/discovery/fold-import.ts +643 -131
  394. package/src/discovery/fold-package-composite.test.ts +264 -0
  395. package/src/discovery/fold-specifiers.test.ts +191 -0
  396. package/src/discovery/param-deps.test.ts +66 -1
  397. package/src/discovery/param-deps.ts +45 -0
  398. package/src/discovery/specifier-resolve.ts +344 -0
  399. package/src/fold/fold.test.ts +39 -1
  400. package/src/fold/fold.ts +83 -9
  401. package/src/fold-provenance.test.ts +140 -0
  402. package/src/graph-ir.test.ts +83 -0
  403. package/src/graph-ir.ts +29 -0
  404. package/src/import/embedded.test.ts +20 -0
  405. package/src/import/embedded.ts +13 -0
  406. package/src/import/parser-options.ts +46 -0
  407. package/src/import/parser.ts +20 -0
  408. package/src/lexicon.ts +79 -3
  409. package/src/lifecycle/gate-ledger.test.ts +14 -0
  410. package/src/lifecycle/gate-ledger.ts +18 -1
  411. package/src/lifecycle/observe.test.ts +18 -0
  412. package/src/lifecycle/observe.ts +6 -4
  413. package/src/lifecycle/plan-digest.test.ts +54 -3
  414. package/src/lifecycle/plan-digest.ts +38 -8
  415. package/src/lifecycle/snapshot.ts +2 -2
  416. package/src/lifecycle/work-lease.test.ts +1 -1
  417. package/src/lifecycle/work-lease.ts +93 -2
  418. package/src/lint/engine.test.ts +55 -0
  419. package/src/lint/engine.ts +30 -4
  420. package/src/lint/output-docs.test.ts +59 -56
  421. package/src/op/activities/activity-contracts.ts +1 -0
  422. package/src/op/activities/apply.test.ts +189 -5
  423. package/src/op/activities/apply.ts +230 -8
  424. package/src/op/activities/index.ts +3 -0
  425. package/src/op/activities/lexicon-upgrade.test.ts +160 -6
  426. package/src/op/activities/lexicon-upgrade.ts +154 -51
  427. package/src/op/activities/propose-upgrade.ts +8 -5
  428. package/src/op/composites/apply-op.ts +12 -5
  429. package/src/op/composites/composites.test.ts +30 -3
  430. package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
  431. package/src/op/composites/lexicon-upgrade-op.ts +29 -8
  432. package/src/op/emulator-lifecycle.test.ts +23 -0
  433. package/src/op/emulator-lifecycle.ts +52 -14
  434. package/src/op/gate-approval.test.ts +91 -0
  435. package/src/op/gate-approval.ts +5 -1
  436. package/src/op/gate.ts +34 -8
  437. package/src/op/index.ts +3 -1
  438. package/src/op/local-executor.test.ts +15 -0
  439. package/src/op/local-executor.ts +40 -12
  440. package/src/op/local-output.ts +1 -1
  441. package/src/op/operator.ts +4 -0
  442. package/src/op/run-context.test.ts +141 -0
  443. package/src/op/run-context.ts +51 -0
  444. package/src/op/runtimes/local.test.ts +14 -0
  445. package/src/op/runtimes/local.ts +2 -0
  446. package/src/op/steward-beside.ts +2 -0
  447. package/src/op/types.ts +8 -3
  448. package/src/op/work-lease-run.test.ts +47 -0
  449. package/src/op/work-lease-run.ts +73 -11
  450. package/src/provenance.ts +35 -0
  451. package/src/serializer.ts +9 -0
  452. package/src/telemetry-attribution.test.ts +91 -0
  453. package/src/telemetry-attribution.ts +145 -0
  454. package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
  455. package/src/workspace/agent-cli.ts +138 -0
  456. package/src/workspace/agent.schema.json +378 -0
  457. package/src/workspace/behold-kinds.test.ts +1 -1
  458. package/src/workspace/box-factory.test.ts +320 -0
  459. package/src/workspace/box-factory.ts +103 -0
  460. package/src/workspace/changes-cli.ts +5 -0
  461. package/src/workspace/changes.schema.json +171 -1
  462. package/src/workspace/changes.ts +61 -4
  463. package/src/workspace/check-live.test.ts +192 -0
  464. package/src/workspace/check.schema.json +64 -0
  465. package/src/workspace/checks/boxes.test.ts +2 -0
  466. package/src/workspace/checks/links.ts +23 -2
  467. package/src/workspace/checks/live.ts +113 -0
  468. package/src/workspace/checks.test.ts +2 -2
  469. package/src/workspace/checks.ts +49 -8
  470. package/src/workspace/compose-graph.test.ts +47 -0
  471. package/src/workspace/compose-graph.ts +127 -3
  472. package/src/workspace/conformance/__fixture__/decisions/decision.kind.mjs +7 -1
  473. package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +5 -0
  474. package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +27 -0
  475. package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +95 -0
  476. package/src/workspace/conformance/__writer_fixture__/decisions/points.json +132 -0
  477. package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +48 -0
  478. package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +108 -0
  479. package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  480. package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  481. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +578 -0
  482. package/src/workspace/conformance/conformance.e2e.test.ts +35 -3
  483. package/src/workspace/conformance/index.mjs +30 -3
  484. package/src/workspace/conformance/index.ts +103 -15
  485. package/src/workspace/conformance/vitest.ts +44 -2
  486. package/src/workspace/conformance/writer-conformance.e2e.test.ts +131 -0
  487. package/src/workspace/conformance/writer.test.ts +156 -0
  488. package/src/workspace/conformance/writer.ts +880 -0
  489. package/src/workspace/decide.ts +7 -1
  490. package/src/workspace/declaration.schema.json +368 -4
  491. package/src/workspace/declaration.ts +270 -1
  492. package/src/workspace/declared-kinds.test.ts +33 -0
  493. package/src/workspace/evidence.schema.json +279 -0
  494. package/src/workspace/export-cli.ts +180 -0
  495. package/src/workspace/export-import.test.ts +282 -0
  496. package/src/workspace/export.ts +486 -0
  497. package/src/workspace/graph-cli.ts +51 -2
  498. package/src/workspace/graph-contract.test.ts +89 -4
  499. package/src/workspace/graph.schema.json +453 -1
  500. package/src/workspace/identity.test.ts +196 -0
  501. package/src/workspace/identity.ts +186 -0
  502. package/src/workspace/import.ts +325 -0
  503. package/src/workspace/intent-cli.ts +64 -10
  504. package/src/workspace/intent-record.schema.json +208 -0
  505. package/src/workspace/intent-record.ts +35 -1
  506. package/src/workspace/intent-why.test.ts +274 -0
  507. package/src/workspace/intent.schema.json +718 -7
  508. package/src/workspace/intent.test.ts +11 -2
  509. package/src/workspace/intent.ts +495 -32
  510. package/src/workspace/kinds.test.ts +5 -5
  511. package/src/workspace/kinds.ts +62 -33
  512. package/src/workspace/lineage-adopt-cli.ts +103 -0
  513. package/src/workspace/lineage-adopt.test.ts +552 -0
  514. package/src/workspace/lineage-adopt.ts +452 -0
  515. package/src/workspace/lineage-check.ts +26 -5
  516. package/src/workspace/lineage-cli.ts +12 -2
  517. package/src/workspace/lineage-hash-index.ts +305 -0
  518. package/src/workspace/lineage-init.test.ts +9 -0
  519. package/src/workspace/lineage-init.ts +29 -9
  520. package/src/workspace/lineage-lock.ts +54 -0
  521. package/src/workspace/lineage-migrations.test.ts +27 -0
  522. package/src/workspace/lineage-migrations.ts +44 -14
  523. package/src/workspace/lineage-provenance.ts +40 -0
  524. package/src/workspace/lineage-upgrade-cli.ts +9 -5
  525. package/src/workspace/lineage-upgrade.test.ts +92 -1
  526. package/src/workspace/lineage-upgrade.ts +111 -16
  527. package/src/workspace/lineage-versions.ts +348 -0
  528. package/src/workspace/links.test.ts +121 -2
  529. package/src/workspace/links.ts +97 -6
  530. package/src/workspace/ls-contract.test.ts +84 -1
  531. package/src/workspace/ls-generated.ts +111 -0
  532. package/src/workspace/ls.schema.json +19 -0
  533. package/src/workspace/ls.ts +8 -1
  534. package/src/workspace/member-commands.ts +3 -1
  535. package/src/workspace/nested-graph.test.ts +176 -0
  536. package/src/workspace/nested-graph.ts +169 -0
  537. package/src/workspace/nesting.ts +37 -0
  538. package/src/workspace/pin-cli.test.ts +71 -0
  539. package/src/workspace/pin-cli.ts +57 -0
  540. package/src/workspace/pin-integrity.test.ts +121 -0
  541. package/src/workspace/pin-integrity.ts +104 -0
  542. package/src/workspace/points-write.schema.json +2 -0
  543. package/src/workspace/principal-classes.test.ts +175 -0
  544. package/src/workspace/principal-classes.ts +307 -0
  545. package/src/workspace/read-contract.test.ts +24 -0
  546. package/src/workspace/reason-codes.test.ts +20 -2
  547. package/src/workspace/reason-codes.ts +53 -3
  548. package/src/workspace/record-sessions.ts +12 -14
  549. package/src/workspace/records-amend.schema.json +6 -0
  550. package/src/workspace/records-checkout.ts +106 -0
  551. package/src/workspace/records-cli.ts +195 -22
  552. package/src/workspace/records-close.schema.json +7 -2
  553. package/src/workspace/records-close.ts +10 -2
  554. package/src/workspace/records-formats.test.ts +13 -5
  555. package/src/workspace/records-new.schema.json +6 -0
  556. package/src/workspace/records-review.schema.json +6 -0
  557. package/src/workspace/records-sessions.test.ts +23 -6
  558. package/src/workspace/records-uncommitted.test.ts +171 -0
  559. package/src/workspace/records-write.test.ts +65 -8
  560. package/src/workspace/records-write.ts +92 -6
  561. package/src/workspace/records.schema.json +127 -4
  562. package/src/workspace/records.ts +123 -5
  563. package/src/workspace/returns.ts +328 -0
  564. package/src/workspace/runs-cli.ts +381 -0
  565. package/src/workspace/runs-write.schema.json +583 -0
  566. package/src/workspace/runs.schema.json +810 -0
  567. package/src/workspace/runs.test.ts +242 -0
  568. package/src/workspace/runs.ts +709 -0
  569. package/src/workspace/signers.schema.json +206 -0
  570. package/src/workspace/status-contract.test.ts +5 -0
  571. package/src/workspace/status-gates.ts +24 -9
  572. package/src/workspace/status.schema.json +127 -2
  573. package/src/workspace/status.ts +21 -1
  574. package/src/workspace/symbols.ts +180 -0
  575. package/src/workspace/template-manifest.ts +22 -4
  576. package/src/workspace/trailer-joins.test.ts +171 -0
  577. package/src/workspace/trailer-joins.ts +82 -0
  578. package/src/workspace/trailers.ts +148 -0
  579. package/src/workspace/trust/attestor.ts +15 -0
  580. package/src/workspace/trust/dsse.ts +134 -0
  581. package/src/workspace/trust/evidence-cli.ts +195 -0
  582. package/src/workspace/trust/evidence.test.ts +241 -0
  583. package/src/workspace/trust/evidence.ts +207 -0
  584. package/src/workspace/trust/policy.ts +110 -3
  585. package/src/workspace/trust/provenance.ts +41 -4
  586. package/src/workspace/trust/record-seal.test.ts +1 -1
  587. package/src/workspace/trust/rotation.test.ts +258 -0
  588. package/src/workspace/trust/rotation.ts +336 -0
  589. package/src/workspace/trust/seal.ts +63 -1
  590. package/src/workspace/trust/signers-cli.ts +178 -0
  591. package/src/workspace/trust/ssh-commit.ts +53 -4
  592. package/src/workspace/trust/test-repo.ts +18 -0
  593. package/src/workspace/trust/trust.test.ts +8 -2
  594. package/src/workspace/trust/verify-cli.ts +1 -0
  595. package/src/workspace/trust/verify.ts +22 -0
  596. package/src/workspace/work-cli.e2e.test.ts +28 -1
  597. package/src/workspace/work-cli.ts +133 -8
  598. package/src/workspace/work-evidence.schema.json +6 -0
  599. package/src/workspace/work-history.schema.json +73 -1
  600. package/src/workspace/work-history.test.ts +48 -5
  601. package/src/workspace/work-kind-fields.test.ts +154 -0
  602. package/src/workspace/work-lease.schema.json +14 -1
  603. package/src/workspace/work.ts +82 -0
  604. package/src/workspace/workspace-principals.schema.json +60 -0
  605. package/src/workspace/write-scope.test.ts +466 -0
  606. package/src/workspace/write-scope.ts +573 -0
  607. package/src/yaml.test.ts +111 -1
  608. package/src/yaml.ts +141 -549
@@ -0,0 +1,325 @@
1
+ /**
2
+ * `chant workspace import`: bring an export back into the workspace it came
3
+ * from (#2552, #2524 D10, requirements X3 and X5, ws-004, ws-073).
4
+ *
5
+ * The source is the export member, or a directory holding a copy of an
6
+ * export, such as the repository a hosted copy was kept in. Its
7
+ * `.chant/export.json` names the workspace and the members that went, and the
8
+ * hash each file had on both sides when it went: the merge base.
9
+ *
10
+ * For each file, three hashes decide. A file the copy did not change is left
11
+ * alone. A file the copy changed is written when the workspace did not
12
+ * change it since the export. A file both changed differently is a conflict,
13
+ * and any conflict refuses the whole import, which then writes nothing. The
14
+ * same holds for removed and added files. Only paths inside the members that
15
+ * went, and the record directories of a whole export, are written: a copy
16
+ * that holds anything else is refused, so an import never writes into another
17
+ * member.
18
+ *
19
+ * Host values switch back (X3): the host-bound values the export recorded
20
+ * are put back in the files the lineage lists, and in the lock. Each lineage
21
+ * scope merges the same way as a file, with the scope's digest as the base.
22
+ *
23
+ * Every write is recorded in `.chant/returns/<id>.json` (./returns.ts). When
24
+ * the copy is a git repository of its own, each written file also carries the
25
+ * commit that last changed it there, with the original signature, and the
26
+ * tree objects that tie that commit to the bytes. Records keep their seals,
27
+ * since their bytes are copied as they are.
28
+ *
29
+ * Last, the export member is written again from the workspace as it now
30
+ * stands (the default), or removed with its declaration entry (`--remove`).
31
+ */
32
+
33
+ import { execFileSync } from "node:child_process";
34
+ import { createHash } from "node:crypto";
35
+ import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
36
+ import { dirname, join, relative, resolve } from "node:path";
37
+ import { readDeclaration, type Declaration } from "./declaration";
38
+ import {
39
+ EXPORT_MANIFEST,
40
+ ExportError,
41
+ exportMember,
42
+ exportWorkspace,
43
+ gitTopOf,
44
+ isLockPath,
45
+ lineageDigest,
46
+ listFiles,
47
+ lockDir,
48
+ rawDeclaration,
49
+ readManifestAt,
50
+ scopedPath,
51
+ switchHostValues,
52
+ under,
53
+ type ExportManifest,
54
+ type ExportResult,
55
+ } from "./export";
56
+ import { fileHash, LOCK_FILE, parseLock, renderLock, type LineageLock } from "./lineage-lock";
57
+ import { buildOrigin, originSigners, RETURNS_DIR, writeReturn, type ReturnRecord } from "./returns";
58
+ import { workingTree } from "./tree";
59
+
60
+ export interface ImportOptions {
61
+ /** The workspace root. */
62
+ root: string;
63
+ /** The returned copy's directory. Absent: the export member. */
64
+ from?: string;
65
+ /** Remove the export member and its declaration entry, rather than writing it again. */
66
+ remove?: boolean;
67
+ dryRun?: boolean;
68
+ }
69
+
70
+ export interface ImportConflict {
71
+ path: string;
72
+ reason: string;
73
+ }
74
+
75
+ export interface ImportResult {
76
+ /** The export the copy started from. */
77
+ export: string;
78
+ /** The copy's directory, as given or the export member's. */
79
+ from: string;
80
+ written: string[];
81
+ removed: string[];
82
+ /** Locks changed, by path. */
83
+ locks: string[];
84
+ /** Paths whose host-bound values were switched back. */
85
+ hostValues: string[];
86
+ conflicts: ImportConflict[];
87
+ /** Paths in the copy that are outside every member that went. */
88
+ outside: string[];
89
+ /** The return record written, relative to the workspace root, or null when nothing changed or for a dry run. */
90
+ returnRecord: string | null;
91
+ return: ReturnRecord | null;
92
+ /** What happened to the export member: written again, removed, or left (nothing changed, a dry run, or a conflict). */
93
+ member: { name: string; action: "regenerated" | "removed" | "left"; note?: string } | null;
94
+ applied: boolean;
95
+ }
96
+
97
+ /** Paths the copy may hold besides member and record files. */
98
+ function ignoredInCopy(path: string): boolean {
99
+ return path === EXPORT_MANIFEST || path === "chant.workspace.json" || path === "chant.workspace.jsonc" || path.startsWith(`${RETURNS_DIR}/`);
100
+ }
101
+
102
+ function readOr(abs: string): Buffer | undefined {
103
+ return existsSync(abs) ? readFileSync(abs) : undefined;
104
+ }
105
+
106
+ /** Plan the import, and apply it unless `dryRun` or a conflict. Throws an {@link ExportError}. */
107
+ export async function importWorkspace(o: ImportOptions): Promise<ImportResult> {
108
+ const root = resolve(o.root);
109
+ const decl = readDeclaration(workingTree(root));
110
+ const fromDir = o.from !== undefined ? resolve(o.from) : join(root, exportMember(decl).dir);
111
+ const manifest = readManifestAt(fromDir);
112
+ if (!manifest) throw new ExportError(`${fromDir} holds no ${EXPORT_MANIFEST}: it is not an export`);
113
+ if (manifest.from.workspace !== decl.name) {
114
+ throw new ExportError(`the export came from workspace ${manifest.from.workspace}, and this one is ${decl.name}`);
115
+ }
116
+ const memberDirs = manifest.members.map((name) => {
117
+ const m = decl.members.find((x) => x.name === name);
118
+ if (!m) throw new ExportError(`member ${name} went with the export, and this workspace no longer declares it`);
119
+ return m.dir;
120
+ });
121
+ const allowed = [...memberDirs, ...manifest.dirs];
122
+ const others = decl.members.filter((m) => !manifest.members.includes(m.name) && m.dir !== ".");
123
+
124
+ // The copy's files and locks.
125
+ const copyFiles = new Map<string, Buffer>();
126
+ const copyLocks = new Map<string, LineageLock>();
127
+ const outside: string[] = [];
128
+ for (const path of listFiles(fromDir)) {
129
+ if (ignoredInCopy(path)) continue;
130
+ if (path === LOCK_FILE) {
131
+ copyLocks.set(path, parseLock(readFileSync(join(fromDir, path), "utf-8")));
132
+ continue;
133
+ }
134
+ if (!allowed.some((d) => under(path, d)) || others.some((m) => under(path, m.dir))) {
135
+ outside.push(path);
136
+ continue;
137
+ }
138
+ if (isLockPath(path)) copyLocks.set(path, parseLock(readFileSync(join(fromDir, path), "utf-8")));
139
+ else copyFiles.set(path, readFileSync(join(fromDir, path)));
140
+ }
141
+
142
+ // Each scope's digest as the copy holds it, before host values go back.
143
+ const copyDigests = new Map<string, string>();
144
+ for (const [path, lock] of copyLocks) for (const [scope, lineage] of Object.entries(lock.scopes)) copyDigests.set(`${path}#${scope}`, lineageDigest(lineage));
145
+
146
+ // Host values back (X3), in the files and in each lock.
147
+ const exportForm = new Map(copyFiles);
148
+ const hostValues = new Set<string>();
149
+ for (const [path, lock] of copyLocks) {
150
+ for (const [scope, lineage] of Object.entries(lock.scopes)) {
151
+ const values = manifest.hostValues[`${path}#${scope}`];
152
+ if (!values) continue;
153
+ const back = Object.fromEntries(Object.entries(values).map(([n, v]) => [n, { from: v.export, to: v.host }]));
154
+ for (const p of switchHostValues(lineage, lockDir(path), scope, back, copyFiles)) hostValues.add(p);
155
+ }
156
+ }
157
+
158
+ const conflicts: ImportConflict[] = [];
159
+ const writes = new Map<string, Buffer>();
160
+ const removes: string[] = [];
161
+ for (const path of [...new Set([...Object.keys(manifest.files), ...copyFiles.keys()])].sort()) {
162
+ if (!allowed.some((d) => under(path, d))) continue;
163
+ const base = manifest.files[path];
164
+ const copy = exportForm.get(path);
165
+ const changedThere = copy === undefined ? base !== undefined : base === undefined || fileHash(copy) !== base.export;
166
+ if (!changedThere) continue;
167
+ const here = readOr(join(root, path));
168
+ const changedHere = here === undefined ? base !== undefined : base === undefined || fileHash(here) !== base.host;
169
+ if (copy === undefined) {
170
+ if (here === undefined) continue;
171
+ if (changedHere) conflicts.push({ path, reason: "the copy removed it, and it changed here since the export" });
172
+ else removes.push(path);
173
+ continue;
174
+ }
175
+ const target = copyFiles.get(path)!;
176
+ if (here !== undefined && here.equals(target)) continue;
177
+ if (changedHere) {
178
+ conflicts.push({ path, reason: here === undefined ? "the copy changed it, and it was removed here since the export" : base === undefined ? "the copy added it, and a different file was added here" : "the copy and this workspace both changed it since the export" });
179
+ continue;
180
+ }
181
+ writes.set(path, target);
182
+ }
183
+
184
+ // Locks, scope by scope.
185
+ const lockWrites = new Map<string, LineageLock>();
186
+ for (const path of [...new Set([...Object.keys(manifest.locks), ...copyLocks.keys()])].sort()) {
187
+ const there = copyLocks.get(path);
188
+ const hereText = readOr(join(root, path));
189
+ const here: LineageLock | null = hereText ? parseLock(hereText.toString("utf-8")) : null;
190
+ const next: LineageLock = here ? JSON.parse(JSON.stringify(here)) : { lockVersion: 1, scopes: {} };
191
+ let changed = false;
192
+ const recorded = manifest.locks[path] ?? {};
193
+ for (const scope of [...new Set([...Object.keys(recorded), ...Object.keys(there?.scopes ?? {})])].sort()) {
194
+ const base = recorded[scope];
195
+ const theirs = there?.scopes[scope];
196
+ const ours = here?.scopes[scope];
197
+ const theirDigest = copyDigests.get(`${path}#${scope}`);
198
+ const changedThere = theirDigest === undefined ? base !== undefined : base === undefined || theirDigest !== base.export;
199
+ if (!changedThere) continue;
200
+ const changedHere = ours === undefined ? base !== undefined : base === undefined || lineageDigest(ours) !== base.host;
201
+ const where = `${path} scope ${scope}`;
202
+ if (changedHere) {
203
+ conflicts.push({ path: where, reason: "the copy and this workspace both changed the lineage since the export" });
204
+ continue;
205
+ }
206
+ if (!theirs) {
207
+ delete next.scopes[scope];
208
+ changed = true;
209
+ continue;
210
+ }
211
+ if (base?.partial && ours) {
212
+ // Only part of the scope went: take the copy's files, and nothing that would move the rest.
213
+ const { files: _f, manualSteps: _m, repinned: _r, ...a } = ours;
214
+ const { files: _f2, manualSteps: _m2, repinned: _r2, ...b } = theirs;
215
+ if (JSON.stringify(a) !== JSON.stringify(b)) {
216
+ conflicts.push({ path: where, reason: "the copy upgraded a scope only part of which went with the export; upgrade it here instead" });
217
+ continue;
218
+ }
219
+ const dir = lockDir(path);
220
+ const went = (f: string) => manifest.files[scopedPath(dir, scope, f)] !== undefined || theirs.files[f] !== undefined;
221
+ const files = Object.fromEntries(Object.entries(ours.files).filter(([f]) => !went(f)));
222
+ next.scopes[scope] = {
223
+ ...ours,
224
+ files: { ...files, ...theirs.files },
225
+ manualSteps: [...ours.manualSteps.filter((s) => !went(s.path)), ...theirs.manualSteps],
226
+ };
227
+ } else {
228
+ next.scopes[scope] = theirs;
229
+ }
230
+ changed = true;
231
+ }
232
+ if (changed) lockWrites.set(path, next);
233
+ }
234
+
235
+ const result: ImportResult = {
236
+ export: manifest.id,
237
+ from: fromDir,
238
+ written: [...writes.keys()],
239
+ removed: removes,
240
+ locks: [...lockWrites.keys()],
241
+ hostValues: [...hostValues].filter((p) => writes.has(p)).sort(),
242
+ conflicts,
243
+ outside,
244
+ returnRecord: null,
245
+ return: null,
246
+ member: null,
247
+ applied: false,
248
+ };
249
+ if (outside.length > 0 || conflicts.length > 0) return result;
250
+ const nothing = writes.size === 0 && removes.length === 0 && lockWrites.size === 0;
251
+
252
+ // The return record: what came back, and where each file was made.
253
+ const ownRepo = gitTopOf(fromDir);
254
+ const own = ownRepo !== undefined && realpathSync(ownRepo) === realpathSync(fromDir);
255
+ let head: string | null = null;
256
+ if (own) {
257
+ try {
258
+ head = execFileSync("git", ["rev-parse", "HEAD"], { cwd: fromDir, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
259
+ } catch {
260
+ head = null;
261
+ }
262
+ }
263
+ const paths: ReturnRecord["paths"] = {};
264
+ for (const [path, data] of writes) {
265
+ const origin = own && head && !hostValues.has(path) ? buildOrigin(fromDir, path, data) : undefined;
266
+ paths[path] = { sha256: fileHash(data), ...(origin ? { origin } : {}) };
267
+ }
268
+ for (const path of lockWrites.keys()) paths[path] = { sha256: fileHash(renderLock(lockWrites.get(path)!)) };
269
+ const origins = Object.values(paths).flatMap((p) => (p.origin ? [p.origin] : []));
270
+ const idBody = JSON.stringify({ export: manifest.id, head, paths: Object.fromEntries(Object.entries(paths).map(([p, v]) => [p, v.sha256])), removes });
271
+ const ret: ReturnRecord = {
272
+ schema: 1,
273
+ id: `ret-${createHash("sha256").update(idBody).digest("hex").slice(0, 12)}`,
274
+ export: { id: manifest.id, workspace: manifest.from.workspace, revision: manifest.from.revision },
275
+ head,
276
+ paths,
277
+ removed: removes,
278
+ hostValues: result.hostValues,
279
+ signers: originSigners(origins),
280
+ };
281
+ if (!nothing) result.return = ret;
282
+ if (o.dryRun) return result;
283
+
284
+ // Apply.
285
+ for (const [path, data] of writes) {
286
+ const abs = join(root, path);
287
+ mkdirSync(dirname(abs), { recursive: true });
288
+ writeFileSync(abs, data);
289
+ }
290
+ for (const path of removes) rmSync(join(root, path), { force: true });
291
+ for (const [path, lock] of lockWrites) {
292
+ const abs = join(root, path);
293
+ mkdirSync(dirname(abs), { recursive: true });
294
+ writeFileSync(abs, renderLock(lock));
295
+ }
296
+ if (!nothing) result.returnRecord = writeReturn(root, ret);
297
+ result.applied = true;
298
+
299
+ // The export member: written again from the workspace as it stands, or removed.
300
+ result.member = await settleExportMember(root, decl, manifest, o.remove === true, fromDir);
301
+ return result;
302
+ }
303
+
304
+ async function settleExportMember(root: string, decl: Declaration, manifest: ExportManifest, remove: boolean, fromDir: string): Promise<ImportResult["member"]> {
305
+ const m = decl.members.find((x) => x.name === manifest.member);
306
+ if (!m) return null;
307
+ if (!remove) {
308
+ const again: ExportResult = await exportWorkspace({
309
+ root,
310
+ to: m.name,
311
+ ...(manifest.whole ? {} : { members: manifest.members }),
312
+ params: Object.fromEntries(Object.values(manifest.hostValues).flatMap((v) => Object.entries(v).map(([n, x]) => [n, x.export]))),
313
+ });
314
+ return { name: m.name, action: "regenerated", note: `${again.manifest.id}, ${again.files} file(s)` };
315
+ }
316
+ rmSync(join(root, m.dir), { recursive: true, force: true });
317
+ const { file, obj } = rawDeclaration(root);
318
+ if (file.endsWith(".jsonc")) {
319
+ return { name: m.name, action: "removed", note: `removed ${m.dir}; ${file} keeps comments, so drop the entry for ${m.name} by hand` };
320
+ }
321
+ obj.members = (obj.members as { name: string }[]).filter((e) => e.name !== m.name);
322
+ writeFileSync(join(root, file), JSON.stringify(obj, null, 2) + "\n");
323
+ const inside = resolve(fromDir) === resolve(root, m.dir);
324
+ return { name: m.name, action: "removed", note: `removed ${m.dir} and its entry in ${file}${inside ? "" : `; the copy at ${relative(root, fromDir) || "."} is left as it is`}` };
325
+ }
@@ -1,9 +1,10 @@
1
1
  /**
2
- * `chant workspace graph --intent <path[:start-end]> [--at <rev>] [--kind <kind file>...] [--json]`
3
- * (#2651): the intent graph over one region (`intent.ts`), printed as JSON
2
+ * `chant workspace graph --intent <path[:start-end]|path#symbol> [--at <rev>] [--kind <kind file>...] [--json]`
3
+ * (#2651, #3034): the intent graph over one region (`intent.ts`), printed as JSON
4
4
  * with `--json` or as a walk, one line per node, in the order of #2650
5
5
  * section B: the region, its decisions, their artifacts, the commits, and the
6
- * findings. Under each decision come the commits made inside its window, and
6
+ * findings, then why the region is like this: who made its current lines and
7
+ * the decisions governing it, most relevant first. Under each decision come the commits made inside its window, and
7
8
  * when any of them is not the decision's own work, the question #2650 B puts
8
9
  * to the person about it (#2656). Without `--kind`, the walk reads every
9
10
  * record kind the declaration names (#2680).
@@ -13,9 +14,9 @@ import { resolve } from "node:path";
13
14
  import { formatError } from "../cli/format";
14
15
  import type { CommandContext } from "../cli/registry";
15
16
  import { intentRecord, type IntentRecordDocument } from "./intent-record";
16
- import { intentGraph, type ArtifactNode, type CommitNode, type DecisionNode, type IntentDocument, type IntentEdge, type IntentNode, type WorkNode } from "./intent";
17
+ import { intentGraph, type ArtifactNode, type CommitNode, type DecisionNode, type IntentDocument, type IntentEdge, type IntentNode, type RunNode, type WhyAnswer, type WorkNode } from "./intent";
17
18
 
18
- const USAGE = "chant workspace graph --intent <path[:start-end]> [--at <rev>] [--kind <kind file>...] [--json]";
19
+ const USAGE = "chant workspace graph --intent <path[:start-end]|path#symbol> [--at <rev>] [--kind <kind file>...] [--json]";
19
20
  const RECORD_USAGE = "chant workspace graph --intent --record <id> [--at <rev>] [--kind <kind file>...] [--json]";
20
21
 
21
22
  type Result = Exclude<IntentDocument, { error: unknown }>;
@@ -45,7 +46,10 @@ function withinLines(doc: Result, d: DecisionNode): string[] {
45
46
  .map((p) => doc.nodes.find((n) => n.id === p.to))
46
47
  .map((n) => (n && "ref" in n ? n.ref : undefined))
47
48
  .filter(Boolean);
48
- const by = unit.length > 0 ? `unit ${unit.join(", ")}` : "no unit";
49
+ const carried = (c.joins?.records ?? []).filter((r) => r.node !== null).map((r) => `${r.kind}:${r.id}`);
50
+ const item = c.joins?.lease?.item;
51
+ if (item && !carried.some((r) => r.endsWith(`:${item}`))) carried.push(`lease on ${item}`);
52
+ const by = unit.length > 0 ? `unit ${unit.join(", ")}` : carried.length > 0 ? `carries ${carried.join(", ")}` : "no unit";
49
53
  const label = e.state === "decided" ? "decided " : "within ";
50
54
  out.push(` ${label} ${short(c.sha)} ${c.subject}; ${by}${e.state === "decided" ? `, ${d.record}'s own work` : `, in ${d.record}'s window and not its work`}`);
51
55
  }
@@ -85,6 +89,17 @@ function artifactLine(doc: Result, a: ArtifactNode): string {
85
89
  return `artifact ${a.path} ${a.pinState}; pinned by ${by.join(", ")}; now ${short(a.currentSha256)}`;
86
90
  }
87
91
 
92
+ /** What chant's own trailers on a commit say (#3149), one line each. */
93
+ function joinLines(j: CommitNode["joins"] | undefined): string[] {
94
+ if (!j) return [];
95
+ const out: string[] = [];
96
+ if (j.agent) out.push(` agent ${j.agent}`);
97
+ if (j.lease) out.push(` lease ${j.lease.token}${j.lease.item ? ` on ${j.lease.item}` : ", no lease history names it"}`);
98
+ for (const r of j.records) out.push(` record ${r.kind}:${r.id}${r.node ? "" : ", in no kind read"}`);
99
+ if (j.applied) out.push(` applied by ${j.applied.by}${j.applied.at ? ` at ${j.applied.at}` : ""}${j.applied.commit ? `, ${short(j.applied.commit)}` : ""}`);
100
+ return out;
101
+ }
102
+
88
103
  function commitLine(doc: Result, c: CommitNode): string[] {
89
104
  const lines = c.lines && c.lines.length > 0 ? `, lines ${c.lines.map((l) => (l.start === l.end ? `${l.start}` : `${l.start}-${l.end}`)).join(", ")}` : "";
90
105
  const out = [`commit ${short(c.sha)} ${c.date.slice(0, 10)} ${c.author.name}: ${c.subject}${lines}; ${c.signature.level}`];
@@ -94,6 +109,40 @@ function commitLine(doc: Result, c: CommitNode): string[] {
94
109
  for (const s of edgesFrom(doc, e.to, "serves")) out.push(` contract ${s.to.slice("contract:".length)}`);
95
110
  for (const s of edgesFrom(doc, e.to, "cites-evidence")) out.push(` evidence ${s.to.slice("evidence:".length)}`);
96
111
  }
112
+ out.push(...joinLines(c.joins));
113
+ for (const e of edgesFrom(doc, c.id, "made-by")) {
114
+ const r = doc.nodes.find((n): n is RunNode => n.kind === "run" && n.id === e.to);
115
+ if (!r) continue;
116
+ const what = r.recorded ? `${[r.harness?.name, r.model].filter(Boolean).join("/") || "no model recorded"}${r.by ? ` for ${r.by}` : ""}${r.cost ? `, ${r.cost.amount} ${r.cost.currency}` : ", unpriced"}` : "not in the run ledger";
117
+ out.push(` run ${r.run}: ${what}`);
118
+ }
119
+ return out;
120
+ }
121
+
122
+ const span = (l: { start: number; end: number }) => (l.start === l.end ? `${l.start}` : `${l.start}-${l.end}`);
123
+
124
+ /** Why the region is like this (#3034): the decisions most relevant first, then who made each span of its current lines, then the gaps. */
125
+ export function whyLines(doc: Result, why: WhyAnswer): string[] {
126
+ const out: string[] = [];
127
+ const record = (id: string) => {
128
+ const n = doc.nodes.find((x) => x.id === id);
129
+ return n && (n.kind === "decision" || n.kind === "work") ? n.record : id;
130
+ };
131
+ const runLabel = (id: string) => {
132
+ const r = doc.nodes.find((n): n is RunNode => n.kind === "run" && n.id === id);
133
+ if (!r) return id;
134
+ const what = [r.harness?.name, r.model].filter(Boolean).join("/");
135
+ return `${r.run}${what ? ` (${what})` : r.recorded ? "" : " (not in the run ledger)"}${r.unit ? ` on ${r.unit}` : ""}`;
136
+ };
137
+ out.push(`why ${why.explained ? "explained" : "unexplained"}${why.lines ? `, lines ${span(why.lines)}` : ""}`);
138
+ for (const d of why.decisions) {
139
+ out.push(` decision ${record(d.decision)} ${d.relevance}${d.lines > 0 ? `, ${d.lines} ${d.lines === 1 ? "line" : "lines"}` : ""}${d.current ? "" : ", superseded"}${d.closed ? ", closed" : ""}`);
140
+ }
141
+ for (const b of why.blame) {
142
+ const by = b.runs.length > 0 ? `; ${b.runs.map(runLabel).join(", ")}${b.narrowedBy ? " (by its hunks)" : ""}` : b.sha ? "; no run" : "";
143
+ out.push(` lines ${span(b)} ${b.sha ? short(b.sha) : "uncommitted"}${by}`);
144
+ }
145
+ for (const g of why.gaps) out.push(` gap ${g.code}: ${g.message}${g.lines ? ` (lines ${g.lines.map(span).join(", ")})` : ""}`);
97
146
  return out;
98
147
  }
99
148
 
@@ -104,7 +153,8 @@ export function formatIntent(doc: Result): string {
104
153
  if (region?.kind === "region") {
105
154
  const lines = region.lines ? `:${region.lines.start}${region.lines.end === region.lines.start ? "" : `-${region.lines.end}`}` : "";
106
155
  const where = doc.at ? `at ${short(doc.at)}` : "in the working tree";
107
- out.push(`region ${region.path}${lines} (${region.type}, member ${region.member ?? "none"}${region.generated ? ", generated" : ""}) ${where}${region.node ? `, from node ${region.node}` : ""}`);
156
+ const symbol = region.symbol ? `#${region.symbol.name} (${region.symbol.kind} ${region.symbol.qualified}, lines ${region.lines ? span(region.lines) : "none"})` : lines;
157
+ out.push(`region ${region.path}${symbol} (${region.type}, member ${region.member ?? "none"}${region.generated ? ", generated" : ""}) ${where}${region.node ? `, from node ${region.node}` : ""}`);
108
158
  }
109
159
  const files = ofKind(doc, "file");
110
160
  if (files.length > 0) out.push(`files ${files.length} under the region, ${files.filter((f) => f.generated).length} generated`);
@@ -121,6 +171,7 @@ export function formatIntent(doc: Result): string {
121
171
  out.push(`finding ${f.code}: ${f.message}${by}`);
122
172
  }
123
173
  for (const r of doc.reasons) out.push(`reason ${r.code}: ${r.message}`);
174
+ if (doc.why) out.push(...whyLines(doc, doc.why));
124
175
  const kinds = doc.kinds.length === 0 ? "; no --kind, so no decisions were read" : "";
125
176
  const work = ofKind(doc, "work").length;
126
177
  out.push(`${doc.summary.commits} commits, ${doc.summary.decisions} decisions, ${work > 0 ? `${work} work ${work === 1 ? "item" : "items"}, ` : ""}${doc.summary.artifacts} artifacts, ${doc.summary.findings} findings${kinds}`);
@@ -136,13 +187,16 @@ export function formatIntentRecord(doc: RecordResult): string {
136
187
  for (const c of doc.commits) {
137
188
  const why =
138
189
  c.bucket === "own"
139
- ? `unit ${c.unit}`
190
+ ? c.unit !== null
191
+ ? `unit ${c.unit}`
192
+ : `carries ${[...(c.joins?.records ?? []).filter((x) => x.node !== null).map((x) => `${x.kind}:${x.id}`), ...(c.joins?.lease?.item ? [`lease on ${c.joins.lease.item}`] : [])].join(", ")}`
140
193
  : c.bucket === "worked"
141
194
  ? `worked by ${c.workedBy.map((w) => w.record).join(", ")}`
142
195
  : c.bucket === "within-other"
143
196
  ? `within ${c.alsoWithin.map((w) => w.record).join(", ")}`
144
197
  : "nothing else accounts for it";
145
- out.push(`${c.bucket.padEnd(12)} ${short(c.sha)} ${c.date.slice(0, 10)} ${c.subject}; ${why}; ${c.files.join(", ") || c.entries.join(", ")}`);
198
+ const runs = (c.runs ?? []).map((r) => `run ${r.id}${r.model ? ` (${r.model})` : ""}`).join(", ");
199
+ out.push(`${c.bucket.padEnd(12)} ${short(c.sha)} ${c.date.slice(0, 10)} ${c.subject}; ${why}${runs ? `; ${runs}` : ""}; ${c.files.join(", ") || c.entries.join(", ")}`);
146
200
  }
147
201
  for (const x of doc.reasons) out.push(`reason ${x.code}: ${x.message}`);
148
202
  const n = doc.counts;
@@ -172,7 +226,7 @@ export async function runWorkspaceIntent(ctx: CommandContext, cwd: string): Prom
172
226
  return runRecord(ctx, cwd, args.kinds ?? (args.kind !== undefined ? [args.kind] : undefined));
173
227
  }
174
228
  if (!args.intent) {
175
- console.error(formatError({ message: "--intent needs a region: a path, path:line or path:start-end", hint: USAGE }));
229
+ console.error(formatError({ message: "--intent needs a region: a path, path:line, path:start-end or path#symbol", hint: USAGE }));
176
230
  return 1;
177
231
  }
178
232
  // No --kind: undefined, so the walk reads the kinds the declaration names (#2680).