@intentius/chant 0.124.13 → 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 (907) 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.js +260 -0
  306. package/dist/gate-resume-run.js +154 -0
  307. package/dist/gated-waves.js +165 -0
  308. package/dist/governance.js +43 -0
  309. package/dist/graph-declared.js +45 -0
  310. package/dist/graph-detail.js +207 -0
  311. package/dist/graph-dot.js +54 -0
  312. package/dist/graph-effective.js +107 -0
  313. package/dist/graph-ir.js +623 -0
  314. package/dist/graph-layout.js +184 -0
  315. package/dist/graph-lens.js +105 -0
  316. package/dist/graph-mermaid.js +83 -0
  317. package/dist/graph-ops.js +39 -0
  318. package/dist/graph-refs.js +156 -0
  319. package/dist/held-elsewhere.js +87 -0
  320. package/dist/identity.js +251 -0
  321. package/dist/import/base-parser.js +34 -0
  322. package/dist/import/embedded.js +255 -0
  323. package/dist/import/generator.js +1 -0
  324. package/dist/import/ir-utils.js +85 -0
  325. package/dist/import/parser-options.js +45 -0
  326. package/dist/import/parser.js +1 -0
  327. package/dist/index.js +118 -0
  328. package/dist/intrinsic-interpolation.js +73 -0
  329. package/dist/intrinsic.js +31 -0
  330. package/dist/join-key.js +35 -0
  331. package/dist/kubectl-context.js +150 -0
  332. package/dist/lexicon-config.js +58 -0
  333. package/dist/lexicon-integrity.js +47 -0
  334. package/dist/lexicon-manifest.js +70 -0
  335. package/dist/lexicon-module.d.ts.map +1 -1
  336. package/dist/lexicon-module.js +241 -0
  337. package/dist/lexicon-output.js +218 -0
  338. package/dist/lexicon-plugin-helpers.js +104 -0
  339. package/dist/lexicon-schema.js +136 -0
  340. package/dist/lexicon.js +130 -0
  341. package/dist/lifecycle/affected.js +224 -0
  342. package/dist/lifecycle/assert-live.js +110 -0
  343. package/dist/lifecycle/build-ledger-store.js +160 -0
  344. package/dist/lifecycle/build-ledger.js +155 -0
  345. package/dist/lifecycle/change-set.js +356 -0
  346. package/dist/lifecycle/converge-ledger.js +161 -0
  347. package/dist/lifecycle/deep-diff.js +233 -0
  348. package/dist/lifecycle/deep-observe.js +147 -0
  349. package/dist/lifecycle/digest.js +143 -0
  350. package/dist/lifecycle/disruption.js +135 -0
  351. package/dist/lifecycle/gate-applied.js +113 -0
  352. package/dist/lifecycle/gate-audit.js +341 -0
  353. package/dist/lifecycle/gate-ledger-select.js +89 -0
  354. package/dist/lifecycle/gate-ledger.js +193 -0
  355. package/dist/lifecycle/gate-origin.js +117 -0
  356. package/dist/lifecycle/gate-pending.js +58 -0
  357. package/dist/lifecycle/git.js +1182 -0
  358. package/dist/lifecycle/identity.js +58 -0
  359. package/dist/lifecycle/index.js +26 -0
  360. package/dist/lifecycle/lease.js +283 -0
  361. package/dist/lifecycle/ledger-port.js +1 -0
  362. package/dist/lifecycle/legacy-digest.js +91 -0
  363. package/dist/lifecycle/live-diff.js +274 -0
  364. package/dist/lifecycle/local-note.js +15 -0
  365. package/dist/lifecycle/member-ledger.js +122 -0
  366. package/dist/lifecycle/observation-baseline.js +155 -0
  367. package/dist/lifecycle/observe.js +375 -0
  368. package/dist/lifecycle/oras-referrer-lookup.js +82 -0
  369. package/dist/lifecycle/override-ledger.js +54 -0
  370. package/dist/lifecycle/plan-digest.js +110 -0
  371. package/dist/lifecycle/plan-ledger.js +129 -0
  372. package/dist/lifecycle/receipt-plan.js +192 -0
  373. package/dist/lifecycle/release-ledger.js +155 -0
  374. package/dist/lifecycle/release-read.js +64 -0
  375. package/dist/lifecycle/replay.js +193 -0
  376. package/dist/lifecycle/rollback.js +102 -0
  377. package/dist/lifecycle/run-ledger.js +183 -0
  378. package/dist/lifecycle/scenario-eval.js +204 -0
  379. package/dist/lifecycle/scenario.js +214 -0
  380. package/dist/lifecycle/snapshot.js +239 -0
  381. package/dist/lifecycle/status.js +447 -0
  382. package/dist/lifecycle/symptoms.js +117 -0
  383. package/dist/lifecycle/teardown.js +255 -0
  384. package/dist/lifecycle/types.js +1 -0
  385. package/dist/lifecycle/unobserved-gate.js +33 -0
  386. package/dist/lifecycle/wave-plans.js +68 -0
  387. package/dist/lifecycle/work-item-id.js +36 -0
  388. package/dist/lifecycle/work-lease.js +393 -0
  389. package/dist/lint/component-checks.js +87 -0
  390. package/dist/lint/config.js +483 -0
  391. package/dist/lint/declarative.js +122 -0
  392. package/dist/lint/discover.d.ts.map +1 -1
  393. package/dist/lint/discover.js +138 -0
  394. package/dist/lint/engine.js +246 -0
  395. package/dist/lint/knowledge-checks.js +64 -0
  396. package/dist/lint/named-checks.js +22 -0
  397. package/dist/lint/output-checks.js +87 -0
  398. package/dist/lint/output-docs.js +163 -0
  399. package/dist/lint/parser.js +33 -0
  400. package/dist/lint/pipeline-change-gate.js +70 -0
  401. package/dist/lint/policy-import.d.ts +1 -1
  402. package/dist/lint/policy-import.d.ts.map +1 -1
  403. package/dist/lint/policy-import.js +62 -0
  404. package/dist/lint/policy-sandbox.js +86 -0
  405. package/dist/lint/policy.js +122 -0
  406. package/dist/lint/post-synth.js +87 -0
  407. package/dist/lint/presets/relaxed.json +26 -0
  408. package/dist/lint/presets/strict.json +24 -24
  409. package/dist/lint/receipt-checks.js +83 -0
  410. package/dist/lint/rule-loader.d.ts.map +1 -1
  411. package/dist/lint/rule-loader.js +89 -0
  412. package/dist/lint/rule-registry.js +86 -0
  413. package/dist/lint/rule.js +1 -0
  414. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
  415. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
  416. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
  417. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
  418. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
  419. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
  420. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
  421. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
  422. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
  423. package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
  424. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
  425. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
  426. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
  427. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
  428. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
  429. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
  430. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
  431. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
  432. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
  433. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
  434. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
  435. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
  436. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
  437. package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
  438. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
  439. package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
  440. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
  441. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
  442. package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
  443. package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
  444. package/dist/lint/rules/comp/index.js +33 -0
  445. package/dist/lint/rules/comp/support.js +129 -0
  446. package/dist/lint/rules/composite-scope.js +51 -0
  447. package/dist/lint/rules/cor017-composite-name-match.js +93 -0
  448. package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
  449. package/dist/lint/rules/cor021-env-literal-name.js +100 -0
  450. package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
  451. package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
  452. package/dist/lint/rules/declarable-naming-convention.js +62 -0
  453. package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
  454. package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
  455. package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
  456. package/dist/lint/rules/evl004-spread-non-const.js +94 -0
  457. package/dist/lint/rules/evl005-resource-block-body.js +41 -0
  458. package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
  459. package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
  460. package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
  461. package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
  462. package/dist/lint/rules/export-required.js +115 -0
  463. package/dist/lint/rules/file-declarable-limit.js +88 -0
  464. package/dist/lint/rules/flat-declarations.js +62 -0
  465. package/dist/lint/rules/index.js +90 -0
  466. package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
  467. package/dist/lint/rules/no-redundant-type-import.js +76 -0
  468. package/dist/lint/rules/no-redundant-value-cast.js +41 -0
  469. package/dist/lint/rules/no-string-ref.js +59 -0
  470. package/dist/lint/rules/no-unused-declarable-import.js +75 -0
  471. package/dist/lint/rules/no-unused-declarable.js +142 -0
  472. package/dist/lint/rules/op/index.js +28 -0
  473. package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
  474. package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
  475. package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
  476. package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
  477. package/dist/lint/rules/op/support.js +11 -0
  478. package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
  479. package/dist/lint/rules/property-kind.js +56 -0
  480. package/dist/lint/rules/single-concern-file.js +71 -0
  481. package/dist/lint/rules/sys001-no-literal-key.js +60 -0
  482. package/dist/lint/selectors.js +168 -0
  483. package/dist/lint/suppressions.js +129 -0
  484. package/dist/lint/typescript.js +17 -0
  485. package/dist/live-endpoint.js +113 -0
  486. package/dist/live-read-session.js +76 -0
  487. package/dist/lsp/lexicon-providers.js +163 -0
  488. package/dist/lsp/types.js +5 -0
  489. package/dist/managed-fields.js +293 -0
  490. package/dist/mcp/types.js +4 -0
  491. package/dist/notify-verify.js +0 -1
  492. package/dist/notify.js +0 -1
  493. package/dist/notify.schema.json +72 -0
  494. package/dist/observation.js +266 -0
  495. package/dist/okf-read.js +134 -0
  496. package/dist/okf.js +275 -0
  497. package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
  498. package/dist/op/activities/activity-contracts.js +313 -0
  499. package/dist/op/activities/apply.js +582 -0
  500. package/dist/op/activities/build.js +18 -0
  501. package/dist/op/activities/change-coverage.js +40 -0
  502. package/dist/op/activities/change-set.js +64 -0
  503. package/dist/op/activities/converge.js +492 -0
  504. package/dist/op/activities/decide.js +211 -0
  505. package/dist/op/activities/env-teardown.js +110 -0
  506. package/dist/op/activities/factory.js +591 -0
  507. package/dist/op/activities/forge-pull-request.js +82 -0
  508. package/dist/op/activities/gh-host.js +78 -0
  509. package/dist/op/activities/guard-validate.js +165 -0
  510. package/dist/op/activities/http-check.js +40 -0
  511. package/dist/op/activities/index.js +59 -0
  512. package/dist/op/activities/lexicon-upgrade.js +629 -0
  513. package/dist/op/activities/lifecycle.js +109 -0
  514. package/dist/op/activities/pipeline-audit.js +147 -0
  515. package/dist/op/activities/policy.js +26 -0
  516. package/dist/op/activities/predict-behaviour.js +341 -0
  517. package/dist/op/activities/propose-upgrade.js +165 -0
  518. package/dist/op/activities/reconcile.js +997 -0
  519. package/dist/op/activities/shell.js +118 -0
  520. package/dist/op/activities/source-release.js +97 -0
  521. package/dist/op/activities/source-rollback.js +165 -0
  522. package/dist/op/activities/teardown.js +17 -0
  523. package/dist/op/activities/util.js +6 -0
  524. package/dist/op/activities/wait.js +51 -0
  525. package/dist/op/activities/work-evidence.js +35 -0
  526. package/dist/op/activities/workflow-audit.js +133 -0
  527. package/dist/op/activity-contract-registry.js +106 -0
  528. package/dist/op/activity-contract.js +232 -0
  529. package/dist/op/activity-failure.js +31 -0
  530. package/dist/op/activity-profiles.js +129 -0
  531. package/dist/op/activity-registry.js +105 -0
  532. package/dist/op/activity-runtime.js +28 -0
  533. package/dist/op/builders.js +801 -0
  534. package/dist/op/change-signal.js +118 -0
  535. package/dist/op/composites/apply-op.js +151 -0
  536. package/dist/op/composites/behaviour-op.js +65 -0
  537. package/dist/op/composites/converge-op.js +141 -0
  538. package/dist/op/composites/index.js +19 -0
  539. package/dist/op/composites/lexicon-upgrade-op.js +107 -0
  540. package/dist/op/composites/pipeline-audit-op.js +50 -0
  541. package/dist/op/composites/reconcile-op.js +84 -0
  542. package/dist/op/composites/watch-op.js +69 -0
  543. package/dist/op/composites/workflow-audit-op.js +57 -0
  544. package/dist/op/converge-rule.js +205 -0
  545. package/dist/op/cron.js +146 -0
  546. package/dist/op/decide-backend.js +181 -0
  547. package/dist/op/decide-config.js +68 -0
  548. package/dist/op/decide-read-inputs.js +141 -0
  549. package/dist/op/discover.d.ts.map +1 -1
  550. package/dist/op/discover.js +213 -0
  551. package/dist/op/duration.js +21 -0
  552. package/dist/op/emulator-freshness.js +80 -0
  553. package/dist/op/emulator-lifecycle.js +269 -0
  554. package/dist/op/factory.js +83 -0
  555. package/dist/op/gate-approval.js +172 -0
  556. package/dist/op/gate-name.js +86 -0
  557. package/dist/op/gate-plan-context.js +167 -0
  558. package/dist/op/gate-point-run.js +67 -0
  559. package/dist/op/gate-point.js +111 -0
  560. package/dist/op/gate-resume-plan.js +155 -0
  561. package/dist/op/gate-resume.js +31 -0
  562. package/dist/op/gate-review.js +290 -0
  563. package/dist/op/gate-run-locator.js +85 -0
  564. package/dist/op/gate-summary.js +100 -0
  565. package/dist/op/gate-wait.js +56 -0
  566. package/dist/op/gate.js +449 -0
  567. package/dist/op/generate-pipeline.js +124 -0
  568. package/dist/op/index.js +51 -0
  569. package/dist/op/lifecycle-receipt-store.js +45 -0
  570. package/dist/op/local-executor.js +1164 -0
  571. package/dist/op/local-output.js +140 -0
  572. package/dist/op/op-ir.js +317 -0
  573. package/dist/op/op-verb-class.js +131 -0
  574. package/dist/op/op-waves-notify.js +136 -0
  575. package/dist/op/op-waves-run.js +1657 -0
  576. package/dist/op/op-waves.js +409 -0
  577. package/dist/op/operator.js +743 -0
  578. package/dist/op/receipt-store.js +94 -0
  579. package/dist/op/resource.js +23 -0
  580. package/dist/op/run-context.js +28 -0
  581. package/dist/op/run-live.js +256 -0
  582. package/dist/op/runtime.js +21 -0
  583. package/dist/op/runtimes/local.js +195 -0
  584. package/dist/op/source-archive.js +131 -0
  585. package/dist/op/step-output-ref.js +397 -0
  586. package/dist/op/steward-beside.js +169 -0
  587. package/dist/op/steward-points.js +138 -0
  588. package/dist/op/steward-turn.js +59 -0
  589. package/dist/op/steward.js +317 -0
  590. package/dist/op/types.js +25 -0
  591. package/dist/op/work-lease-decl.js +81 -0
  592. package/dist/op/work-lease-run.js +393 -0
  593. package/dist/override-gate.js +284 -0
  594. package/dist/owner-chain.js +74 -0
  595. package/dist/ownership.js +92 -0
  596. package/dist/params.js +61 -0
  597. package/dist/plan-summary.js +711 -0
  598. package/dist/point-decision.js +211 -0
  599. package/dist/pr-forge.js +810 -0
  600. package/dist/pr-loop.js +203 -0
  601. package/dist/project-codegen.js +191 -0
  602. package/dist/project-root.js +74 -0
  603. package/dist/project-validation.js +50 -0
  604. package/dist/provenance.js +157 -0
  605. package/dist/pseudo-parameter.js +40 -0
  606. package/dist/reconcile.js +450 -0
  607. package/dist/resource-attributes.js +33 -0
  608. package/dist/runtime-adapter.js +77 -0
  609. package/dist/runtime.js +66 -0
  610. package/dist/secret-materialization.js +153 -0
  611. package/dist/secret-provenance.js +250 -0
  612. package/dist/serializer-walker.js +112 -0
  613. package/dist/serializer.js +1 -0
  614. package/dist/sort.js +45 -0
  615. package/dist/stack-output.js +115 -0
  616. package/dist/telemetry-attribution.js +149 -0
  617. package/dist/terraform/__fixtures__/build-graph.js +63 -0
  618. package/dist/terraform/adopt-state.js +40 -0
  619. package/dist/terraform/aws-resources.js +384 -0
  620. package/dist/terraform/bridge.js +204 -0
  621. package/dist/terraform/carve-provider.js +155 -0
  622. package/dist/terraform/carve.js +138 -0
  623. package/dist/terraform/data-source-shape.js +57 -0
  624. package/dist/terraform/emit-source.js +36 -0
  625. package/dist/terraform/excise.js +123 -0
  626. package/dist/terraform/graduate.js +128 -0
  627. package/dist/terraform/graph.js +435 -0
  628. package/dist/terraform/hcl2json.js +60 -0
  629. package/dist/terraform/manifest.js +149 -0
  630. package/dist/terraform/parse.js +81 -0
  631. package/dist/terraform/providers/aws.js +146 -0
  632. package/dist/terraform/providers/gcp.js +294 -0
  633. package/dist/terraform/providers/index.js +17 -0
  634. package/dist/terraform/providers/kubernetes.js +253 -0
  635. package/dist/terraform/score.js +151 -0
  636. package/dist/terraform/state.js +67 -0
  637. package/dist/terraform/tier-map.js +74 -0
  638. package/dist/terraform/types.js +13 -0
  639. package/dist/terraform/unified-diff.js +132 -0
  640. package/dist/testing.js +295 -0
  641. package/dist/toml-emit.js +153 -0
  642. package/dist/toml-parse.js +355 -0
  643. package/dist/toml-utils.js +60 -0
  644. package/dist/toml.js +428 -0
  645. package/dist/ts-loader.d.ts +46 -0
  646. package/dist/ts-loader.d.ts.map +1 -0
  647. package/dist/ts-loader.js +103 -0
  648. package/dist/types.js +1 -0
  649. package/dist/utils.js +61 -0
  650. package/dist/validation.js +20 -0
  651. package/dist/vendor/js-yaml-load.js +1662 -0
  652. package/dist/workspace/__fixtures__/contract-repo.js +103 -0
  653. package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
  654. package/dist/workspace/__fixtures__/sessions.js +91 -0
  655. package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
  656. package/dist/workspace/agent-cli.js +99 -0
  657. package/dist/workspace/agent.schema.json +390 -0
  658. package/dist/workspace/answers-ledger.js +89 -0
  659. package/dist/workspace/box-cli.js +142 -0
  660. package/dist/workspace/box-factory-write.js +196 -0
  661. package/dist/workspace/box-factory-write.schema.json +342 -0
  662. package/dist/workspace/box-factory.js +88 -0
  663. package/dist/workspace/box-intent.js +126 -0
  664. package/dist/workspace/box-isolation.js +169 -0
  665. package/dist/workspace/box-listing-write.schema.json +204 -0
  666. package/dist/workspace/box-listing.js +298 -0
  667. package/dist/workspace/box-publish.js +352 -0
  668. package/dist/workspace/box-publish.schema.json +498 -0
  669. package/dist/workspace/box-services.js +39 -0
  670. package/dist/workspace/broker-protocol.js +359 -0
  671. package/dist/workspace/broker-protocol.schema.json +228 -0
  672. package/dist/workspace/change-set.schema.json +460 -0
  673. package/dist/workspace/changes-cli.js +56 -0
  674. package/dist/workspace/changes.js +446 -0
  675. package/dist/workspace/changes.schema.json +642 -0
  676. package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
  677. package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
  678. package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
  679. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
  680. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
  681. package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
  682. package/dist/workspace/chant-migrations.js +113 -0
  683. package/dist/workspace/check.schema.json +433 -0
  684. package/dist/workspace/checks/box-isolation.js +62 -0
  685. package/dist/workspace/checks/boxes.js +491 -0
  686. package/dist/workspace/checks/diagrams.js +104 -0
  687. package/dist/workspace/checks/generated.js +419 -0
  688. package/dist/workspace/checks/ledgers.js +212 -0
  689. package/dist/workspace/checks/links.js +191 -0
  690. package/dist/workspace/checks/live.js +100 -0
  691. package/dist/workspace/checks/pipelines.js +188 -0
  692. package/dist/workspace/checks/records.js +169 -0
  693. package/dist/workspace/checks.js +426 -0
  694. package/dist/workspace/ci-green-cli.js +125 -0
  695. package/dist/workspace/ci-green-forge.js +83 -0
  696. package/dist/workspace/ci-green-workflow.js +199 -0
  697. package/dist/workspace/ci-green.js +325 -0
  698. package/dist/workspace/ci-last-green.schema.json +158 -0
  699. package/dist/workspace/compose-graph.js +235 -0
  700. package/dist/workspace/compose-reports.js +146 -0
  701. package/dist/workspace/composites.js +264 -0
  702. package/dist/workspace/composites.schema.json +617 -0
  703. package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
  704. package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
  705. package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
  706. package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
  707. package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
  708. package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
  709. package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
  710. package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
  711. package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
  712. package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
  713. package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
  714. package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
  715. package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
  716. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  717. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  718. package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
  719. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  720. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  721. package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
  722. package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
  723. package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  724. package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  725. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
  726. package/dist/workspace/conformance/broker.js +736 -0
  727. package/dist/workspace/conformance/index.js +673 -0
  728. package/dist/workspace/conformance/vitest.js +108 -0
  729. package/dist/workspace/conformance/writer.js +1080 -0
  730. package/dist/workspace/decide.js +879 -0
  731. package/dist/workspace/decision-points.schema.json +135 -135
  732. package/dist/workspace/declaration-write-cli.js +74 -0
  733. package/dist/workspace/declaration-write.js +238 -0
  734. package/dist/workspace/declaration.js +938 -0
  735. package/dist/workspace/declaration.schema.json +1413 -1413
  736. package/dist/workspace/declared-kinds.js +106 -0
  737. package/dist/workspace/environments.js +164 -0
  738. package/dist/workspace/evidence.schema.json +279 -0
  739. package/dist/workspace/export-cli.js +185 -0
  740. package/dist/workspace/export.js +499 -0
  741. package/dist/workspace/factory-rules.js +175 -0
  742. package/dist/workspace/generated-files.js +92 -0
  743. package/dist/workspace/glob.js +45 -0
  744. package/dist/workspace/graph-cache.js +352 -0
  745. package/dist/workspace/graph-cli.js +348 -0
  746. package/dist/workspace/graph.schema.json +1338 -0
  747. package/dist/workspace/identity-gate-rule.js +75 -0
  748. package/dist/workspace/identity.js +126 -0
  749. package/dist/workspace/import.js +283 -0
  750. package/dist/workspace/init.js +620 -0
  751. package/dist/workspace/intent-cli.js +263 -0
  752. package/dist/workspace/intent-joins.js +201 -0
  753. package/dist/workspace/intent-record.js +352 -0
  754. package/dist/workspace/intent-record.schema.json +864 -0
  755. package/dist/workspace/intent.js +1582 -0
  756. package/dist/workspace/intent.schema.json +2420 -0
  757. package/dist/workspace/json-edit.js +221 -0
  758. package/dist/workspace/jsonc.js +235 -0
  759. package/dist/workspace/kind-readers.js +103 -0
  760. package/dist/workspace/kinds.js +587 -0
  761. package/dist/workspace/lexicon-symbols.js +112 -0
  762. package/dist/workspace/lineage-adopt-cli.js +102 -0
  763. package/dist/workspace/lineage-adopt.js +360 -0
  764. package/dist/workspace/lineage-check.js +282 -0
  765. package/dist/workspace/lineage-cli.js +121 -0
  766. package/dist/workspace/lineage-hash-index.js +284 -0
  767. package/dist/workspace/lineage-init.js +507 -0
  768. package/dist/workspace/lineage-lock.js +387 -0
  769. package/dist/workspace/lineage-merge.js +45 -0
  770. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  771. package/dist/workspace/lineage-migrations.js +329 -0
  772. package/dist/workspace/lineage-provenance.js +36 -0
  773. package/dist/workspace/lineage-update.js +138 -0
  774. package/dist/workspace/lineage-upgrade-cli.js +131 -0
  775. package/dist/workspace/lineage-upgrade.js +889 -0
  776. package/dist/workspace/lineage-vendor.js +171 -0
  777. package/dist/workspace/lineage-version.js +128 -0
  778. package/dist/workspace/lineage-versions.js +275 -0
  779. package/dist/workspace/links.js +330 -0
  780. package/dist/workspace/ls-generated.js +95 -0
  781. package/dist/workspace/ls.js +277 -0
  782. package/dist/workspace/ls.schema.json +333 -0
  783. package/dist/workspace/member-commands.js +508 -0
  784. package/dist/workspace/member-handles.js +216 -0
  785. package/dist/workspace/member-pipeline.js +258 -0
  786. package/dist/workspace/member-run.js +117 -0
  787. package/dist/workspace/member-write.schema.json +193 -0
  788. package/dist/workspace/nested-graph.js +156 -0
  789. package/dist/workspace/nesting.js +38 -0
  790. package/dist/workspace/patch.js +301 -0
  791. package/dist/workspace/patch.schema.json +321 -0
  792. package/dist/workspace/pin-cli.js +55 -0
  793. package/dist/workspace/pin-integrity.js +100 -0
  794. package/dist/workspace/plan-summary.schema.json +155 -0
  795. package/dist/workspace/point-answer.schema.json +129 -129
  796. package/dist/workspace/points-cli.js +291 -0
  797. package/dist/workspace/points-write.schema.json +660 -0
  798. package/dist/workspace/points.js +521 -0
  799. package/dist/workspace/points.schema.json +916 -0
  800. package/dist/workspace/pr-report.schema.json +108 -0
  801. package/dist/workspace/principal-classes.js +245 -0
  802. package/dist/workspace/reason-codes.js +326 -0
  803. package/dist/workspace/record-assets.js +151 -0
  804. package/dist/workspace/record-decided.js +105 -0
  805. package/dist/workspace/record-sessions.js +96 -0
  806. package/dist/workspace/record-source.js +114 -0
  807. package/dist/workspace/records-amend.schema.json +284 -0
  808. package/dist/workspace/records-checkout.js +76 -0
  809. package/dist/workspace/records-cli.js +707 -0
  810. package/dist/workspace/records-close.js +116 -0
  811. package/dist/workspace/records-close.schema.json +278 -0
  812. package/dist/workspace/records-new.schema.json +202 -0
  813. package/dist/workspace/records-review.schema.json +367 -0
  814. package/dist/workspace/records-since.js +317 -0
  815. package/dist/workspace/records-since.schema.json +218 -0
  816. package/dist/workspace/records-write.js +1229 -0
  817. package/dist/workspace/records.js +1345 -0
  818. package/dist/workspace/records.schema.json +604 -0
  819. package/dist/workspace/reference-kinds/app/package.json +10 -0
  820. package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  821. package/dist/workspace/returns.js +303 -0
  822. package/dist/workspace/root-refusal.js +75 -0
  823. package/dist/workspace/run-statement.schema.json +622 -0
  824. package/dist/workspace/runs-cli.js +584 -0
  825. package/dist/workspace/runs-write.schema.json +994 -0
  826. package/dist/workspace/runs.js +708 -0
  827. package/dist/workspace/runs.schema.json +1257 -0
  828. package/dist/workspace/runtimes.js +76 -0
  829. package/dist/workspace/session-kinds.js +83 -0
  830. package/dist/workspace/signers.schema.json +206 -0
  831. package/dist/workspace/source-block.js +125 -0
  832. package/dist/workspace/squash.js +177 -0
  833. package/dist/workspace/status-gates.js +162 -0
  834. package/dist/workspace/status-stewards.js +330 -0
  835. package/dist/workspace/status.js +514 -0
  836. package/dist/workspace/status.schema.json +998 -0
  837. package/dist/workspace/steward-index.js +191 -0
  838. package/dist/workspace/symbols.js +188 -0
  839. package/dist/workspace/template-manifest.js +227 -0
  840. package/dist/workspace/template-pins.js +115 -0
  841. package/dist/workspace/trailer-joins.js +65 -0
  842. package/dist/workspace/trailers.js +111 -0
  843. package/dist/workspace/tree.js +136 -0
  844. package/dist/workspace/trust/attestor.js +63 -0
  845. package/dist/workspace/trust/dsse.js +108 -0
  846. package/dist/workspace/trust/evidence-cli.js +175 -0
  847. package/dist/workspace/trust/evidence.js +161 -0
  848. package/dist/workspace/trust/gate-seal.js +226 -0
  849. package/dist/workspace/trust/policy.js +190 -0
  850. package/dist/workspace/trust/provenance.js +180 -0
  851. package/dist/workspace/trust/rotation.js +298 -0
  852. package/dist/workspace/trust/run-commits.js +101 -0
  853. package/dist/workspace/trust/run-statement.js +182 -0
  854. package/dist/workspace/trust/seal.js +272 -0
  855. package/dist/workspace/trust/signers-cli.js +152 -0
  856. package/dist/workspace/trust/ssh-commit.js +178 -0
  857. package/dist/workspace/trust/test-repo.js +118 -0
  858. package/dist/workspace/trust/trust-files.js +193 -0
  859. package/dist/workspace/trust/verify-cli.js +63 -0
  860. package/dist/workspace/trust/verify.js +192 -0
  861. package/dist/workspace/which-chant.js +141 -0
  862. package/dist/workspace/wip-cli.js +95 -0
  863. package/dist/workspace/wip-write.schema.json +504 -0
  864. package/dist/workspace/wip.js +631 -0
  865. package/dist/workspace/wip.schema.json +334 -0
  866. package/dist/workspace/work-cli.js +448 -0
  867. package/dist/workspace/work-evidence.js +122 -0
  868. package/dist/workspace/work-evidence.schema.json +222 -0
  869. package/dist/workspace/work-history.schema.json +421 -0
  870. package/dist/workspace/work-lease.schema.json +246 -0
  871. package/dist/workspace/work-size.js +77 -0
  872. package/dist/workspace/work.js +283 -0
  873. package/dist/workspace/workspace-kinds.schema.json +259 -259
  874. package/dist/workspace/workspace-principals.schema.json +53 -53
  875. package/dist/workspace/write-lock-cli.js +105 -0
  876. package/dist/workspace/write-lock.js +424 -0
  877. package/dist/workspace/write-lock.schema.json +172 -0
  878. package/dist/workspace/write-scope.js +484 -0
  879. package/dist/yaml.js +459 -0
  880. package/package.json +2 -2
  881. package/src/cli/commands/check-lexicon-plugin.ts +2 -0
  882. package/src/cli/commands/lint.ts +3 -0
  883. package/src/cli/commands/migrate.ts +2 -0
  884. package/src/cli/compiled-cli.e2e.test.ts +165 -0
  885. package/src/cli/main.ts +121 -27
  886. package/src/cli/mcp/workspace-tools.ts +1 -1
  887. package/src/codegen/pinned-upgrade.ts +2 -0
  888. package/src/components/discover.ts +2 -0
  889. package/src/components/sandbox/driver.ts +3 -1
  890. package/src/config-import.ts +3 -0
  891. package/src/discovery/fold-import.ts +23 -14
  892. package/src/discovery/import.ts +2 -0
  893. package/src/discovery/sandbox/driver.ts +3 -1
  894. package/src/lexicon-module.ts +3 -0
  895. package/src/lint/config.ts +1 -1
  896. package/src/lint/discover.ts +28 -8
  897. package/src/lint/policy-import.ts +4 -1
  898. package/src/lint/rule-loader.ts +2 -0
  899. package/src/op/discover.ts +3 -0
  900. package/src/ts-loader.test.ts +23 -0
  901. package/src/ts-loader.ts +122 -0
  902. package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
  903. package/src/workspace/declaration.ts +1 -1
  904. package/src/workspace/kinds.ts +1 -1
  905. package/src/workspace/lineage-migrations.ts +2 -0
  906. package/src/workspace/points.ts +1 -1
  907. package/src/workspace/principal-classes.ts +1 -1
@@ -0,0 +1,393 @@
1
+ /**
2
+ * An Op run under a work item's lease (#2748, the Steward's gap 4 in #2731).
3
+ *
4
+ * An Op that declares `workLease` (`./types.ts`) runs its steps under the work
5
+ * lease of one work item (`../lifecycle/work-lease.ts`, ws-055). The local
6
+ * executor (`./local-executor.ts`) drives the {@link RunWorkLease} here:
7
+ *
8
+ * - Claim. Before the first step when the item is a literal or named by the
9
+ * run (`chant run <op> --work <id>`); right after the producing step when
10
+ * the item is a reference to a step's output. A list of candidates is tried
11
+ * in order and the first one nobody holds is taken. When nothing can be
12
+ * claimed the run ends `ok` with its remaining steps skipped, and the claim's
13
+ * record carries the refusal, which names who holds the item.
14
+ * - Heartbeat. While the steps run, the lease is renewed every third of its
15
+ * time to live, keeping its fencing token. A renewal the lease refuses (it
16
+ * ran out and someone else claimed it, or it was released) means the lease
17
+ * is lost: the in-flight step's abort signal fires, no further step starts,
18
+ * and the run fails with `lease-lost`. A renewal that fails for any other
19
+ * reason (the remote didn't answer) is retried at the next beat; if that
20
+ * goes on past the expiry, the next renewal is refused and the lease is lost
21
+ * then. These are the semantics of chud's dispatcher
22
+ * (packages/runtime/src/dispatch.mjs), which this replaces.
23
+ * - Fence. Before the run's record is written, one last renewal checks that
24
+ * the lease is still this run's, with the same token. Refused, the run is
25
+ * recorded as failed with `lease-lost`, never as done.
26
+ * - Release. When the run ends, the lease is given back with the run's
27
+ * outcome (`done`, `not_done`, `gated`, `waiting`, or the Op's own
28
+ * `outcome`), which lands on `_leases/<id>.jsonl`. Outcomes are a closed
29
+ * list (`WORK_LEASE_OUTCOMES`, #3147): an Op's own outcome outside it is
30
+ * released `not_done`, with a note naming it. A lost lease is not
31
+ * released: it isn't this run's to give back.
32
+ *
33
+ * Steps read the lease through {@link workLeaseOutput}: its item, holder,
34
+ * token and expiry, and for an Op that changes the checkout, the worktree and
35
+ * branch it works in. An activity that writes somewhere a token can fence
36
+ * (another ledger, a remote) passes the token along.
37
+ *
38
+ * ## Changing the checkout
39
+ *
40
+ * An Op with `changesCheckout` (applying a build, `chant workspace upgrade`)
41
+ * must declare `workLease`, and its leased steps get a git worktree of their
42
+ * own: `chant/work/<item>` checked out under the repository's git directory,
43
+ * from the checkout's HEAD, or from the branch as an earlier run left it. The
44
+ * worktree is removed when the run ends and the branch keeps whatever the
45
+ * steps committed, for the runner to deliver. The checkout a coding agent is
46
+ * editing, its index and its uncommitted files, are never touched.
47
+ *
48
+ * A run that ends `not_done` keeps its attempt aside (#3147): whatever the
49
+ * steps committed on the branch since the run started, and anything they
50
+ * left uncommitted in the worktree, is committed to
51
+ * `refs/chant/kept/[<member>/]<item>/<token>`, and the branch goes back to
52
+ * where the run started. The next attempt starts clean, and the earlier one
53
+ * stays readable by its lease token (`chant workspace work history`).
54
+ */
55
+ import { existsSync, rmSync } from "node:fs";
56
+ import { isAbsolute, join, resolve } from "node:path";
57
+ import { getRuntime } from "../runtime-adapter.js";
58
+ import { claimWorkLease, DEFAULT_WORK_LEASE_TTL_MS, isWorkLeaseOutcome, keptAttemptRef, releaseWorkLease, renewWorkLease, workLeaseRef, isWorkItemId, workItemIdProblem, } from "../lifecycle/work-lease.js";
59
+ import { resolveMemberLedger } from "../lifecycle/member-ledger.js";
60
+ import { currentHolderId } from "../lifecycle/lease.js";
61
+ import { parseDuration } from "./duration.js";
62
+ import { isStepOutputRef, stepOutput } from "./step-output-ref.js";
63
+ import { WORK_LEASE_STEP_ID } from "./types.js";
64
+ export { WORK_LEASE_STEP_ID } from "./types.js";
65
+ export { workLeaseProblems, workLeaseNeedsRunItem } from "./work-lease-decl.js";
66
+ /** Why a run under a work lease failed when the lease was lost: chud's reason, kept. */
67
+ export const LEASE_LOST = "lease-lost";
68
+ /** The branch prefix an Op that changes the checkout works on. */
69
+ export const WORK_BRANCH_PREFIX = "chant/work/";
70
+ /**
71
+ * A reference to the run's work lease, for a step's args:
72
+ * `workLeaseOutput("token")`, `workLeaseOutput("worktree")`, or the whole
73
+ * {@link WorkLeaseOutput} with no path.
74
+ */
75
+ export function workLeaseOutput(path) {
76
+ return stepOutput(WORK_LEASE_STEP_ID, path);
77
+ }
78
+ /**
79
+ * The holder a steward's turn claims work leases as:
80
+ * `<steward>/<op>@<process>`. `chant workspace status --json` reads it back
81
+ * to show the lease a steward's current turn holds beside its Ops.
82
+ */
83
+ export function stewardWorkHolder(steward, op, process = currentHolderId()) {
84
+ return `${steward}/${op}@${process}`;
85
+ }
86
+ function resolvePath(value, path) {
87
+ if (!path)
88
+ return value;
89
+ return path.split(".").reduce((acc, key) => (acc == null ? acc : acc[key]), value);
90
+ }
91
+ async function git(args, cwd) {
92
+ const out = await getRuntime().spawn(["git", ...args], { cwd });
93
+ return { ok: out.exitCode === 0, stdout: out.stdout.trim(), stderr: out.stderr.trim() };
94
+ }
95
+ /** One run's hold on one work item's lease. Created by the executor for an Op with `workLease`. */
96
+ export class RunWorkLease {
97
+ constructor(config, opts) {
98
+ this.config = config;
99
+ this.opts = opts;
100
+ /** Set once the claim was made or given up on. */
101
+ this.attempted = false;
102
+ this.abort = new AbortController();
103
+ if (!config.workLease)
104
+ throw new Error(`Op "${config.name}" declares no workLease`);
105
+ this.spec = config.workLease;
106
+ this.holder = opts.holder ?? currentHolderId();
107
+ this.ttlMs = this.spec.ttl ? parseDuration(this.spec.ttl) : DEFAULT_WORK_LEASE_TTL_MS;
108
+ this.lostSignal = this.abort.signal;
109
+ }
110
+ /** The directory whose ledger holds the lease: the kind file's, or the project's. */
111
+ get ledgerCwd() {
112
+ const kind = this.spec.kind;
113
+ if (!kind)
114
+ return this.opts.cwd;
115
+ const file = isAbsolute(kind) ? kind : resolve(this.opts.cwd, kind);
116
+ return resolve(file, "..");
117
+ }
118
+ /** Whether the claim is due at a step boundary, given the results so far. */
119
+ due(resultsById) {
120
+ if (this.attempted)
121
+ return false;
122
+ if (this.opts.item !== undefined)
123
+ return true;
124
+ const item = this.spec.item;
125
+ return !isStepOutputRef(item) || resultsById.has(item.step);
126
+ }
127
+ /** The candidate ids, in order. Empty when the reference resolved to nothing. */
128
+ candidates(resultsById) {
129
+ if (this.opts.item !== undefined)
130
+ return [this.opts.item];
131
+ const item = this.spec.item;
132
+ const value = isStepOutputRef(item) ? resolvePath(resultsById.get(item.step), item.path) : item;
133
+ if (value === undefined || value === null || value === "")
134
+ return [];
135
+ const list = Array.isArray(value) ? value : [value];
136
+ return list.filter((v) => v !== undefined && v !== null && v !== "").map((v) => {
137
+ if (!isWorkItemId(v)) {
138
+ throw new Error(`Op "${this.config.name}": workLease.item resolved to ${JSON.stringify(v)}, which can't key a work lease${typeof v === "string" ? ` (${workItemIdProblem(v)})` : ""}`);
139
+ }
140
+ return v;
141
+ });
142
+ }
143
+ /**
144
+ * Claim the first candidate nobody holds. On a claim, the heartbeat starts,
145
+ * and for an Op that changes the checkout its worktree is made. Throws when
146
+ * the claim could not be made for a reason other than someone holding it
147
+ * (git failed): the run fails, as for any failing step.
148
+ */
149
+ async claim(resultsById) {
150
+ this.attempted = true;
151
+ const tried = this.candidates(resultsById);
152
+ if (tried.length === 0) {
153
+ this.refusal = "nothing to claim: the work item resolved to no id";
154
+ return { kind: "unclaimed", refusal: this.refusal, tried };
155
+ }
156
+ const refused = [];
157
+ for (const id of tried) {
158
+ const result = await claimWorkLease(id, this.holder, { cwd: this.ledgerCwd, ttlMs: this.ttlMs, note: `op ${this.config.name}` });
159
+ if (!result.ok) {
160
+ refused.push(`${result.reason}: ${result.message}`);
161
+ continue;
162
+ }
163
+ const { prefix, members } = await resolveMemberLedger(this.ledgerCwd);
164
+ const lease = {
165
+ ...pick(result.lease),
166
+ ref: workLeaseRef(id, prefix),
167
+ worktree: null,
168
+ branch: null,
169
+ };
170
+ this.lease = lease;
171
+ if (this.config.changesCheckout) {
172
+ try {
173
+ const made = await this.makeWorktree(id, members);
174
+ lease.worktree = made.worktree;
175
+ lease.branch = made.branch;
176
+ }
177
+ catch (err) {
178
+ await releaseWorkLease(id, this.holder, { cwd: this.ledgerCwd, token: lease.token, outcome: "not_done", note: "the worktree could not be made" }).catch(() => undefined);
179
+ this.lease = undefined;
180
+ throw err;
181
+ }
182
+ }
183
+ this.startHeartbeat();
184
+ return { kind: "claimed", lease, tried };
185
+ }
186
+ this.refusal = refused.join("; ");
187
+ return { kind: "unclaimed", refusal: this.refusal, tried };
188
+ }
189
+ /**
190
+ * A worktree for `id` on `chant/work/[<member>/]<id>`, under the git
191
+ * directory so the checkout's own `git status` never lists it. Starts from
192
+ * the branch when an earlier run left it, from HEAD otherwise.
193
+ */
194
+ async makeWorktree(id, members) {
195
+ const cwd = this.opts.cwd;
196
+ const common = await git(["rev-parse", "--git-common-dir"], cwd);
197
+ if (!common.ok)
198
+ throw new Error(`Op "${this.config.name}" changes the checkout, but ${cwd} is not a git checkout: ${common.stderr}`);
199
+ const commonDir = isAbsolute(common.stdout) ? common.stdout : resolve(cwd, common.stdout);
200
+ const scope = members.join("/");
201
+ const branch = `${WORK_BRANCH_PREFIX}${scope ? `${scope}/` : ""}${id}`;
202
+ const worktree = join(commonDir, "chant-work", ...members, id);
203
+ if (existsSync(worktree)) {
204
+ await git(["worktree", "remove", "--force", worktree], cwd);
205
+ rmSync(worktree, { recursive: true, force: true });
206
+ }
207
+ await git(["worktree", "prune"], cwd);
208
+ const exists = (await git(["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`], cwd)).ok;
209
+ const add = exists
210
+ ? await git(["worktree", "add", "--quiet", worktree, branch], cwd)
211
+ : await git(["worktree", "add", "--quiet", "-b", branch, worktree, "HEAD"], cwd);
212
+ if (!add.ok)
213
+ throw new Error(`Op "${this.config.name}": could not make the worktree for ${id} on ${branch}: ${add.stderr}`);
214
+ const base = await git(["rev-parse", "HEAD"], worktree);
215
+ if (base.ok)
216
+ this.start = { base: base.stdout, members };
217
+ return { worktree, branch };
218
+ }
219
+ lose(why) {
220
+ if (this.lost !== undefined)
221
+ return;
222
+ this.lost = why;
223
+ this.stopHeartbeat();
224
+ this.abort.abort(new Error(`${LEASE_LOST}: ${why}`));
225
+ }
226
+ /** One renewal. Refused, the lease is lost; failed otherwise, the next beat retries. */
227
+ async renew() {
228
+ const lease = this.lease;
229
+ if (!lease || this.lost !== undefined)
230
+ return;
231
+ try {
232
+ const result = await renewWorkLease(lease.item, this.holder, { cwd: this.ledgerCwd, ttlMs: this.ttlMs, token: lease.token });
233
+ if (result.ok) {
234
+ lease.expiresAt = result.lease.expiresAt;
235
+ return;
236
+ }
237
+ // The remote refusing the push is the lease held elsewhere only when it
238
+ // says who holds it; unreachable, the next beat tries again.
239
+ if (result.reason === "lease-push-rejected" && !result.heldBy) {
240
+ this.opts.onRenewError?.(result.message);
241
+ return;
242
+ }
243
+ if (result.reason === "lease-race") {
244
+ this.opts.onRenewError?.(result.message);
245
+ return;
246
+ }
247
+ this.lose(result.message);
248
+ }
249
+ catch (err) {
250
+ this.opts.onRenewError?.(err instanceof Error ? err.message : String(err));
251
+ }
252
+ }
253
+ startHeartbeat() {
254
+ const every = Math.max(1000, Math.floor(this.ttlMs / 3));
255
+ this.timer = setInterval(() => {
256
+ if (this.beat)
257
+ return;
258
+ this.beat = this.renew().finally(() => {
259
+ this.beat = undefined;
260
+ });
261
+ }, every);
262
+ this.timer.unref?.();
263
+ }
264
+ stopHeartbeat() {
265
+ if (this.timer)
266
+ clearInterval(this.timer);
267
+ this.timer = undefined;
268
+ }
269
+ /**
270
+ * The last renewal before the run's record is written, after the heartbeat
271
+ * stops. Returns whether the lease is still this run's.
272
+ */
273
+ async fence() {
274
+ if (!this.lease)
275
+ return this.lost === undefined;
276
+ this.stopHeartbeat();
277
+ await this.beat;
278
+ if (this.lost !== undefined)
279
+ return false;
280
+ const lease = this.lease;
281
+ try {
282
+ const result = await renewWorkLease(lease.item, this.holder, { cwd: this.ledgerCwd, ttlMs: this.ttlMs, token: lease.token });
283
+ if (result.ok)
284
+ lease.expiresAt = result.lease.expiresAt;
285
+ else
286
+ this.lose(result.message);
287
+ }
288
+ catch (err) {
289
+ this.lose(`the lease could not be renewed before the run was recorded: ${err instanceof Error ? err.message : String(err)}`);
290
+ }
291
+ return this.lost === undefined;
292
+ }
293
+ /**
294
+ * End the run's hold: stop the heartbeat, remove the worktree (the branch
295
+ * keeps what was committed), and give the lease back with the outcome
296
+ * unless it was lost.
297
+ */
298
+ async finish(status, resultsById) {
299
+ this.stopHeartbeat();
300
+ await this.beat;
301
+ const lease = this.lease;
302
+ const base = {
303
+ item: lease?.item ?? null,
304
+ holder: this.holder,
305
+ token: lease?.token ?? null,
306
+ branch: lease?.branch ?? null,
307
+ released: false,
308
+ outcome: null,
309
+ kept: null,
310
+ lost: this.lost ?? null,
311
+ refusal: this.refusal ?? null,
312
+ };
313
+ if (!lease)
314
+ return base;
315
+ let outcome = status === "ok" ? "done" : status === "gated" || status === "waiting" ? status : "not_done";
316
+ let note = `op ${this.config.name}`;
317
+ if (status === "ok" && this.spec.outcome && isStepOutputRef(this.spec.outcome)) {
318
+ const declared = resolvePath(resultsById.get(this.spec.outcome.step), this.spec.outcome.path);
319
+ if (typeof declared === "string" && declared.trim() !== "") {
320
+ const word = declared.trim();
321
+ if (isWorkLeaseOutcome(word))
322
+ outcome = word;
323
+ else {
324
+ outcome = "not_done";
325
+ note = `op ${this.config.name}: its outcome ${JSON.stringify(word.slice(0, 80))} is not a work lease outcome`;
326
+ }
327
+ }
328
+ }
329
+ let kept = null;
330
+ if (lease.worktree && this.lost === undefined && outcome === "not_done") {
331
+ kept = await this.keepAttempt(lease).catch(() => null);
332
+ }
333
+ if (lease.worktree) {
334
+ await git(["worktree", "remove", "--force", lease.worktree], this.opts.cwd).catch(() => undefined);
335
+ rmSync(lease.worktree, { recursive: true, force: true });
336
+ await git(["worktree", "prune"], this.opts.cwd).catch(() => undefined);
337
+ }
338
+ if (this.lost !== undefined)
339
+ return base;
340
+ const released = await releaseWorkLease(lease.item, this.holder, {
341
+ cwd: this.ledgerCwd,
342
+ token: lease.token,
343
+ outcome,
344
+ note,
345
+ }).catch(() => undefined);
346
+ // #3172: the box's replicate policy may push the kept attempt and the work branch now. Best effort.
347
+ // Loaded only here, so an Op run outside a workspace never loads workspace modules (#2526).
348
+ if (released?.ok)
349
+ (await import("../workspace/wip.js")).replicateAfter("release", this.opts.cwd);
350
+ return { ...base, kept, released: released?.ok === true, outcome: released?.ok ? outcome : null };
351
+ }
352
+ /**
353
+ * Keep a `not_done` attempt aside (#3147): commit what the steps left in
354
+ * the worktree, committed or not, at `refs/chant/kept/.../<item>/<token>`,
355
+ * and move the branch back to where the run started. Returns the ref, or
356
+ * null when the attempt changed nothing.
357
+ */
358
+ async keepAttempt(lease) {
359
+ const dir = lease.worktree;
360
+ const start = this.start;
361
+ if (!dir || !start)
362
+ return null;
363
+ const head = await git(["rev-parse", "HEAD"], dir);
364
+ if (!head.ok)
365
+ return null;
366
+ if (!(await git(["add", "-A"], dir)).ok)
367
+ return null;
368
+ const tree = await git(["write-tree"], dir);
369
+ const headTree = await git(["rev-parse", `${head.stdout}^{tree}`], dir);
370
+ if (!tree.ok || !headTree.ok)
371
+ return null;
372
+ let commit = head.stdout;
373
+ if (tree.stdout !== headTree.stdout) {
374
+ // An identity only when git has none, so a configured one is kept.
375
+ const ident = (await git(["var", "GIT_COMMITTER_IDENT"], dir)).ok && (await git(["var", "GIT_AUTHOR_IDENT"], dir)).ok;
376
+ const who = ident ? [] : ["-c", "user.name=chant", "-c", "user.email=chant@localhost"];
377
+ const made = await git([...who, "commit-tree", tree.stdout, "-p", head.stdout, "-m", `${lease.item}: not done, kept (lease ${lease.token})`], dir);
378
+ if (!made.ok)
379
+ return null;
380
+ commit = made.stdout;
381
+ }
382
+ if (commit === start.base)
383
+ return null;
384
+ const ref = keptAttemptRef(lease.item, lease.token, start.members);
385
+ if (!(await git(["update-ref", ref, commit], dir)).ok)
386
+ return null;
387
+ await git(["reset", "-q", "--hard", start.base], dir);
388
+ return ref;
389
+ }
390
+ }
391
+ function pick(lease) {
392
+ return { item: lease.item, holder: lease.holder, token: lease.token, acquiredAt: lease.acquiredAt, expiresAt: lease.expiresAt };
393
+ }
@@ -0,0 +1,284 @@
1
+ /**
2
+ * The override gate (#3760, decision #3756): a person's recorded, reasoned
3
+ * decision to apply one plan a policy denied, spent once a run applies it.
4
+ *
5
+ * The policy engines stay in the products (OPA and conftest in terragucci,
6
+ * config rules in SQL Yodeler). They say a plan is denied and by which rules.
7
+ * This module records and decides the overrides of those denials, so a
8
+ * product keeps a thin layer over it:
9
+ *
10
+ * - A denial is a pending fact on `_gates/policy-override.jsonl` on
11
+ * `chant/lifecycle`, gate the subject (a root, an environment, whatever the
12
+ * product applies one plan to), with the rules that denied it
13
+ * ({@link overridePending}). Its `planDigest` is the override digest
14
+ * ({@link overrideDigest}), which binds the subject, the plan digest and
15
+ * the rule ids, so `chant approve` copies it by default.
16
+ * - An override is an approval of that gate and digest, written with
17
+ * `chant approve policy-override <subject> --rule <id> --reason <text>`
18
+ * (`--sign` under `sealed`). The reason is its `note`.
19
+ * - It counts ({@link decideOverride}) when it is newer than the subject's
20
+ * newest pending fact, names this digest, was written by a person the
21
+ * overriders at base list ({@link overridersAt}), gives a reason, and under
22
+ * `sealed` carries a seal that verifies for its approver against the
23
+ * signers file at base. A line a job wrote (one that carries `via` or a
24
+ * forge `review`) or an agent wrote never counts.
25
+ * - Before a run applies under an override it appends an applied record
26
+ * ({@link appliedOverride}) to `_gates/policy-override/applied.jsonl`. An
27
+ * override with an applied record is spent: it counts for nothing again, so
28
+ * a plan that is denied again waits for its own override, and a spent
29
+ * override of an older plan is not reported as a moved plan.
30
+ *
31
+ * Like `./gate-decision.ts` it reads the lines it is handed and writes
32
+ * nothing; `override-gate-bundle.test.ts` holds its import graph to the
33
+ * same bundle. chant's own writers are in `./lifecycle/override-ledger.ts`.
34
+ */
35
+ import { createHash } from "node:crypto";
36
+ import { spawnSync } from "node:child_process";
37
+ import { OVERRIDE_GATE_OP } from "./op/gate-name.js";
38
+ import { latestPendingGate } from "./lifecycle/gate-ledger-select.js";
39
+ import { samePlanDigest } from "./lifecycle/plan-digest.js";
40
+ import { gateSealRefusal } from "./workspace/trust/gate-seal.js";
41
+ import { DEFAULT_SIGNERS_PATH } from "./workspace/trust/trust-files.js";
42
+ /** The op every override and denial is recorded under. `./lifecycle/gate-audit.ts` reads this op as overrides by default. */
43
+ export const OVERRIDE_OP = OVERRIDE_GATE_OP;
44
+ /** The ledger file on `chant/lifecycle` that holds denials and overrides. */
45
+ export const OVERRIDE_LEDGER = `_gates/${OVERRIDE_OP}.jsonl`;
46
+ /** The file beside it that holds the overrides a run applied under. chant reads only the `.jsonl` files directly under `_gates/` as gate ledgers, so it never reads these lines as gate records. */
47
+ export const OVERRIDE_APPLIED = `_gates/${OVERRIDE_OP}/applied.jsonl`;
48
+ /** Where the overriders are read at base when the caller names no other file: one principal per line, `#` starts a comment. */
49
+ export const OVERRIDERS_PATH = ".chant/overriders";
50
+ // ── the digest ───────────────────────────────────────────────────────────
51
+ /** The rules as an override names them: trimmed, each once, sorted. */
52
+ export function sortedRules(rules) {
53
+ return [...new Set(rules.map((r) => r.trim()).filter(Boolean))].sort();
54
+ }
55
+ /**
56
+ * The digest an override binds: the subject, its plan digest and the rules
57
+ * that denied it, as `sha256:<hex>` over their LF-joined lines after the op
58
+ * name. A plan that moved, or a different set of rules, gives another digest,
59
+ * so an override of one denial never lets another through.
60
+ */
61
+ export function overrideDigest(subject, planDigest, rules) {
62
+ const text = [OVERRIDE_OP, subject, planDigest, ...sortedRules(rules)].join("\n");
63
+ return `sha256:${createHash("sha256").update(text).digest("hex")}`;
64
+ }
65
+ /** The command that overrides a denial. */
66
+ export function overrideCommand(subject, rules, sealed = false) {
67
+ return `chant approve ${OVERRIDE_OP} ${subject} ${sortedRules(rules).map((r) => `--rule ${r}`).join(" ")} --reason "<why>"${sealed ? " --sign" : ""}`;
68
+ }
69
+ /** The pending fact a run records when the policy denies a plan and no override counts for it ({@link decideOverride} returns no `standing` fact). Appending it is the caller's. */
70
+ export function overridePending(input) {
71
+ const rules = sortedRules(input.rules);
72
+ return {
73
+ version: 1,
74
+ kind: "pending",
75
+ op: OVERRIDE_OP,
76
+ gate: input.subject,
77
+ timestamp: input.timestamp,
78
+ expiresAt: input.expiresAt,
79
+ planDigest: overrideDigest(input.subject, input.planDigest, rules),
80
+ plan: input.planDigest,
81
+ rules,
82
+ description: input.description ?? `the policy denied this plan (${rules.join(", ")})`,
83
+ ...(input.runId ? { runId: input.runId } : {}),
84
+ ...(input.url ? { url: input.url } : {}),
85
+ };
86
+ }
87
+ const time = (iso) => new Date(iso).getTime();
88
+ /** The denials on the ledger: each subject's newest pending fact of the override op that names a plan. Sorted by subject. */
89
+ export function recordedDenials(pending) {
90
+ const newest = new Map();
91
+ for (const p of pending) {
92
+ if (p.op !== OVERRIDE_OP || !p.planDigest)
93
+ continue;
94
+ const before = newest.get(p.gate);
95
+ if (!before || time(p.timestamp) >= time(before.timestamp))
96
+ newest.set(p.gate, p);
97
+ }
98
+ return [...newest.values()]
99
+ .map((p) => {
100
+ const r = p;
101
+ return { ...p, plan: typeof r.plan === "string" ? r.plan : "", rules: Array.isArray(r.rules) ? sortedRules(r.rules.filter((x) => typeof x === "string")) : [] };
102
+ })
103
+ .sort((a, b) => (a.gate < b.gate ? -1 : a.gate > b.gate ? 1 : 0));
104
+ }
105
+ /** The principals in an overriders file: one per line, blank lines and `#` comments skipped. */
106
+ export function parseOverriders(text) {
107
+ const out = [];
108
+ for (const raw of text.split("\n")) {
109
+ const line = raw.replace(/#.*$/, "").trim();
110
+ if (line && !out.includes(line))
111
+ out.push(line);
112
+ }
113
+ return out;
114
+ }
115
+ /**
116
+ * The overriders at `base` (a commit the repository holds, such as
117
+ * `baseCommit(repo)` from `@intentius/chant/gate-decision`), from `path`
118
+ * (default {@link OVERRIDERS_PATH}). Read at base, so the change being
119
+ * applied cannot add the person who overrides its own denial. A product that
120
+ * keeps its list in its own config at base reads it there and passes the
121
+ * principals to {@link decideOverride} instead.
122
+ */
123
+ export function overridersAt(repo, base, path = OVERRIDERS_PATH) {
124
+ const r = spawnSync("git", ["cat-file", "blob", `${base}:${path}`], { cwd: repo, encoding: "utf-8" });
125
+ if (r.status !== 0)
126
+ return { base, path, active: false, principals: [] };
127
+ return { base, path, active: true, principals: parseOverriders(r.stdout) };
128
+ }
129
+ /** The applied records in the text of an applied file. Malformed lines, and lines of another kind, are skipped. */
130
+ export function parseAppliedOverrides(text) {
131
+ const out = [];
132
+ for (const line of text.split("\n").map((l) => l.trim()).filter(Boolean)) {
133
+ try {
134
+ const r = JSON.parse(line);
135
+ if (r.version === 1 && r.kind === "applied" && typeof r.op === "string" && typeof r.gate === "string" && typeof r.planDigest === "string" && typeof r.approvedAt === "string") {
136
+ out.push(r);
137
+ }
138
+ }
139
+ catch {
140
+ continue;
141
+ }
142
+ }
143
+ return out;
144
+ }
145
+ const norm = (s) => s.normalize("NFKC").trim().toLowerCase();
146
+ /** Why this ledger line does not count as an override, or null when it does. */
147
+ export function overrideRefusal(rule, r) {
148
+ const line = r;
149
+ if (line.via !== undefined)
150
+ return `the override line was written by a job (via ${String(line.via)}), and an override is a person's`;
151
+ if (r.review !== undefined)
152
+ return `the override line came from the review of #${r.review.pr}, and an override is a person's own line`;
153
+ if (r.approver?.kind === "agent")
154
+ return `the override by ${r.resolvedBy} was recorded by an agent, and an override is a person's`;
155
+ const where = `${rule.overridersPath ?? OVERRIDERS_PATH} at base`;
156
+ if (!rule.overriders.map(norm).includes(norm(r.resolvedBy))) {
157
+ return `${r.resolvedBy} is not listed in ${where}${rule.overriders.length ? ` (${rule.overriders.join(", ")})` : ", which lists nobody"}`;
158
+ }
159
+ if (!r.note?.trim())
160
+ return `the override by ${r.resolvedBy} gives no reason`;
161
+ if (rule.mode === "sealed") {
162
+ const signers = rule.signers ?? { base: null, signersPath: DEFAULT_SIGNERS_PATH, active: false, signers: [], problems: ["no signers were read for this sealed override"] };
163
+ return gateSealRefusal(signers, r);
164
+ }
165
+ return null;
166
+ }
167
+ /**
168
+ * Decide one denied plan against the override ledger, as `decideGateApproval`
169
+ * decides a gate: a line counts only when it is an override of this subject
170
+ * newer than the subject's newest pending fact, names this digest, passes
171
+ * {@link overrideRefusal}, and is not spent (an applied record of its digest
172
+ * made at or after it). The newest counting line wins.
173
+ *
174
+ * Decide before recording a denial: an override written after an expired
175
+ * pending fact still counts, and a run that records a fresh fact first would
176
+ * make it older than the anchor.
177
+ */
178
+ export function decideOverride(input) {
179
+ const rules = sortedRules(input.rules);
180
+ const digest = overrideDigest(input.subject, input.planDigest, rules);
181
+ const pending = input.ledger.pending.filter((p) => p.op === OVERRIDE_OP);
182
+ const latest = latestPendingGate(pending, input.subject);
183
+ const since = latest ? time(latest.timestamp) : 0;
184
+ const applied = (input.applied ?? []).filter((a) => a.op === OVERRIDE_OP && a.gate === input.subject);
185
+ const spentBy = (r) => r.planDigest === undefined ? undefined : applied.find((a) => samePlanDigest(a.planDigest, r.planDigest) && time(a.approvedAt) >= time(r.timestamp));
186
+ const newer = (r, best) => !best || time(r.timestamp) >= time(best.timestamp);
187
+ let matched;
188
+ let mismatched;
189
+ let used;
190
+ const refusals = [];
191
+ for (const r of input.ledger.resolutions) {
192
+ if (r.op !== OVERRIDE_OP || r.gate !== input.subject || time(r.timestamp) < since)
193
+ continue;
194
+ const why = overrideRefusal(input, r);
195
+ const spent = spentBy(r);
196
+ if (samePlanDigest(r.planDigest, digest)) {
197
+ if (why !== null)
198
+ refusals.push(why);
199
+ else if (spent)
200
+ refusals.push(`the override by ${r.resolvedBy} at ${r.timestamp} is spent: a run applied under it at ${spent.timestamp}`);
201
+ else if (newer(r, matched))
202
+ matched = r;
203
+ }
204
+ else if (why !== null) {
205
+ continue;
206
+ }
207
+ else if (spent) {
208
+ if (newer(r, used))
209
+ used = r;
210
+ }
211
+ else if (newer(r, mismatched)) {
212
+ mismatched = r;
213
+ }
214
+ }
215
+ if (matched) {
216
+ return {
217
+ status: "overridden",
218
+ digest,
219
+ override: {
220
+ subject: input.subject,
221
+ by: matched.resolvedBy,
222
+ at: matched.timestamp,
223
+ reason: matched.note.trim(),
224
+ rules,
225
+ planDigest: input.planDigest,
226
+ digest,
227
+ sealed: input.mode === "sealed",
228
+ resolution: matched,
229
+ },
230
+ };
231
+ }
232
+ const now = input.now ?? new Date().toISOString();
233
+ const standing = latest && time(latest.expiresAt) > time(now) && samePlanDigest(latest.planDigest, digest)
234
+ ? recordedDenials([latest])[0]
235
+ : undefined;
236
+ if (mismatched)
237
+ return { status: "moved", digest, by: mismatched.resolvedBy, was: mismatched.planDigest, refusals, ...(standing ? { standing } : {}) };
238
+ return {
239
+ status: "none",
240
+ digest,
241
+ refusals,
242
+ ...(standing ? { standing } : {}),
243
+ ...(used ? { spent: { digest: used.planDigest, by: used.resolvedBy, at: used.timestamp } } : {}),
244
+ };
245
+ }
246
+ /**
247
+ * The applied record a run appends before it applies under `override`, which
248
+ * spends it. Appending it is the caller's. It reads only the subject, the
249
+ * override digest and the override's time and approver, so a product that
250
+ * carries those through its own record can pass them without the ledger line
251
+ * (#3823); a whole {@link StandingOverride} still works.
252
+ */
253
+ export function appliedOverride(override, at) {
254
+ return {
255
+ version: 1,
256
+ kind: "applied",
257
+ op: OVERRIDE_OP,
258
+ gate: override.subject,
259
+ planDigest: override.digest,
260
+ approvedAt: override.at,
261
+ approvedBy: override.by,
262
+ timestamp: at.timestamp,
263
+ ...(at.runId ? { runId: at.runId } : {}),
264
+ ...(at.commit ? { commit: at.commit } : {}),
265
+ };
266
+ }
267
+ /**
268
+ * The applied records as applies for the audit reader
269
+ * (`@intentius/chant/lifecycle/gate-audit`), each citing the override it
270
+ * spent, so the trail shows an `override-spent` entry for it and a gap when
271
+ * the ledger holds no such override. A product that records its applies
272
+ * elsewhere cites the override on its own apply instead.
273
+ */
274
+ export function overrideAuditApplies(applied, path = OVERRIDE_APPLIED) {
275
+ return applied.map((a, i) => ({
276
+ ref: `${path}:${i + 1}`,
277
+ at: a.timestamp,
278
+ gate: a.gate,
279
+ op: a.op,
280
+ approval: "not-required",
281
+ overrides: [{ gate: a.gate, digest: a.planDigest }],
282
+ detail: { approvedBy: a.approvedBy, approvedAt: a.approvedAt, ...(a.runId ? { runId: a.runId } : {}), ...(a.commit ? { commit: a.commit } : {}) },
283
+ }));
284
+ }