@intentius/chant 0.101.0 → 0.102.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. package/dist/agents/checks.d.ts.map +1 -1
  2. package/dist/attrref.d.ts.map +1 -1
  3. package/dist/audit/discover.d.ts.map +1 -1
  4. package/dist/audit/nginx.d.ts.map +1 -1
  5. package/dist/audit/prior-art.d.ts +48 -0
  6. package/dist/audit/prior-art.d.ts.map +1 -1
  7. package/dist/behaviour-kinds.d.ts.map +1 -1
  8. package/dist/builder.d.ts.map +1 -1
  9. package/dist/cli/commands/carve-emit.d.ts.map +1 -1
  10. package/dist/cli/commands/check-lexicon.d.ts +16 -0
  11. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  12. package/dist/cli/commands/import.d.ts +8 -0
  13. package/dist/cli/commands/import.d.ts.map +1 -1
  14. package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
  15. package/dist/cli/commands/init.d.ts +19 -0
  16. package/dist/cli/commands/init.d.ts.map +1 -1
  17. package/dist/cli/commands/onboard.d.ts +9 -0
  18. package/dist/cli/commands/onboard.d.ts.map +1 -1
  19. package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
  20. package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
  21. package/dist/cli/handlers/dev.d.ts.map +1 -1
  22. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  23. package/dist/cli/handlers/misc.d.ts.map +1 -1
  24. package/dist/cli/handlers/operator.d.ts +9 -0
  25. package/dist/cli/handlers/operator.d.ts.map +1 -1
  26. package/dist/cli/handlers/run.d.ts.map +1 -1
  27. package/dist/cli/lsp/server.d.ts.map +1 -1
  28. package/dist/cli/main.d.ts.map +1 -1
  29. package/dist/cli/mcp/server.d.ts.map +1 -1
  30. package/dist/cli/mcp/tools/build.d.ts.map +1 -1
  31. package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
  32. package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
  33. package/dist/cli/mcp/tools/import.d.ts.map +1 -1
  34. package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
  35. package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
  36. package/dist/cli/mcp/tools/search.d.ts.map +1 -1
  37. package/dist/cli/mcp/workspace-tools.d.ts +1 -1
  38. package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
  39. package/dist/cli/registry.d.ts +11 -2
  40. package/dist/cli/registry.d.ts.map +1 -1
  41. package/dist/codegen/fetch.d.ts.map +1 -1
  42. package/dist/codegen/naming.d.ts.map +1 -1
  43. package/dist/codegen/pinned-upgrade.d.ts +67 -3
  44. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  45. package/dist/codegen/registry.d.ts.map +1 -1
  46. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  47. package/dist/components/capability.d.ts.map +1 -1
  48. package/dist/components/driver.d.ts.map +1 -1
  49. package/dist/components/fan-out.d.ts.map +1 -1
  50. package/dist/components/starter-plugin.d.ts.map +1 -1
  51. package/dist/components/verbs/process-runner.d.ts.map +1 -1
  52. package/dist/components/verbs/r2-sync.d.ts.map +1 -1
  53. package/dist/components/verbs/run-agent.d.ts.map +1 -1
  54. package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
  55. package/dist/components/verbs/sign.d.ts.map +1 -1
  56. package/dist/components/verbs/verify.d.ts.map +1 -1
  57. package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
  58. package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
  59. package/dist/components/verbs/wrangler.d.ts.map +1 -1
  60. package/dist/composite.d.ts.map +1 -1
  61. package/dist/config.d.ts +19 -7
  62. package/dist/config.d.ts.map +1 -1
  63. package/dist/declarable.d.ts +16 -0
  64. package/dist/declarable.d.ts.map +1 -1
  65. package/dist/discovery/cache.d.ts.map +1 -1
  66. package/dist/discovery/fold-import.d.ts +15 -5
  67. package/dist/discovery/fold-import.d.ts.map +1 -1
  68. package/dist/discovery/param-deps.d.ts +16 -0
  69. package/dist/discovery/param-deps.d.ts.map +1 -1
  70. package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
  71. package/dist/discovery/specifier-resolve.d.ts +37 -0
  72. package/dist/discovery/specifier-resolve.d.ts.map +1 -0
  73. package/dist/errors.d.ts.map +1 -1
  74. package/dist/fold/fold.d.ts +3 -1
  75. package/dist/fold/fold.d.ts.map +1 -1
  76. package/dist/graph-detail.d.ts.map +1 -1
  77. package/dist/graph-ir.d.ts.map +1 -1
  78. package/dist/graph-layout.d.ts.map +1 -1
  79. package/dist/import/base-parser.d.ts.map +1 -1
  80. package/dist/import/embedded.d.ts +7 -0
  81. package/dist/import/embedded.d.ts.map +1 -1
  82. package/dist/import/parser-options.d.ts +14 -0
  83. package/dist/import/parser-options.d.ts.map +1 -0
  84. package/dist/import/parser.d.ts +17 -0
  85. package/dist/import/parser.d.ts.map +1 -1
  86. package/dist/kubectl-context.d.ts.map +1 -1
  87. package/dist/lexicon-output.d.ts.map +1 -1
  88. package/dist/lexicon-schema.d.ts +3 -3
  89. package/dist/lexicon.d.ts +55 -3
  90. package/dist/lexicon.d.ts.map +1 -1
  91. package/dist/lifecycle/assert-live.d.ts.map +1 -1
  92. package/dist/lifecycle/gate-ledger.d.ts +15 -0
  93. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  94. package/dist/lifecycle/git.d.ts.map +1 -1
  95. package/dist/lifecycle/member-ledger.d.ts.map +1 -1
  96. package/dist/lifecycle/observe.d.ts.map +1 -1
  97. package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
  98. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  99. package/dist/lifecycle/scenario.d.ts.map +1 -1
  100. package/dist/lifecycle/status.d.ts.map +1 -1
  101. package/dist/lifecycle/work-lease.d.ts +61 -2
  102. package/dist/lifecycle/work-lease.d.ts.map +1 -1
  103. package/dist/lint/config.d.ts +8 -8
  104. package/dist/lint/engine.d.ts +6 -0
  105. package/dist/lint/engine.d.ts.map +1 -1
  106. package/dist/lsp/lexicon-providers.d.ts.map +1 -1
  107. package/dist/op/activities/activity-contracts.d.ts +11 -11
  108. package/dist/op/activities/apply.d.ts +79 -9
  109. package/dist/op/activities/apply.d.ts.map +1 -1
  110. package/dist/op/activities/decide.d.ts.map +1 -1
  111. package/dist/op/activities/index.d.ts +1 -1
  112. package/dist/op/activities/index.d.ts.map +1 -1
  113. package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
  114. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
  115. package/dist/op/activity-contract.d.ts +1 -1
  116. package/dist/op/activity-failure.d.ts.map +1 -1
  117. package/dist/op/activity-profiles.d.ts.map +1 -1
  118. package/dist/op/builders.d.ts.map +1 -1
  119. package/dist/op/composites/apply-op.d.ts +12 -5
  120. package/dist/op/composites/apply-op.d.ts.map +1 -1
  121. package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
  122. package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
  123. package/dist/op/decide-backend.d.ts.map +1 -1
  124. package/dist/op/decide-read-inputs.d.ts.map +1 -1
  125. package/dist/op/emulator-lifecycle.d.ts +21 -2
  126. package/dist/op/emulator-lifecycle.d.ts.map +1 -1
  127. package/dist/op/gate-approval.d.ts +5 -1
  128. package/dist/op/gate-approval.d.ts.map +1 -1
  129. package/dist/op/gate-wait.d.ts.map +1 -1
  130. package/dist/op/gate.d.ts +19 -3
  131. package/dist/op/gate.d.ts.map +1 -1
  132. package/dist/op/index.d.ts +2 -0
  133. package/dist/op/index.d.ts.map +1 -1
  134. package/dist/op/local-executor.d.ts +6 -0
  135. package/dist/op/local-executor.d.ts.map +1 -1
  136. package/dist/op/operator.d.ts.map +1 -1
  137. package/dist/op/run-context.d.ts +39 -0
  138. package/dist/op/run-context.d.ts.map +1 -0
  139. package/dist/op/run-live.d.ts.map +1 -1
  140. package/dist/op/runtimes/local.d.ts.map +1 -1
  141. package/dist/op/source-archive.d.ts.map +1 -1
  142. package/dist/op/steward-beside.d.ts.map +1 -1
  143. package/dist/op/steward-points.d.ts.map +1 -1
  144. package/dist/op/steward.d.ts.map +1 -1
  145. package/dist/op/types.d.ts +8 -3
  146. package/dist/op/types.d.ts.map +1 -1
  147. package/dist/op/work-lease-run.d.ts +24 -4
  148. package/dist/op/work-lease-run.d.ts.map +1 -1
  149. package/dist/project-root.d.ts.map +1 -1
  150. package/dist/provenance.d.ts +21 -0
  151. package/dist/provenance.d.ts.map +1 -1
  152. package/dist/pseudo-parameter.d.ts.map +1 -1
  153. package/dist/reconcile.d.ts.map +1 -1
  154. package/dist/secret-materialization.d.ts.map +1 -1
  155. package/dist/terraform/emit-source.d.ts.map +1 -1
  156. package/dist/terraform/parse.d.ts.map +1 -1
  157. package/dist/testing.d.ts.map +1 -1
  158. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  159. package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
  160. package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
  161. package/dist/workspace/agent-cli.d.ts +5 -0
  162. package/dist/workspace/agent-cli.d.ts.map +1 -1
  163. package/dist/workspace/box-factory.d.ts +73 -0
  164. package/dist/workspace/box-factory.d.ts.map +1 -0
  165. package/dist/workspace/changes.d.ts.map +1 -1
  166. package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
  167. package/dist/workspace/checks/boxes.d.ts.map +1 -1
  168. package/dist/workspace/checks.d.ts +5 -0
  169. package/dist/workspace/checks.d.ts.map +1 -1
  170. package/dist/workspace/compose-graph.d.ts +10 -0
  171. package/dist/workspace/compose-graph.d.ts.map +1 -1
  172. package/dist/workspace/conformance/index.d.ts +67 -6
  173. package/dist/workspace/conformance/index.d.ts.map +1 -1
  174. package/dist/workspace/conformance/vitest.d.ts +12 -3
  175. package/dist/workspace/conformance/vitest.d.ts.map +1 -1
  176. package/dist/workspace/conformance/writer.d.ts +368 -0
  177. package/dist/workspace/conformance/writer.d.ts.map +1 -0
  178. package/dist/workspace/decide.d.ts +1 -1
  179. package/dist/workspace/decide.d.ts.map +1 -1
  180. package/dist/workspace/declaration.d.ts +91 -4
  181. package/dist/workspace/declaration.d.ts.map +1 -1
  182. package/dist/workspace/declaration.schema.json +234 -5
  183. package/dist/workspace/generated-files.d.ts.map +1 -1
  184. package/dist/workspace/graph-cache.d.ts.map +1 -1
  185. package/dist/workspace/graph-cli.d.ts +2 -0
  186. package/dist/workspace/graph-cli.d.ts.map +1 -1
  187. package/dist/workspace/identity.d.ts +111 -0
  188. package/dist/workspace/identity.d.ts.map +1 -0
  189. package/dist/workspace/intent-cli.d.ts +7 -4
  190. package/dist/workspace/intent-cli.d.ts.map +1 -1
  191. package/dist/workspace/intent-record.d.ts +8 -1
  192. package/dist/workspace/intent-record.d.ts.map +1 -1
  193. package/dist/workspace/intent.d.ts +149 -5
  194. package/dist/workspace/intent.d.ts.map +1 -1
  195. package/dist/workspace/kinds.d.ts +18 -4
  196. package/dist/workspace/kinds.d.ts.map +1 -1
  197. package/dist/workspace/lineage-hash-index.d.ts.map +1 -1
  198. package/dist/workspace/lineage-lock.d.ts +2 -2
  199. package/dist/workspace/lineage-lock.d.ts.map +1 -1
  200. package/dist/workspace/links.d.ts.map +1 -1
  201. package/dist/workspace/points.d.ts.map +1 -1
  202. package/dist/workspace/principal-classes.d.ts +114 -0
  203. package/dist/workspace/principal-classes.d.ts.map +1 -0
  204. package/dist/workspace/reason-codes.d.ts +21 -1
  205. package/dist/workspace/reason-codes.d.ts.map +1 -1
  206. package/dist/workspace/record-assets.d.ts.map +1 -1
  207. package/dist/workspace/records-checkout.d.ts +54 -0
  208. package/dist/workspace/records-checkout.d.ts.map +1 -0
  209. package/dist/workspace/records-cli.d.ts +27 -1
  210. package/dist/workspace/records-cli.d.ts.map +1 -1
  211. package/dist/workspace/records-close.d.ts +1 -1
  212. package/dist/workspace/records-close.d.ts.map +1 -1
  213. package/dist/workspace/records-since.d.ts.map +1 -1
  214. package/dist/workspace/records-write.d.ts +5 -4
  215. package/dist/workspace/records-write.d.ts.map +1 -1
  216. package/dist/workspace/records.d.ts +15 -0
  217. package/dist/workspace/records.d.ts.map +1 -1
  218. package/dist/workspace/runs-cli.d.ts +164 -0
  219. package/dist/workspace/runs-cli.d.ts.map +1 -0
  220. package/dist/workspace/runs.d.ts +423 -0
  221. package/dist/workspace/runs.d.ts.map +1 -0
  222. package/dist/workspace/source-block.d.ts +1 -1
  223. package/dist/workspace/source-block.d.ts.map +1 -1
  224. package/dist/workspace/status-gates.d.ts +15 -3
  225. package/dist/workspace/status-gates.d.ts.map +1 -1
  226. package/dist/workspace/status.d.ts +10 -0
  227. package/dist/workspace/status.d.ts.map +1 -1
  228. package/dist/workspace/symbols.d.ts +52 -0
  229. package/dist/workspace/symbols.d.ts.map +1 -0
  230. package/dist/workspace/trailer-joins.d.ts +46 -0
  231. package/dist/workspace/trailer-joins.d.ts.map +1 -0
  232. package/dist/workspace/trailers.d.ts +89 -0
  233. package/dist/workspace/trailers.d.ts.map +1 -0
  234. package/dist/workspace/trust/attestor.d.ts.map +1 -1
  235. package/dist/workspace/trust/rotation.d.ts.map +1 -1
  236. package/dist/workspace/trust/seal.d.ts +33 -0
  237. package/dist/workspace/trust/seal.d.ts.map +1 -1
  238. package/dist/workspace/trust/test-repo.d.ts.map +1 -1
  239. package/dist/workspace/work-cli.d.ts +39 -3
  240. package/dist/workspace/work-cli.d.ts.map +1 -1
  241. package/dist/workspace/work-evidence.d.ts +1 -1
  242. package/dist/workspace/work-evidence.d.ts.map +1 -1
  243. package/dist/workspace/work.d.ts +26 -1
  244. package/dist/workspace/work.d.ts.map +1 -1
  245. package/dist/workspace/workspace-principals.schema.json +60 -0
  246. package/dist/workspace/write-scope.d.ts +79 -19
  247. package/dist/workspace/write-scope.d.ts.map +1 -1
  248. package/dist/yaml.d.ts +21 -39
  249. package/dist/yaml.d.ts.map +1 -1
  250. package/package.json +2 -2
  251. package/src/audit/prior-art.ts +15 -0
  252. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
  253. package/src/cli/commands/carve-emit-state.test.ts +4 -0
  254. package/src/cli/commands/carve-emit.ts +5 -19
  255. package/src/cli/commands/check-lexicon.test.ts +62 -1
  256. package/src/cli/commands/check-lexicon.ts +36 -6
  257. package/src/cli/commands/import-live.test.ts +18 -0
  258. package/src/cli/commands/import-parser-options.test.ts +133 -0
  259. package/src/cli/commands/import.ts +21 -3
  260. package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
  261. package/src/cli/commands/init.test.ts +8 -1
  262. package/src/cli/commands/init.ts +23 -8
  263. package/src/cli/commands/lint.test.ts +37 -0
  264. package/src/cli/commands/onboard.test.ts +53 -3
  265. package/src/cli/commands/onboard.ts +52 -4
  266. package/src/cli/commands/pinned-upgrade.ts +73 -33
  267. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
  268. package/src/cli/handlers/components.ts +2 -2
  269. package/src/cli/handlers/dev.ts +8 -6
  270. package/src/cli/handlers/lifecycle.test.ts +67 -0
  271. package/src/cli/handlers/lifecycle.ts +6 -5
  272. package/src/cli/handlers/misc.ts +2 -0
  273. package/src/cli/handlers/operator.ts +87 -3
  274. package/src/cli/handlers/run.test.ts +111 -0
  275. package/src/cli/handlers/run.ts +85 -24
  276. package/src/cli/handlers/scenario.ts +2 -2
  277. package/src/cli/main.test.ts +1 -0
  278. package/src/cli/main.ts +65 -11
  279. package/src/cli/mcp/workspace-tools.test.ts +5 -2
  280. package/src/cli/mcp/workspace-tools.ts +29 -2
  281. package/src/cli/registry.ts +11 -2
  282. package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
  283. package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
  284. package/src/codegen/pinned-upgrade.test.ts +104 -0
  285. package/src/codegen/pinned-upgrade.ts +250 -56
  286. package/src/codegen/testdata/postgres-tags.json +242 -0
  287. package/src/config.test.ts +21 -0
  288. package/src/config.ts +15 -0
  289. package/src/declarable.test.ts +21 -0
  290. package/src/declarable.ts +19 -0
  291. package/src/discovery/fold-composite.test.ts +41 -5
  292. package/src/discovery/fold-import.test.ts +129 -0
  293. package/src/discovery/fold-import.ts +643 -131
  294. package/src/discovery/fold-package-composite.test.ts +264 -0
  295. package/src/discovery/fold-specifiers.test.ts +191 -0
  296. package/src/discovery/param-deps.test.ts +66 -1
  297. package/src/discovery/param-deps.ts +45 -0
  298. package/src/discovery/specifier-resolve.ts +344 -0
  299. package/src/fold/fold.test.ts +39 -1
  300. package/src/fold/fold.ts +83 -9
  301. package/src/fold-provenance.test.ts +140 -0
  302. package/src/graph-ir.test.ts +83 -0
  303. package/src/graph-ir.ts +29 -0
  304. package/src/import/embedded.test.ts +20 -0
  305. package/src/import/embedded.ts +13 -0
  306. package/src/import/parser-options.ts +46 -0
  307. package/src/import/parser.ts +20 -0
  308. package/src/lexicon.ts +55 -3
  309. package/src/lifecycle/gate-ledger.ts +16 -0
  310. package/src/lifecycle/observe.test.ts +18 -0
  311. package/src/lifecycle/observe.ts +6 -4
  312. package/src/lifecycle/snapshot.ts +2 -2
  313. package/src/lifecycle/work-lease.test.ts +1 -1
  314. package/src/lifecycle/work-lease.ts +93 -2
  315. package/src/lint/engine.test.ts +55 -0
  316. package/src/lint/engine.ts +30 -4
  317. package/src/lint/output-docs.test.ts +59 -56
  318. package/src/op/activities/apply.test.ts +189 -5
  319. package/src/op/activities/apply.ts +230 -8
  320. package/src/op/activities/index.ts +3 -0
  321. package/src/op/activities/lexicon-upgrade.test.ts +160 -6
  322. package/src/op/activities/lexicon-upgrade.ts +154 -51
  323. package/src/op/composites/apply-op.ts +12 -5
  324. package/src/op/composites/composites.test.ts +30 -3
  325. package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
  326. package/src/op/composites/lexicon-upgrade-op.ts +29 -8
  327. package/src/op/emulator-lifecycle.test.ts +23 -0
  328. package/src/op/emulator-lifecycle.ts +52 -14
  329. package/src/op/gate-approval.test.ts +74 -0
  330. package/src/op/gate-approval.ts +5 -1
  331. package/src/op/gate.ts +31 -5
  332. package/src/op/index.ts +2 -0
  333. package/src/op/local-executor.test.ts +15 -0
  334. package/src/op/local-executor.ts +40 -12
  335. package/src/op/local-output.ts +1 -1
  336. package/src/op/operator.ts +4 -0
  337. package/src/op/run-context.test.ts +141 -0
  338. package/src/op/run-context.ts +51 -0
  339. package/src/op/runtimes/local.test.ts +14 -0
  340. package/src/op/runtimes/local.ts +2 -0
  341. package/src/op/steward-beside.ts +2 -0
  342. package/src/op/types.ts +8 -3
  343. package/src/op/work-lease-run.test.ts +47 -0
  344. package/src/op/work-lease-run.ts +73 -11
  345. package/src/provenance.ts +35 -0
  346. package/src/workspace/__fixtures__/studio-template-84c8b21.json +1 -1
  347. package/src/workspace/agent-cli.ts +7 -3
  348. package/src/workspace/agent.schema.json +22 -0
  349. package/src/workspace/box-factory.test.ts +320 -0
  350. package/src/workspace/box-factory.ts +103 -0
  351. package/src/workspace/changes.schema.json +12 -20
  352. package/src/workspace/changes.ts +4 -1
  353. package/src/workspace/checks/boxes.test.ts +2 -0
  354. package/src/workspace/checks.ts +29 -5
  355. package/src/workspace/compose-graph.ts +7 -0
  356. package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +27 -0
  357. package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +95 -0
  358. package/src/workspace/conformance/__writer_fixture__/decisions/points.json +132 -0
  359. package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +48 -0
  360. package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +108 -0
  361. package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  362. package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  363. package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +578 -0
  364. package/src/workspace/conformance/conformance.e2e.test.ts +35 -3
  365. package/src/workspace/conformance/index.mjs +30 -3
  366. package/src/workspace/conformance/index.ts +103 -15
  367. package/src/workspace/conformance/vitest.ts +44 -2
  368. package/src/workspace/conformance/writer-conformance.e2e.test.ts +131 -0
  369. package/src/workspace/conformance/writer.test.ts +156 -0
  370. package/src/workspace/conformance/writer.ts +880 -0
  371. package/src/workspace/decide.ts +7 -1
  372. package/src/workspace/declaration.schema.json +234 -5
  373. package/src/workspace/declaration.ts +174 -10
  374. package/src/workspace/graph-cli.ts +5 -2
  375. package/src/workspace/graph.schema.json +247 -0
  376. package/src/workspace/identity.test.ts +196 -0
  377. package/src/workspace/identity.ts +186 -0
  378. package/src/workspace/intent-cli.ts +64 -10
  379. package/src/workspace/intent-record.schema.json +208 -0
  380. package/src/workspace/intent-record.ts +35 -1
  381. package/src/workspace/intent-why.test.ts +274 -0
  382. package/src/workspace/intent.schema.json +718 -7
  383. package/src/workspace/intent.test.ts +11 -2
  384. package/src/workspace/intent.ts +495 -32
  385. package/src/workspace/kinds.ts +44 -37
  386. package/src/workspace/points-write.schema.json +1 -0
  387. package/src/workspace/principal-classes.test.ts +175 -0
  388. package/src/workspace/principal-classes.ts +307 -0
  389. package/src/workspace/reason-codes.test.ts +11 -3
  390. package/src/workspace/reason-codes.ts +24 -1
  391. package/src/workspace/records-amend.schema.json +2 -0
  392. package/src/workspace/records-checkout.ts +106 -0
  393. package/src/workspace/records-cli.ts +103 -11
  394. package/src/workspace/records-close.schema.json +1 -0
  395. package/src/workspace/records-new.schema.json +2 -0
  396. package/src/workspace/records-review.schema.json +2 -0
  397. package/src/workspace/records-uncommitted.test.ts +171 -0
  398. package/src/workspace/records-write.ts +28 -6
  399. package/src/workspace/records.schema.json +72 -1
  400. package/src/workspace/records.ts +27 -0
  401. package/src/workspace/runs-cli.ts +381 -0
  402. package/src/workspace/runs-write.schema.json +583 -0
  403. package/src/workspace/runs.schema.json +810 -0
  404. package/src/workspace/runs.test.ts +242 -0
  405. package/src/workspace/runs.ts +709 -0
  406. package/src/workspace/status-contract.test.ts +5 -0
  407. package/src/workspace/status-gates.ts +22 -8
  408. package/src/workspace/status.schema.json +127 -2
  409. package/src/workspace/status.ts +21 -1
  410. package/src/workspace/symbols.ts +180 -0
  411. package/src/workspace/trailer-joins.test.ts +171 -0
  412. package/src/workspace/trailer-joins.ts +82 -0
  413. package/src/workspace/trailers.ts +148 -0
  414. package/src/workspace/trust/seal.ts +52 -1
  415. package/src/workspace/work-cli.e2e.test.ts +28 -1
  416. package/src/workspace/work-cli.ts +133 -8
  417. package/src/workspace/work-evidence.schema.json +2 -0
  418. package/src/workspace/work-history.schema.json +73 -1
  419. package/src/workspace/work-history.test.ts +48 -5
  420. package/src/workspace/work-kind-fields.test.ts +154 -0
  421. package/src/workspace/work-lease.schema.json +14 -1
  422. package/src/workspace/work.ts +82 -0
  423. package/src/workspace/workspace-principals.schema.json +60 -0
  424. package/src/workspace/write-scope.test.ts +128 -2
  425. package/src/workspace/write-scope.ts +170 -45
  426. package/src/yaml.test.ts +111 -1
  427. package/src/yaml.ts +141 -549
@@ -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).
@@ -402,6 +402,16 @@
402
402
  "$ref": "#/$defs/recordRef"
403
403
  },
404
404
  "description": "Each other decision whose window holds the commit and whose path: entries cover one of the commit's files."
405
+ },
406
+ "joins": {
407
+ "$ref": "#/$defs/trailerJoins"
408
+ },
409
+ "runs": {
410
+ "type": "array",
411
+ "items": {
412
+ "$ref": "#/$defs/runRef"
413
+ },
414
+ "description": "The agent runs that made the commit (#3033). Added within version 1, so an older document may lack it."
405
415
  }
406
416
  }
407
417
  },
@@ -524,6 +534,204 @@
524
534
  },
525
535
  "commits": false
526
536
  }
537
+ },
538
+ "trailerJoins": {
539
+ "type": "object",
540
+ "description": "What chant's own commit trailers join the commit to (#3149, ws-075). Added within version 1, so an older document may lack it.",
541
+ "required": [
542
+ "agent",
543
+ "lease",
544
+ "run",
545
+ "records",
546
+ "applied"
547
+ ],
548
+ "properties": {
549
+ "agent": {
550
+ "type": [
551
+ "string",
552
+ "null"
553
+ ],
554
+ "description": "Chant-Agent: the agent session that wrote the commit (ws-067)."
555
+ },
556
+ "lease": {
557
+ "oneOf": [
558
+ {
559
+ "type": "null"
560
+ },
561
+ {
562
+ "type": "object",
563
+ "required": [
564
+ "token",
565
+ "item"
566
+ ],
567
+ "properties": {
568
+ "token": {
569
+ "type": "string",
570
+ "description": "Chant-Lease: the work lease's fencing token."
571
+ },
572
+ "item": {
573
+ "type": [
574
+ "string",
575
+ "null"
576
+ ],
577
+ "description": "The work item a lease history on the local chant/lifecycle branch names for the token, or null when none does."
578
+ }
579
+ }
580
+ }
581
+ ]
582
+ },
583
+ "run": {
584
+ "type": [
585
+ "string",
586
+ "null"
587
+ ],
588
+ "description": "Chant-Run: the agent run that made the commit (#3033)."
589
+ },
590
+ "records": {
591
+ "type": "array",
592
+ "description": "Each well-formed Chant-Record value, <kind>:<id>, in order.",
593
+ "items": {
594
+ "type": "object",
595
+ "required": [
596
+ "kind",
597
+ "id",
598
+ "node"
599
+ ],
600
+ "properties": {
601
+ "kind": {
602
+ "type": "string",
603
+ "description": "The record kind's name."
604
+ },
605
+ "id": {
606
+ "type": "string"
607
+ },
608
+ "node": {
609
+ "type": [
610
+ "string",
611
+ "null"
612
+ ],
613
+ "description": "The id of the record's node, record:<kind>/<id>, when a kind read has the record; null otherwise."
614
+ }
615
+ }
616
+ }
617
+ },
618
+ "applied": {
619
+ "oneOf": [
620
+ {
621
+ "type": "null"
622
+ },
623
+ {
624
+ "type": "object",
625
+ "required": [
626
+ "by",
627
+ "at",
628
+ "commit"
629
+ ],
630
+ "properties": {
631
+ "by": {
632
+ "type": "string",
633
+ "description": "Chant-Applied-By: who applied the branch."
634
+ },
635
+ "at": {
636
+ "type": [
637
+ "string",
638
+ "null"
639
+ ],
640
+ "description": "Chant-Applied-At, ISO 8601, or null when it is missing."
641
+ },
642
+ "commit": {
643
+ "type": [
644
+ "string",
645
+ "null"
646
+ ],
647
+ "description": "Chant-Applied-Commit: the applied branch's tip, or null when it is missing or not a commit id."
648
+ }
649
+ }
650
+ }
651
+ ]
652
+ }
653
+ }
654
+ },
655
+ "runRef": {
656
+ "type": "object",
657
+ "description": "An agent run that made the commit (#3033).",
658
+ "required": [
659
+ "id",
660
+ "recorded",
661
+ "state",
662
+ "harness",
663
+ "model",
664
+ "provider",
665
+ "by",
666
+ "agent",
667
+ "unit",
668
+ "joinedBy"
669
+ ],
670
+ "properties": {
671
+ "id": {
672
+ "type": "string"
673
+ },
674
+ "recorded": {
675
+ "type": "boolean",
676
+ "description": "Whether the run ledger on the local chant/lifecycle branch has the run. When false, only the id is known."
677
+ },
678
+ "state": {
679
+ "enum": [
680
+ "running",
681
+ "ended",
682
+ null
683
+ ]
684
+ },
685
+ "harness": {
686
+ "type": [
687
+ "string",
688
+ "null"
689
+ ]
690
+ },
691
+ "model": {
692
+ "type": [
693
+ "string",
694
+ "null"
695
+ ]
696
+ },
697
+ "provider": {
698
+ "type": [
699
+ "string",
700
+ "null"
701
+ ]
702
+ },
703
+ "by": {
704
+ "type": [
705
+ "string",
706
+ "null"
707
+ ],
708
+ "description": "The principal the run worked for."
709
+ },
710
+ "agent": {
711
+ "type": [
712
+ "string",
713
+ "null"
714
+ ]
715
+ },
716
+ "unit": {
717
+ "type": [
718
+ "string",
719
+ "null"
720
+ ],
721
+ "description": "The work item it worked on."
722
+ },
723
+ "joinedBy": {
724
+ "type": "array",
725
+ "minItems": 1,
726
+ "items": {
727
+ "enum": [
728
+ "trailer",
729
+ "record"
730
+ ]
731
+ },
732
+ "description": "trailer: the commit carries Chant-Run with the run's id. record: the run's end lists the commit."
733
+ }
734
+ }
527
735
  }
528
736
  }
529
737
  }
@@ -17,7 +17,8 @@
17
17
  *
18
18
  * - `own`: the record's own work, as the region walk judges it: a commit a
19
19
  * plugin joins to a unit whose unit or contract names the record, or that
20
- * serves a contract the record constrains.
20
+ * serves a contract the record constrains; or a commit whose own trailers
21
+ * (#3149) name the record, or a work item that implements it.
21
22
  * - `worked`: inside the window of a work item that is not dropped and that
22
23
  * implements the record, or whose `path:` entries cover a file the commit
23
24
  * changed in the record's region.
@@ -52,6 +53,8 @@ import { constraintCovers, isWorkspacePath, memberHolding } from "./record-asset
52
53
  import type { DecidedIn } from "./record-decided";
53
54
  import { RecordReadError } from "./records";
54
55
  import type { RecordView } from "./records-cli";
56
+ import { runsForCommits, type RunRef } from "./runs";
57
+ import { readTrailerJoins, type CommitTrailerJoins } from "./trailer-joins";
55
58
  import { joinPath } from "./tree";
56
59
  import { locateWorkspace } from "./which-chant";
57
60
  import { idList } from "./work";
@@ -91,6 +94,10 @@ export interface RecordCommit {
91
94
  pullRequest: number | null;
92
95
  /** The unit a plugin joined the commit to, or null. */
93
96
  unit: string | null;
97
+ /** What chant's own trailers join the commit to (#3149), as a commit node in `graph --intent` reports it. */
98
+ joins: CommitTrailerJoins;
99
+ /** The agent runs that made the commit (#3033): the one its Chant-Run names, and any whose record lists it. */
100
+ runs: RunRef[];
94
101
  /** The record's constrains entries whose history listed the commit. */
95
102
  entries: string[];
96
103
  /** The files the commit changed in the record's region, from the workspace root. Empty when git lists none, as for a merge that changed nothing against its first parent there. */
@@ -299,11 +306,36 @@ async function walk(query: IntentRecordQuery, head: Head): Promise<IntentRecordR
299
306
  const failedPlugins = new Set<string>();
300
307
  const constrainedContracts = constrains.filter((c) => c.granularity === "contract").map((c) => c.entry);
301
308
  const commits: RecordCommit[] = [];
309
+ // chant's own trailers (#3149): the record named outright, or a work item that implements it.
310
+ const trailerJoins = readTrailerJoins(top, [...details.values()]);
311
+ const recordKinds = new Map(kinds.filter((k) => k.records).map((k) => [k.records!.loaded.kind.name, k]));
312
+ const workKinds = kinds.filter((k) => k.records?.loaded.kind.work);
313
+ const runJoins = await runsForCommits(
314
+ top,
315
+ located.rootOnDisk,
316
+ shas.map((sha) => ({ sha, run: trailerJoins.get(sha)?.joins.run ?? null })),
317
+ );
318
+ const workImplements = (k: LoadedKind, id: string): boolean | undefined => {
319
+ const v = k.records!.views.find((x) => x.id === id);
320
+ return v ? idList(v.data, k.records!.loaded.kind.work!.implements).includes(view.id!) : undefined;
321
+ };
302
322
  for (const sha of shas) {
303
323
  const c = details.get(sha);
304
324
  if (!c) continue;
305
325
  let unit: string | null = null;
306
326
  let isOwn = false;
327
+ const joins = trailerJoins.get(sha)!.joins;
328
+ for (const r of joins.records) {
329
+ const k = recordKinds.get(r.kind);
330
+ if (!k || !k.records!.views.some((v) => v.id === r.id)) continue;
331
+ r.node = `record:${r.kind}/${r.id}`;
332
+ if (k.records!.loaded.kind.work ? workImplements(k, r.id) : r.kind === kind.name && r.id === view.id) isOwn = true;
333
+ }
334
+ const item = joins.lease?.item;
335
+ if (item) {
336
+ const holding = workKinds.filter((k) => k.records!.views.some((v) => v.id === item));
337
+ if (holding.length === 1 && workImplements(holding[0], item)) isOwn = true;
338
+ }
307
339
  for (const k of kinds) {
308
340
  if (!k.joins) continue;
309
341
  let result;
@@ -334,6 +366,8 @@ async function walk(query: IntentRecordQuery, head: Head): Promise<IntentRecordR
334
366
  trailers: c.trailers,
335
367
  pullRequest: pr ? Number(pr[1]) : null,
336
368
  unit,
369
+ joins,
370
+ runs: runJoins.refs.get(sha) ?? [],
337
371
  entries: listed.get(sha)!,
338
372
  files: files.get(sha) ?? [],
339
373
  bucket: isOwn ? "own" : workedBy.length > 0 ? "worked" : alsoWithin.length > 0 ? "within-other" : "unexplained",