@intentius/chant 0.124.13 → 0.124.15

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 (991) 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.d.ts +6 -0
  35. package/dist/build.d.ts.map +1 -1
  36. package/dist/build.js +669 -0
  37. package/dist/builder.js +44 -0
  38. package/dist/cdk/advise.js +30 -0
  39. package/dist/cdk/assembly.js +122 -0
  40. package/dist/cdk/graph.js +444 -0
  41. package/dist/cdk/tier-map.js +64 -0
  42. package/dist/cdk/types.js +24 -0
  43. package/dist/change-set.d.ts +24 -2
  44. package/dist/change-set.d.ts.map +1 -1
  45. package/dist/change-set.js +361 -0
  46. package/dist/child-project.js +21 -0
  47. package/dist/ci-jobs.d.ts +227 -0
  48. package/dist/ci-jobs.d.ts.map +1 -0
  49. package/dist/ci-jobs.js +448 -0
  50. package/dist/claimed-fields.js +135 -0
  51. package/dist/cli/build-options.js +70 -0
  52. package/dist/cli/build-params-cli.js +139 -0
  53. package/dist/cli/command-group.js +123 -0
  54. package/dist/cli/commands/audit-agents.js +326 -0
  55. package/dist/cli/commands/audit.js +571 -0
  56. package/dist/cli/commands/build.js +920 -0
  57. package/dist/cli/commands/carve-apply.js +153 -0
  58. package/dist/cli/commands/carve-bridge.js +201 -0
  59. package/dist/cli/commands/carve-emit.js +332 -0
  60. package/dist/cli/commands/carve-status.js +119 -0
  61. package/dist/cli/commands/carve.js +204 -0
  62. package/dist/cli/commands/check-lexicon-docs.js +79 -0
  63. package/dist/cli/commands/check-lexicon-examples.js +177 -0
  64. package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
  65. package/dist/cli/commands/check-lexicon-mcp.js +82 -0
  66. package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
  67. package/dist/cli/commands/check-lexicon-plugin.js +104 -0
  68. package/dist/cli/commands/check-lexicon.js +766 -0
  69. package/dist/cli/commands/describe.js +85 -0
  70. package/dist/cli/commands/diff.js +175 -0
  71. package/dist/cli/commands/doctor.js +350 -0
  72. package/dist/cli/commands/import-agents.js +155 -0
  73. package/dist/cli/commands/import.js +670 -0
  74. package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
  75. package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
  76. package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
  77. package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
  78. package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
  79. package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
  80. package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
  81. package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
  82. package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
  83. package/dist/cli/commands/init-lexicon.js +172 -0
  84. package/dist/cli/commands/init.js +381 -0
  85. package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
  86. package/dist/cli/commands/lexicon-surface-diff.js +145 -0
  87. package/dist/cli/commands/licenses.js +125 -0
  88. package/dist/cli/commands/lint.d.ts.map +1 -1
  89. package/dist/cli/commands/lint.js +948 -0
  90. package/dist/cli/commands/list.js +63 -0
  91. package/dist/cli/commands/migrate.d.ts.map +1 -1
  92. package/dist/cli/commands/migrate.js +423 -0
  93. package/dist/cli/commands/onboard.js +403 -0
  94. package/dist/cli/commands/pinned-upgrade.js +191 -0
  95. package/dist/cli/commands/update.js +194 -0
  96. package/dist/cli/commands/vendor.js +217 -0
  97. package/dist/cli/conflict-check.js +104 -0
  98. package/dist/cli/debug.js +8 -0
  99. package/dist/cli/format.js +104 -0
  100. package/dist/cli/handlers/build.js +267 -0
  101. package/dist/cli/handlers/carve-apply.js +30 -0
  102. package/dist/cli/handlers/carve-bridge.js +28 -0
  103. package/dist/cli/handlers/carve-emit.js +50 -0
  104. package/dist/cli/handlers/carve-status.js +26 -0
  105. package/dist/cli/handlers/carve.js +40 -0
  106. package/dist/cli/handlers/change-set.js +46 -0
  107. package/dist/cli/handlers/components.js +730 -0
  108. package/dist/cli/handlers/dev.js +113 -0
  109. package/dist/cli/handlers/emulator.js +233 -0
  110. package/dist/cli/handlers/explain.js +54 -0
  111. package/dist/cli/handlers/fan-out.js +422 -0
  112. package/dist/cli/handlers/gate-resume.js +275 -0
  113. package/dist/cli/handlers/generate.js +84 -0
  114. package/dist/cli/handlers/graph.js +969 -0
  115. package/dist/cli/handlers/init.js +102 -0
  116. package/dist/cli/handlers/lifecycle.js +1727 -0
  117. package/dist/cli/handlers/lint.js +62 -0
  118. package/dist/cli/handlers/migrate.js +48 -0
  119. package/dist/cli/handlers/misc.js +391 -0
  120. package/dist/cli/handlers/operator.js +1162 -0
  121. package/dist/cli/handlers/override-approve.js +102 -0
  122. package/dist/cli/handlers/pr.js +503 -0
  123. package/dist/cli/handlers/promote.js +342 -0
  124. package/dist/cli/handlers/run-generate.js +206 -0
  125. package/dist/cli/handlers/run-wave.js +66 -0
  126. package/dist/cli/handlers/run.js +1191 -0
  127. package/dist/cli/handlers/scenario.js +325 -0
  128. package/dist/cli/handlers/search.js +924 -0
  129. package/dist/cli/handlers/serve.js +32 -0
  130. package/dist/cli/handlers/vendor.js +154 -0
  131. package/dist/cli/index.js +3 -0
  132. package/dist/cli/is-entry-point.js +23 -0
  133. package/dist/cli/lsp/capabilities.js +28 -0
  134. package/dist/cli/lsp/diagnostics.js +34 -0
  135. package/dist/cli/lsp/server.js +329 -0
  136. package/dist/cli/main.d.ts.map +1 -1
  137. package/dist/cli/main.js +2540 -0
  138. package/dist/cli/mcp/lifecycle-tools.js +80 -0
  139. package/dist/cli/mcp/op-tools.js +306 -0
  140. package/dist/cli/mcp/resource-handlers.js +258 -0
  141. package/dist/cli/mcp/resources/context.js +85 -0
  142. package/dist/cli/mcp/server.js +353 -0
  143. package/dist/cli/mcp/tools/build.js +111 -0
  144. package/dist/cli/mcp/tools/composites.js +95 -0
  145. package/dist/cli/mcp/tools/explain.js +166 -0
  146. package/dist/cli/mcp/tools/import.js +49 -0
  147. package/dist/cli/mcp/tools/lint.js +41 -0
  148. package/dist/cli/mcp/tools/scaffold.js +111 -0
  149. package/dist/cli/mcp/tools/search.js +112 -0
  150. package/dist/cli/mcp/types.js +1 -0
  151. package/dist/cli/mcp/workspace-plugins.js +91 -0
  152. package/dist/cli/mcp/workspace-tools.d.ts +1 -1
  153. package/dist/cli/mcp/workspace-tools.js +564 -0
  154. package/dist/cli/mcp-config.js +70 -0
  155. package/dist/cli/plugins.js +313 -0
  156. package/dist/cli/registry.js +23 -0
  157. package/dist/cli/reporters/stylish.js +329 -0
  158. package/dist/cli/version.js +15 -0
  159. package/dist/cli/watch.js +79 -0
  160. package/dist/codegen/bound-property-types.js +82 -0
  161. package/dist/codegen/coverage.js +119 -0
  162. package/dist/codegen/docs-file-markers.js +60 -0
  163. package/dist/codegen/docs-pages.js +115 -0
  164. package/dist/codegen/docs-rule-scanning.js +164 -0
  165. package/dist/codegen/docs-rules.js +76 -0
  166. package/dist/codegen/docs-sections.js +117 -0
  167. package/dist/codegen/docs-sidebar.js +65 -0
  168. package/dist/codegen/docs-types.js +4 -0
  169. package/dist/codegen/docs.js +356 -0
  170. package/dist/codegen/fetch.js +340 -0
  171. package/dist/codegen/generate-post-synth-barrel.js +63 -0
  172. package/dist/codegen/generate-registry.js +71 -0
  173. package/dist/codegen/generate-runtime-index.js +56 -0
  174. package/dist/codegen/generate-typescript.js +119 -0
  175. package/dist/codegen/generate.js +115 -0
  176. package/dist/codegen/json-patch.js +141 -0
  177. package/dist/codegen/json-schema-to-ts.js +344 -0
  178. package/dist/codegen/json-schema.js +246 -0
  179. package/dist/codegen/lexicon-regen.js +412 -0
  180. package/dist/codegen/naming.js +217 -0
  181. package/dist/codegen/okf-lexicon.js +245 -0
  182. package/dist/codegen/package.js +150 -0
  183. package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
  184. package/dist/codegen/pinned-upgrade.js +494 -0
  185. package/dist/codegen/registry.js +60 -0
  186. package/dist/codegen/rehype-base-url.mjs +68 -0
  187. package/dist/codegen/rolling-upgrade.js +217 -0
  188. package/dist/codegen/surface-snapshot.js +537 -0
  189. package/dist/codegen/testdata/postgres-tags.json +242 -0
  190. package/dist/codegen/topo-sort.js +36 -0
  191. package/dist/codegen/typecheck.js +115 -0
  192. package/dist/codegen/validate.js +200 -0
  193. package/dist/codegen/version-bump.js +35 -0
  194. package/dist/components/auto-release.js +143 -0
  195. package/dist/components/builders.js +47 -0
  196. package/dist/components/capability-plugin-loader.js +175 -0
  197. package/dist/components/capability-plugin-schema.js +46 -0
  198. package/dist/components/capability-plugin.js +99 -0
  199. package/dist/components/capability.js +60 -0
  200. package/dist/components/changed-files.js +72 -0
  201. package/dist/components/cli-support.js +427 -0
  202. package/dist/components/component.js +120 -0
  203. package/dist/components/component.schema.json +271 -0
  204. package/dist/components/config-defaults.js +130 -0
  205. package/dist/components/deploy-units.js +60 -0
  206. package/dist/components/discover.d.ts.map +1 -1
  207. package/dist/components/discover.js +189 -0
  208. package/dist/components/driver-output.js +86 -0
  209. package/dist/components/driver.js +728 -0
  210. package/dist/components/fan-out-output.js +165 -0
  211. package/dist/components/fan-out-record.js +94 -0
  212. package/dist/components/fan-out-run.js +373 -0
  213. package/dist/components/fan-out-support.js +60 -0
  214. package/dist/components/fan-out.js +273 -0
  215. package/dist/components/gate-plan.js +41 -0
  216. package/dist/components/gated-wave-pipeline.js +46 -0
  217. package/dist/components/index.js +24 -0
  218. package/dist/components/layers.js +28 -0
  219. package/dist/components/manifest-persistence.js +108 -0
  220. package/dist/components/pilots/alb-ecs.pilot.js +59 -0
  221. package/dist/components/pilots/dynamodb.pilot.js +51 -0
  222. package/dist/components/pilots/jar-emr.pilot.js +65 -0
  223. package/dist/components/pilots/lambda.pilot.js +52 -0
  224. package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
  225. package/dist/components/pilots/project.js +12 -0
  226. package/dist/components/pr-pipeline.d.ts.map +1 -1
  227. package/dist/components/pr-pipeline.js +135 -0
  228. package/dist/components/pr-run.js +363 -0
  229. package/dist/components/presets/ecs-fargate.js +72 -0
  230. package/dist/components/presets/index.js +28 -0
  231. package/dist/components/presets/lambda.js +34 -0
  232. package/dist/components/presets/single-host-compose.js +41 -0
  233. package/dist/components/promote.js +549 -0
  234. package/dist/components/registry.js +34 -0
  235. package/dist/components/run-progress.js +33 -0
  236. package/dist/components/sandbox/driver.d.ts.map +1 -1
  237. package/dist/components/sandbox/driver.js +93 -0
  238. package/dist/components/sandbox/run.js +115 -0
  239. package/dist/components/starter-plugin.js +104 -0
  240. package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
  241. package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
  242. package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
  243. package/dist/components/verbs/bom-writer.js +287 -0
  244. package/dist/components/verbs/build-archive.js +188 -0
  245. package/dist/components/verbs/build.js +142 -0
  246. package/dist/components/verbs/cloud-executor.js +110 -0
  247. package/dist/components/verbs/component-bom.js +125 -0
  248. package/dist/components/verbs/ensure-secret.js +50 -0
  249. package/dist/components/verbs/index.js +61 -0
  250. package/dist/components/verbs/license-policy.js +75 -0
  251. package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
  252. package/dist/components/verbs/process-runner.js +78 -0
  253. package/dist/components/verbs/r2-sync.js +93 -0
  254. package/dist/components/verbs/reproducibility.js +62 -0
  255. package/dist/components/verbs/run-agent.js +577 -0
  256. package/dist/components/verbs/sbom-generator.js +119 -0
  257. package/dist/components/verbs/sbom.js +97 -0
  258. package/dist/components/verbs/shell.js +32 -0
  259. package/dist/components/verbs/sign.js +221 -0
  260. package/dist/components/verbs/stub.js +28 -0
  261. package/dist/components/verbs/tool-sbom-generator.js +154 -0
  262. package/dist/components/verbs/verify.js +112 -0
  263. package/dist/components/verbs/vex.js +131 -0
  264. package/dist/components/verbs/vuln-gate.js +152 -0
  265. package/dist/components/verbs/vuln-scan.js +288 -0
  266. package/dist/components/verbs/wait-verify.js +106 -0
  267. package/dist/components/verbs/wrangler.js +179 -0
  268. package/dist/components/wave-plan.js +102 -0
  269. package/dist/composite.d.ts +10 -2
  270. package/dist/composite.d.ts.map +1 -1
  271. package/dist/composite.js +313 -0
  272. package/dist/config-import.d.ts.map +1 -1
  273. package/dist/config-import.js +22 -0
  274. package/dist/config-sandbox.js +122 -0
  275. package/dist/config-static.js +206 -0
  276. package/dist/config.js +605 -0
  277. package/dist/content-digest.js +23 -0
  278. package/dist/declarable.js +114 -0
  279. package/dist/deep-observation.js +437 -0
  280. package/dist/detectLexicon.js +54 -0
  281. package/dist/discovery/cache.js +70 -0
  282. package/dist/discovery/collect.d.ts +2 -1
  283. package/dist/discovery/collect.d.ts.map +1 -1
  284. package/dist/discovery/collect.js +223 -0
  285. package/dist/discovery/cycles.js +95 -0
  286. package/dist/discovery/entity-wire-codec.js +391 -0
  287. package/dist/discovery/entity-wire.js +42 -0
  288. package/dist/discovery/files.js +121 -0
  289. package/dist/discovery/fold-import.d.ts.map +1 -1
  290. package/dist/discovery/fold-import.js +4073 -0
  291. package/dist/discovery/fold-rank.js +292 -0
  292. package/dist/discovery/graph.js +115 -0
  293. package/dist/discovery/host-composite.d.ts +35 -0
  294. package/dist/discovery/host-composite.d.ts.map +1 -0
  295. package/dist/discovery/host-composite.js +93 -0
  296. package/dist/discovery/import.d.ts.map +1 -1
  297. package/dist/discovery/import.js +65 -0
  298. package/dist/discovery/index.d.ts +9 -0
  299. package/dist/discovery/index.d.ts.map +1 -1
  300. package/dist/discovery/index.js +333 -0
  301. package/dist/discovery/param-deps.js +487 -0
  302. package/dist/discovery/resolve.js +39 -0
  303. package/dist/discovery/sandbox/bundle.js +214 -0
  304. package/dist/discovery/sandbox/child-errors.js +26 -0
  305. package/dist/discovery/sandbox/config-run.js +100 -0
  306. package/dist/discovery/sandbox/config-wire.js +183 -0
  307. package/dist/discovery/sandbox/driver.d.ts.map +1 -1
  308. package/dist/discovery/sandbox/driver.js +333 -0
  309. package/dist/discovery/sandbox/fork.js +229 -0
  310. package/dist/discovery/sandbox/policy-run.js +142 -0
  311. package/dist/discovery/sandbox/policy-wire.js +152 -0
  312. package/dist/discovery/sandbox/run.js +77 -0
  313. package/dist/discovery/specifier-resolve.js +320 -0
  314. package/dist/discovery/walk.js +284 -0
  315. package/dist/effect-receipt.js +340 -0
  316. package/dist/env.js +55 -0
  317. package/dist/errors.js +62 -0
  318. package/dist/fold/fold.js +1434 -0
  319. package/dist/fold/foldable-helpers.js +229 -0
  320. package/dist/fold/subset.js +696 -0
  321. package/dist/fold-provenance.js +414 -0
  322. package/dist/gate-decision.d.ts +20 -9
  323. package/dist/gate-decision.d.ts.map +1 -1
  324. package/dist/gate-decision.js +313 -0
  325. package/dist/gate-resume-run.js +154 -0
  326. package/dist/gated-waves.js +165 -0
  327. package/dist/governance.js +43 -0
  328. package/dist/graph-declared.js +45 -0
  329. package/dist/graph-detail.js +207 -0
  330. package/dist/graph-dot.js +54 -0
  331. package/dist/graph-effective.js +107 -0
  332. package/dist/graph-ir.js +623 -0
  333. package/dist/graph-layout.js +184 -0
  334. package/dist/graph-lens.js +105 -0
  335. package/dist/graph-mermaid.js +83 -0
  336. package/dist/graph-ops.js +39 -0
  337. package/dist/graph-refs.js +156 -0
  338. package/dist/held-elsewhere.js +87 -0
  339. package/dist/identity.js +251 -0
  340. package/dist/import/base-parser.js +34 -0
  341. package/dist/import/embedded.js +255 -0
  342. package/dist/import/generator.js +1 -0
  343. package/dist/import/ir-utils.js +85 -0
  344. package/dist/import/parser-options.js +45 -0
  345. package/dist/import/parser.js +1 -0
  346. package/dist/index.js +118 -0
  347. package/dist/intrinsic-interpolation.js +73 -0
  348. package/dist/intrinsic.js +31 -0
  349. package/dist/join-key.js +35 -0
  350. package/dist/kubectl-context.js +150 -0
  351. package/dist/lexicon-config.js +58 -0
  352. package/dist/lexicon-integrity.js +47 -0
  353. package/dist/lexicon-manifest.js +70 -0
  354. package/dist/lexicon-module.d.ts.map +1 -1
  355. package/dist/lexicon-module.js +241 -0
  356. package/dist/lexicon-output.js +218 -0
  357. package/dist/lexicon-plugin-helpers.js +104 -0
  358. package/dist/lexicon-schema.js +136 -0
  359. package/dist/lexicon.js +130 -0
  360. package/dist/lifecycle/affected.js +224 -0
  361. package/dist/lifecycle/assert-live.js +110 -0
  362. package/dist/lifecycle/build-ledger-store.js +160 -0
  363. package/dist/lifecycle/build-ledger.js +155 -0
  364. package/dist/lifecycle/change-set.js +356 -0
  365. package/dist/lifecycle/converge-ledger.js +161 -0
  366. package/dist/lifecycle/deep-diff.js +233 -0
  367. package/dist/lifecycle/deep-observe.js +147 -0
  368. package/dist/lifecycle/digest.js +143 -0
  369. package/dist/lifecycle/disruption.js +135 -0
  370. package/dist/lifecycle/gate-applied.js +113 -0
  371. package/dist/lifecycle/gate-audit.d.ts +69 -2
  372. package/dist/lifecycle/gate-audit.d.ts.map +1 -1
  373. package/dist/lifecycle/gate-audit.js +415 -0
  374. package/dist/lifecycle/gate-ledger-select.js +89 -0
  375. package/dist/lifecycle/gate-ledger.d.ts +24 -0
  376. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  377. package/dist/lifecycle/gate-ledger.js +201 -0
  378. package/dist/lifecycle/gate-origin.js +117 -0
  379. package/dist/lifecycle/gate-pending.js +58 -0
  380. package/dist/lifecycle/git.js +1182 -0
  381. package/dist/lifecycle/identity.js +58 -0
  382. package/dist/lifecycle/index.js +26 -0
  383. package/dist/lifecycle/lease.js +283 -0
  384. package/dist/lifecycle/ledger-port.js +1 -0
  385. package/dist/lifecycle/legacy-digest.js +91 -0
  386. package/dist/lifecycle/live-diff.js +274 -0
  387. package/dist/lifecycle/local-note.js +15 -0
  388. package/dist/lifecycle/member-ledger.js +122 -0
  389. package/dist/lifecycle/observation-baseline.js +155 -0
  390. package/dist/lifecycle/observe.js +375 -0
  391. package/dist/lifecycle/oras-referrer-lookup.js +82 -0
  392. package/dist/lifecycle/override-ledger.js +54 -0
  393. package/dist/lifecycle/plan-digest.js +110 -0
  394. package/dist/lifecycle/plan-ledger.js +129 -0
  395. package/dist/lifecycle/receipt-plan.js +192 -0
  396. package/dist/lifecycle/release-ledger.js +155 -0
  397. package/dist/lifecycle/release-read.js +64 -0
  398. package/dist/lifecycle/replay.js +193 -0
  399. package/dist/lifecycle/rollback.js +102 -0
  400. package/dist/lifecycle/run-ledger.js +183 -0
  401. package/dist/lifecycle/scenario-eval.js +204 -0
  402. package/dist/lifecycle/scenario.js +214 -0
  403. package/dist/lifecycle/snapshot.js +239 -0
  404. package/dist/lifecycle/status.js +447 -0
  405. package/dist/lifecycle/symptoms.js +117 -0
  406. package/dist/lifecycle/teardown.js +255 -0
  407. package/dist/lifecycle/types.js +1 -0
  408. package/dist/lifecycle/unobserved-gate.js +33 -0
  409. package/dist/lifecycle/wave-plans.js +68 -0
  410. package/dist/lifecycle/work-item-id.js +36 -0
  411. package/dist/lifecycle/work-lease.js +393 -0
  412. package/dist/lint/component-checks.js +87 -0
  413. package/dist/lint/config.js +483 -0
  414. package/dist/lint/declarative.js +122 -0
  415. package/dist/lint/discover.d.ts.map +1 -1
  416. package/dist/lint/discover.js +138 -0
  417. package/dist/lint/engine.js +246 -0
  418. package/dist/lint/knowledge-checks.js +64 -0
  419. package/dist/lint/named-checks.js +22 -0
  420. package/dist/lint/output-checks.js +87 -0
  421. package/dist/lint/output-docs.js +163 -0
  422. package/dist/lint/parser.js +33 -0
  423. package/dist/lint/pipeline-change-gate.js +70 -0
  424. package/dist/lint/policy-import.d.ts +1 -1
  425. package/dist/lint/policy-import.d.ts.map +1 -1
  426. package/dist/lint/policy-import.js +62 -0
  427. package/dist/lint/policy-sandbox.js +86 -0
  428. package/dist/lint/policy.js +122 -0
  429. package/dist/lint/post-synth.js +87 -0
  430. package/dist/lint/presets/relaxed.json +26 -0
  431. package/dist/lint/presets/strict.json +24 -24
  432. package/dist/lint/receipt-checks.js +83 -0
  433. package/dist/lint/rule-loader.d.ts.map +1 -1
  434. package/dist/lint/rule-loader.js +89 -0
  435. package/dist/lint/rule-registry.js +86 -0
  436. package/dist/lint/rule.js +1 -0
  437. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
  438. package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
  439. package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
  440. package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
  441. package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
  442. package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
  443. package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
  444. package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
  445. package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
  446. package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
  447. package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
  448. package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
  449. package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
  450. package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
  451. package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
  452. package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
  453. package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
  454. package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
  455. package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
  456. package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
  457. package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
  458. package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
  459. package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
  460. package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
  461. package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
  462. package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
  463. package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
  464. package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
  465. package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
  466. package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
  467. package/dist/lint/rules/comp/index.js +33 -0
  468. package/dist/lint/rules/comp/support.js +129 -0
  469. package/dist/lint/rules/composite-scope.js +51 -0
  470. package/dist/lint/rules/cor017-composite-name-match.js +93 -0
  471. package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
  472. package/dist/lint/rules/cor021-env-literal-name.js +100 -0
  473. package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
  474. package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
  475. package/dist/lint/rules/declarable-naming-convention.js +62 -0
  476. package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
  477. package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
  478. package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
  479. package/dist/lint/rules/evl004-spread-non-const.js +94 -0
  480. package/dist/lint/rules/evl005-resource-block-body.js +41 -0
  481. package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
  482. package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
  483. package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
  484. package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
  485. package/dist/lint/rules/export-required.js +115 -0
  486. package/dist/lint/rules/file-declarable-limit.js +88 -0
  487. package/dist/lint/rules/flat-declarations.js +62 -0
  488. package/dist/lint/rules/index.js +90 -0
  489. package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
  490. package/dist/lint/rules/no-redundant-type-import.js +76 -0
  491. package/dist/lint/rules/no-redundant-value-cast.js +41 -0
  492. package/dist/lint/rules/no-string-ref.js +59 -0
  493. package/dist/lint/rules/no-unused-declarable-import.js +75 -0
  494. package/dist/lint/rules/no-unused-declarable.js +142 -0
  495. package/dist/lint/rules/op/index.js +28 -0
  496. package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
  497. package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
  498. package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
  499. package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
  500. package/dist/lint/rules/op/support.js +11 -0
  501. package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
  502. package/dist/lint/rules/property-kind.js +56 -0
  503. package/dist/lint/rules/single-concern-file.js +71 -0
  504. package/dist/lint/rules/sys001-no-literal-key.js +60 -0
  505. package/dist/lint/selectors.js +168 -0
  506. package/dist/lint/suppressions.js +129 -0
  507. package/dist/lint/typescript.js +17 -0
  508. package/dist/live-endpoint.js +113 -0
  509. package/dist/live-read-session.js +76 -0
  510. package/dist/lsp/lexicon-providers.js +163 -0
  511. package/dist/lsp/types.js +5 -0
  512. package/dist/managed-fields.js +293 -0
  513. package/dist/mcp/types.js +4 -0
  514. package/dist/notify-verify.js +0 -1
  515. package/dist/notify.js +0 -1
  516. package/dist/notify.schema.json +72 -0
  517. package/dist/observation.js +266 -0
  518. package/dist/okf-read.js +134 -0
  519. package/dist/okf.js +275 -0
  520. package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
  521. package/dist/op/activities/activity-contracts.d.ts +1 -1
  522. package/dist/op/activities/activity-contracts.js +313 -0
  523. package/dist/op/activities/apply.js +582 -0
  524. package/dist/op/activities/build.js +18 -0
  525. package/dist/op/activities/change-coverage.js +40 -0
  526. package/dist/op/activities/change-set.d.ts +8 -3
  527. package/dist/op/activities/change-set.d.ts.map +1 -1
  528. package/dist/op/activities/change-set.js +67 -0
  529. package/dist/op/activities/converge.js +492 -0
  530. package/dist/op/activities/decide.js +211 -0
  531. package/dist/op/activities/env-teardown.js +110 -0
  532. package/dist/op/activities/factory.js +591 -0
  533. package/dist/op/activities/forge-pull-request.js +82 -0
  534. package/dist/op/activities/gh-host.js +78 -0
  535. package/dist/op/activities/guard-validate.js +165 -0
  536. package/dist/op/activities/http-check.js +40 -0
  537. package/dist/op/activities/index.js +59 -0
  538. package/dist/op/activities/lexicon-upgrade.js +629 -0
  539. package/dist/op/activities/lifecycle.js +109 -0
  540. package/dist/op/activities/pipeline-audit.js +147 -0
  541. package/dist/op/activities/policy.js +26 -0
  542. package/dist/op/activities/predict-behaviour.js +341 -0
  543. package/dist/op/activities/propose-upgrade.js +165 -0
  544. package/dist/op/activities/reconcile.d.ts +28 -16
  545. package/dist/op/activities/reconcile.d.ts.map +1 -1
  546. package/dist/op/activities/reconcile.js +1011 -0
  547. package/dist/op/activities/shell.js +118 -0
  548. package/dist/op/activities/source-release.js +97 -0
  549. package/dist/op/activities/source-rollback.js +165 -0
  550. package/dist/op/activities/teardown.js +17 -0
  551. package/dist/op/activities/util.js +6 -0
  552. package/dist/op/activities/wait.js +51 -0
  553. package/dist/op/activities/work-evidence.js +35 -0
  554. package/dist/op/activities/workflow-audit.js +133 -0
  555. package/dist/op/activity-contract-registry.js +106 -0
  556. package/dist/op/activity-contract.js +232 -0
  557. package/dist/op/activity-failure.js +31 -0
  558. package/dist/op/activity-profiles.js +129 -0
  559. package/dist/op/activity-registry.js +105 -0
  560. package/dist/op/activity-runtime.js +28 -0
  561. package/dist/op/builders.d.ts +1 -1
  562. package/dist/op/builders.d.ts.map +1 -1
  563. package/dist/op/builders.js +801 -0
  564. package/dist/op/change-signal.js +118 -0
  565. package/dist/op/composites/apply-op.js +151 -0
  566. package/dist/op/composites/behaviour-op.js +65 -0
  567. package/dist/op/composites/converge-op.js +141 -0
  568. package/dist/op/composites/index.js +19 -0
  569. package/dist/op/composites/lexicon-upgrade-op.js +107 -0
  570. package/dist/op/composites/pipeline-audit-op.js +50 -0
  571. package/dist/op/composites/reconcile-op.js +84 -0
  572. package/dist/op/composites/watch-op.js +69 -0
  573. package/dist/op/composites/workflow-audit-op.js +57 -0
  574. package/dist/op/converge-rule.js +205 -0
  575. package/dist/op/cron.js +146 -0
  576. package/dist/op/decide-backend.js +181 -0
  577. package/dist/op/decide-config.js +68 -0
  578. package/dist/op/decide-read-inputs.js +141 -0
  579. package/dist/op/discover.d.ts.map +1 -1
  580. package/dist/op/discover.js +213 -0
  581. package/dist/op/duration.js +21 -0
  582. package/dist/op/emulator-freshness.js +80 -0
  583. package/dist/op/emulator-lifecycle.js +269 -0
  584. package/dist/op/factory.js +83 -0
  585. package/dist/op/gate-approval.js +172 -0
  586. package/dist/op/gate-name.js +86 -0
  587. package/dist/op/gate-plan-context.js +167 -0
  588. package/dist/op/gate-point-run.js +67 -0
  589. package/dist/op/gate-point.js +111 -0
  590. package/dist/op/gate-resume-plan.js +155 -0
  591. package/dist/op/gate-resume.js +31 -0
  592. package/dist/op/gate-review.js +290 -0
  593. package/dist/op/gate-run-locator.js +85 -0
  594. package/dist/op/gate-summary.js +100 -0
  595. package/dist/op/gate-wait.js +56 -0
  596. package/dist/op/gate.js +449 -0
  597. package/dist/op/generate-pipeline.js +124 -0
  598. package/dist/op/index.js +51 -0
  599. package/dist/op/lifecycle-receipt-store.js +45 -0
  600. package/dist/op/local-executor.js +1164 -0
  601. package/dist/op/local-output.js +140 -0
  602. package/dist/op/op-ir.js +317 -0
  603. package/dist/op/op-verb-class.js +131 -0
  604. package/dist/op/op-waves-notify.js +136 -0
  605. package/dist/op/op-waves-run.d.ts +1 -1
  606. package/dist/op/op-waves-run.d.ts.map +1 -1
  607. package/dist/op/op-waves-run.js +1657 -0
  608. package/dist/op/op-waves.js +409 -0
  609. package/dist/op/operator.js +743 -0
  610. package/dist/op/receipt-store.js +94 -0
  611. package/dist/op/resource.js +23 -0
  612. package/dist/op/run-context.js +28 -0
  613. package/dist/op/run-live.js +256 -0
  614. package/dist/op/runtime.js +21 -0
  615. package/dist/op/runtimes/local.js +195 -0
  616. package/dist/op/source-archive.js +131 -0
  617. package/dist/op/step-output-ref.js +397 -0
  618. package/dist/op/steward-beside.js +169 -0
  619. package/dist/op/steward-points.js +138 -0
  620. package/dist/op/steward-turn.js +59 -0
  621. package/dist/op/steward.js +317 -0
  622. package/dist/op/types.js +25 -0
  623. package/dist/op/work-lease-decl.js +81 -0
  624. package/dist/op/work-lease-run.js +393 -0
  625. package/dist/override-gate.js +284 -0
  626. package/dist/owner-chain.js +74 -0
  627. package/dist/ownership.js +92 -0
  628. package/dist/params.js +61 -0
  629. package/dist/plan-summary.js +711 -0
  630. package/dist/point-decision.js +211 -0
  631. package/dist/pr-forge.js +810 -0
  632. package/dist/pr-loop.js +203 -0
  633. package/dist/project-codegen.js +191 -0
  634. package/dist/project-root.js +74 -0
  635. package/dist/project-validation.js +50 -0
  636. package/dist/provenance.js +157 -0
  637. package/dist/pseudo-parameter.js +40 -0
  638. package/dist/reconcile.js +450 -0
  639. package/dist/resource-attributes.js +33 -0
  640. package/dist/runtime-adapter.js +77 -0
  641. package/dist/runtime.js +66 -0
  642. package/dist/secret-materialization.js +153 -0
  643. package/dist/secret-provenance.js +250 -0
  644. package/dist/serializer-walker.js +112 -0
  645. package/dist/serializer.js +1 -0
  646. package/dist/sort.js +45 -0
  647. package/dist/stack-output.js +115 -0
  648. package/dist/telemetry-attribution.js +149 -0
  649. package/dist/terraform/__fixtures__/build-graph.js +63 -0
  650. package/dist/terraform/adopt-state.js +40 -0
  651. package/dist/terraform/aws-resources.js +384 -0
  652. package/dist/terraform/bridge.js +204 -0
  653. package/dist/terraform/carve-provider.js +155 -0
  654. package/dist/terraform/carve.js +138 -0
  655. package/dist/terraform/data-source-shape.js +57 -0
  656. package/dist/terraform/emit-source.js +36 -0
  657. package/dist/terraform/excise.js +123 -0
  658. package/dist/terraform/graduate.js +128 -0
  659. package/dist/terraform/graph.js +435 -0
  660. package/dist/terraform/hcl2json.js +60 -0
  661. package/dist/terraform/manifest.js +149 -0
  662. package/dist/terraform/parse.js +81 -0
  663. package/dist/terraform/providers/aws.js +146 -0
  664. package/dist/terraform/providers/gcp.js +294 -0
  665. package/dist/terraform/providers/index.js +17 -0
  666. package/dist/terraform/providers/kubernetes.js +253 -0
  667. package/dist/terraform/score.js +151 -0
  668. package/dist/terraform/state.js +67 -0
  669. package/dist/terraform/tier-map.js +74 -0
  670. package/dist/terraform/types.js +13 -0
  671. package/dist/terraform/unified-diff.js +132 -0
  672. package/dist/testing.js +295 -0
  673. package/dist/toml-emit.js +153 -0
  674. package/dist/toml-parse.js +355 -0
  675. package/dist/toml-utils.js +60 -0
  676. package/dist/toml.js +428 -0
  677. package/dist/ts-loader.d.ts +46 -0
  678. package/dist/ts-loader.d.ts.map +1 -0
  679. package/dist/ts-loader.js +103 -0
  680. package/dist/types.js +1 -0
  681. package/dist/utils.js +61 -0
  682. package/dist/validation.js +20 -0
  683. package/dist/vendor/js-yaml-load.js +1662 -0
  684. package/dist/workspace/__fixtures__/contract-repo.d.ts +7 -0
  685. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  686. package/dist/workspace/__fixtures__/contract-repo.js +119 -0
  687. package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
  688. package/dist/workspace/__fixtures__/sessions.d.ts +1 -1
  689. package/dist/workspace/__fixtures__/sessions.d.ts.map +1 -1
  690. package/dist/workspace/__fixtures__/sessions.js +91 -0
  691. package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
  692. package/dist/workspace/agent-cli.js +99 -0
  693. package/dist/workspace/agent.schema.json +390 -0
  694. package/dist/workspace/answers-ledger.js +89 -0
  695. package/dist/workspace/box-cli.js +142 -0
  696. package/dist/workspace/box-factory-write.js +196 -0
  697. package/dist/workspace/box-factory-write.schema.json +342 -0
  698. package/dist/workspace/box-factory.js +88 -0
  699. package/dist/workspace/box-intent.js +126 -0
  700. package/dist/workspace/box-isolation.js +169 -0
  701. package/dist/workspace/box-listing-write.schema.json +204 -0
  702. package/dist/workspace/box-listing.js +298 -0
  703. package/dist/workspace/box-publish.js +352 -0
  704. package/dist/workspace/box-publish.schema.json +498 -0
  705. package/dist/workspace/box-services.js +39 -0
  706. package/dist/workspace/broker-protocol.js +359 -0
  707. package/dist/workspace/broker-protocol.schema.json +228 -0
  708. package/dist/workspace/change-set.schema.json +462 -0
  709. package/dist/workspace/changes-cli.js +56 -0
  710. package/dist/workspace/changes.js +446 -0
  711. package/dist/workspace/changes.schema.json +642 -0
  712. package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
  713. package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
  714. package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
  715. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
  716. package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
  717. package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
  718. package/dist/workspace/chant-migrations.js +113 -0
  719. package/dist/workspace/check.schema.json +433 -0
  720. package/dist/workspace/checks/box-isolation.js +62 -0
  721. package/dist/workspace/checks/boxes.js +491 -0
  722. package/dist/workspace/checks/diagrams.js +104 -0
  723. package/dist/workspace/checks/generated.js +419 -0
  724. package/dist/workspace/checks/ledgers.js +212 -0
  725. package/dist/workspace/checks/links.js +191 -0
  726. package/dist/workspace/checks/live.js +100 -0
  727. package/dist/workspace/checks/pipelines.js +188 -0
  728. package/dist/workspace/checks/records.js +169 -0
  729. package/dist/workspace/checks.js +426 -0
  730. package/dist/workspace/ci-green-cli.js +125 -0
  731. package/dist/workspace/ci-green-forge.js +83 -0
  732. package/dist/workspace/ci-green-workflow.d.ts +3 -1
  733. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  734. package/dist/workspace/ci-green-workflow.js +202 -0
  735. package/dist/workspace/ci-green.js +325 -0
  736. package/dist/workspace/ci-last-green.schema.json +158 -0
  737. package/dist/workspace/class-data.d.ts +84 -0
  738. package/dist/workspace/class-data.d.ts.map +1 -0
  739. package/dist/workspace/class-data.js +238 -0
  740. package/dist/workspace/compose-graph.js +235 -0
  741. package/dist/workspace/compose-reports.js +146 -0
  742. package/dist/workspace/composites.js +264 -0
  743. package/dist/workspace/composites.schema.json +617 -0
  744. package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
  745. package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
  746. package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
  747. package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
  748. package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
  749. package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
  750. package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
  751. package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
  752. package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
  753. package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
  754. package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
  755. package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
  756. package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
  757. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
  758. package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
  759. package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
  760. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
  761. package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
  762. package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
  763. package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
  764. package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
  765. package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
  766. package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
  767. package/dist/workspace/conformance/broker.js +736 -0
  768. package/dist/workspace/conformance/index.js +673 -0
  769. package/dist/workspace/conformance/vitest.js +108 -0
  770. package/dist/workspace/conformance/writer.js +1080 -0
  771. package/dist/workspace/decide.js +879 -0
  772. package/dist/workspace/decision-points.schema.json +135 -135
  773. package/dist/workspace/declaration-write-cli.js +74 -0
  774. package/dist/workspace/declaration-write.js +238 -0
  775. package/dist/workspace/declaration.js +938 -0
  776. package/dist/workspace/declaration.schema.json +1413 -1413
  777. package/dist/workspace/declared-kinds.js +106 -0
  778. package/dist/workspace/environments.js +164 -0
  779. package/dist/workspace/evidence.schema.json +279 -0
  780. package/dist/workspace/export-cli.js +185 -0
  781. package/dist/workspace/export.js +499 -0
  782. package/dist/workspace/factory-rules.js +175 -0
  783. package/dist/workspace/generated-files.js +92 -0
  784. package/dist/workspace/glob.js +45 -0
  785. package/dist/workspace/graph-cache.js +352 -0
  786. package/dist/workspace/graph-cli.js +348 -0
  787. package/dist/workspace/graph.schema.json +1338 -0
  788. package/dist/workspace/identity-gate-rule.js +75 -0
  789. package/dist/workspace/identity.js +126 -0
  790. package/dist/workspace/import.js +283 -0
  791. package/dist/workspace/init.js +620 -0
  792. package/dist/workspace/intent-cli.js +263 -0
  793. package/dist/workspace/intent-joins.js +201 -0
  794. package/dist/workspace/intent-record.js +352 -0
  795. package/dist/workspace/intent-record.schema.json +864 -0
  796. package/dist/workspace/intent.js +1582 -0
  797. package/dist/workspace/intent.schema.json +2420 -0
  798. package/dist/workspace/json-edit.js +221 -0
  799. package/dist/workspace/jsonc.js +235 -0
  800. package/dist/workspace/kind-readers.js +103 -0
  801. package/dist/workspace/kinds.d.ts +3 -7
  802. package/dist/workspace/kinds.d.ts.map +1 -1
  803. package/dist/workspace/kinds.js +553 -0
  804. package/dist/workspace/lexicon-symbols.js +112 -0
  805. package/dist/workspace/lineage-adopt-cli.js +102 -0
  806. package/dist/workspace/lineage-adopt.js +360 -0
  807. package/dist/workspace/lineage-check.js +282 -0
  808. package/dist/workspace/lineage-cli.js +121 -0
  809. package/dist/workspace/lineage-hash-index.js +284 -0
  810. package/dist/workspace/lineage-init.js +507 -0
  811. package/dist/workspace/lineage-lock.js +387 -0
  812. package/dist/workspace/lineage-merge.js +45 -0
  813. package/dist/workspace/lineage-migrations.d.ts.map +1 -1
  814. package/dist/workspace/lineage-migrations.js +329 -0
  815. package/dist/workspace/lineage-provenance.js +36 -0
  816. package/dist/workspace/lineage-update.js +138 -0
  817. package/dist/workspace/lineage-upgrade-cli.js +131 -0
  818. package/dist/workspace/lineage-upgrade.js +889 -0
  819. package/dist/workspace/lineage-vendor.js +171 -0
  820. package/dist/workspace/lineage-version.js +128 -0
  821. package/dist/workspace/lineage-versions.js +275 -0
  822. package/dist/workspace/links.js +330 -0
  823. package/dist/workspace/ls-generated.js +95 -0
  824. package/dist/workspace/ls.js +277 -0
  825. package/dist/workspace/ls.schema.json +333 -0
  826. package/dist/workspace/member-commands.js +508 -0
  827. package/dist/workspace/member-handles.js +216 -0
  828. package/dist/workspace/member-pipeline.js +258 -0
  829. package/dist/workspace/member-run.js +117 -0
  830. package/dist/workspace/member-write.schema.json +193 -0
  831. package/dist/workspace/nested-graph.js +156 -0
  832. package/dist/workspace/nesting.js +38 -0
  833. package/dist/workspace/patch.js +301 -0
  834. package/dist/workspace/patch.schema.json +321 -0
  835. package/dist/workspace/pin-cli.js +55 -0
  836. package/dist/workspace/pin-integrity.js +100 -0
  837. package/dist/workspace/plan-summary.schema.json +155 -0
  838. package/dist/workspace/point-answer.schema.json +129 -129
  839. package/dist/workspace/points-cli.js +291 -0
  840. package/dist/workspace/points-write.schema.json +660 -0
  841. package/dist/workspace/points.js +521 -0
  842. package/dist/workspace/points.schema.json +916 -0
  843. package/dist/workspace/pr-report.schema.json +108 -0
  844. package/dist/workspace/principal-classes.d.ts +4 -11
  845. package/dist/workspace/principal-classes.d.ts.map +1 -1
  846. package/dist/workspace/principal-classes.js +162 -0
  847. package/dist/workspace/reason-codes.js +326 -0
  848. package/dist/workspace/record-assets.js +151 -0
  849. package/dist/workspace/record-decided.js +105 -0
  850. package/dist/workspace/record-sessions.js +96 -0
  851. package/dist/workspace/record-source.js +114 -0
  852. package/dist/workspace/records-amend.schema.json +284 -0
  853. package/dist/workspace/records-checkout.js +76 -0
  854. package/dist/workspace/records-cli.js +707 -0
  855. package/dist/workspace/records-close.js +116 -0
  856. package/dist/workspace/records-close.schema.json +278 -0
  857. package/dist/workspace/records-new.schema.json +202 -0
  858. package/dist/workspace/records-review.schema.json +367 -0
  859. package/dist/workspace/records-since.js +317 -0
  860. package/dist/workspace/records-since.schema.json +218 -0
  861. package/dist/workspace/records-write.js +1229 -0
  862. package/dist/workspace/records.js +1345 -0
  863. package/dist/workspace/records.schema.json +604 -0
  864. package/dist/workspace/reference-kinds/app/package.json +10 -0
  865. package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
  866. package/dist/workspace/returns.js +303 -0
  867. package/dist/workspace/root-refusal.js +75 -0
  868. package/dist/workspace/run-statement.schema.json +622 -0
  869. package/dist/workspace/runs-cli.js +584 -0
  870. package/dist/workspace/runs-write.schema.json +994 -0
  871. package/dist/workspace/runs.js +708 -0
  872. package/dist/workspace/runs.schema.json +1257 -0
  873. package/dist/workspace/runtimes.js +76 -0
  874. package/dist/workspace/session-kinds.js +83 -0
  875. package/dist/workspace/signers.schema.json +206 -0
  876. package/dist/workspace/source-block.js +125 -0
  877. package/dist/workspace/squash.js +177 -0
  878. package/dist/workspace/status-gates.js +162 -0
  879. package/dist/workspace/status-stewards.js +330 -0
  880. package/dist/workspace/status.js +514 -0
  881. package/dist/workspace/status.schema.json +998 -0
  882. package/dist/workspace/steward-index.js +191 -0
  883. package/dist/workspace/symbols.js +188 -0
  884. package/dist/workspace/template-manifest.js +227 -0
  885. package/dist/workspace/template-pins.js +115 -0
  886. package/dist/workspace/trailer-joins.js +65 -0
  887. package/dist/workspace/trailers.js +111 -0
  888. package/dist/workspace/tree.js +136 -0
  889. package/dist/workspace/trust/attestor.js +63 -0
  890. package/dist/workspace/trust/dsse.js +108 -0
  891. package/dist/workspace/trust/evidence-cli.js +175 -0
  892. package/dist/workspace/trust/evidence.js +161 -0
  893. package/dist/workspace/trust/gate-seal.js +226 -0
  894. package/dist/workspace/trust/policy.js +190 -0
  895. package/dist/workspace/trust/provenance.js +180 -0
  896. package/dist/workspace/trust/rotation.js +298 -0
  897. package/dist/workspace/trust/run-commits.js +101 -0
  898. package/dist/workspace/trust/run-statement.js +182 -0
  899. package/dist/workspace/trust/seal.js +272 -0
  900. package/dist/workspace/trust/signers-cli.js +152 -0
  901. package/dist/workspace/trust/ssh-commit.js +178 -0
  902. package/dist/workspace/trust/test-repo.js +118 -0
  903. package/dist/workspace/trust/trust-files.js +193 -0
  904. package/dist/workspace/trust/verify-cli.js +63 -0
  905. package/dist/workspace/trust/verify.js +192 -0
  906. package/dist/workspace/which-chant.js +141 -0
  907. package/dist/workspace/wip-cli.js +95 -0
  908. package/dist/workspace/wip-write.schema.json +504 -0
  909. package/dist/workspace/wip.js +631 -0
  910. package/dist/workspace/wip.schema.json +334 -0
  911. package/dist/workspace/work-cli.js +448 -0
  912. package/dist/workspace/work-evidence.js +122 -0
  913. package/dist/workspace/work-evidence.schema.json +222 -0
  914. package/dist/workspace/work-history.schema.json +421 -0
  915. package/dist/workspace/work-lease.schema.json +246 -0
  916. package/dist/workspace/work-size.js +77 -0
  917. package/dist/workspace/work.js +283 -0
  918. package/dist/workspace/workspace-kinds.schema.json +259 -259
  919. package/dist/workspace/workspace-principals.schema.json +53 -53
  920. package/dist/workspace/write-lock-cli.js +105 -0
  921. package/dist/workspace/write-lock.js +424 -0
  922. package/dist/workspace/write-lock.schema.json +172 -0
  923. package/dist/workspace/write-scope.js +484 -0
  924. package/dist/yaml.js +459 -0
  925. package/package.json +2 -2
  926. package/src/build.ts +8 -0
  927. package/src/change-set.test.ts +48 -0
  928. package/src/change-set.ts +52 -2
  929. package/src/ci-jobs.test.ts +49 -0
  930. package/src/ci-jobs.ts +515 -0
  931. package/src/cli/commands/check-lexicon-plugin.ts +2 -0
  932. package/src/cli/commands/lint.ts +3 -0
  933. package/src/cli/commands/migrate.ts +2 -0
  934. package/src/cli/compiled-cli.e2e.test.ts +165 -0
  935. package/src/cli/main.ts +121 -27
  936. package/src/cli/mcp/workspace-tools.ts +1 -1
  937. package/src/codegen/pinned-upgrade.ts +2 -0
  938. package/src/components/discover.ts +2 -0
  939. package/src/components/pr-pipeline.ts +3 -2
  940. package/src/components/sandbox/driver.ts +3 -1
  941. package/src/composite.ts +15 -3
  942. package/src/config-import.ts +3 -0
  943. package/src/discovery/collect.ts +15 -1
  944. package/src/discovery/fold-build-parity.test.ts +71 -0
  945. package/src/discovery/fold-import.ts +25 -127
  946. package/src/discovery/fold-project-provenance.test.ts +21 -4
  947. package/src/discovery/host-composite.ts +101 -0
  948. package/src/discovery/import.ts +2 -0
  949. package/src/discovery/index.ts +11 -1
  950. package/src/discovery/sandbox/driver.ts +3 -1
  951. package/src/gate-decision-bundle.test.ts +5 -4
  952. package/src/gate-decision-identity.test.ts +59 -6
  953. package/src/gate-decision.ts +81 -21
  954. package/src/lexicon-module.ts +3 -0
  955. package/src/lifecycle/gate-audit.test.ts +55 -1
  956. package/src/lifecycle/gate-audit.ts +116 -3
  957. package/src/lifecycle/gate-ledger.test.ts +20 -1
  958. package/src/lifecycle/gate-ledger.ts +33 -1
  959. package/src/lint/config.ts +1 -1
  960. package/src/lint/discover.ts +28 -8
  961. package/src/lint/policy-import.ts +4 -1
  962. package/src/lint/rule-loader.ts +2 -0
  963. package/src/op/activities/activity-contracts.ts +1 -1
  964. package/src/op/activities/change-set.ts +11 -3
  965. package/src/op/activities/lexicon-upgrade.test.ts +2 -0
  966. package/src/op/activities/reconcile.test.ts +62 -2
  967. package/src/op/activities/reconcile.ts +46 -22
  968. package/src/op/builders.ts +1 -1
  969. package/src/op/discover.ts +3 -0
  970. package/src/op/op-waves-run.ts +4 -3
  971. package/src/op/op-waves.test.ts +2 -0
  972. package/src/op/work-lease-run.test.ts +12 -4
  973. package/src/ts-loader.test.ts +23 -0
  974. package/src/ts-loader.ts +122 -0
  975. package/src/workspace/__fixtures__/contract-repo.ts +17 -1
  976. package/src/workspace/__fixtures__/sessions.ts +3 -3
  977. package/src/workspace/change-set.schema.json +5 -3
  978. package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
  979. package/src/workspace/ci-green-workflow.test.ts +4 -4
  980. package/src/workspace/ci-green-workflow.ts +5 -2
  981. package/src/workspace/class-data.test.ts +64 -0
  982. package/src/workspace/class-data.ts +236 -0
  983. package/src/workspace/declaration.ts +1 -1
  984. package/src/workspace/kinds.ts +7 -36
  985. package/src/workspace/lineage-migrations.ts +2 -0
  986. package/src/workspace/points.ts +1 -1
  987. package/src/workspace/principal-classes.ts +12 -95
  988. package/src/workspace/records-formats.test.ts +7 -2
  989. package/src/workspace/records-sessions-write.test.ts +3 -3
  990. package/src/workspace/status-contract.e2e.test.ts +37 -0
  991. package/src/workspace/status-contract.test.ts +23 -21
@@ -0,0 +1,743 @@
1
+ import { discoverOps } from "./discover.js";
2
+ import { runOpLocally, OpRunFailure } from "./local-executor.js";
3
+ import { acquireLease, releaseLease, stillHoldsLease, currentHolderId, readLease, DEFAULT_LEASE_TTL_MS } from "../lifecycle/lease.js";
4
+ import { randomUUID } from "node:crypto";
5
+ import { readRunLedger, runEnvOf } from "../lifecycle/run-ledger.js";
6
+ import { readGateLedger, latestResolutionSince } from "../lifecycle/gate-ledger.js";
7
+ import { enterStewardTurn } from "./steward-turn.js";
8
+ import { stewardBesideOf, stewardLeaseName, stewardTurnLeaseName, stewardTurnOps } from "./steward.js";
9
+ import { askReady, spawnBesideRun } from "./steward-beside.js";
10
+ import { stewardWorkHolder } from "./work-lease-run.js";
11
+ import { StaleLockError } from "../lifecycle/git.js";
12
+ import { cronMatches, cronDueBetween } from "./cron.js";
13
+ import { createChangeSignalGate, DEFAULT_SIGNAL_FLOOR_MS } from "./change-signal.js";
14
+ /**
15
+ * Poll interval between rounds — the operator's own cadence, and the fallback
16
+ * for an Op that declares none. Since #2120 an Op can carry its own
17
+ * `schedule.cron` (`./composites/converge-op.ts`), which this loop honours per
18
+ * Op: the round still wakes every `intervalMs`, but an Op with a cron is
19
+ * ticked only on the minutes that cron fires. Chosen short enough to converge
20
+ * promptly, long enough not to hammer `chant lifecycle plan --live` every few
21
+ * seconds — and short enough that a per-minute cron is not missed.
22
+ */
23
+ export const DEFAULT_OPERATOR_INTERVAL_MS = 60000;
24
+ /** One ConvergeOp's own `labels.Env` (`./composites/converge-op.ts` always sets it). `undefined` for a non-ConvergeOp or a hand-built one missing it — filtered out by `isConvergeOp` before this is trusted. */
25
+ function envOf(config) {
26
+ return config.labels?.Env;
27
+ }
28
+ function isConvergeOp(config) {
29
+ return config.labels?.Converge === "true";
30
+ }
31
+ /** Discover every `ConvergeOp` in the project (`labels.Converge === "true"`), optionally filtered to one environment. Ops that don't declare an `Env` label are excluded from an `--env`-filtered discovery (there's nothing to match), but included when no `env` filter is given. */
32
+ export async function discoverConvergeOps(opts) {
33
+ const { ops, errors } = await discoverOps({ cwd: opts?.cwd });
34
+ const converge = [...ops.values()].filter((d) => isConvergeOp(d.config));
35
+ const filtered = opts?.env ? converge.filter((d) => envOf(d.config) === opts.env) : converge;
36
+ return { ops: filtered.sort((a, b) => a.config.name.localeCompare(b.config.name)), errors };
37
+ }
38
+ /** A fresh {@link BesideState}. */
39
+ export function createBesideState() {
40
+ return { running: new Map(), started: new Map(), ended: [] };
41
+ }
42
+ /**
43
+ * Release the per-Op leases a stopped operator still holds (#2879), best
44
+ * effort: a lease that is gone or taken over since is left alone, and one that
45
+ * can't be released expires on its TTL as before.
46
+ */
47
+ export async function releaseHeldLeases(held, holder, opts = {}) {
48
+ const entries = [...held];
49
+ held.clear();
50
+ await Promise.allSettled(entries.map(([op, token]) => releaseLease(op, holder, token, opts)));
51
+ }
52
+ /** Wait for every run in flight beside the turns to end. `chant operator --steward --once` does before it exits. */
53
+ export async function waitForBesideRuns(state) {
54
+ await Promise.all([...state.running.values()].map((r) => r.handle.done));
55
+ }
56
+ /**
57
+ * Ask every run in flight beside the turns to stop, and wait up to `graceMs`
58
+ * for them to end. The operator does when it stops, so no run it started
59
+ * outlives it holding the Op's lease past its renewals.
60
+ */
61
+ export async function stopBesideRuns(state, graceMs = 10000) {
62
+ const runs = [...state.running.values()];
63
+ for (const r of runs)
64
+ r.handle.stop();
65
+ let timer;
66
+ await Promise.race([
67
+ Promise.all(runs.map((r) => r.handle.done)),
68
+ new Promise((resolve) => {
69
+ timer = setTimeout(resolve, graceMs);
70
+ timer.unref?.();
71
+ }),
72
+ ]);
73
+ if (timer)
74
+ clearTimeout(timer);
75
+ }
76
+ /**
77
+ * The steward's Ops whose newest run is the steward's own and stopped on a
78
+ * decision point, with that question's state now. The questions are read
79
+ * from the workspace the way `points` reads them; a workspace that can't be
80
+ * read leaves every run waiting.
81
+ */
82
+ async function stewardWaits(steward, opts) {
83
+ const out = new Map();
84
+ const runs = [];
85
+ for (const op of steward.ops) {
86
+ try {
87
+ const newest = (await readRunLedger(runEnvOf(op), op.name, { cwd: opts.cwd })).records.at(-1);
88
+ if (newest?.status === "waiting" && newest.point && newest.steward === steward.name) {
89
+ runs.push({ op: op.name, question: newest.point.id, point: newest.point.point, state: newest.point.state });
90
+ }
91
+ }
92
+ catch {
93
+ // A ledger that can't be read has no waiting run to resume.
94
+ }
95
+ }
96
+ if (runs.length === 0)
97
+ return out;
98
+ const states = await (opts.readQuestions ?? readQuestionStates)(opts.cwd ?? process.cwd());
99
+ for (const r of runs) {
100
+ const now = states?.get(r.question);
101
+ const answered = states !== null && (now === undefined || now === "answered");
102
+ out.set(r.op, { question: r.question, point: r.point, state: now ?? r.state, answered });
103
+ }
104
+ return out;
105
+ }
106
+ /**
107
+ * The steward's Ops whose newest run is the steward's own and stopped at a
108
+ * gate, and whether the gate has been approved since. A gate ledger that
109
+ * can't be read leaves the run where it stopped.
110
+ */
111
+ async function stewardGates(steward, opts) {
112
+ const out = new Map();
113
+ for (const op of steward.ops) {
114
+ try {
115
+ const newest = (await readRunLedger(runEnvOf(op), op.name, { cwd: opts.cwd })).records.at(-1);
116
+ if (newest?.status !== "gated" || !newest.gate || newest.steward !== steward.name)
117
+ continue;
118
+ const gateOp = newest.gate.op ?? op.name;
119
+ const { resolutions } = await readGateLedger(gateOp, { cwd: opts.cwd });
120
+ const approved = latestResolutionSince(resolutions, newest.gate.name, newest.gate.since) !== undefined;
121
+ out.set(op.name, { gateOp, gate: newest.gate.name, approved });
122
+ }
123
+ catch {
124
+ // A ledger that can't be read has no gated run to resume.
125
+ }
126
+ }
127
+ return out;
128
+ }
129
+ /** Every question's state in the workspace, by id, or null when the workspace's points can't be read. */
130
+ async function readQuestionStates(cwd) {
131
+ const { readQuestionStates: read } = await import("../workspace/points-cli.js");
132
+ return read(cwd);
133
+ }
134
+ /** Take or renew a local steward's own lease (#2731). */
135
+ export async function acquireStewardLease(steward, holder, opts = {}) {
136
+ return acquireLease(stewardLeaseName(steward), holder, { ...opts, ttlMs: opts.ttlMs ?? DEFAULT_LEASE_TTL_MS });
137
+ }
138
+ /**
139
+ * How long a caller contending for a steward's turn lease
140
+ * (`acquireStewardTurn`) retries before giving up (#2750). Long enough to
141
+ * ride out a race with a turn that is just ending; short enough that a
142
+ * genuinely busy steward is reported back promptly. A round never waits
143
+ * (`waitMs` omitted there): it already runs on its own timer and simply
144
+ * tries the turn again next round, exactly as it already does for a busy
145
+ * per-op lease. `chant run <op>` (`../cli/handlers/run.ts`) is the caller
146
+ * that waits, since a human is standing at the terminal for the answer.
147
+ */
148
+ export const STEWARD_TURN_WAIT_MS = 2000;
149
+ /** How often {@link acquireStewardTurn} retries while it waits. */
150
+ const STEWARD_TURN_POLL_MS = 150;
151
+ /**
152
+ * Take the steward's turn lease (#2750): the lease every run of one of its
153
+ * Ops — a round's scheduled tick, or `chant run <op>` typed by hand — holds
154
+ * for exactly as long as that one run takes, so the two are never beside each
155
+ * other. Distinct from {@link acquireStewardLease}, which one `chant operator
156
+ * --steward` process holds for its whole life: this one is held per-run, so a
157
+ * hand run succeeds the moment a round's tick ends, not only once the daemon
158
+ * itself stops.
159
+ *
160
+ * Contention never queues past `waitMs` (0 by default): consistent with a
161
+ * round's own leases, which skip and report rather than wait (see this
162
+ * module's doc), and with the fountain form, whose busy teammate is likewise
163
+ * refused rather than retried. A caller that wants to ride out a race with a
164
+ * turn about to end passes `waitMs`, and this polls every
165
+ * {@link STEWARD_TURN_POLL_MS} until it acquires or the wait runs out.
166
+ */
167
+ export async function acquireStewardTurn(steward, holder, opts = {}) {
168
+ const deadline = Date.now() + (opts.waitMs ?? 0);
169
+ for (;;) {
170
+ const result = await acquireLease(stewardTurnLeaseName(steward), holder, {
171
+ cwd: opts.cwd,
172
+ ttlMs: opts.ttlMs ?? DEFAULT_LEASE_TTL_MS,
173
+ now: opts.now,
174
+ });
175
+ if (result.acquired || result.reason !== "held" || Date.now() >= deadline)
176
+ return result;
177
+ await new Promise((r) => setTimeout(r, STEWARD_TURN_POLL_MS));
178
+ }
179
+ }
180
+ /** Release a steward's turn lease, best-effort — a run whose turn was never actually acquired (or already lost) has nothing to release. */
181
+ async function releaseStewardTurn(steward, holder, token, opts = {}) {
182
+ await releaseLease(stewardTurnLeaseName(steward), holder, token, opts).catch(() => false);
183
+ }
184
+ /**
185
+ * The Ops one round runs as turns: a steward's Ops but those beside its turns
186
+ * (#2861), or every ConvergeOp. A steward's Op with no schedule is considered
187
+ * only to resume a run of the steward's that waits on a decision point.
188
+ */
189
+ async function roundOps(opts) {
190
+ if (opts.steward)
191
+ return stewardTurnOps(opts.steward);
192
+ const { ops } = await discoverConvergeOps({ cwd: opts.cwd, env: opts.env });
193
+ return ops.map((d) => d.config);
194
+ }
195
+ /**
196
+ * Run exactly one round: for every discovered ConvergeOp (filtered per
197
+ * `opts.env`), try its lease; tick the ones this holder wins. Returns one
198
+ * event per discovered op, in discovery order — deterministic, so tests can
199
+ * assert on it directly without depending on log output.
200
+ */
201
+ export async function runOperatorRound(opts) {
202
+ const holder = opts.holder ?? currentHolderId();
203
+ const events = [];
204
+ const steward = opts.steward;
205
+ const leaseOpts = { cwd: opts.cwd, ttlMs: opts.leaseTtlMs, now: opts.now };
206
+ // A local steward is one writer (#2731): its round runs only while it holds
207
+ // its own lease, renewed here and again after every tick, so a turn longer
208
+ // than the lease's TTL still keeps it.
209
+ const holdSteward = async () => {
210
+ if (!steward)
211
+ return true;
212
+ let acquired;
213
+ try {
214
+ acquired = await acquireStewardLease(steward.name, holder, leaseOpts);
215
+ }
216
+ catch (err) {
217
+ events.push({
218
+ kind: "lease-error",
219
+ op: stewardLeaseName(steward.name),
220
+ env: "-",
221
+ error: err instanceof Error ? err.message : String(err),
222
+ });
223
+ return false;
224
+ }
225
+ if (acquired.acquired)
226
+ return true;
227
+ events.push({
228
+ kind: "steward-busy",
229
+ op: stewardLeaseName(steward.name),
230
+ env: "-",
231
+ steward: steward.name,
232
+ ...(acquired.heldBy?.holder ? { heldBy: acquired.heldBy.holder } : {}),
233
+ });
234
+ return false;
235
+ };
236
+ if (!(await holdSteward()))
237
+ return events;
238
+ // The runs started beside the turns that ended since the last round (#2861).
239
+ const besideState = opts.besideState ?? createBesideState();
240
+ events.push(...besideState.ended.splice(0));
241
+ // A steward's Ops whose last run waits on a decision point (#2749), read
242
+ // once per round, and the state of those questions now.
243
+ const waiting = steward ? await stewardWaits(steward, opts) : new Map();
244
+ // And those whose last run stopped at a gate (#2779), with whether it has
245
+ // been approved since.
246
+ const gated = steward ? await stewardGates(steward, opts) : new Map();
247
+ let stewardLost = false;
248
+ for (const config of await roundOps(opts)) {
249
+ const env = steward ? runEnvOf(config) : (envOf(config) ?? "unknown");
250
+ const wait = waiting.get(config.name);
251
+ const stopped = gated.get(config.name);
252
+ let resumed;
253
+ let approved;
254
+ // A run waiting on a question that is now answered is resumed on this
255
+ // round, whatever its cron says. One whose question is still open is left
256
+ // until a person answers it, unless its cron fires, which asks again.
257
+ if (wait?.answered)
258
+ resumed = wait.question;
259
+ // The same for a run stopped at a gate that is now approved (#2779).
260
+ if (stopped?.approved)
261
+ approved = { op: stopped.gateOp, gate: stopped.gate };
262
+ const standing = wait
263
+ ? { kind: "waiting-on-point", op: config.name, env, point: wait.point, question: wait.question, state: wait.state }
264
+ : stopped
265
+ ? { kind: "waiting-on-gate", op: config.name, env, gateOp: stopped.gateOp, gate: stopped.gate }
266
+ : undefined;
267
+ const resuming = resumed !== undefined || approved !== undefined;
268
+ // An Op that declares its own cadence (#2120) is ticked on that cron
269
+ // rather than on every round. Level-triggered: the question is whether a
270
+ // firing minute has passed since this Op was last looked at, so a round
271
+ // that arrives late still owes exactly one tick — a converge tick
272
+ // re-observes everything anyway, and several missed fires are one tick's
273
+ // worth of work.
274
+ const cron = config.schedule?.cron;
275
+ if (cron) {
276
+ const now = (opts.now ?? (() => new Date()))();
277
+ const lastSeen = opts.scheduleState?.get(config.name);
278
+ const due = lastSeen === undefined ? cronMatches(cron, now) : cronDueBetween(cron, lastSeen, now);
279
+ opts.scheduleState?.set(config.name, now);
280
+ if (!due && !resuming) {
281
+ events.push(standing ?? { kind: "skipped-not-due", op: config.name, env, cron });
282
+ continue;
283
+ }
284
+ }
285
+ else if (steward && !resuming) {
286
+ // An unscheduled Op runs when someone asks for it; the steward runs it
287
+ // only to resume its own waiting or gated run.
288
+ if (standing)
289
+ events.push(standing);
290
+ continue;
291
+ }
292
+ let acquired;
293
+ try {
294
+ acquired = await acquireLease(config.name, holder, {
295
+ cwd: opts.cwd,
296
+ ttlMs: opts.leaseTtlMs ?? DEFAULT_LEASE_TTL_MS,
297
+ now: opts.now,
298
+ });
299
+ }
300
+ catch (err) {
301
+ // Not lease contention — the acquire attempt itself failed (most
302
+ // likely a StaleLockError, ./lifecycle/git.ts's diagnosable
303
+ // stand-in for "a previous operator was killed mid-write"). Report it
304
+ // for this op and move on to the next; never abort the whole round.
305
+ const message = err instanceof StaleLockError ? err.message : err instanceof Error ? err.message : String(err);
306
+ events.push({ kind: "lease-error", op: config.name, env, error: message });
307
+ continue;
308
+ }
309
+ if (!acquired.acquired) {
310
+ events.push({ kind: "skipped-lease-held", op: config.name, env, heldBy: acquired.heldBy?.holder });
311
+ continue;
312
+ }
313
+ const lease = acquired.lease;
314
+ opts.heldLeases?.set(config.name, lease.token);
315
+ // A local steward is one turn at a time (#2750): a hand run (`chant run
316
+ // <op>`) holds this same lease for as long as it runs, so a round never
317
+ // ticks beside one. It is one lease for the whole steward, not one per
318
+ // op, so finding it held stops the round outright — every op still ahead
319
+ // of it in `roundOps` would fail the identical check.
320
+ let turn;
321
+ if (steward) {
322
+ try {
323
+ turn = await acquireStewardTurn(steward.name, holder, { cwd: opts.cwd, ttlMs: opts.leaseTtlMs, now: opts.now });
324
+ }
325
+ catch (err) {
326
+ // Not turn contention — the acquire attempt itself failed (most
327
+ // likely a StaleLockError). Same shape as the per-op acquire's own
328
+ // catch above: report it and stop, rather than let it propagate and
329
+ // leak the per-op lease this round just took.
330
+ await releaseLease(config.name, holder, lease.token, { cwd: opts.cwd }).catch(() => false);
331
+ opts.heldLeases?.delete(config.name);
332
+ const message = err instanceof StaleLockError ? err.message : err instanceof Error ? err.message : String(err);
333
+ events.push({ kind: "lease-error", op: stewardTurnLeaseName(steward.name), env, error: message });
334
+ break;
335
+ }
336
+ if (!turn.acquired) {
337
+ await releaseLease(config.name, holder, lease.token, { cwd: opts.cwd }).catch(() => false);
338
+ opts.heldLeases?.delete(config.name);
339
+ events.push({ kind: "turn-busy", op: config.name, env, steward: steward.name, heldBy: turn.heldBy?.holder });
340
+ break;
341
+ }
342
+ }
343
+ // The run is the steward's turn (#2749): a decision point it asks names the
344
+ // steward and makes its model call through the steward's broker, and an
345
+ // answer from inside the turn is refused.
346
+ const runId = randomUUID();
347
+ const restoreTurn = steward
348
+ ? enterStewardTurn({ steward: steward.name, capabilities: steward.capabilities, vault: steward.vault, run: runId })
349
+ : undefined;
350
+ try {
351
+ const result = await runOpLocally(config, opts.activities, opts.profiles, opts.signal, {
352
+ runId,
353
+ // #2522: the environment the operator was started for (`--env`, or a
354
+ // steward's environment) reaches the activities through the run
355
+ // context, as `chant run --env` does.
356
+ ...(opts.env ?? opts.stewardEnv ? { env: opts.env ?? opts.stewardEnv } : {}),
357
+ ...(steward ? { steward: steward.name } : {}),
358
+ ledger: { cwd: opts.cwd },
359
+ // A steward's turn claims work leases as `<steward>/<op>@<holder>`
360
+ // (#2748), which is how `workspace status` finds the lease it holds.
361
+ ...(steward ? { work: { holder: stewardWorkHolder(steward.name, config.name, holder) } } : {}),
362
+ // #2301: without a sink, `settle` catches a failed ledger append and
363
+ // drops it. That is the failure this tick can least afford to lose —
364
+ // the message below points the reader at the ledger record, which is
365
+ // exactly the artifact a failed append means is not there.
366
+ onLedgerError: (err) => events.push({
367
+ kind: "tick-failed",
368
+ op: config.name,
369
+ env,
370
+ error: `Op "${config.name}" ran, but its record could not be appended to the run ledger: ` +
371
+ `${err instanceof Error ? err.message : String(err)}`,
372
+ }),
373
+ });
374
+ const held = await stillHoldsLease(config.name, holder, lease.token, { cwd: opts.cwd });
375
+ events.push(held
376
+ ? {
377
+ kind: "ticked",
378
+ op: config.name,
379
+ env,
380
+ result,
381
+ ...(resumed !== undefined ? { resumed } : {}),
382
+ ...(approved !== undefined ? { approved } : {}),
383
+ }
384
+ : { kind: "fenced", op: config.name, env });
385
+ }
386
+ catch (err) {
387
+ // #2301: "see its ledger record" was the whole message, and it sent the
388
+ // reader to an artifact that a failed ledger append means is missing —
389
+ // while `err.result` was carrying the failing steps all along. Name the
390
+ // failing steps here, and fall back to `cause` for a failure that
391
+ // produced no step record at all.
392
+ const message = err instanceof OpRunFailure
393
+ ? failureDetail(config.name, err)
394
+ : err instanceof Error
395
+ ? err.message
396
+ : String(err);
397
+ events.push({ kind: "tick-failed", op: config.name, env, error: message });
398
+ }
399
+ finally {
400
+ restoreTurn?.();
401
+ if (steward && turn?.acquired)
402
+ await releaseStewardTurn(steward.name, holder, turn.lease.token, { cwd: opts.cwd });
403
+ }
404
+ if (!(await holdSteward())) {
405
+ stewardLost = true;
406
+ break;
407
+ }
408
+ }
409
+ // The Ops beside the turns (#2861) are considered whatever became of the
410
+ // turns: a turn in progress holds none of them. Only a steward that lost its
411
+ // own lease starts nothing.
412
+ if (steward && !stewardLost) {
413
+ await besideRound(steward, opts, holder, besideState, waiting, gated, events);
414
+ }
415
+ return events;
416
+ }
417
+ /**
418
+ * One round for a steward's Ops beside its turns (#2861). For each one not
419
+ * already running: start it when a run of the steward's waits on a question
420
+ * now answered or a gate now approved, when its cron fires, or when its ready
421
+ * step names work it has not started a run for. The run is started and not
422
+ * waited for.
423
+ */
424
+ async function besideRound(steward, opts, holder, state, waiting, gated, events) {
425
+ for (const beside of stewardBesideOf(steward)) {
426
+ const config = steward.ops.find((op) => op.name === beside.op);
427
+ if (!config)
428
+ continue;
429
+ const env = runEnvOf(config);
430
+ // The cron is read whether or not a run is in flight, so a fire during a
431
+ // run is dropped (overlap "skip") rather than owed afterwards.
432
+ const cron = config.schedule?.cron;
433
+ let due = false;
434
+ if (cron) {
435
+ const now = (opts.now ?? (() => new Date()))();
436
+ const lastSeen = opts.scheduleState?.get(config.name);
437
+ due = lastSeen === undefined ? cronMatches(cron, now) : cronDueBetween(cron, lastSeen, now);
438
+ opts.scheduleState?.set(config.name, now);
439
+ }
440
+ const mine = state.running.get(config.name);
441
+ if (mine) {
442
+ events.push({ kind: "beside-running", op: config.name, env, heldBy: mine.holder });
443
+ continue;
444
+ }
445
+ // A run another process holds the lease for: a hand `chant run`, or one
446
+ // this steward started before its operator restarted.
447
+ let current;
448
+ try {
449
+ current = (await readLease(config.name, { cwd: opts.cwd })).record;
450
+ }
451
+ catch (err) {
452
+ events.push({ kind: "lease-error", op: config.name, env, error: err instanceof Error ? err.message : String(err) });
453
+ continue;
454
+ }
455
+ const now = (opts.now ?? (() => new Date()))();
456
+ if (current && new Date(current.expiresAt).getTime() > now.getTime()) {
457
+ events.push({ kind: "beside-running", op: config.name, env, heldBy: current.holder });
458
+ continue;
459
+ }
460
+ const wait = waiting.get(config.name);
461
+ const stopped = gated.get(config.name);
462
+ const standing = wait
463
+ ? { kind: "waiting-on-point", op: config.name, env, point: wait.point, question: wait.question, state: wait.state }
464
+ : stopped
465
+ ? { kind: "waiting-on-gate", op: config.name, env, gateOp: stopped.gateOp, gate: stopped.gate }
466
+ : undefined;
467
+ let why;
468
+ if (wait?.answered)
469
+ why = "resumed";
470
+ else if (stopped?.approved)
471
+ why = "approved";
472
+ else if (due)
473
+ why = "cron";
474
+ let keys;
475
+ if (!why && beside.ready) {
476
+ const answer = await askReady(beside.ready, opts.activities, opts.signal);
477
+ if ("error" in answer) {
478
+ events.push({ kind: "ready-failed", op: config.name, env, error: answer.error });
479
+ continue;
480
+ }
481
+ if (answer.ready) {
482
+ const seen = state.started.get(config.name) ?? new Set();
483
+ if (answer.keys.length === 0 || answer.keys.some((k) => !seen.has(k))) {
484
+ why = "ready";
485
+ keys = answer.keys;
486
+ }
487
+ else {
488
+ events.push(standing ?? { kind: "skipped-not-ready", op: config.name, env, already: answer.keys });
489
+ continue;
490
+ }
491
+ }
492
+ else {
493
+ events.push(standing ?? { kind: "skipped-not-ready", op: config.name, env });
494
+ continue;
495
+ }
496
+ }
497
+ if (!why) {
498
+ const idle = standing ?? (cron ? { kind: "skipped-not-due", op: config.name, env, cron } : undefined);
499
+ if (idle)
500
+ events.push(idle);
501
+ continue;
502
+ }
503
+ const runHolder = stewardWorkHolder(steward.name, config.name, holder);
504
+ let handle;
505
+ try {
506
+ handle = (opts.launchBeside ?? spawnBesideRun)({
507
+ op: config,
508
+ steward: steward.name,
509
+ ...(opts.stewardEnv !== undefined ? { env: opts.stewardEnv } : {}),
510
+ holder: runHolder,
511
+ cwd: opts.cwd ?? process.cwd(),
512
+ ...(opts.leaseTtlMs !== undefined ? { leaseTtlMs: opts.leaseTtlMs } : {}),
513
+ });
514
+ }
515
+ catch (err) {
516
+ events.push({ kind: "tick-failed", op: config.name, env, error: err instanceof Error ? err.message : String(err) });
517
+ continue;
518
+ }
519
+ if (keys) {
520
+ const seen = state.started.get(config.name) ?? new Set();
521
+ for (const k of keys)
522
+ seen.add(k);
523
+ state.started.set(config.name, seen);
524
+ }
525
+ state.running.set(config.name, { handle, holder: runHolder, why });
526
+ void handle.done.then((exit) => {
527
+ state.running.delete(config.name);
528
+ state.ended.push({ kind: "beside-ended", op: config.name, env, code: exit.code, ...(exit.error ? { error: exit.error } : {}) });
529
+ });
530
+ events.push({
531
+ kind: "beside-started",
532
+ op: config.name,
533
+ env,
534
+ why,
535
+ holder: runHolder,
536
+ ...(keys && keys.length > 0 ? { keys } : {}),
537
+ ...(why === "resumed" && wait ? { resumed: wait.question } : {}),
538
+ ...(why === "approved" && stopped ? { approved: { op: stopped.gateOp, gate: stopped.gate } } : {}),
539
+ });
540
+ }
541
+ }
542
+ /**
543
+ * What a failed tick says about itself (#2301).
544
+ *
545
+ * `chant operator` renders its own events rather than going through
546
+ * `renderHuman`, so the executor's step records reached nobody here even after
547
+ * the executor stopped dropping them. Every failing step's message, in order,
548
+ * or the underlying error when the run failed without producing one.
549
+ */
550
+ function failureDetail(op, err) {
551
+ const failed = err.result.records.filter((r) => r.status === "fail" && r.error);
552
+ if (failed.length > 0) {
553
+ return `Op "${op}" failed: ${failed.map((r) => `${r.fn}: ${r.error}`).join("; ")}`;
554
+ }
555
+ const cause = err.cause;
556
+ if (cause !== undefined) {
557
+ return `Op "${op}" failed: ${cause instanceof Error ? cause.message : String(cause)}`;
558
+ }
559
+ return `Op "${op}" failed — see its ledger record for step-level detail`;
560
+ }
561
+ /** Abortable sleep — resolves early (without throwing) if `signal` fires mid-wait, so the operator loop can stop promptly on Ctrl-C rather than finishing out a long interval. */
562
+ function sleepAbortable(ms, signal) {
563
+ return new Promise((resolve) => {
564
+ if (signal?.aborted)
565
+ return resolve();
566
+ const timer = setTimeout(() => {
567
+ signal?.removeEventListener("abort", onAbort);
568
+ resolve();
569
+ }, ms);
570
+ const onAbort = () => {
571
+ clearTimeout(timer);
572
+ resolve();
573
+ };
574
+ signal?.addEventListener("abort", onAbort, { once: true });
575
+ });
576
+ }
577
+ /** Render one signal event as `chant operator`'s log line shape. */
578
+ export function formatSignalLine(event) {
579
+ switch (event.kind) {
580
+ case "subscribed":
581
+ return `operator: ${event.lexicon} change signal subscribed (the timer still runs)`;
582
+ case "subscribe-failed":
583
+ return `operator: ${event.lexicon} change signal unavailable, polling on the timer (${event.error})`;
584
+ case "subscription-lost":
585
+ return `operator: ${event.lexicon} change signal lost, polling on the timer until the next round re-subscribes (${event.error})`;
586
+ case "woken":
587
+ return `operator: woken by a change signal after ${event.afterMs}ms, running an ordinary round`;
588
+ }
589
+ }
590
+ /**
591
+ * Run rounds forever, sleeping `intervalMs` between them, until
592
+ * `opts.signal` aborts. The daemon is a convenience, never a requirement
593
+ * (issue: "if it dies, nothing breaks and nothing is lost") — this function
594
+ * is exactly `while (!aborted) { round(); sleep(); }`, nothing durable lives
595
+ * in its own memory that a restart would need to recover.
596
+ *
597
+ * With `subscribers` (#1981) the sleep gains a second wake source, and only a
598
+ * wake source. A signal aborts the current sleep; the round that follows is
599
+ * the same round the timer would have run, deriving everything from a fresh
600
+ * observation. Nothing a subscription reports reaches a tick, because the
601
+ * seam has nowhere to put it: `onChange` takes no arguments.
602
+ */
603
+ export async function runOperatorForever(opts) {
604
+ const holder = opts.holder ?? currentHolderId();
605
+ // Per-op cron state (#2120) lives for the life of the loop. A restart starts
606
+ // it empty, which means the first round ticks a scheduled Op only if it
607
+ // lands on a firing minute — a fresh operator owes no catch-up for the ticks
608
+ // it was not running for.
609
+ const scheduleState = opts.scheduleState ?? new Map();
610
+ // The runs a steward starts beside its turns (#2861), for the life of the
611
+ // loop. When the loop stops, so do they.
612
+ const besideState = opts.besideState ?? createBesideState();
613
+ // The per-Op leases the rounds leave held (#2879), released when the loop stops.
614
+ const heldLeases = opts.heldLeases ?? new Map();
615
+ const intervalMs = opts.intervalMs ?? DEFAULT_OPERATOR_INTERVAL_MS;
616
+ const subscribers = opts.subscribers ?? [];
617
+ // Nothing to subscribe to: the loop below is the loop that shipped before
618
+ // #1981, and takes none of the machinery's cost.
619
+ if (subscribers.length === 0) {
620
+ try {
621
+ while (!opts.signal?.aborted) {
622
+ const events = await runOperatorRound({ ...opts, holder, scheduleState, besideState, heldLeases });
623
+ opts.onRound?.(events);
624
+ if (opts.signal?.aborted)
625
+ break;
626
+ await sleepAbortable(intervalMs, opts.signal);
627
+ }
628
+ }
629
+ finally {
630
+ await stopBesideRuns(besideState);
631
+ await releaseHeldLeases(heldLeases, holder, { cwd: opts.cwd });
632
+ }
633
+ return;
634
+ }
635
+ const gate = createChangeSignalGate({ floorMs: opts.signalFloorMs ?? DEFAULT_SIGNAL_FLOOR_MS });
636
+ // The subscriptions the loop currently holds, by lexicon. A lexicon absent
637
+ // from this map is one to (re-)subscribe on the next round, which is how a
638
+ // killed watch comes back without a special retry path.
639
+ const live = new Map();
640
+ // Stops every subscription at once when the loop ends, whatever ends it.
641
+ const subscriptionsAbort = new AbortController();
642
+ const closeAll = async () => {
643
+ subscriptionsAbort.abort();
644
+ const open = [...live.values()];
645
+ live.clear();
646
+ // A close that throws must not mask why the loop is unwinding.
647
+ await Promise.allSettled(open.map((s) => s.close()));
648
+ };
649
+ const ensureSubscribed = async () => {
650
+ for (const subscriber of subscribers) {
651
+ if (live.has(subscriber.lexicon) || subscriptionsAbort.signal.aborted)
652
+ continue;
653
+ try {
654
+ const subscription = await subscriber.subscribe({
655
+ onChange: () => gate.signal(),
656
+ onError: (error) => {
657
+ // Reported once, then forgotten: dropping it from `live` is what
658
+ // makes the next round re-subscribe. The loop itself is untouched.
659
+ if (!live.delete(subscriber.lexicon))
660
+ return;
661
+ opts.onSignalEvent?.({ kind: "subscription-lost", lexicon: subscriber.lexicon, error });
662
+ },
663
+ signal: subscriptionsAbort.signal,
664
+ });
665
+ live.set(subscriber.lexicon, subscription);
666
+ opts.onSignalEvent?.({ kind: "subscribed", lexicon: subscriber.lexicon });
667
+ }
668
+ catch (err) {
669
+ // A subscription that cannot be established is a slower loop, never a
670
+ // stopped one: report it and fall through to the timer.
671
+ opts.onSignalEvent?.({
672
+ kind: "subscribe-failed",
673
+ lexicon: subscriber.lexicon,
674
+ error: err instanceof Error ? err.message : String(err),
675
+ });
676
+ }
677
+ }
678
+ };
679
+ try {
680
+ while (!opts.signal?.aborted) {
681
+ gate.roundStarted();
682
+ const startedAt = Date.now();
683
+ const events = await runOperatorRound({ ...opts, holder, scheduleState, besideState, heldLeases });
684
+ opts.onRound?.(events);
685
+ if (opts.signal?.aborted)
686
+ break;
687
+ await ensureSubscribed();
688
+ if (opts.signal?.aborted)
689
+ break;
690
+ const reason = await gate.wait(intervalMs, opts.signal);
691
+ if (reason === "signal") {
692
+ opts.onSignalEvent?.({ kind: "woken", afterMs: Date.now() - startedAt });
693
+ }
694
+ }
695
+ }
696
+ finally {
697
+ await closeAll();
698
+ await stopBesideRuns(besideState);
699
+ await releaseHeldLeases(heldLeases, holder, { cwd: opts.cwd });
700
+ }
701
+ }
702
+ /** Render one round's events as `chant operator`'s log line shape — one line per ticked/skipped/failed op, reusing each ticked op's own `convergeTick` log line (`OpRunResult`'s outcome attribute doesn't carry it, so this reads the tick's step record's `Remediated`... actually the human-readable summary comes from the ledger, not the run result — see `../cli/handlers/operator.ts` for where `chant operator status` reads it back). This formats what's available from the round itself: which op, which env, and whether it ticked, skipped, or failed. */
703
+ export function formatRoundLine(event) {
704
+ switch (event.kind) {
705
+ case "ticked":
706
+ return `operator: ${event.op}@${event.env} ticked=1 status=${event.result.status}` +
707
+ (event.result.gate ? ` gate="${event.result.gate.gate}"` : "") +
708
+ (event.result.point ? ` point="${event.result.point.id}"` : "") +
709
+ (event.resumed ? ` resumed="${event.resumed}"` : "") +
710
+ (event.approved ? ` approved="${event.approved.op}/${event.approved.gate}"` : "");
711
+ case "waiting-on-point":
712
+ return `operator: ${event.op}@${event.env} waiting=1(point:${event.question}:${event.state})`;
713
+ case "waiting-on-gate":
714
+ return `operator: ${event.op}@${event.env} gated=1(gate:${event.gateOp}/${event.gate})`;
715
+ case "skipped-lease-held":
716
+ return `operator: ${event.op}@${event.env} skipped=1(lease-held${event.heldBy ? `:${event.heldBy}` : ""})`;
717
+ case "skipped-not-due":
718
+ return `operator: ${event.op}@${event.env} skipped=1(not-due:${event.cron})`;
719
+ case "tick-failed":
720
+ return `operator: ${event.op}@${event.env} failed=1 error="${event.error}"`;
721
+ case "fenced":
722
+ return `operator: ${event.op}@${event.env} fenced=1(lease lost mid-tick — ledger record still written)`;
723
+ case "lease-error":
724
+ return `operator: ${event.op}@${event.env} error=1(lease acquire failed — ${event.error})`;
725
+ case "steward-busy":
726
+ return `operator: steward ${event.steward} skipped=1(steward-lease-held${event.heldBy ? `:${event.heldBy}` : ""})`;
727
+ case "turn-busy":
728
+ return `operator: ${event.op}@${event.env} skipped=1(turn-held${event.heldBy ? `:${event.heldBy}` : ""}, steward "${event.steward}" is already mid-turn)`;
729
+ case "beside-started":
730
+ return `operator: ${event.op}@${event.env} started=1(beside:${event.why}) holder="${event.holder}"` +
731
+ (event.keys ? ` keys="${event.keys.join(",")}"` : "") +
732
+ (event.resumed ? ` resumed="${event.resumed}"` : "") +
733
+ (event.approved ? ` approved="${event.approved.op}/${event.approved.gate}"` : "");
734
+ case "beside-running":
735
+ return `operator: ${event.op}@${event.env} skipped=1(beside-running${event.heldBy ? `:${event.heldBy}` : ""})`;
736
+ case "beside-ended":
737
+ return `operator: ${event.op}@${event.env} ended=1(beside) exit=${event.code ?? "none"}` + (event.error ? ` error="${event.error}"` : "");
738
+ case "skipped-not-ready":
739
+ return `operator: ${event.op}@${event.env} skipped=1(not-ready${event.already ? `:already-started:${event.already.join(",")}` : ""})`;
740
+ case "ready-failed":
741
+ return `operator: ${event.op}@${event.env} failed=1(ready) error="${event.error}"`;
742
+ }
743
+ }