@intentius/chant 0.124.12 → 0.124.14

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 (928) hide show
  1. package/bin/chant +11 -0
  2. package/dist/agents/checks.js +326 -0
  3. package/dist/agents/discover.js +885 -0
  4. package/dist/agents/importer.js +17 -0
  5. package/dist/agents/index.js +12 -0
  6. package/dist/agents/types.js +19 -0
  7. package/dist/apply.js +151 -0
  8. package/dist/attrref.js +70 -0
  9. package/dist/audit/catalog.js +350 -0
  10. package/dist/audit/core.js +252 -0
  11. package/dist/audit/discover.js +633 -0
  12. package/dist/audit/fetch.js +666 -0
  13. package/dist/audit/lineage.js +91 -0
  14. package/dist/audit/nginx.js +366 -0
  15. package/dist/audit/prior-art.js +132 -0
  16. package/dist/audit/proof.js +321 -0
  17. package/dist/audit/report-html.js +194 -0
  18. package/dist/audit/report-model.js +198 -0
  19. package/dist/audit/report.js +102 -0
  20. package/dist/audit/rules-doc.js +144 -0
  21. package/dist/audit/secrets.js +405 -0
  22. package/dist/audit/terraform-state.js +140 -0
  23. package/dist/audit/wrangler.js +262 -0
  24. package/dist/behaviour-delta.js +401 -0
  25. package/dist/behaviour-engine.js +357 -0
  26. package/dist/behaviour-graph.js +83 -0
  27. package/dist/behaviour-http.js +188 -0
  28. package/dist/behaviour-kinds.js +172 -0
  29. package/dist/behaviour-overlay.js +50 -0
  30. package/dist/behaviour-predict.js +188 -0
  31. package/dist/behaviour-request.js +194 -0
  32. package/dist/behaviour.js +1325 -0
  33. package/dist/build-params.js +108 -0
  34. package/dist/build.js +668 -0
  35. package/dist/builder.js +44 -0
  36. package/dist/cdk/advise.js +30 -0
  37. package/dist/cdk/assembly.js +122 -0
  38. package/dist/cdk/graph.js +444 -0
  39. package/dist/cdk/tier-map.js +64 -0
  40. package/dist/cdk/types.js +24 -0
  41. package/dist/change-set.js +312 -0
  42. package/dist/child-project.js +21 -0
  43. package/dist/claimed-fields.js +135 -0
  44. package/dist/cli/build-options.js +70 -0
  45. package/dist/cli/build-params-cli.js +139 -0
  46. package/dist/cli/command-group.js +123 -0
  47. package/dist/cli/commands/audit-agents.js +326 -0
  48. package/dist/cli/commands/audit.js +571 -0
  49. package/dist/cli/commands/build.js +920 -0
  50. package/dist/cli/commands/carve-apply.js +153 -0
  51. package/dist/cli/commands/carve-bridge.js +201 -0
  52. package/dist/cli/commands/carve-emit.js +332 -0
  53. package/dist/cli/commands/carve-status.js +119 -0
  54. package/dist/cli/commands/carve.js +204 -0
  55. package/dist/cli/commands/check-lexicon-docs.js +79 -0
  56. package/dist/cli/commands/check-lexicon-examples.js +177 -0
  57. package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
  58. package/dist/cli/commands/check-lexicon-mcp.js +82 -0
  59. package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
  60. package/dist/cli/commands/check-lexicon-plugin.js +104 -0
  61. package/dist/cli/commands/check-lexicon.js +766 -0
  62. package/dist/cli/commands/describe.js +85 -0
  63. package/dist/cli/commands/diff.js +175 -0
  64. package/dist/cli/commands/doctor.js +350 -0
  65. package/dist/cli/commands/import-agents.js +155 -0
  66. package/dist/cli/commands/import.js +670 -0
  67. package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
  68. package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
  69. package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
  70. package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
  71. package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
  72. package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
  73. package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
  74. package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
  75. package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
  76. package/dist/cli/commands/init-lexicon.js +172 -0
  77. package/dist/cli/commands/init.js +381 -0
  78. package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
  79. package/dist/cli/commands/lexicon-surface-diff.js +145 -0
  80. package/dist/cli/commands/licenses.js +125 -0
  81. package/dist/cli/commands/lint.d.ts.map +1 -1
  82. package/dist/cli/commands/lint.js +948 -0
  83. package/dist/cli/commands/list.js +63 -0
  84. package/dist/cli/commands/migrate.d.ts.map +1 -1
  85. package/dist/cli/commands/migrate.js +423 -0
  86. package/dist/cli/commands/onboard.js +403 -0
  87. package/dist/cli/commands/pinned-upgrade.js +191 -0
  88. package/dist/cli/commands/update.js +194 -0
  89. package/dist/cli/commands/vendor.js +217 -0
  90. package/dist/cli/conflict-check.js +104 -0
  91. package/dist/cli/debug.js +8 -0
  92. package/dist/cli/format.js +104 -0
  93. package/dist/cli/handlers/build.js +267 -0
  94. package/dist/cli/handlers/carve-apply.js +30 -0
  95. package/dist/cli/handlers/carve-bridge.js +28 -0
  96. package/dist/cli/handlers/carve-emit.js +50 -0
  97. package/dist/cli/handlers/carve-status.js +26 -0
  98. package/dist/cli/handlers/carve.js +40 -0
  99. package/dist/cli/handlers/change-set.js +46 -0
  100. package/dist/cli/handlers/components.js +730 -0
  101. package/dist/cli/handlers/dev.js +113 -0
  102. package/dist/cli/handlers/emulator.js +233 -0
  103. package/dist/cli/handlers/explain.js +54 -0
  104. package/dist/cli/handlers/fan-out.js +422 -0
  105. package/dist/cli/handlers/gate-resume.js +275 -0
  106. package/dist/cli/handlers/generate.js +84 -0
  107. package/dist/cli/handlers/graph.js +969 -0
  108. package/dist/cli/handlers/init.js +102 -0
  109. package/dist/cli/handlers/lifecycle.js +1727 -0
  110. package/dist/cli/handlers/lint.js +62 -0
  111. package/dist/cli/handlers/migrate.js +48 -0
  112. package/dist/cli/handlers/misc.js +391 -0
  113. package/dist/cli/handlers/operator.js +1162 -0
  114. package/dist/cli/handlers/override-approve.js +102 -0
  115. package/dist/cli/handlers/pr.js +503 -0
  116. package/dist/cli/handlers/promote.js +342 -0
  117. package/dist/cli/handlers/run-generate.js +206 -0
  118. package/dist/cli/handlers/run-wave.js +66 -0
  119. package/dist/cli/handlers/run.js +1191 -0
  120. package/dist/cli/handlers/scenario.js +325 -0
  121. package/dist/cli/handlers/search.js +924 -0
  122. package/dist/cli/handlers/serve.js +32 -0
  123. package/dist/cli/handlers/vendor.js +154 -0
  124. package/dist/cli/index.js +3 -0
  125. package/dist/cli/is-entry-point.js +23 -0
  126. package/dist/cli/lsp/capabilities.js +28 -0
  127. package/dist/cli/lsp/diagnostics.js +34 -0
  128. package/dist/cli/lsp/server.js +329 -0
  129. package/dist/cli/main.d.ts.map +1 -1
  130. package/dist/cli/main.js +2540 -0
  131. package/dist/cli/mcp/lifecycle-tools.js +80 -0
  132. package/dist/cli/mcp/op-tools.js +306 -0
  133. package/dist/cli/mcp/resource-handlers.js +258 -0
  134. package/dist/cli/mcp/resources/context.js +85 -0
  135. package/dist/cli/mcp/server.js +353 -0
  136. package/dist/cli/mcp/tools/build.js +111 -0
  137. package/dist/cli/mcp/tools/composites.js +95 -0
  138. package/dist/cli/mcp/tools/explain.js +166 -0
  139. package/dist/cli/mcp/tools/import.js +49 -0
  140. package/dist/cli/mcp/tools/lint.js +41 -0
  141. package/dist/cli/mcp/tools/scaffold.js +111 -0
  142. package/dist/cli/mcp/tools/search.js +112 -0
  143. package/dist/cli/mcp/types.js +1 -0
  144. package/dist/cli/mcp/workspace-plugins.js +91 -0
  145. package/dist/cli/mcp/workspace-tools.d.ts +1 -1
  146. package/dist/cli/mcp/workspace-tools.js +564 -0
  147. package/dist/cli/mcp-config.js +70 -0
  148. package/dist/cli/plugins.js +313 -0
  149. package/dist/cli/registry.js +23 -0
  150. package/dist/cli/reporters/stylish.js +329 -0
  151. package/dist/cli/version.js +15 -0
  152. package/dist/cli/watch.js +79 -0
  153. package/dist/codegen/bound-property-types.js +82 -0
  154. package/dist/codegen/coverage.js +119 -0
  155. package/dist/codegen/docs-file-markers.js +60 -0
  156. package/dist/codegen/docs-pages.js +115 -0
  157. package/dist/codegen/docs-rule-scanning.js +164 -0
  158. package/dist/codegen/docs-rules.js +76 -0
  159. package/dist/codegen/docs-sections.js +117 -0
  160. package/dist/codegen/docs-sidebar.js +65 -0
  161. package/dist/codegen/docs-types.js +4 -0
  162. package/dist/codegen/docs.js +356 -0
  163. package/dist/codegen/fetch.js +340 -0
  164. package/dist/codegen/generate-post-synth-barrel.js +63 -0
  165. package/dist/codegen/generate-registry.js +71 -0
  166. package/dist/codegen/generate-runtime-index.js +56 -0
  167. package/dist/codegen/generate-typescript.js +119 -0
  168. package/dist/codegen/generate.js +115 -0
  169. package/dist/codegen/json-patch.js +141 -0
  170. package/dist/codegen/json-schema-to-ts.js +344 -0
  171. package/dist/codegen/json-schema.js +246 -0
  172. package/dist/codegen/lexicon-regen.js +412 -0
  173. package/dist/codegen/naming.js +217 -0
  174. package/dist/codegen/okf-lexicon.js +245 -0
  175. package/dist/codegen/package.js +150 -0
  176. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  177. package/dist/codegen/pinned-upgrade.js +494 -0
  178. package/dist/codegen/registry.js +60 -0
  179. package/dist/codegen/rehype-base-url.mjs +68 -0
  180. package/dist/codegen/rolling-upgrade.js +217 -0
  181. package/dist/codegen/surface-snapshot.js +537 -0
  182. package/dist/codegen/testdata/postgres-tags.json +242 -0
  183. package/dist/codegen/topo-sort.js +36 -0
  184. package/dist/codegen/typecheck.js +115 -0
  185. package/dist/codegen/validate.js +200 -0
  186. package/dist/codegen/version-bump.js +35 -0
  187. package/dist/components/auto-release.js +143 -0
  188. package/dist/components/builders.js +47 -0
  189. package/dist/components/capability-plugin-loader.js +175 -0
  190. package/dist/components/capability-plugin-schema.js +46 -0
  191. package/dist/components/capability-plugin.js +99 -0
  192. package/dist/components/capability.js +60 -0
  193. package/dist/components/changed-files.js +72 -0
  194. package/dist/components/cli-support.js +427 -0
  195. package/dist/components/component.js +120 -0
  196. package/dist/components/component.schema.json +271 -0
  197. package/dist/components/config-defaults.js +130 -0
  198. package/dist/components/deploy-units.js +60 -0
  199. package/dist/components/discover.d.ts.map +1 -1
  200. package/dist/components/discover.js +189 -0
  201. package/dist/components/driver-output.js +86 -0
  202. package/dist/components/driver.js +728 -0
  203. package/dist/components/fan-out-output.js +165 -0
  204. package/dist/components/fan-out-record.js +94 -0
  205. package/dist/components/fan-out-run.js +373 -0
  206. package/dist/components/fan-out-support.js +60 -0
  207. package/dist/components/fan-out.js +273 -0
  208. package/dist/components/gate-plan.js +41 -0
  209. package/dist/components/gated-wave-pipeline.js +46 -0
  210. package/dist/components/index.js +24 -0
  211. package/dist/components/layers.js +28 -0
  212. package/dist/components/manifest-persistence.js +108 -0
  213. package/dist/components/pilots/alb-ecs.pilot.js +59 -0
  214. package/dist/components/pilots/dynamodb.pilot.js +51 -0
  215. package/dist/components/pilots/jar-emr.pilot.js +65 -0
  216. package/dist/components/pilots/lambda.pilot.js +52 -0
  217. package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
  218. package/dist/components/pilots/project.js +12 -0
  219. package/dist/components/pr-pipeline.js +134 -0
  220. package/dist/components/pr-run.js +363 -0
  221. package/dist/components/presets/ecs-fargate.js +72 -0
  222. package/dist/components/presets/index.js +28 -0
  223. package/dist/components/presets/lambda.js +34 -0
  224. package/dist/components/presets/single-host-compose.js +41 -0
  225. package/dist/components/promote.js +549 -0
  226. package/dist/components/registry.js +34 -0
  227. package/dist/components/run-progress.js +33 -0
  228. package/dist/components/sandbox/driver.d.ts.map +1 -1
  229. package/dist/components/sandbox/driver.js +93 -0
  230. package/dist/components/sandbox/run.js +115 -0
  231. package/dist/components/starter-plugin.js +104 -0
  232. package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
  233. package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
  234. package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
  235. package/dist/components/verbs/bom-writer.js +287 -0
  236. package/dist/components/verbs/build-archive.js +188 -0
  237. package/dist/components/verbs/build.js +142 -0
  238. package/dist/components/verbs/cloud-executor.js +110 -0
  239. package/dist/components/verbs/component-bom.js +125 -0
  240. package/dist/components/verbs/ensure-secret.js +50 -0
  241. package/dist/components/verbs/index.js +61 -0
  242. package/dist/components/verbs/license-policy.js +75 -0
  243. package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
  244. package/dist/components/verbs/process-runner.js +78 -0
  245. package/dist/components/verbs/r2-sync.js +93 -0
  246. package/dist/components/verbs/reproducibility.js +62 -0
  247. package/dist/components/verbs/run-agent.js +577 -0
  248. package/dist/components/verbs/sbom-generator.js +119 -0
  249. package/dist/components/verbs/sbom.js +97 -0
  250. package/dist/components/verbs/shell.js +32 -0
  251. package/dist/components/verbs/sign.js +221 -0
  252. package/dist/components/verbs/stub.js +28 -0
  253. package/dist/components/verbs/tool-sbom-generator.js +154 -0
  254. package/dist/components/verbs/verify.js +112 -0
  255. package/dist/components/verbs/vex.js +131 -0
  256. package/dist/components/verbs/vuln-gate.js +152 -0
  257. package/dist/components/verbs/vuln-scan.js +288 -0
  258. package/dist/components/verbs/wait-verify.js +106 -0
  259. package/dist/components/verbs/wrangler.js +179 -0
  260. package/dist/components/wave-plan.js +102 -0
  261. package/dist/composite.js +305 -0
  262. package/dist/config-import.d.ts.map +1 -1
  263. package/dist/config-import.js +22 -0
  264. package/dist/config-sandbox.js +122 -0
  265. package/dist/config-static.js +206 -0
  266. package/dist/config.js +605 -0
  267. package/dist/content-digest.js +23 -0
  268. package/dist/declarable.js +114 -0
  269. package/dist/deep-observation.js +437 -0
  270. package/dist/detectLexicon.js +54 -0
  271. package/dist/discovery/cache.js +70 -0
  272. package/dist/discovery/collect.js +208 -0
  273. package/dist/discovery/cycles.js +95 -0
  274. package/dist/discovery/entity-wire-codec.js +391 -0
  275. package/dist/discovery/entity-wire.js +42 -0
  276. package/dist/discovery/files.js +121 -0
  277. package/dist/discovery/fold-import.d.ts.map +1 -1
  278. package/dist/discovery/fold-import.js +4178 -0
  279. package/dist/discovery/fold-rank.js +292 -0
  280. package/dist/discovery/graph.js +115 -0
  281. package/dist/discovery/import.d.ts.map +1 -1
  282. package/dist/discovery/import.js +65 -0
  283. package/dist/discovery/index.js +333 -0
  284. package/dist/discovery/param-deps.js +487 -0
  285. package/dist/discovery/resolve.js +39 -0
  286. package/dist/discovery/sandbox/bundle.js +214 -0
  287. package/dist/discovery/sandbox/child-errors.js +26 -0
  288. package/dist/discovery/sandbox/config-run.js +100 -0
  289. package/dist/discovery/sandbox/config-wire.js +183 -0
  290. package/dist/discovery/sandbox/driver.d.ts.map +1 -1
  291. package/dist/discovery/sandbox/driver.js +333 -0
  292. package/dist/discovery/sandbox/fork.js +229 -0
  293. package/dist/discovery/sandbox/policy-run.js +142 -0
  294. package/dist/discovery/sandbox/policy-wire.js +152 -0
  295. package/dist/discovery/sandbox/run.js +77 -0
  296. package/dist/discovery/specifier-resolve.js +320 -0
  297. package/dist/discovery/walk.js +284 -0
  298. package/dist/effect-receipt.js +340 -0
  299. package/dist/env.js +55 -0
  300. package/dist/errors.js +62 -0
  301. package/dist/fold/fold.js +1434 -0
  302. package/dist/fold/foldable-helpers.js +229 -0
  303. package/dist/fold/subset.js +696 -0
  304. package/dist/fold-provenance.js +414 -0
  305. package/dist/gate-decision.d.ts +36 -4
  306. package/dist/gate-decision.d.ts.map +1 -1
  307. package/dist/gate-decision.js +260 -0
  308. package/dist/gate-resume-run.js +154 -0
  309. package/dist/gated-waves.js +165 -0
  310. package/dist/governance.js +43 -0
  311. package/dist/graph-declared.js +45 -0
  312. package/dist/graph-detail.js +207 -0
  313. package/dist/graph-dot.js +54 -0
  314. package/dist/graph-effective.js +107 -0
  315. package/dist/graph-ir.js +623 -0
  316. package/dist/graph-layout.js +184 -0
  317. package/dist/graph-lens.js +105 -0
  318. package/dist/graph-mermaid.js +83 -0
  319. package/dist/graph-ops.js +39 -0
  320. package/dist/graph-refs.js +156 -0
  321. package/dist/held-elsewhere.js +87 -0
  322. package/dist/identity.js +251 -0
  323. package/dist/import/base-parser.js +34 -0
  324. package/dist/import/embedded.js +255 -0
  325. package/dist/import/generator.js +1 -0
  326. package/dist/import/ir-utils.js +85 -0
  327. package/dist/import/parser-options.js +45 -0
  328. package/dist/import/parser.js +1 -0
  329. package/dist/index.js +118 -0
  330. package/dist/intrinsic-interpolation.js +73 -0
  331. package/dist/intrinsic.js +31 -0
  332. package/dist/join-key.js +35 -0
  333. package/dist/kubectl-context.js +150 -0
  334. package/dist/lexicon-config.js +58 -0
  335. package/dist/lexicon-integrity.js +47 -0
  336. package/dist/lexicon-manifest.js +70 -0
  337. package/dist/lexicon-module.d.ts.map +1 -1
  338. package/dist/lexicon-module.js +241 -0
  339. package/dist/lexicon-output.js +218 -0
  340. package/dist/lexicon-plugin-helpers.js +104 -0
  341. package/dist/lexicon-schema.js +136 -0
  342. package/dist/lexicon.js +130 -0
  343. package/dist/lifecycle/affected.js +224 -0
  344. package/dist/lifecycle/assert-live.js +110 -0
  345. package/dist/lifecycle/build-ledger-store.js +160 -0
  346. package/dist/lifecycle/build-ledger.js +155 -0
  347. package/dist/lifecycle/change-set.js +356 -0
  348. package/dist/lifecycle/converge-ledger.js +161 -0
  349. package/dist/lifecycle/deep-diff.js +233 -0
  350. package/dist/lifecycle/deep-observe.js +147 -0
  351. package/dist/lifecycle/digest.js +143 -0
  352. package/dist/lifecycle/disruption.js +135 -0
  353. package/dist/lifecycle/gate-applied.js +113 -0
  354. package/dist/lifecycle/gate-audit.js +341 -0
  355. package/dist/lifecycle/gate-ledger-select.js +89 -0
  356. package/dist/lifecycle/gate-ledger.d.ts +8 -0
  357. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  358. package/dist/lifecycle/gate-ledger.js +193 -0
  359. package/dist/lifecycle/gate-origin.js +117 -0
  360. package/dist/lifecycle/gate-pending.js +58 -0
  361. package/dist/lifecycle/git.js +1182 -0
  362. package/dist/lifecycle/identity.js +58 -0
  363. package/dist/lifecycle/index.js +26 -0
  364. package/dist/lifecycle/lease.js +283 -0
  365. package/dist/lifecycle/ledger-port.js +1 -0
  366. package/dist/lifecycle/legacy-digest.js +91 -0
  367. package/dist/lifecycle/live-diff.js +274 -0
  368. package/dist/lifecycle/local-note.js +15 -0
  369. package/dist/lifecycle/member-ledger.js +122 -0
  370. package/dist/lifecycle/observation-baseline.js +155 -0
  371. package/dist/lifecycle/observe.js +375 -0
  372. package/dist/lifecycle/oras-referrer-lookup.js +82 -0
  373. package/dist/lifecycle/override-ledger.js +54 -0
  374. package/dist/lifecycle/plan-digest.js +110 -0
  375. package/dist/lifecycle/plan-ledger.js +129 -0
  376. package/dist/lifecycle/receipt-plan.js +192 -0
  377. package/dist/lifecycle/release-ledger.js +155 -0
  378. package/dist/lifecycle/release-read.js +64 -0
  379. package/dist/lifecycle/replay.js +193 -0
  380. package/dist/lifecycle/rollback.js +102 -0
  381. package/dist/lifecycle/run-ledger.js +183 -0
  382. package/dist/lifecycle/scenario-eval.js +204 -0
  383. package/dist/lifecycle/scenario.js +214 -0
  384. package/dist/lifecycle/snapshot.js +239 -0
  385. package/dist/lifecycle/status.js +447 -0
  386. package/dist/lifecycle/symptoms.js +117 -0
  387. package/dist/lifecycle/teardown.js +255 -0
  388. package/dist/lifecycle/types.js +1 -0
  389. package/dist/lifecycle/unobserved-gate.js +33 -0
  390. package/dist/lifecycle/wave-plans.js +68 -0
  391. package/dist/lifecycle/work-item-id.js +36 -0
  392. package/dist/lifecycle/work-lease.js +393 -0
  393. package/dist/lint/component-checks.js +87 -0
  394. package/dist/lint/config.js +483 -0
  395. package/dist/lint/declarative.js +122 -0
  396. package/dist/lint/discover.d.ts.map +1 -1
  397. package/dist/lint/discover.js +138 -0
  398. package/dist/lint/engine.js +246 -0
  399. package/dist/lint/knowledge-checks.js +64 -0
  400. package/dist/lint/named-checks.js +22 -0
  401. package/dist/lint/output-checks.js +87 -0
  402. package/dist/lint/output-docs.js +163 -0
  403. package/dist/lint/parser.js +33 -0
  404. package/dist/lint/pipeline-change-gate.js +70 -0
  405. package/dist/lint/policy-import.d.ts +1 -1
  406. package/dist/lint/policy-import.d.ts.map +1 -1
  407. package/dist/lint/policy-import.js +62 -0
  408. package/dist/lint/policy-sandbox.js +86 -0
  409. package/dist/lint/policy.js +122 -0
  410. package/dist/lint/post-synth.js +87 -0
  411. package/dist/lint/presets/relaxed.json +26 -0
  412. package/dist/lint/presets/strict.json +24 -24
  413. package/dist/lint/receipt-checks.js +83 -0
  414. package/dist/lint/rule-loader.d.ts.map +1 -1
  415. package/dist/lint/rule-loader.js +89 -0
  416. package/dist/lint/rule-registry.js +86 -0
  417. package/dist/lint/rule.js +1 -0
  418. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
  419. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
  420. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
  421. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
  422. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
  423. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
  424. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
  425. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
  426. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
  427. package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
  428. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
  429. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
  430. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
  431. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
  432. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
  433. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
  434. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
  435. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
  436. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
  437. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
  438. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
  439. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
  440. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
  441. package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
  442. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
  443. package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
  444. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
  445. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
  446. package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
  447. package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
  448. package/dist/lint/rules/comp/index.js +33 -0
  449. package/dist/lint/rules/comp/support.js +129 -0
  450. package/dist/lint/rules/composite-scope.js +51 -0
  451. package/dist/lint/rules/cor017-composite-name-match.js +93 -0
  452. package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
  453. package/dist/lint/rules/cor021-env-literal-name.js +100 -0
  454. package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
  455. package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
  456. package/dist/lint/rules/declarable-naming-convention.js +62 -0
  457. package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
  458. package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
  459. package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
  460. package/dist/lint/rules/evl004-spread-non-const.js +94 -0
  461. package/dist/lint/rules/evl005-resource-block-body.js +41 -0
  462. package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
  463. package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
  464. package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
  465. package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
  466. package/dist/lint/rules/export-required.js +115 -0
  467. package/dist/lint/rules/file-declarable-limit.js +88 -0
  468. package/dist/lint/rules/flat-declarations.js +62 -0
  469. package/dist/lint/rules/index.js +90 -0
  470. package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
  471. package/dist/lint/rules/no-redundant-type-import.js +76 -0
  472. package/dist/lint/rules/no-redundant-value-cast.js +41 -0
  473. package/dist/lint/rules/no-string-ref.js +59 -0
  474. package/dist/lint/rules/no-unused-declarable-import.js +75 -0
  475. package/dist/lint/rules/no-unused-declarable.js +142 -0
  476. package/dist/lint/rules/op/index.js +28 -0
  477. package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
  478. package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
  479. package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
  480. package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
  481. package/dist/lint/rules/op/support.js +11 -0
  482. package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
  483. package/dist/lint/rules/property-kind.js +56 -0
  484. package/dist/lint/rules/single-concern-file.js +71 -0
  485. package/dist/lint/rules/sys001-no-literal-key.js +60 -0
  486. package/dist/lint/selectors.js +168 -0
  487. package/dist/lint/suppressions.js +129 -0
  488. package/dist/lint/typescript.js +17 -0
  489. package/dist/live-endpoint.js +113 -0
  490. package/dist/live-read-session.js +76 -0
  491. package/dist/lsp/lexicon-providers.js +163 -0
  492. package/dist/lsp/types.js +5 -0
  493. package/dist/managed-fields.js +293 -0
  494. package/dist/mcp/types.js +4 -0
  495. package/dist/notify-verify.js +0 -1
  496. package/dist/notify.js +0 -1
  497. package/dist/notify.schema.json +72 -0
  498. package/dist/observation.js +266 -0
  499. package/dist/okf-read.js +134 -0
  500. package/dist/okf.js +275 -0
  501. package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
  502. package/dist/op/activities/activity-contracts.js +313 -0
  503. package/dist/op/activities/apply.js +582 -0
  504. package/dist/op/activities/build.js +18 -0
  505. package/dist/op/activities/change-coverage.js +40 -0
  506. package/dist/op/activities/change-set.js +64 -0
  507. package/dist/op/activities/converge.js +492 -0
  508. package/dist/op/activities/decide.js +211 -0
  509. package/dist/op/activities/env-teardown.js +110 -0
  510. package/dist/op/activities/factory.js +591 -0
  511. package/dist/op/activities/forge-pull-request.js +82 -0
  512. package/dist/op/activities/gh-host.js +78 -0
  513. package/dist/op/activities/guard-validate.js +165 -0
  514. package/dist/op/activities/http-check.js +40 -0
  515. package/dist/op/activities/index.js +59 -0
  516. package/dist/op/activities/lexicon-upgrade.js +629 -0
  517. package/dist/op/activities/lifecycle.js +109 -0
  518. package/dist/op/activities/pipeline-audit.js +147 -0
  519. package/dist/op/activities/policy.js +26 -0
  520. package/dist/op/activities/predict-behaviour.js +341 -0
  521. package/dist/op/activities/propose-upgrade.js +165 -0
  522. package/dist/op/activities/reconcile.js +997 -0
  523. package/dist/op/activities/shell.js +118 -0
  524. package/dist/op/activities/source-release.js +97 -0
  525. package/dist/op/activities/source-rollback.js +165 -0
  526. package/dist/op/activities/teardown.js +17 -0
  527. package/dist/op/activities/util.js +6 -0
  528. package/dist/op/activities/wait.js +51 -0
  529. package/dist/op/activities/work-evidence.js +35 -0
  530. package/dist/op/activities/workflow-audit.js +133 -0
  531. package/dist/op/activity-contract-registry.js +106 -0
  532. package/dist/op/activity-contract.js +232 -0
  533. package/dist/op/activity-failure.js +31 -0
  534. package/dist/op/activity-profiles.js +129 -0
  535. package/dist/op/activity-registry.js +105 -0
  536. package/dist/op/activity-runtime.js +28 -0
  537. package/dist/op/builders.js +801 -0
  538. package/dist/op/change-signal.js +118 -0
  539. package/dist/op/composites/apply-op.js +151 -0
  540. package/dist/op/composites/behaviour-op.js +65 -0
  541. package/dist/op/composites/converge-op.js +141 -0
  542. package/dist/op/composites/index.js +19 -0
  543. package/dist/op/composites/lexicon-upgrade-op.js +107 -0
  544. package/dist/op/composites/pipeline-audit-op.js +50 -0
  545. package/dist/op/composites/reconcile-op.js +84 -0
  546. package/dist/op/composites/watch-op.js +69 -0
  547. package/dist/op/composites/workflow-audit-op.js +57 -0
  548. package/dist/op/converge-rule.js +205 -0
  549. package/dist/op/cron.js +146 -0
  550. package/dist/op/decide-backend.js +181 -0
  551. package/dist/op/decide-config.js +68 -0
  552. package/dist/op/decide-read-inputs.js +141 -0
  553. package/dist/op/discover.d.ts.map +1 -1
  554. package/dist/op/discover.js +213 -0
  555. package/dist/op/duration.js +21 -0
  556. package/dist/op/emulator-freshness.js +80 -0
  557. package/dist/op/emulator-lifecycle.js +269 -0
  558. package/dist/op/factory.js +83 -0
  559. package/dist/op/gate-approval.js +172 -0
  560. package/dist/op/gate-name.js +86 -0
  561. package/dist/op/gate-plan-context.js +167 -0
  562. package/dist/op/gate-point-run.js +67 -0
  563. package/dist/op/gate-point.js +111 -0
  564. package/dist/op/gate-resume-plan.js +155 -0
  565. package/dist/op/gate-resume.js +31 -0
  566. package/dist/op/gate-review.js +290 -0
  567. package/dist/op/gate-run-locator.js +85 -0
  568. package/dist/op/gate-summary.js +100 -0
  569. package/dist/op/gate-wait.js +56 -0
  570. package/dist/op/gate.js +449 -0
  571. package/dist/op/generate-pipeline.js +124 -0
  572. package/dist/op/index.js +51 -0
  573. package/dist/op/lifecycle-receipt-store.js +45 -0
  574. package/dist/op/local-executor.js +1164 -0
  575. package/dist/op/local-output.js +140 -0
  576. package/dist/op/op-ir.js +317 -0
  577. package/dist/op/op-verb-class.js +131 -0
  578. package/dist/op/op-waves-notify.js +136 -0
  579. package/dist/op/op-waves-run.d.ts +1 -1
  580. package/dist/op/op-waves-run.d.ts.map +1 -1
  581. package/dist/op/op-waves-run.js +1657 -0
  582. package/dist/op/op-waves.js +409 -0
  583. package/dist/op/operator.js +743 -0
  584. package/dist/op/receipt-store.js +94 -0
  585. package/dist/op/resource.js +23 -0
  586. package/dist/op/run-context.js +28 -0
  587. package/dist/op/run-live.js +256 -0
  588. package/dist/op/runtime.js +21 -0
  589. package/dist/op/runtimes/local.js +195 -0
  590. package/dist/op/source-archive.js +131 -0
  591. package/dist/op/step-output-ref.js +397 -0
  592. package/dist/op/steward-beside.js +169 -0
  593. package/dist/op/steward-points.js +138 -0
  594. package/dist/op/steward-turn.js +59 -0
  595. package/dist/op/steward.js +317 -0
  596. package/dist/op/types.js +25 -0
  597. package/dist/op/work-lease-decl.js +81 -0
  598. package/dist/op/work-lease-run.js +393 -0
  599. package/dist/override-gate.js +284 -0
  600. package/dist/owner-chain.js +74 -0
  601. package/dist/ownership.js +92 -0
  602. package/dist/params.js +61 -0
  603. package/dist/plan-summary.js +711 -0
  604. package/dist/point-decision.js +211 -0
  605. package/dist/pr-forge.js +810 -0
  606. package/dist/pr-loop.js +203 -0
  607. package/dist/project-codegen.js +191 -0
  608. package/dist/project-root.js +74 -0
  609. package/dist/project-validation.js +50 -0
  610. package/dist/provenance.js +157 -0
  611. package/dist/pseudo-parameter.js +40 -0
  612. package/dist/reconcile.js +450 -0
  613. package/dist/resource-attributes.js +33 -0
  614. package/dist/runtime-adapter.js +77 -0
  615. package/dist/runtime.js +66 -0
  616. package/dist/secret-materialization.js +153 -0
  617. package/dist/secret-provenance.js +250 -0
  618. package/dist/serializer-walker.js +112 -0
  619. package/dist/serializer.js +1 -0
  620. package/dist/sort.js +45 -0
  621. package/dist/stack-output.js +115 -0
  622. package/dist/telemetry-attribution.js +149 -0
  623. package/dist/terraform/__fixtures__/build-graph.js +63 -0
  624. package/dist/terraform/adopt-state.js +40 -0
  625. package/dist/terraform/aws-resources.js +384 -0
  626. package/dist/terraform/bridge.js +204 -0
  627. package/dist/terraform/carve-provider.js +155 -0
  628. package/dist/terraform/carve.js +138 -0
  629. package/dist/terraform/data-source-shape.js +57 -0
  630. package/dist/terraform/emit-source.js +36 -0
  631. package/dist/terraform/excise.js +123 -0
  632. package/dist/terraform/graduate.js +128 -0
  633. package/dist/terraform/graph.js +435 -0
  634. package/dist/terraform/hcl2json.js +60 -0
  635. package/dist/terraform/manifest.js +149 -0
  636. package/dist/terraform/parse.js +81 -0
  637. package/dist/terraform/providers/aws.js +146 -0
  638. package/dist/terraform/providers/gcp.js +294 -0
  639. package/dist/terraform/providers/index.js +17 -0
  640. package/dist/terraform/providers/kubernetes.js +253 -0
  641. package/dist/terraform/score.js +151 -0
  642. package/dist/terraform/state.js +67 -0
  643. package/dist/terraform/tier-map.js +74 -0
  644. package/dist/terraform/types.js +13 -0
  645. package/dist/terraform/unified-diff.js +132 -0
  646. package/dist/testing.js +295 -0
  647. package/dist/toml-emit.js +153 -0
  648. package/dist/toml-parse.js +355 -0
  649. package/dist/toml-utils.js +60 -0
  650. package/dist/toml.js +428 -0
  651. package/dist/ts-loader.d.ts +46 -0
  652. package/dist/ts-loader.d.ts.map +1 -0
  653. package/dist/ts-loader.js +103 -0
  654. package/dist/types.js +1 -0
  655. package/dist/utils.js +61 -0
  656. package/dist/validation.js +20 -0
  657. package/dist/vendor/js-yaml-load.js +1662 -0
  658. package/dist/workspace/__fixtures__/contract-repo.js +103 -0
  659. package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
  660. package/dist/workspace/__fixtures__/sessions.js +91 -0
  661. package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
  662. package/dist/workspace/agent-cli.js +99 -0
  663. package/dist/workspace/agent.schema.json +390 -0
  664. package/dist/workspace/answers-ledger.js +89 -0
  665. package/dist/workspace/box-cli.js +142 -0
  666. package/dist/workspace/box-factory-write.js +196 -0
  667. package/dist/workspace/box-factory-write.schema.json +342 -0
  668. package/dist/workspace/box-factory.js +88 -0
  669. package/dist/workspace/box-intent.js +126 -0
  670. package/dist/workspace/box-isolation.js +169 -0
  671. package/dist/workspace/box-listing-write.schema.json +204 -0
  672. package/dist/workspace/box-listing.js +298 -0
  673. package/dist/workspace/box-publish.js +352 -0
  674. package/dist/workspace/box-publish.schema.json +498 -0
  675. package/dist/workspace/box-services.js +39 -0
  676. package/dist/workspace/broker-protocol.js +359 -0
  677. package/dist/workspace/broker-protocol.schema.json +228 -0
  678. package/dist/workspace/change-set.schema.json +460 -0
  679. package/dist/workspace/changes-cli.js +56 -0
  680. package/dist/workspace/changes.js +446 -0
  681. package/dist/workspace/changes.schema.json +642 -0
  682. package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
  683. package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
  684. package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
  685. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
  686. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
  687. package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
  688. package/dist/workspace/chant-migrations.js +113 -0
  689. package/dist/workspace/check.schema.json +433 -0
  690. package/dist/workspace/checks/box-isolation.js +62 -0
  691. package/dist/workspace/checks/boxes.js +491 -0
  692. package/dist/workspace/checks/diagrams.js +104 -0
  693. package/dist/workspace/checks/generated.js +419 -0
  694. package/dist/workspace/checks/ledgers.js +212 -0
  695. package/dist/workspace/checks/links.js +191 -0
  696. package/dist/workspace/checks/live.js +100 -0
  697. package/dist/workspace/checks/pipelines.js +188 -0
  698. package/dist/workspace/checks/records.js +169 -0
  699. package/dist/workspace/checks.js +426 -0
  700. package/dist/workspace/ci-green-cli.js +125 -0
  701. package/dist/workspace/ci-green-forge.js +83 -0
  702. package/dist/workspace/ci-green-workflow.js +199 -0
  703. package/dist/workspace/ci-green.js +325 -0
  704. package/dist/workspace/ci-last-green.schema.json +158 -0
  705. package/dist/workspace/compose-graph.js +235 -0
  706. package/dist/workspace/compose-reports.js +146 -0
  707. package/dist/workspace/composites.js +264 -0
  708. package/dist/workspace/composites.schema.json +617 -0
  709. package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
  710. package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
  711. package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
  712. package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
  713. package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
  714. package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
  715. package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
  716. package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
  717. package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
  718. package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
  719. package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
  720. package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
  721. package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
  722. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  723. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  724. package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
  725. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  726. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  727. package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
  728. package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
  729. package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  730. package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  731. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
  732. package/dist/workspace/conformance/broker.js +736 -0
  733. package/dist/workspace/conformance/index.js +673 -0
  734. package/dist/workspace/conformance/vitest.js +108 -0
  735. package/dist/workspace/conformance/writer.js +1080 -0
  736. package/dist/workspace/decide.js +879 -0
  737. package/dist/workspace/decision-points.schema.json +135 -135
  738. package/dist/workspace/declaration-write-cli.js +74 -0
  739. package/dist/workspace/declaration-write.js +238 -0
  740. package/dist/workspace/declaration.js +938 -0
  741. package/dist/workspace/declaration.schema.json +1413 -1413
  742. package/dist/workspace/declared-kinds.js +106 -0
  743. package/dist/workspace/environments.js +164 -0
  744. package/dist/workspace/evidence.schema.json +279 -0
  745. package/dist/workspace/export-cli.js +185 -0
  746. package/dist/workspace/export.js +499 -0
  747. package/dist/workspace/factory-rules.js +175 -0
  748. package/dist/workspace/generated-files.js +92 -0
  749. package/dist/workspace/glob.js +45 -0
  750. package/dist/workspace/graph-cache.js +352 -0
  751. package/dist/workspace/graph-cli.js +348 -0
  752. package/dist/workspace/graph.schema.json +1338 -0
  753. package/dist/workspace/identity-gate-rule.d.ts +65 -0
  754. package/dist/workspace/identity-gate-rule.d.ts.map +1 -0
  755. package/dist/workspace/identity-gate-rule.js +75 -0
  756. package/dist/workspace/identity.d.ts +4 -2
  757. package/dist/workspace/identity.d.ts.map +1 -1
  758. package/dist/workspace/identity.js +126 -0
  759. package/dist/workspace/import.js +283 -0
  760. package/dist/workspace/init.js +620 -0
  761. package/dist/workspace/intent-cli.js +263 -0
  762. package/dist/workspace/intent-joins.js +201 -0
  763. package/dist/workspace/intent-record.js +352 -0
  764. package/dist/workspace/intent-record.schema.json +864 -0
  765. package/dist/workspace/intent.js +1582 -0
  766. package/dist/workspace/intent.schema.json +2420 -0
  767. package/dist/workspace/json-edit.js +221 -0
  768. package/dist/workspace/jsonc.js +235 -0
  769. package/dist/workspace/kind-readers.js +103 -0
  770. package/dist/workspace/kinds.js +587 -0
  771. package/dist/workspace/lexicon-symbols.js +112 -0
  772. package/dist/workspace/lineage-adopt-cli.js +102 -0
  773. package/dist/workspace/lineage-adopt.js +360 -0
  774. package/dist/workspace/lineage-check.js +282 -0
  775. package/dist/workspace/lineage-cli.js +121 -0
  776. package/dist/workspace/lineage-hash-index.js +284 -0
  777. package/dist/workspace/lineage-init.js +507 -0
  778. package/dist/workspace/lineage-lock.js +387 -0
  779. package/dist/workspace/lineage-merge.js +45 -0
  780. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  781. package/dist/workspace/lineage-migrations.js +329 -0
  782. package/dist/workspace/lineage-provenance.js +36 -0
  783. package/dist/workspace/lineage-update.js +138 -0
  784. package/dist/workspace/lineage-upgrade-cli.js +131 -0
  785. package/dist/workspace/lineage-upgrade.js +889 -0
  786. package/dist/workspace/lineage-vendor.js +171 -0
  787. package/dist/workspace/lineage-version.js +128 -0
  788. package/dist/workspace/lineage-versions.js +275 -0
  789. package/dist/workspace/links.js +330 -0
  790. package/dist/workspace/ls-generated.js +95 -0
  791. package/dist/workspace/ls.js +277 -0
  792. package/dist/workspace/ls.schema.json +333 -0
  793. package/dist/workspace/member-commands.js +508 -0
  794. package/dist/workspace/member-handles.js +216 -0
  795. package/dist/workspace/member-pipeline.js +258 -0
  796. package/dist/workspace/member-run.js +117 -0
  797. package/dist/workspace/member-write.schema.json +193 -0
  798. package/dist/workspace/nested-graph.js +156 -0
  799. package/dist/workspace/nesting.js +38 -0
  800. package/dist/workspace/patch.js +301 -0
  801. package/dist/workspace/patch.schema.json +321 -0
  802. package/dist/workspace/pin-cli.js +55 -0
  803. package/dist/workspace/pin-integrity.js +100 -0
  804. package/dist/workspace/plan-summary.schema.json +155 -0
  805. package/dist/workspace/point-answer.schema.json +129 -129
  806. package/dist/workspace/points-cli.js +291 -0
  807. package/dist/workspace/points-write.schema.json +660 -0
  808. package/dist/workspace/points.js +521 -0
  809. package/dist/workspace/points.schema.json +916 -0
  810. package/dist/workspace/pr-report.schema.json +108 -0
  811. package/dist/workspace/principal-classes.d.ts +3 -14
  812. package/dist/workspace/principal-classes.d.ts.map +1 -1
  813. package/dist/workspace/principal-classes.js +245 -0
  814. package/dist/workspace/reason-codes.js +326 -0
  815. package/dist/workspace/record-assets.js +151 -0
  816. package/dist/workspace/record-decided.js +105 -0
  817. package/dist/workspace/record-sessions.js +96 -0
  818. package/dist/workspace/record-source.js +114 -0
  819. package/dist/workspace/records-amend.schema.json +284 -0
  820. package/dist/workspace/records-checkout.js +76 -0
  821. package/dist/workspace/records-cli.js +707 -0
  822. package/dist/workspace/records-close.js +116 -0
  823. package/dist/workspace/records-close.schema.json +278 -0
  824. package/dist/workspace/records-new.schema.json +202 -0
  825. package/dist/workspace/records-review.schema.json +367 -0
  826. package/dist/workspace/records-since.js +317 -0
  827. package/dist/workspace/records-since.schema.json +218 -0
  828. package/dist/workspace/records-write.js +1229 -0
  829. package/dist/workspace/records.js +1345 -0
  830. package/dist/workspace/records.schema.json +604 -0
  831. package/dist/workspace/reference-kinds/app/package.json +10 -0
  832. package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  833. package/dist/workspace/returns.js +303 -0
  834. package/dist/workspace/root-refusal.js +75 -0
  835. package/dist/workspace/run-statement.schema.json +622 -0
  836. package/dist/workspace/runs-cli.js +584 -0
  837. package/dist/workspace/runs-write.schema.json +994 -0
  838. package/dist/workspace/runs.js +708 -0
  839. package/dist/workspace/runs.schema.json +1257 -0
  840. package/dist/workspace/runtimes.js +76 -0
  841. package/dist/workspace/session-kinds.js +83 -0
  842. package/dist/workspace/signers.schema.json +206 -0
  843. package/dist/workspace/source-block.js +125 -0
  844. package/dist/workspace/squash.js +177 -0
  845. package/dist/workspace/status-gates.js +162 -0
  846. package/dist/workspace/status-stewards.js +330 -0
  847. package/dist/workspace/status.js +514 -0
  848. package/dist/workspace/status.schema.json +998 -0
  849. package/dist/workspace/steward-index.js +191 -0
  850. package/dist/workspace/symbols.js +188 -0
  851. package/dist/workspace/template-manifest.js +227 -0
  852. package/dist/workspace/template-pins.js +115 -0
  853. package/dist/workspace/trailer-joins.js +65 -0
  854. package/dist/workspace/trailers.js +111 -0
  855. package/dist/workspace/tree.js +136 -0
  856. package/dist/workspace/trust/attestor.js +63 -0
  857. package/dist/workspace/trust/dsse.js +108 -0
  858. package/dist/workspace/trust/evidence-cli.js +175 -0
  859. package/dist/workspace/trust/evidence.js +161 -0
  860. package/dist/workspace/trust/gate-seal.js +226 -0
  861. package/dist/workspace/trust/policy.js +190 -0
  862. package/dist/workspace/trust/provenance.js +180 -0
  863. package/dist/workspace/trust/rotation.js +298 -0
  864. package/dist/workspace/trust/run-commits.js +101 -0
  865. package/dist/workspace/trust/run-statement.js +182 -0
  866. package/dist/workspace/trust/seal.js +272 -0
  867. package/dist/workspace/trust/signers-cli.js +152 -0
  868. package/dist/workspace/trust/ssh-commit.js +178 -0
  869. package/dist/workspace/trust/test-repo.js +118 -0
  870. package/dist/workspace/trust/trust-files.js +193 -0
  871. package/dist/workspace/trust/verify-cli.js +63 -0
  872. package/dist/workspace/trust/verify.js +192 -0
  873. package/dist/workspace/which-chant.js +141 -0
  874. package/dist/workspace/wip-cli.js +95 -0
  875. package/dist/workspace/wip-write.schema.json +504 -0
  876. package/dist/workspace/wip.js +631 -0
  877. package/dist/workspace/wip.schema.json +334 -0
  878. package/dist/workspace/work-cli.js +448 -0
  879. package/dist/workspace/work-evidence.js +122 -0
  880. package/dist/workspace/work-evidence.schema.json +222 -0
  881. package/dist/workspace/work-history.schema.json +421 -0
  882. package/dist/workspace/work-lease.schema.json +246 -0
  883. package/dist/workspace/work-size.js +77 -0
  884. package/dist/workspace/work.js +283 -0
  885. package/dist/workspace/workspace-kinds.schema.json +259 -259
  886. package/dist/workspace/workspace-principals.schema.json +53 -53
  887. package/dist/workspace/write-lock-cli.js +105 -0
  888. package/dist/workspace/write-lock.js +424 -0
  889. package/dist/workspace/write-lock.schema.json +172 -0
  890. package/dist/workspace/write-scope.js +484 -0
  891. package/dist/yaml.js +459 -0
  892. package/package.json +2 -2
  893. package/src/cli/commands/check-lexicon-plugin.ts +2 -0
  894. package/src/cli/commands/lint.ts +36 -6
  895. package/src/cli/commands/migrate.ts +2 -0
  896. package/src/cli/compiled-cli.e2e.test.ts +165 -0
  897. package/src/cli/main.ts +121 -27
  898. package/src/cli/mcp/workspace-tools.ts +1 -1
  899. package/src/codegen/pinned-upgrade.ts +2 -0
  900. package/src/components/discover.ts +2 -0
  901. package/src/components/sandbox/driver.ts +3 -1
  902. package/src/config-import.ts +3 -0
  903. package/src/discovery/fold-import.ts +23 -14
  904. package/src/discovery/import.ts +2 -0
  905. package/src/discovery/sandbox/driver.ts +3 -1
  906. package/src/gate-decision-bundle.test.ts +3 -2
  907. package/src/gate-decision-identity.test.ts +176 -0
  908. package/src/gate-decision.ts +100 -22
  909. package/src/lexicon-module.ts +3 -0
  910. package/src/lifecycle/gate-ledger.ts +8 -0
  911. package/src/lint/config.ts +1 -1
  912. package/src/lint/discover.ts +28 -8
  913. package/src/lint/policy-import.ts +4 -1
  914. package/src/lint/rule-loader.ts +2 -0
  915. package/src/op/discover.ts +3 -0
  916. package/src/op/op-waves-point.test.ts +1 -0
  917. package/src/op/op-waves-run.ts +5 -4
  918. package/src/op/op-waves.test.ts +14 -0
  919. package/src/ts-loader.test.ts +23 -0
  920. package/src/ts-loader.ts +122 -0
  921. package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
  922. package/src/workspace/declaration.ts +1 -1
  923. package/src/workspace/identity-gate-rule.ts +109 -0
  924. package/src/workspace/identity.ts +8 -18
  925. package/src/workspace/kinds.ts +1 -1
  926. package/src/workspace/lineage-migrations.ts +2 -0
  927. package/src/workspace/points.ts +1 -1
  928. package/src/workspace/principal-classes.ts +5 -30
@@ -0,0 +1,326 @@
1
+ /**
2
+ * The workspace read contract's closed list of reason codes (#2536, #2524
3
+ * D15, ws-017, ws-020).
4
+ *
5
+ * Every code a `chant workspace` read prints is here: the error that stops a
6
+ * read, the reason an unreadable member, group, ledger or record is listed
7
+ * with, and the lineage lock findings of `check`. Each command's own list
8
+ * (`WORKSPACE_ERROR_CODES`, `MEMBER_REASON_CODES`, `STATUS_REASON_CODES`,
9
+ * `RECORD_REASON_CODES` and the rest) is a subset of this one, which the
10
+ * compiler checks through `satisfies`. `reason-codes.test.ts` checks that the
11
+ * output schemas and the source emit nothing outside it.
12
+ *
13
+ * The list is closed: a reader may switch on a code, and a new code is a
14
+ * contract change. Within contract version 1, before the floor release, codes
15
+ * may still be added; after it, a new code means a new contract version.
16
+ *
17
+ * `chant workspace check` also reports `WSP` ids. Those are the declaration
18
+ * check catalog (`checks.ts`), a separate closed list, and a finding whose
19
+ * cause is one of the codes here carries that code too.
20
+ */
21
+ /** The version of the read contract this chant writes: the declaration format, the output schemas and these codes. */
22
+ export const READ_CONTRACT_VERSION = 1;
23
+ /** The first chant release that writes contract version 1. A reader that needs the contract refuses an older chant. */
24
+ export const READ_CONTRACT_FLOOR = "0.81.0";
25
+ /** Each code and what it means. The key order is the order the docs list them in. */
26
+ export const REASONS = {
27
+ // Reading the declaration (ls, graph, check, status).
28
+ "declaration-missing": "No chant.workspace.json or .jsonc between the directory and the git root.",
29
+ "declaration-ambiguous": "Both chant.workspace.json and chant.workspace.jsonc exist.",
30
+ "declaration-unparseable": "The declaration is not valid JSON, or not valid JSONC for .jsonc.",
31
+ "declaration-invalid": "The declaration does not match its schema, repeats a name, or --member names no entry.",
32
+ "placement-invalid": "A member or group match breaks a placement rule.",
33
+ "reader-too-old": "The declaration's minReader is newer than the chant reading it.",
34
+ "root-chant-required": "The declaration pins a chant version other than the reader's, and that chant is not installed at the workspace root.",
35
+ // --at and git.
36
+ "not-a-git-repository": "--at, or a ledger read, needs a git repository and there is none.",
37
+ "revision-unknown": "--at names no commit.",
38
+ "live-at-revision": "graph was given --live and --at: a live read is of the account now, not of a revision.",
39
+ // status.
40
+ "environment-invalid": "An environment name that can't name a ledger directory.",
41
+ // A member or group that can't be read (ls, graph).
42
+ "dir-missing": "The member's directory does not exist.",
43
+ "unknown-kind": "No built-in kind or pinned package supplies the member's kind.",
44
+ "kind-probe-failed": "The member's directory is not what its kind reads.",
45
+ "no-matches": "An example group matches no directory holding a chant project.",
46
+ // A member graph leaves out (graph, and the other per-member commands).
47
+ "kind-not-run": "The member's kind is one the per-member commands don't run, such as other.",
48
+ "command-failed": "The member's own command exited with a failure, or the lexicon that reads the member through its kind's graph block isn't installed where the workspace resolves its pin.",
49
+ "output-unreadable": "The member's command printed something that isn't the document asked for.",
50
+ "ir-version-unsupported": "The member's IR has a version this chant can't read.",
51
+ // A ledger status can't fully read.
52
+ "ledger-unreadable": "Reading the ledger failed, so nothing from it is listed.",
53
+ "ledger-malformed": "Some lines of the ledger aren't release records; the rest are listed.",
54
+ // A member's gates status can't list (status, #2674).
55
+ "gates-no-ledger": "The checkout has no chant/lifecycle branch, so there is no gate ledger to read.",
56
+ "gates-no-gate-ledger": "The branch has no gate ledger for the member: no run of it has reached a gate.",
57
+ "gates-ledger-unreadable": "Reading the member's gate ledger failed, so no gate is listed.",
58
+ // A member's stewards status can't fully list (status, #2731).
59
+ "stewards-unreadable": "An *.op.ts file could not be imported, so a steward it declares may be missing.",
60
+ "stewards-conflict": "A steward was dropped: its name, or an Op it lists, belongs to another steward.",
61
+ "steward-runs-unreadable": "Reading an Op's run ledger, or a ConvergeOp's converge ledger, failed, so its last run or last tick is null.",
62
+ // A record that isn't valid (records).
63
+ "record-unparseable": "No front matter, a YAML error or a value outside the JSON subset of YAML, or for a JSON kind a file that is not one object or repeats a member name.",
64
+ "record-schema-invalid": "The record's front matter, or its JSON object, does not match the kind's schema.",
65
+ "record-id-duplicate": "Another record earlier in path order has the same id.",
66
+ "record-supersedes-unknown": "A supersedes link names an id no record has.",
67
+ "record-supersedes-conflict": "A second closed record supersedes a record another one already superseded.",
68
+ "record-remediates-unknown": "A remediates link names an id no record has.",
69
+ "record-remediates-not-closed": "A remediates link names a record that isn't closed; a record still open is amended instead.",
70
+ "record-seal-mismatch": "A closed record's seal is not the whole-file seal of its text now: the record changed after it closed.",
71
+ // A review session that isn't valid (records, #2673).
72
+ "session-seal-mismatch": "A closed session's seal is not the whole-file seal of its text now: the session changed after it closed, or was sealed by the rule before #2546.",
73
+ "session-verdict-unknown-record": "A session's verdict names a record that none of the session kind's subject records has.",
74
+ // A record that is valid but warned about (records, #2549).
75
+ "asset-drift": "A file the record pins by hash has changed: its bytes no longer hash to the pinned sha256.",
76
+ "asset-missing": "A file the record pins by hash does not exist in the tree read.",
77
+ "asset-stale": "A file the record pins is unchanged at the hash a record it supersedes pinned: the decision changed and the artifact did not follow.",
78
+ "record-supersedes-pending": "A supersedes link from a record whose state is weaker than the record it names, so the link has no effect yet.",
79
+ "record-no-evidence": "The record's evidence list is empty: it cites nothing and pins no file. Information for a reviewer, never an error.",
80
+ "review-undigested": "A verdict names no digest of the text it judged. It still counts, and an amendment does not stop it counting.",
81
+ "source-transcript-drift": "The record's source block pins a transcript by hash, the file it names can be read here, and its bytes hash to something else: it is not the transcript the record means.",
82
+ // A work record that is valid but warned about (records and graph --intent, #2683).
83
+ "work-needs-unknown": "A work record's needs list names a work id no record has, so the item stays blocked.",
84
+ "work-implements-unknown": "A work record's implements list names a decision id no decision has.",
85
+ "work-needs-cycle": "A work record needs itself through its needs links, so it can never be ready.",
86
+ "work-implements-undecided": "A work record implements a decision whose state is not approved, such as proposed.",
87
+ "work-done-unpinned": "A work record is done and its evidence list is empty: nothing shows the work was done.",
88
+ "work-closed-without-date": "A work record is done or dropped and has no closing date.",
89
+ "work-done-gap-open": "A work record is done, and the finding it came from still fires on its region. graph --intent raises it, and records does by walking that region.",
90
+ "work-acceptance-unmet": "A work record is done, and one of its acceptance criteria has no passing evidence of the verification it expects. check fails on it (WSP117).",
91
+ "work-acceptance-self-verified": "A passing manual verdict on a work record's criterion names the record's implementer, so it does not count: a manual verdict comes from someone else.",
92
+ "work-contract-unknown": "A work record names a contract that no record of its kind's contract kind has.",
93
+ "work-contract-undecided": "A work record names a contract whose state is not approved, such as a draft.",
94
+ "work-tier-unknown": "A work record names a builder tier that its kind's work.tier.tiers does not list.",
95
+ // An answer to a decision point that is valid but warned about (records, points, ws-058, #2739).
96
+ "answer-points-unreadable": "The points file the answer kind names can't be read, or is not valid.",
97
+ "answer-point-unknown": "The answer's point is not declared in the points file the answer kind names.",
98
+ "answer-point-changed": "The point's declaration changed since the question was asked, so the answer is to an older version of the question.",
99
+ // A verdict the quorum does not count (records, #2671, #2672).
100
+ "review-decider": "The verdict is the decider's own, and the quorum counts verdicts besides the decider's.",
101
+ "review-agent": "The reviewer holds the agent role in the trust policy at base.",
102
+ "review-duplicate": "A later verdict by the same principal replaces this one. Names are compared after NFKC, trimming and lower-casing.",
103
+ "review-older-digest": "The verdict names a digest other than the record's text now: the record changed after the verdict.",
104
+ "review-unattested": "An attestation policy is active at base, and the verdict carries no seal that verifies for its reviewer.",
105
+ // A seal that is not attested (records): a verdict's (#2687) or a record's author seal (#2688). Each reports one of these in its attestation, unless its seal verified.
106
+ "seal-missing": "The verdict, or the record, carries no seal.",
107
+ "seal-signer-unlisted": "The reviewer, or the record's author, has no key in the signers file at base, so the seal can't count.",
108
+ "seal-signature-invalid": "The seal is malformed, names a signer other than the reviewer or author, or its signature does not verify over the verdict or record.",
109
+ "seal-unverifiable": "Nothing here can say whose seal it is: there is no signers file at base, ssh-keygen is not installed, or the record came back in a return sealed by a signer no admission lists yet.",
110
+ // A record whose author seal is not attested under a signers file at base (records, #2688). A warning: the record is still read.
111
+ "record-unattested": "A signers file is active at base, and the record names an author whose seal does not verify: it has none, the author has no key in the file, or the signature fails.",
112
+ // A records read that fails (records).
113
+ "kind-unreadable": "The record kind file is missing or could not be imported.",
114
+ "kind-invalid": "The record kind file exports no recordKind, or its shape is wrong.",
115
+ "schema-unreadable": "The schema file the record kind names is missing or is not JSON.",
116
+ "schema-id-mismatch": "The schema's $id differs from the id the record kind names.",
117
+ "schema-invalid": "The record schema itself does not compile.",
118
+ "location-missing": "The records directory does not exist, in the tree or at the revision.",
119
+ // A records write that is refused (records new, amend and review, #2670). Nothing is written.
120
+ "write-usage-invalid": "The command line lacks a value the write needs, or gives one it does not take.",
121
+ "write-input-invalid": "The fields given with --from or --set can't be read, are not JSON, or are not a JSON object.",
122
+ "record-not-found": "No record of the kind has the id given.",
123
+ "record-id-taken": "The id given for a new record is already used, by a record or a file name.",
124
+ "record-id-unallocatable": "No id was given and none can be allocated: the records share no single prefix and --prefix names none.",
125
+ "record-path-unmatched": "The file name made from the record's id and title does not match the kind's location.",
126
+ "record-closed": "The record is in a closed state, so nothing in it changes; a new record supersedes it instead.",
127
+ "amend-id-immutable": "An amendment changes the record's id, and ids are never renumbered.",
128
+ "amend-supersede-instead": "The record is approved, and the amendment changes a field the approval rule does not let change in place; a new record supersedes it instead.",
129
+ "review-unsupported": "The kind's schema has no reviews field, so its records take no review.",
130
+ "review-note-required": "A dissent was given with no note: a dissent needs a reason.",
131
+ "review-sign-failed": "--sign was given and no seal could be made: the key can't be read or used, git names no ssh signing key, or ssh-keygen is not installed.",
132
+ "record-state-not-initial": "A record written through chant serve mcp gives a state other than the kind's first: a new record opens proposed, and a person moves it on.",
133
+ "source-harvest-not-proposed": "A harvested record (source.via harvest) was written in a state other than the kind's first: a harvest proposes, and a person decides.",
134
+ "ratify-quorum-not-met": "The write puts a record in its kind's ratified state (reviews.ratified), and the record's quorum is not met: too few agreeing verdicts count.",
135
+ "record-sign-failed": "--sign was given and no author seal could be made: the record names no author, the key can't be read or used, git names no ssh signing key, or ssh-keygen is not installed.",
136
+ // Concurrent writers in one working tree (#3173, ws-089): a write that is refused rather than overwrite another's.
137
+ "record-conflict": "--expect named a digest the record no longer has: another write changed it after the caller read it. The refusal names the digest it has now; re-read the record and write again.",
138
+ "write-lock-timeout": "Another write held the working tree's write lock for longer than the write waits (CHANT_WRITE_LOCK_WAIT_MS); the refusal names the holder. Run the write again.",
139
+ "write-lock-not-held": "CHANT_WRITE_LOCK names a batch's lock token that no longer holds the working tree's write lock: the batch released it, or it expired and another writer took it.",
140
+ // Write scope (#2548): a records write that is refused, and a commit check --changes reports, outside the writer's scope.
141
+ "write-scope-member": "The write is to a file, or to a record kind, of a member outside the writer's scope: an agent session writes only the members it is bound to, and writeScope.<class>.members leaves the member out.",
142
+ "write-scope-kind": "The write is to a record kind writeScope.<class>.records does not list, with a verb it does not list for the kind, or deletes a record.",
143
+ "write-scope-protected": "The write is to a file writeScope.<class>.protected lists, or one under a directory it lists, outside the top-level keys or JSON Pointers the entry's except allows (#3146, #3308).",
144
+ "write-scope-class-unknown": "The declaration's writeScope at base names a principal class no pinned package supplies, and the writer is judged human, so it may be in that class; the write is refused until the package is installed at the pinned version or the entry removed (#3080).",
145
+ "agent-unknown": "CHANT_AGENT, or a commit's Chant-Agent trailer, names an agent session the declaration at base does not declare.",
146
+ "principal-unidentified": "chant.workspace.json at base sets identity.attribution to identified, and the write names a person by a bare name: --by, an author field or a decision point's answerer must be a forge identity (github:<login>, gitlab:<login>, <forge>@<host>:<login>), a principal the signers file at base lists, or an agent, runner or service principal (#3163).",
147
+ // A review given in a session (records review --session, #2693).
148
+ "session-unknown": "--session names no session of a session kind whose subjects are the record's kind.",
149
+ "session-not-open": "--session names a session in a closed state, which takes no more verdicts.",
150
+ // Decision points (points, points ask, points answer, ws-058, #2739).
151
+ "points-undeclared": "No record kind with an answers block is declared, or given with --kind, so there is no points file to ask.",
152
+ "points-invalid": "The points file an answer kind names can't be read, or does not match decision-points.schema.json and the rules checked in code.",
153
+ "point-unknown": "No points file declares the point asked, or the one an answer names.",
154
+ "point-inputs-invalid": "The inputs given to an ask are not a JSON object of the point's declared inputs.",
155
+ "point-decider-failed": "A model decider that fails closed (unreachable: fail) could not answer, so the ask wrote nothing.",
156
+ "answer-not-candidate": "The people's answer is not one of the question's candidates.",
157
+ "quorum-not-met": "Too few of the people who answered count toward the point's quorum: distinct, not holding the agent role, not the steward that asked, and holding one of its roles when it names any. Nobody named over MCP or ACP counts (#3817).",
158
+ "answer-in-steward-turn": "The answer was given during a steward's turn, or by a process it started: a steward never answers a decision point, and a person answers it through hud or at a shell.",
159
+ "answer-never-over-mcp": "The answer or retraction came over MCP or ACP, or from a process a session on one started, and the question constrains a gate that is never resolved there: a person answers it at a shell or through hud (#3817).",
160
+ "answer-not-answered": "points retract names a question that has no answer to retract: it is escalated or proposed, and people answer it instead (#3351).",
161
+ "answer-field-unsupported": "The answer kind's copy of point-answer.schema.json predates a field the write needs, a note, a relay, a retraction or an ad-hoc question's asked: copy the schema anew to turn it on (#3351, #3402, #3403).",
162
+ "point-candidates-invalid": "points ask names an ad-hoc point without --candidates, a declared point with them, or candidates that are not a question and criteria of the point's question type (#3403).",
163
+ // records --since that fails (#2673).
164
+ "since-rev-unknown": "--since names no commit, or a session with no opening revision and no commit that added it.",
165
+ "since-session-unknown": "--since has the shape of a session id and names no commit, and no session the kind or the declaration reads has that id.",
166
+ "since-session-open": "--since names a session that is still open, so the comparison runs to the working tree.",
167
+ // The intent graph (graph --intent, #2651): a read that fails.
168
+ "intent-region-invalid": "The region's path, or its line range, does not exist in the tree read.",
169
+ "intent-record-unknown": "graph --intent --record names an id that no record of a decision kind read has.",
170
+ "intent-symbol-unsupported": "The region names a symbol, path#symbol, in a file no symbol resolver reads; a line range still works.",
171
+ "intent-symbol-unknown": "The region names a symbol the file does not declare in the tree read.",
172
+ "intent-symbol-ambiguous": "The region names a symbol that matches more than one declaration in the file; its qualified name picks one.",
173
+ // The intent graph: part of the walk that can't be read. The document is still printed.
174
+ "intent-history-shallow": "The repository is a shallow clone, so the region's history stops at the clone's boundary.",
175
+ "intent-plugin-failed": "A kind file's commitJoins, which joins commits to units, contracts and evidence, failed for a commit.",
176
+ "squash-unfollowed": "A squash commit's pull request ref (refs/pull/<n>/head) is not in the clone and could not be fetched from origin, so its original commits are not followed; the read keeps its answer without them.",
177
+ // The intent graph: findings, each a node in the graph.
178
+ "intent-commit-undecided": "A commit changed the region when no decision constrained it at path granularity.",
179
+ "intent-commit-bare": "A commit names no unit, carries no record through its Chant-Record or Chant-Lease trailer, and has no pull request and no decision covering the region at its time.",
180
+ "intent-pin-drifted": "A decision's pinned artifact no longer hashes to the pin.",
181
+ "intent-pin-missing": "A decision's pinned artifact does not exist in the tree read.",
182
+ "intent-pin-stale": "A current decision pins an artifact at the hash a record it supersedes pinned, and the artifact has not changed since: the decision moved on and the artifact did not.",
183
+ "intent-artifact-unpinned": "An artifact decisions in the graph pinned, which no current decision pins.",
184
+ "intent-decision-superseded-live": "Every decision constraining the region is superseded.",
185
+ "intent-decision-provisional": "The current decisions constraining the region are all in states their kind does not close, such as decided.",
186
+ "intent-decision-contested": "A current decision constraining the region has an open concern: a dissent neither addressed nor withdrawn.",
187
+ "intent-constraint-coarse": "The region is constrained only through its member, not by path.",
188
+ "intent-constraint-lost": "A decision's path constraint names a path that does not exist in the tree read.",
189
+ "intent-evidence-unpinned": "A decision's evidence has no hash: a URL, or a path with no sha256.",
190
+ "intent-trailer-unverified": "A commit carries a trailer a plugin says claims authorship, and the commit is not attested.",
191
+ "intent-region-unconstrained": "No decision constrains the region at any granularity.",
192
+ "intent-decision-unimplemented": "A decided decision constrains the region, no work item that is not dropped implements it, and no commit falls in its window.",
193
+ "intent-work-blocked": "A work item constraining the region has commits in its window while a work item it needs is not done.",
194
+ "intent-work-open-decided-code": "Commits in the region are a decision's own work while the work item implementing that decision is still open.",
195
+ "intent-commit-join-conflict": "A commit joined to an agent run by its Chant-Run trailer or the run's record has the patch-id of a commit another run recorded, so it is not joined to that run by content.",
196
+ // The intent graph's answer to why the region is like this (#3034): what it can't account for.
197
+ "intent-why-no-decision": "No current decision governs the region at any granularity, and none is carried out by the commits or runs that made its current lines.",
198
+ "intent-why-no-run": "None of the region's current lines was made by a commit an agent run is joined to.",
199
+ "intent-why-uncommitted": "Some of the region's lines are not committed yet.",
200
+ "intent-why-run-ambiguous": "Some lines come from a commit several agent runs made, and no run's recorded hunks say which wrote them.",
201
+ // The forward coverage check (check --changes, #2773): findings, one per changed path.
202
+ "change-uncovered": "A path the diff changes is covered by no current decided record and no open work item, by path or by its member.",
203
+ "change-out-of-scope": "A record in hand for the change, such as the work item it is for or a decision that item implements, lists a path the diff changes in its out_of_scope.",
204
+ // The patch read (workspace patch): a read that fails.
205
+ "patch-path-invalid": "workspace patch --path names a path that is not relative and inside the workspace.",
206
+ // Composite instances joined to components (graph --composites, #2662): why the list is empty or has no component.
207
+ "composites-no-chant-member": "No member of kind chant was read, so nothing declares a composite instance or a component.",
208
+ "composites-none-declared": "The members read declare no composite instance.",
209
+ "composites-no-component": "The members read declare no component, so no composite instance has one.",
210
+ // The runtimes a member's components can deploy on (graph --composites, #2674).
211
+ "runtimes-config-unreadable": "The member's chant.config.ts could not be read, so only the built-in local runtime is listed, and no environment from the config.",
212
+ "runtimes-lexicon-unreadable": "A lexicon the member's config lists could not be loaded, so it is not listed as a runtime.",
213
+ // The environments a member's components may deploy to (graph --composites, #2695).
214
+ "environments-none-declared": "The member's chant.config.ts declares no environments, so only local and the environments in its ledger are listed.",
215
+ "environments-ledger-undeclared": "The member's ledger has releases in an environment its config's environments don't cover, so chant run --env would refuse it and it is not listed.",
216
+ "environments-ledger-unreadable": "The chant/lifecycle branch exists and the member's ledger environments could not be listed.",
217
+ "environments-component-undeclared": "A component declares an environment its member's chant.config.ts environments don't cover, so chant run --env would refuse it and it is not listed (#3153).",
218
+ // A declared diagram's source or render (check, #2764). Each is also a WSP finding.
219
+ "diagram-source-missing": "A declared diagram's source file does not exist in the tree read.",
220
+ "diagram-render-missing": "A declared diagram's render file does not exist in the tree read.",
221
+ "diagram-render-drift": "A declared diagram records a sourceHash, and the source's bytes now hash to something else: the render is stale for its source.",
222
+ // A box that holds a credential (check, #2726). Each is also a WSP finding.
223
+ "box-credential-declared": "A file in a box member's directory carries a literal secret: a credential's shape, or a literal where a credential goes. A variable or secret-manager reference is not one.",
224
+ "box-capability-unbrokered": "A capability in a member's box block names no broker, so the box would hold its credential.",
225
+ // The credential fountain itself hands a persistent box (check, #2780). Also a WSP finding.
226
+ "box-fountain-callback-undeclared": "A box member builds a fountain Box, whose persistent sandbox fountain gives a callback token scoped to its owner, and the member's box block does not declare the fountain-callback capability brokered by fountain with scope owner.",
227
+ // A box's intent, the decision record its box block names (check, #2850). Each is also a WSP finding.
228
+ "box-intent-unknown": "A box block names an intent, and no record of a declared kind named decision has that id.",
229
+ "box-intent-unconstrained": "The decision record a box names as its intent constrains no member or path of this workspace: no member: entry for a declared member and no path: entry at, above or inside one's directory.",
230
+ // Why a workspace isn't plantable (status and graph, #3146): not a finding, since a workspace need not be.
231
+ "box-none": "No member's box block declares services, so the workspace has no box for a host to plant.",
232
+ "box-several": "More than one member's box block declares services, and a planted workspace runs one box.",
233
+ // The work lease (chant workspace work claim|renew|release, #2732): why the command could not run.
234
+ "work-kind-missing": "No work kind to find the item in: --kind names a kind with no work block, or the declaration names no work kind.",
235
+ "work-kind-ambiguous": "More than one declared work kind has a record with the id, so --kind must name one.",
236
+ "work-item-unknown": "No work record has the id, so there is nothing to lease.",
237
+ "work-item-closed": "A claim on a work item in a closed state, such as done or dropped: there is no work left to claim.",
238
+ // Evidence attached to a criterion under the run's work lease (#2772): why it was refused. Nothing is written.
239
+ "work-criterion-unknown": "The work record lists no acceptance criterion with the id the evidence names, or its kind has no acceptance criteria.",
240
+ // The work lease: why a claim, renew or release was refused (exit 2).
241
+ "lease-held": "Someone holds a live lease on the work item: another worker, or, for a claim, the same one.",
242
+ "lease-not-held": "Nobody holds a live lease on the work item: it expired, was released or was never claimed.",
243
+ "lease-token-mismatch": "The live lease on the work item carries another fencing token than the one given.",
244
+ "lease-race": "Another writer changed the lease between this command's read and its write.",
245
+ "lease-push-rejected": "The remote refused the lease push: another clone claimed the item first, or the remote could not be reached.",
246
+ // The agent run record (chant workspace runs, #3033): why a write was refused, and what a read could not see. Nothing is written on a refusal.
247
+ "run-exists": "runs start or runs record was given a run id the ledger already has.",
248
+ "run-unknown": "runs end names a run the ledger has no start for.",
249
+ "run-ended": "runs end names a run whose end is already recorded.",
250
+ "runs-no-ledger": "The checkout has no chant/lifecycle branch, so there are no agent runs to read.",
251
+ "runs-ledger-malformed": "Some lines of the agent run ledger aren't run events; the rest are read.",
252
+ // The agent-run statement (runs sign, statement and verify, #3192): why a statement is refused or does not verify.
253
+ "run-not-ended": "runs sign or runs statement names a run with no end recorded. A statement is signed over the run's whole record.",
254
+ "run-statement-invalid": "The envelope's payload is not an in-toto Statement v1 with chant's agent-run predicate, or has a field the predicate does not define.",
255
+ "run-statement-signer-mismatch": "The statement names a signer other than the runner whose key signed it.",
256
+ "run-statement-mismatch": "A listed runner key signed the statement, and it does not match the run's record: another run, a record that hashes differently, or another unit, harness, model, provider or principal.",
257
+ // A box's listing written through chant (box listing set, #3308): why the write was refused. Nothing is written.
258
+ "listing-member-unknown": "box listing set names a member the declaration does not declare.",
259
+ "listing-box-missing": "box listing set names a member whose entry declares no box block, so it has no listing.",
260
+ "listing-cover-invalid": "The cover can't be read, is not a PNG, JPEG or WebP picture, is larger than 5 MiB, has a path outside the workspace, or has an extension other than its picture format's.",
261
+ // A declaration's members and hosts written through chant (member add|remove, host set, #3596): why the write was refused. Nothing is written.
262
+ "member-exists": "member add names a member the declaration already has, with an entry other than the one given.",
263
+ "member-unknown": "member remove names a member the declaration does not declare.",
264
+ // A box's factory written through chant (box factory set, #3600): why the write was refused. Nothing is written.
265
+ "factory-member-unknown": "box factory set names a member the declaration does not declare.",
266
+ "factory-box-missing": "box factory set names a member whose entry declares no box block, so it has no factory.",
267
+ // A box's work published through chant (box publish, #3165, ws-088): why the call printed no result.
268
+ "publish-member-unknown": "box publish names a member the declaration does not declare.",
269
+ "publish-none": "box publish names a member whose box block names no publisher, or which declares no box block.",
270
+ "publish-refused": "The box's publisher refused (it exited 2): nothing was published, and its message says why.",
271
+ "publish-failed": "The box's publisher could not be run, failed (a nonzero exit other than 2) or ran out of time; its message says what it had done.",
272
+ "publish-answer-invalid": "The box's publisher exited 0 and printed no JSON object, or one box-publish.schema.json does not allow.",
273
+ "publish-unrecorded": "The commit the publisher named is not in the repository, or lacks the apply record of ws-075: Chant-Applied-By naming --by, Chant-Applied-At, Chant-Applied-Commit and a Chant-Record for the item, or a Chant-Record for each record sent.",
274
+ // Work in progress under refs/chant/wip/<branch> and its replication (wip save|restore|push|fetch, #3172): why the write was refused. Nothing is written.
275
+ "wip-no-branch": "HEAD is detached, or names a branch with no commit yet, so there is no branch to keep work in progress for.",
276
+ "wip-none": "wip restore was given no snapshot, and the branch has none under refs/chant/wip/<branch>.",
277
+ "wip-snapshot-unknown": "wip restore names something that is not a work-in-progress snapshot chant took.",
278
+ "wip-branch-other": "wip restore names a snapshot taken on another branch than the one checked out.",
279
+ "wip-race": "Another writer moved refs/chant/wip/<branch> between this command's read and its write.",
280
+ "wip-policy-none": "wip push or wip fetch was run, and no box block declares replicate, so there is no remote.",
281
+ "wip-remote-unknown": "The replicate policy names a git remote the checkout does not have; the host adds it, with its credential, before chant pushes.",
282
+ // Which commits passed CI (ci last-green and ci tick, #3573): why nothing was read.
283
+ "ci-green-undeclared": "The declaration has no ci.green block, so chant does not know which check runs make a commit green.",
284
+ "ci-branch-unknown": "The checkout has no ref for the branch ci.green names: neither the remote-tracking branch nor a local one.",
285
+ // A box whose isolation fails (check, #2727). Each is also a WSP finding.
286
+ "box-isolation-collision": "Two boxes on one host resolve to the same port, state path or cookie name, or two ports in one box share an offset.",
287
+ "box-isolation-literal": "A host's stateRoot or a box's state entry is a literal machine path instead of one derived from an environment reference and the box's name.",
288
+ // The signer set's history (signers and verify, #2553): why a version is not a valid rotation of the one before. Nothing verifies past it.
289
+ "signers-file-missing": "There is no signers file at the base revision, so there is no signer history to read.",
290
+ "signers-removed": "The signers file was removed. Commits merged before the removal keep the set they were judged by; nothing after it verifies.",
291
+ "rotation-unparseable": "The rotation file beside the signers file is not JSON.",
292
+ "rotation-invalid": "The rotation file does not match its shape: schema 1, a version, the previous set's digest, a threshold and signatures.",
293
+ "rotation-first-version": "The first signer set's rotation file names a version other than 1, or a previous digest.",
294
+ "rotation-missing": "The signer set or its threshold changed and no rotation file signed by the set before it came with the change.",
295
+ "rotation-version-skew": "The rotation names a version other than the one after the set it replaces, as a replayed or skipped rotation does.",
296
+ "rotation-previous-mismatch": "The rotation names a previous digest other than the set it replaces, as a rollback to an older set does.",
297
+ "rotation-threshold-unsatisfiable": "The new threshold is more than the number of distinct signers in the new set, so no later rotation could meet it.",
298
+ "rotation-threshold-not-met": "Fewer distinct signers of the set before signed the rotation, in the chant-signers namespace, than that set's threshold.",
299
+ // Runner evidence (evidence sign and verify, #2553): why evidence is refused.
300
+ "trust-policy-unreadable": "The trust policy at base can't be read, or its signer history is broken, so no runner key is trusted.",
301
+ "envelope-unreadable": "The --envelope file can't be read, or is not JSON.",
302
+ "envelope-invalid": "The file is not a DSSE envelope: payloadType, payload in canonical base64, and signatures with keyid and sig.",
303
+ "envelope-untrusted": "No signature in the envelope verifies against a runner key the policy at base lists.",
304
+ "evidence-payload-type": "The envelope's payload type is not application/vnd.in-toto+json.",
305
+ "evidence-statement-invalid": "The payload is not an in-toto Statement v1 with chant's runner-evidence predicate, or has a field the predicate does not define.",
306
+ "evidence-runner-mismatch": "The statement names a runner other than the one whose key signed it.",
307
+ "runner-key-invalid": "The key given to evidence sign or runs sign is not an Ed25519 private key in PEM.",
308
+ "runner-key-is-signer": "The key given to evidence sign or runs sign is a person's key in the signers file. Evidence and run statements are signed by a service or CI identity.",
309
+ "runner-key-unlisted": "The policy at base lists no runner with the key given to evidence sign or runs sign.",
310
+ // The lineage lock (check).
311
+ "lock-invalid": "The lineage lock can't be read.",
312
+ "manual-step-open": "A scope in the lineage lock has an open manual step.",
313
+ };
314
+ /** Every code, in the order of {@link REASONS}. */
315
+ export const REASON_CODES = Object.keys(REASONS);
316
+ export function isReasonCode(value) {
317
+ return typeof value === "string" && Object.prototype.hasOwnProperty.call(REASONS, value);
318
+ }
319
+ export const PLUGIN_CODE = /^plugin:([^:\s]+):([a-z0-9]+(?:-[a-z0-9]+)*)$/;
320
+ /** Whether `value` is a plugin code, and, given `name` (a kind's name or its `commitJoinsName`), one in that namespace. */
321
+ export function isPluginCode(value, name) {
322
+ if (typeof value !== "string")
323
+ return false;
324
+ const m = value.match(PLUGIN_CODE);
325
+ return !!m && (name === undefined || m[1] === name);
326
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Asset pins and record links (#2549; #2524 D4, D6, D18).
3
+ *
4
+ * Artifact relationships are derived from decisions. A decision record pins
5
+ * the workspace files it rests on in `evidence`, each as `{title, path,
6
+ * sha256}`, and names what it governs in `constrains`, as `member:<name>` or
7
+ * `path:<path>`. There is no direct link from a design artifact to code or to
8
+ * another artifact: a reader walks from a file to the decisions whose
9
+ * `constrains` cover it, and from them to their pinned assets.
10
+ *
11
+ * A pin is checked against the tree a read looks at (the working tree, or a
12
+ * revision's git objects). A file whose bytes hash differently is `drifted`,
13
+ * and one that is gone is `missing`. Neither makes the record invalid: the
14
+ * record is still what was decided, and the drift is reported beside it.
15
+ *
16
+ * Which front-matter fields hold pins and links is the kind's data
17
+ * (`pins.field`, `constrains.field`), so this module never names `evidence`.
18
+ */
19
+ import { sha256Hex } from "../content-digest.js";
20
+ /**
21
+ * A path from the workspace root: `/` separators, no leading `/`, no `.` or
22
+ * `..` segment, no empty segment, no backslash or control character and no
23
+ * trailing `/`. The decision schema holds the same pattern.
24
+ */
25
+ export const WORKSPACE_PATH_PATTERN = String.raw `(?!/)(?!(?:[^/]*/)*\.{1,2}(?:/|$))(?!.*//)[^\\\u0000-\u001f]*[^/\\\u0000-\u001f]`;
26
+ const WORKSPACE_PATH = new RegExp(`^${WORKSPACE_PATH_PATTERN}$`, "u");
27
+ const SHA256 = /^[0-9a-f]{64}$/;
28
+ export function isWorkspacePath(value) {
29
+ return typeof value === "string" && WORKSPACE_PATH.test(value);
30
+ }
31
+ /** The well-formed pins in a record's `field` list: entries with a workspace path and a hex sha256. */
32
+ export function pinEntries(data, field) {
33
+ const list = data?.[field];
34
+ if (!Array.isArray(list))
35
+ return [];
36
+ const out = [];
37
+ for (const e of list) {
38
+ if (e === null || typeof e !== "object" || Array.isArray(e))
39
+ continue;
40
+ const { path, sha256 } = e;
41
+ if (isWorkspacePath(path) && typeof sha256 === "string" && SHA256.test(sha256))
42
+ out.push({ path, sha256 });
43
+ }
44
+ return out;
45
+ }
46
+ /** The hex SHA-256 of the file at `path` in `tree`, or undefined when it is not a file there. */
47
+ export function fileDigest(tree, path) {
48
+ if (tree.stat(path) !== "file")
49
+ return undefined;
50
+ const bytes = tree.bytes ? tree.bytes(path) : Buffer.from(tree.read(path), "utf-8");
51
+ return sha256Hex(bytes);
52
+ }
53
+ /** Check each pin against `tree`, rooted at the workspace root. */
54
+ export function checkPins(pins, tree) {
55
+ const assets = [];
56
+ const warnings = [];
57
+ for (const pin of pins) {
58
+ const actual = fileDigest(tree, pin.path) ?? null;
59
+ const state = actual === null ? "missing" : actual === pin.sha256 ? "pinned" : "drifted";
60
+ assets.push({ ...pin, actual, state });
61
+ if (state === "missing") {
62
+ // Worded the same for the working tree and a revision (#2745): a missing
63
+ // file is missing either way, and `tree.label` would otherwise make the
64
+ // same finding read differently depending on which one was read.
65
+ warnings.push({ code: "asset-missing", message: `evidence pins ${pin.path}, which does not exist` });
66
+ }
67
+ else if (state === "drifted") {
68
+ warnings.push({
69
+ code: "asset-drift",
70
+ message: `${pin.path} changed since it was pinned: sha256 ${pin.sha256.slice(0, 12)} is pinned, the file${tree.label} hashes to ${actual.slice(0, 12)}`,
71
+ });
72
+ }
73
+ }
74
+ return { assets, warnings };
75
+ }
76
+ // ── Record links ─────────────────────────────────────────────────────────────
77
+ /** The kinds of link a record has in `chant workspace graph`. Closed. */
78
+ export const RECORD_LINK_KINDS = ["asset", "constrains"];
79
+ /** The member whose directory holds `path` (the deepest one), or null. */
80
+ export function memberHolding(path, members) {
81
+ let best = null;
82
+ for (const m of members) {
83
+ const inside = m.dir === "." || path === m.dir || path.startsWith(`${m.dir}/`);
84
+ if (inside && (!best || best.dir === "." || m.dir.length > best.dir.length))
85
+ best = m;
86
+ }
87
+ return best?.name ?? null;
88
+ }
89
+ /** Whether a `path:` constraint covers `file`: the same path, or a directory above it. */
90
+ export function constraintCovers(constraint, file) {
91
+ return file === constraint || file.startsWith(`${constraint}/`);
92
+ }
93
+ /**
94
+ * The link rows of the records of one kind: an `asset` row per pin and a
95
+ * `constrains` row per `member:` or `path:` entry. Superseded records and
96
+ * records with no id have none, since their links no longer hold. Paths
97
+ * resolve in `tree` (the workspace root), members in `members`.
98
+ */
99
+ export function recordLinkRows(kindName, records, constrainsField, tree, members) {
100
+ const rows = [];
101
+ for (const r of records) {
102
+ if (r.id === null || r.supersededBy !== null)
103
+ continue;
104
+ const base = { origin: "declared", resolves: "source", recordKind: kindName, record: r.id, recordPath: r.path };
105
+ for (const a of r.assets) {
106
+ rows.push({
107
+ kind: "asset",
108
+ ...base,
109
+ target: a.path,
110
+ member: memberHolding(a.path, members),
111
+ status: a.state,
112
+ reason: a.state === "missing"
113
+ ? `${a.path} does not exist${tree.label}`
114
+ : a.state === "drifted"
115
+ ? `${a.path} changed since ${r.id} pinned it`
116
+ : a.state === "stale"
117
+ ? `${a.path} has not changed since a record ${r.id} supersedes pinned it`
118
+ : null,
119
+ sha256: a.sha256,
120
+ actual: a.actual,
121
+ });
122
+ }
123
+ const list = constrainsField ? r.data?.[constrainsField] : undefined;
124
+ if (!Array.isArray(list))
125
+ continue;
126
+ for (const entry of list) {
127
+ if (typeof entry !== "string")
128
+ continue;
129
+ if (entry.startsWith("member:")) {
130
+ const name = entry.slice("member:".length);
131
+ const known = members.some((m) => m.name === name);
132
+ rows.push({ kind: "constrains", ...base, target: entry, member: known ? name : null, status: known ? "resolved" : "missing", reason: known ? null : `${name} is not a member of this workspace` });
133
+ }
134
+ else if (entry.startsWith("path:")) {
135
+ const path = entry.slice("path:".length);
136
+ if (!isWorkspacePath(path))
137
+ continue;
138
+ const exists = tree.stat(path) !== undefined;
139
+ rows.push({
140
+ kind: "constrains",
141
+ ...base,
142
+ target: entry,
143
+ member: memberHolding(path, members),
144
+ status: exists ? "resolved" : "missing",
145
+ reason: exists ? null : `${path} does not exist${tree.label}`,
146
+ });
147
+ }
148
+ }
149
+ }
150
+ return rows;
151
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The commit that decided a record: the commit reachable from a revision that
3
+ * last moved the record's file into an approved state and kept it there. A
4
+ * record added in an approved state was decided by the commit that added it.
5
+ *
6
+ * "Approved" is `isDecided` from `work.ts`: a state the kind's `approval`
7
+ * ranks above 0, or, for a kind with no `approval`, one of its
8
+ * `closedStates`. For the decision kind that is decided, ratified and
9
+ * superseded, and not proposed or withdrawn. Walking the file's history
10
+ * newest first, the commit is the oldest one in the unbroken run of approved
11
+ * versions that ends at the revision: a record decided, then ratified, keeps
12
+ * the commit that decided it, and one withdrawn and decided again gets the
13
+ * second decision.
14
+ *
15
+ * The intent graph's windows open here (`intent.ts`): a commit made while a
16
+ * record was only proposed is not in its window. A record that is not
17
+ * approved at the revision has no deciding commit, and its window opens at
18
+ * the commit that added it, as it always did.
19
+ *
20
+ * History is read with two git processes for any number of records: one
21
+ * `git log` over their paths and one `git cat-file --batch` for the versions.
22
+ */
23
+ import { execFileSync } from "node:child_process";
24
+ import { parseRecord } from "./records.js";
25
+ import { isDecided } from "./work.js";
26
+ function tryGit(top, args, input) {
27
+ try {
28
+ return execFileSync("git", args, { cwd: top, input, stdio: [input === undefined ? "ignore" : "pipe", "pipe", "pipe"], maxBuffer: 512 * 1024 * 1024 });
29
+ }
30
+ catch {
31
+ return undefined;
32
+ }
33
+ }
34
+ /** Each `sha:path` blob's text, or undefined when git has none. */
35
+ function blobs(top, names) {
36
+ const out = new Map();
37
+ if (names.length === 0)
38
+ return out;
39
+ const buf = tryGit(top, ["cat-file", "--batch"], `${names.join("\n")}\n`);
40
+ if (!buf)
41
+ return out;
42
+ let at = 0;
43
+ for (const name of names) {
44
+ const nl = buf.indexOf(0x0a, at);
45
+ if (nl < 0)
46
+ break;
47
+ const header = buf.subarray(at, nl).toString("utf-8");
48
+ at = nl + 1;
49
+ const m = header.match(/^[0-9a-f]+ (\w+) (\d+)$/);
50
+ if (!m)
51
+ continue; // "<name> missing"
52
+ const size = Number(m[2]);
53
+ if (m[1] === "blob")
54
+ out.set(name, buf.subarray(at, at + size).toString("utf-8"));
55
+ at += size + 1;
56
+ }
57
+ return out;
58
+ }
59
+ /**
60
+ * For each record path (from the repository root), the commit reachable from
61
+ * `rev` that decided it, or null when the record is not approved at `rev` or
62
+ * has no history there.
63
+ */
64
+ export function decidedCommits(top, rev, paths, kind) {
65
+ const out = new Map(paths.map((p) => [p, null]));
66
+ const stateField = kind.stateField;
67
+ if (!stateField || paths.length === 0)
68
+ return out;
69
+ const log = tryGit(top, ["log", "--no-renames", "--format=%x00%H%x1f%aI%x1f%s", "--name-only", rev, "--", ...paths])?.toString("utf-8");
70
+ if (log === undefined)
71
+ return out;
72
+ const wanted = new Set(paths);
73
+ const commits = new Map();
74
+ /** Each path's commits, newest first. */
75
+ const history = new Map();
76
+ for (const chunk of log.split("\0")) {
77
+ if (!chunk)
78
+ continue;
79
+ const nl = chunk.indexOf("\n");
80
+ const [sha, date, subject] = (nl < 0 ? chunk : chunk.slice(0, nl)).split("\x1f");
81
+ commits.set(sha, { date, subject });
82
+ for (const f of (nl < 0 ? "" : chunk.slice(nl + 1)).split("\n")) {
83
+ if (!wanted.has(f))
84
+ continue;
85
+ const list = history.get(f) ?? [];
86
+ list.push(sha);
87
+ history.set(f, list);
88
+ }
89
+ }
90
+ const texts = blobs(top, [...history].flatMap(([p, shas]) => shas.map((s) => `${s}:${p}`)));
91
+ for (const [path, shas] of history) {
92
+ let decided = null;
93
+ for (const sha of shas) {
94
+ const text = texts.get(`${sha}:${path}`);
95
+ const fm = text === undefined ? undefined : parseRecord(kind.format, text);
96
+ const state = fm?.ok ? fm.value[stateField] : undefined;
97
+ if (typeof state !== "string" || !isDecided(kind, state))
98
+ break;
99
+ decided = sha;
100
+ }
101
+ if (decided)
102
+ out.set(path, { sha: decided, ...commits.get(decided) });
103
+ }
104
+ return out;
105
+ }