@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.
- package/bin/chant +11 -0
- package/dist/agents/checks.js +326 -0
- package/dist/agents/discover.js +885 -0
- package/dist/agents/importer.js +17 -0
- package/dist/agents/index.js +12 -0
- package/dist/agents/types.js +19 -0
- package/dist/apply.js +151 -0
- package/dist/attrref.js +70 -0
- package/dist/audit/catalog.js +350 -0
- package/dist/audit/core.js +252 -0
- package/dist/audit/discover.js +633 -0
- package/dist/audit/fetch.js +666 -0
- package/dist/audit/lineage.js +91 -0
- package/dist/audit/nginx.js +366 -0
- package/dist/audit/prior-art.js +132 -0
- package/dist/audit/proof.js +321 -0
- package/dist/audit/report-html.js +194 -0
- package/dist/audit/report-model.js +198 -0
- package/dist/audit/report.js +102 -0
- package/dist/audit/rules-doc.js +144 -0
- package/dist/audit/secrets.js +405 -0
- package/dist/audit/terraform-state.js +140 -0
- package/dist/audit/wrangler.js +262 -0
- package/dist/behaviour-delta.js +401 -0
- package/dist/behaviour-engine.js +357 -0
- package/dist/behaviour-graph.js +83 -0
- package/dist/behaviour-http.js +188 -0
- package/dist/behaviour-kinds.js +172 -0
- package/dist/behaviour-overlay.js +50 -0
- package/dist/behaviour-predict.js +188 -0
- package/dist/behaviour-request.js +194 -0
- package/dist/behaviour.js +1325 -0
- package/dist/build-params.js +108 -0
- package/dist/build.d.ts +6 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +669 -0
- package/dist/builder.js +44 -0
- package/dist/cdk/advise.js +30 -0
- package/dist/cdk/assembly.js +122 -0
- package/dist/cdk/graph.js +444 -0
- package/dist/cdk/tier-map.js +64 -0
- package/dist/cdk/types.js +24 -0
- package/dist/change-set.d.ts +24 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +361 -0
- package/dist/child-project.js +21 -0
- package/dist/ci-jobs.d.ts +227 -0
- package/dist/ci-jobs.d.ts.map +1 -0
- package/dist/ci-jobs.js +448 -0
- package/dist/claimed-fields.js +135 -0
- package/dist/cli/build-options.js +70 -0
- package/dist/cli/build-params-cli.js +139 -0
- package/dist/cli/command-group.js +123 -0
- package/dist/cli/commands/audit-agents.js +326 -0
- package/dist/cli/commands/audit.js +571 -0
- package/dist/cli/commands/build.js +920 -0
- package/dist/cli/commands/carve-apply.js +153 -0
- package/dist/cli/commands/carve-bridge.js +201 -0
- package/dist/cli/commands/carve-emit.js +332 -0
- package/dist/cli/commands/carve-status.js +119 -0
- package/dist/cli/commands/carve.js +204 -0
- package/dist/cli/commands/check-lexicon-docs.js +79 -0
- package/dist/cli/commands/check-lexicon-examples.js +177 -0
- package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
- package/dist/cli/commands/check-lexicon-mcp.js +82 -0
- package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-plugin.js +104 -0
- package/dist/cli/commands/check-lexicon.js +766 -0
- package/dist/cli/commands/describe.js +85 -0
- package/dist/cli/commands/diff.js +175 -0
- package/dist/cli/commands/doctor.js +350 -0
- package/dist/cli/commands/import-agents.js +155 -0
- package/dist/cli/commands/import.js +670 -0
- package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
- package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
- package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
- package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
- package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
- package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
- package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
- package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
- package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
- package/dist/cli/commands/init-lexicon.js +172 -0
- package/dist/cli/commands/init.js +381 -0
- package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
- package/dist/cli/commands/lexicon-surface-diff.js +145 -0
- package/dist/cli/commands/licenses.js +125 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +948 -0
- package/dist/cli/commands/list.js +63 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +423 -0
- package/dist/cli/commands/onboard.js +403 -0
- package/dist/cli/commands/pinned-upgrade.js +191 -0
- package/dist/cli/commands/update.js +194 -0
- package/dist/cli/commands/vendor.js +217 -0
- package/dist/cli/conflict-check.js +104 -0
- package/dist/cli/debug.js +8 -0
- package/dist/cli/format.js +104 -0
- package/dist/cli/handlers/build.js +267 -0
- package/dist/cli/handlers/carve-apply.js +30 -0
- package/dist/cli/handlers/carve-bridge.js +28 -0
- package/dist/cli/handlers/carve-emit.js +50 -0
- package/dist/cli/handlers/carve-status.js +26 -0
- package/dist/cli/handlers/carve.js +40 -0
- package/dist/cli/handlers/change-set.js +46 -0
- package/dist/cli/handlers/components.js +730 -0
- package/dist/cli/handlers/dev.js +113 -0
- package/dist/cli/handlers/emulator.js +233 -0
- package/dist/cli/handlers/explain.js +54 -0
- package/dist/cli/handlers/fan-out.js +422 -0
- package/dist/cli/handlers/gate-resume.js +275 -0
- package/dist/cli/handlers/generate.js +84 -0
- package/dist/cli/handlers/graph.js +969 -0
- package/dist/cli/handlers/init.js +102 -0
- package/dist/cli/handlers/lifecycle.js +1727 -0
- package/dist/cli/handlers/lint.js +62 -0
- package/dist/cli/handlers/migrate.js +48 -0
- package/dist/cli/handlers/misc.js +391 -0
- package/dist/cli/handlers/operator.js +1162 -0
- package/dist/cli/handlers/override-approve.js +102 -0
- package/dist/cli/handlers/pr.js +503 -0
- package/dist/cli/handlers/promote.js +342 -0
- package/dist/cli/handlers/run-generate.js +206 -0
- package/dist/cli/handlers/run-wave.js +66 -0
- package/dist/cli/handlers/run.js +1191 -0
- package/dist/cli/handlers/scenario.js +325 -0
- package/dist/cli/handlers/search.js +924 -0
- package/dist/cli/handlers/serve.js +32 -0
- package/dist/cli/handlers/vendor.js +154 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/is-entry-point.js +23 -0
- package/dist/cli/lsp/capabilities.js +28 -0
- package/dist/cli/lsp/diagnostics.js +34 -0
- package/dist/cli/lsp/server.js +329 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +2540 -0
- package/dist/cli/mcp/lifecycle-tools.js +80 -0
- package/dist/cli/mcp/op-tools.js +306 -0
- package/dist/cli/mcp/resource-handlers.js +258 -0
- package/dist/cli/mcp/resources/context.js +85 -0
- package/dist/cli/mcp/server.js +353 -0
- package/dist/cli/mcp/tools/build.js +111 -0
- package/dist/cli/mcp/tools/composites.js +95 -0
- package/dist/cli/mcp/tools/explain.js +166 -0
- package/dist/cli/mcp/tools/import.js +49 -0
- package/dist/cli/mcp/tools/lint.js +41 -0
- package/dist/cli/mcp/tools/scaffold.js +111 -0
- package/dist/cli/mcp/tools/search.js +112 -0
- package/dist/cli/mcp/types.js +1 -0
- package/dist/cli/mcp/workspace-plugins.js +91 -0
- package/dist/cli/mcp/workspace-tools.d.ts +1 -1
- package/dist/cli/mcp/workspace-tools.js +564 -0
- package/dist/cli/mcp-config.js +70 -0
- package/dist/cli/plugins.js +313 -0
- package/dist/cli/registry.js +23 -0
- package/dist/cli/reporters/stylish.js +329 -0
- package/dist/cli/version.js +15 -0
- package/dist/cli/watch.js +79 -0
- package/dist/codegen/bound-property-types.js +82 -0
- package/dist/codegen/coverage.js +119 -0
- package/dist/codegen/docs-file-markers.js +60 -0
- package/dist/codegen/docs-pages.js +115 -0
- package/dist/codegen/docs-rule-scanning.js +164 -0
- package/dist/codegen/docs-rules.js +76 -0
- package/dist/codegen/docs-sections.js +117 -0
- package/dist/codegen/docs-sidebar.js +65 -0
- package/dist/codegen/docs-types.js +4 -0
- package/dist/codegen/docs.js +356 -0
- package/dist/codegen/fetch.js +340 -0
- package/dist/codegen/generate-post-synth-barrel.js +63 -0
- package/dist/codegen/generate-registry.js +71 -0
- package/dist/codegen/generate-runtime-index.js +56 -0
- package/dist/codegen/generate-typescript.js +119 -0
- package/dist/codegen/generate.js +115 -0
- package/dist/codegen/json-patch.js +141 -0
- package/dist/codegen/json-schema-to-ts.js +344 -0
- package/dist/codegen/json-schema.js +246 -0
- package/dist/codegen/lexicon-regen.js +412 -0
- package/dist/codegen/naming.js +217 -0
- package/dist/codegen/okf-lexicon.js +245 -0
- package/dist/codegen/package.js +150 -0
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.js +494 -0
- package/dist/codegen/registry.js +60 -0
- package/dist/codegen/rehype-base-url.mjs +68 -0
- package/dist/codegen/rolling-upgrade.js +217 -0
- package/dist/codegen/surface-snapshot.js +537 -0
- package/dist/codegen/testdata/postgres-tags.json +242 -0
- package/dist/codegen/topo-sort.js +36 -0
- package/dist/codegen/typecheck.js +115 -0
- package/dist/codegen/validate.js +200 -0
- package/dist/codegen/version-bump.js +35 -0
- package/dist/components/auto-release.js +143 -0
- package/dist/components/builders.js +47 -0
- package/dist/components/capability-plugin-loader.js +175 -0
- package/dist/components/capability-plugin-schema.js +46 -0
- package/dist/components/capability-plugin.js +99 -0
- package/dist/components/capability.js +60 -0
- package/dist/components/changed-files.js +72 -0
- package/dist/components/cli-support.js +427 -0
- package/dist/components/component.js +120 -0
- package/dist/components/component.schema.json +271 -0
- package/dist/components/config-defaults.js +130 -0
- package/dist/components/deploy-units.js +60 -0
- package/dist/components/discover.d.ts.map +1 -1
- package/dist/components/discover.js +189 -0
- package/dist/components/driver-output.js +86 -0
- package/dist/components/driver.js +728 -0
- package/dist/components/fan-out-output.js +165 -0
- package/dist/components/fan-out-record.js +94 -0
- package/dist/components/fan-out-run.js +373 -0
- package/dist/components/fan-out-support.js +60 -0
- package/dist/components/fan-out.js +273 -0
- package/dist/components/gate-plan.js +41 -0
- package/dist/components/gated-wave-pipeline.js +46 -0
- package/dist/components/index.js +24 -0
- package/dist/components/layers.js +28 -0
- package/dist/components/manifest-persistence.js +108 -0
- package/dist/components/pilots/alb-ecs.pilot.js +59 -0
- package/dist/components/pilots/dynamodb.pilot.js +51 -0
- package/dist/components/pilots/jar-emr.pilot.js +65 -0
- package/dist/components/pilots/lambda.pilot.js +52 -0
- package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
- package/dist/components/pilots/project.js +12 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +135 -0
- package/dist/components/pr-run.js +363 -0
- package/dist/components/presets/ecs-fargate.js +72 -0
- package/dist/components/presets/index.js +28 -0
- package/dist/components/presets/lambda.js +34 -0
- package/dist/components/presets/single-host-compose.js +41 -0
- package/dist/components/promote.js +549 -0
- package/dist/components/registry.js +34 -0
- package/dist/components/run-progress.js +33 -0
- package/dist/components/sandbox/driver.d.ts.map +1 -1
- package/dist/components/sandbox/driver.js +93 -0
- package/dist/components/sandbox/run.js +115 -0
- package/dist/components/starter-plugin.js +104 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
- package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
- package/dist/components/verbs/bom-writer.js +287 -0
- package/dist/components/verbs/build-archive.js +188 -0
- package/dist/components/verbs/build.js +142 -0
- package/dist/components/verbs/cloud-executor.js +110 -0
- package/dist/components/verbs/component-bom.js +125 -0
- package/dist/components/verbs/ensure-secret.js +50 -0
- package/dist/components/verbs/index.js +61 -0
- package/dist/components/verbs/license-policy.js +75 -0
- package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
- package/dist/components/verbs/process-runner.js +78 -0
- package/dist/components/verbs/r2-sync.js +93 -0
- package/dist/components/verbs/reproducibility.js +62 -0
- package/dist/components/verbs/run-agent.js +577 -0
- package/dist/components/verbs/sbom-generator.js +119 -0
- package/dist/components/verbs/sbom.js +97 -0
- package/dist/components/verbs/shell.js +32 -0
- package/dist/components/verbs/sign.js +221 -0
- package/dist/components/verbs/stub.js +28 -0
- package/dist/components/verbs/tool-sbom-generator.js +154 -0
- package/dist/components/verbs/verify.js +112 -0
- package/dist/components/verbs/vex.js +131 -0
- package/dist/components/verbs/vuln-gate.js +152 -0
- package/dist/components/verbs/vuln-scan.js +288 -0
- package/dist/components/verbs/wait-verify.js +106 -0
- package/dist/components/verbs/wrangler.js +179 -0
- package/dist/components/wave-plan.js +102 -0
- package/dist/composite.d.ts +10 -2
- package/dist/composite.d.ts.map +1 -1
- package/dist/composite.js +313 -0
- package/dist/config-import.d.ts.map +1 -1
- package/dist/config-import.js +22 -0
- package/dist/config-sandbox.js +122 -0
- package/dist/config-static.js +206 -0
- package/dist/config.js +605 -0
- package/dist/content-digest.js +23 -0
- package/dist/declarable.js +114 -0
- package/dist/deep-observation.js +437 -0
- package/dist/detectLexicon.js +54 -0
- package/dist/discovery/cache.js +70 -0
- package/dist/discovery/collect.d.ts +2 -1
- package/dist/discovery/collect.d.ts.map +1 -1
- package/dist/discovery/collect.js +223 -0
- package/dist/discovery/cycles.js +95 -0
- package/dist/discovery/entity-wire-codec.js +391 -0
- package/dist/discovery/entity-wire.js +42 -0
- package/dist/discovery/files.js +121 -0
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/fold-import.js +4073 -0
- package/dist/discovery/fold-rank.js +292 -0
- package/dist/discovery/graph.js +115 -0
- package/dist/discovery/host-composite.d.ts +35 -0
- package/dist/discovery/host-composite.d.ts.map +1 -0
- package/dist/discovery/host-composite.js +93 -0
- package/dist/discovery/import.d.ts.map +1 -1
- package/dist/discovery/import.js +65 -0
- package/dist/discovery/index.d.ts +9 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +333 -0
- package/dist/discovery/param-deps.js +487 -0
- package/dist/discovery/resolve.js +39 -0
- package/dist/discovery/sandbox/bundle.js +214 -0
- package/dist/discovery/sandbox/child-errors.js +26 -0
- package/dist/discovery/sandbox/config-run.js +100 -0
- package/dist/discovery/sandbox/config-wire.js +183 -0
- package/dist/discovery/sandbox/driver.d.ts.map +1 -1
- package/dist/discovery/sandbox/driver.js +333 -0
- package/dist/discovery/sandbox/fork.js +229 -0
- package/dist/discovery/sandbox/policy-run.js +142 -0
- package/dist/discovery/sandbox/policy-wire.js +152 -0
- package/dist/discovery/sandbox/run.js +77 -0
- package/dist/discovery/specifier-resolve.js +320 -0
- package/dist/discovery/walk.js +284 -0
- package/dist/effect-receipt.js +340 -0
- package/dist/env.js +55 -0
- package/dist/errors.js +62 -0
- package/dist/fold/fold.js +1434 -0
- package/dist/fold/foldable-helpers.js +229 -0
- package/dist/fold/subset.js +696 -0
- package/dist/fold-provenance.js +414 -0
- package/dist/gate-decision.d.ts +20 -9
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +313 -0
- package/dist/gate-resume-run.js +154 -0
- package/dist/gated-waves.js +165 -0
- package/dist/governance.js +43 -0
- package/dist/graph-declared.js +45 -0
- package/dist/graph-detail.js +207 -0
- package/dist/graph-dot.js +54 -0
- package/dist/graph-effective.js +107 -0
- package/dist/graph-ir.js +623 -0
- package/dist/graph-layout.js +184 -0
- package/dist/graph-lens.js +105 -0
- package/dist/graph-mermaid.js +83 -0
- package/dist/graph-ops.js +39 -0
- package/dist/graph-refs.js +156 -0
- package/dist/held-elsewhere.js +87 -0
- package/dist/identity.js +251 -0
- package/dist/import/base-parser.js +34 -0
- package/dist/import/embedded.js +255 -0
- package/dist/import/generator.js +1 -0
- package/dist/import/ir-utils.js +85 -0
- package/dist/import/parser-options.js +45 -0
- package/dist/import/parser.js +1 -0
- package/dist/index.js +118 -0
- package/dist/intrinsic-interpolation.js +73 -0
- package/dist/intrinsic.js +31 -0
- package/dist/join-key.js +35 -0
- package/dist/kubectl-context.js +150 -0
- package/dist/lexicon-config.js +58 -0
- package/dist/lexicon-integrity.js +47 -0
- package/dist/lexicon-manifest.js +70 -0
- package/dist/lexicon-module.d.ts.map +1 -1
- package/dist/lexicon-module.js +241 -0
- package/dist/lexicon-output.js +218 -0
- package/dist/lexicon-plugin-helpers.js +104 -0
- package/dist/lexicon-schema.js +136 -0
- package/dist/lexicon.js +130 -0
- package/dist/lifecycle/affected.js +224 -0
- package/dist/lifecycle/assert-live.js +110 -0
- package/dist/lifecycle/build-ledger-store.js +160 -0
- package/dist/lifecycle/build-ledger.js +155 -0
- package/dist/lifecycle/change-set.js +356 -0
- package/dist/lifecycle/converge-ledger.js +161 -0
- package/dist/lifecycle/deep-diff.js +233 -0
- package/dist/lifecycle/deep-observe.js +147 -0
- package/dist/lifecycle/digest.js +143 -0
- package/dist/lifecycle/disruption.js +135 -0
- package/dist/lifecycle/gate-applied.js +113 -0
- package/dist/lifecycle/gate-audit.d.ts +69 -2
- package/dist/lifecycle/gate-audit.d.ts.map +1 -1
- package/dist/lifecycle/gate-audit.js +415 -0
- package/dist/lifecycle/gate-ledger-select.js +89 -0
- package/dist/lifecycle/gate-ledger.d.ts +24 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +201 -0
- package/dist/lifecycle/gate-origin.js +117 -0
- package/dist/lifecycle/gate-pending.js +58 -0
- package/dist/lifecycle/git.js +1182 -0
- package/dist/lifecycle/identity.js +58 -0
- package/dist/lifecycle/index.js +26 -0
- package/dist/lifecycle/lease.js +283 -0
- package/dist/lifecycle/ledger-port.js +1 -0
- package/dist/lifecycle/legacy-digest.js +91 -0
- package/dist/lifecycle/live-diff.js +274 -0
- package/dist/lifecycle/local-note.js +15 -0
- package/dist/lifecycle/member-ledger.js +122 -0
- package/dist/lifecycle/observation-baseline.js +155 -0
- package/dist/lifecycle/observe.js +375 -0
- package/dist/lifecycle/oras-referrer-lookup.js +82 -0
- package/dist/lifecycle/override-ledger.js +54 -0
- package/dist/lifecycle/plan-digest.js +110 -0
- package/dist/lifecycle/plan-ledger.js +129 -0
- package/dist/lifecycle/receipt-plan.js +192 -0
- package/dist/lifecycle/release-ledger.js +155 -0
- package/dist/lifecycle/release-read.js +64 -0
- package/dist/lifecycle/replay.js +193 -0
- package/dist/lifecycle/rollback.js +102 -0
- package/dist/lifecycle/run-ledger.js +183 -0
- package/dist/lifecycle/scenario-eval.js +204 -0
- package/dist/lifecycle/scenario.js +214 -0
- package/dist/lifecycle/snapshot.js +239 -0
- package/dist/lifecycle/status.js +447 -0
- package/dist/lifecycle/symptoms.js +117 -0
- package/dist/lifecycle/teardown.js +255 -0
- package/dist/lifecycle/types.js +1 -0
- package/dist/lifecycle/unobserved-gate.js +33 -0
- package/dist/lifecycle/wave-plans.js +68 -0
- package/dist/lifecycle/work-item-id.js +36 -0
- package/dist/lifecycle/work-lease.js +393 -0
- package/dist/lint/component-checks.js +87 -0
- package/dist/lint/config.js +483 -0
- package/dist/lint/declarative.js +122 -0
- package/dist/lint/discover.d.ts.map +1 -1
- package/dist/lint/discover.js +138 -0
- package/dist/lint/engine.js +246 -0
- package/dist/lint/knowledge-checks.js +64 -0
- package/dist/lint/named-checks.js +22 -0
- package/dist/lint/output-checks.js +87 -0
- package/dist/lint/output-docs.js +163 -0
- package/dist/lint/parser.js +33 -0
- package/dist/lint/pipeline-change-gate.js +70 -0
- package/dist/lint/policy-import.d.ts +1 -1
- package/dist/lint/policy-import.d.ts.map +1 -1
- package/dist/lint/policy-import.js +62 -0
- package/dist/lint/policy-sandbox.js +86 -0
- package/dist/lint/policy.js +122 -0
- package/dist/lint/post-synth.js +87 -0
- package/dist/lint/presets/relaxed.json +26 -0
- package/dist/lint/presets/strict.json +24 -24
- package/dist/lint/receipt-checks.js +83 -0
- package/dist/lint/rule-loader.d.ts.map +1 -1
- package/dist/lint/rule-loader.js +89 -0
- package/dist/lint/rule-registry.js +86 -0
- package/dist/lint/rule.js +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
- package/dist/lint/rules/comp/index.js +33 -0
- package/dist/lint/rules/comp/support.js +129 -0
- package/dist/lint/rules/composite-scope.js +51 -0
- package/dist/lint/rules/cor017-composite-name-match.js +93 -0
- package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
- package/dist/lint/rules/cor021-env-literal-name.js +100 -0
- package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
- package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
- package/dist/lint/rules/declarable-naming-convention.js +62 -0
- package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
- package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
- package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
- package/dist/lint/rules/evl004-spread-non-const.js +94 -0
- package/dist/lint/rules/evl005-resource-block-body.js +41 -0
- package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
- package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
- package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
- package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
- package/dist/lint/rules/export-required.js +115 -0
- package/dist/lint/rules/file-declarable-limit.js +88 -0
- package/dist/lint/rules/flat-declarations.js +62 -0
- package/dist/lint/rules/index.js +90 -0
- package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
- package/dist/lint/rules/no-redundant-type-import.js +76 -0
- package/dist/lint/rules/no-redundant-value-cast.js +41 -0
- package/dist/lint/rules/no-string-ref.js +59 -0
- package/dist/lint/rules/no-unused-declarable-import.js +75 -0
- package/dist/lint/rules/no-unused-declarable.js +142 -0
- package/dist/lint/rules/op/index.js +28 -0
- package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
- package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
- package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
- package/dist/lint/rules/op/support.js +11 -0
- package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
- package/dist/lint/rules/property-kind.js +56 -0
- package/dist/lint/rules/single-concern-file.js +71 -0
- package/dist/lint/rules/sys001-no-literal-key.js +60 -0
- package/dist/lint/selectors.js +168 -0
- package/dist/lint/suppressions.js +129 -0
- package/dist/lint/typescript.js +17 -0
- package/dist/live-endpoint.js +113 -0
- package/dist/live-read-session.js +76 -0
- package/dist/lsp/lexicon-providers.js +163 -0
- package/dist/lsp/types.js +5 -0
- package/dist/managed-fields.js +293 -0
- package/dist/mcp/types.js +4 -0
- package/dist/notify-verify.js +0 -1
- package/dist/notify.js +0 -1
- package/dist/notify.schema.json +72 -0
- package/dist/observation.js +266 -0
- package/dist/okf-read.js +134 -0
- package/dist/okf.js +275 -0
- package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
- package/dist/op/activities/activity-contracts.d.ts +1 -1
- package/dist/op/activities/activity-contracts.js +313 -0
- package/dist/op/activities/apply.js +582 -0
- package/dist/op/activities/build.js +18 -0
- package/dist/op/activities/change-coverage.js +40 -0
- package/dist/op/activities/change-set.d.ts +8 -3
- package/dist/op/activities/change-set.d.ts.map +1 -1
- package/dist/op/activities/change-set.js +67 -0
- package/dist/op/activities/converge.js +492 -0
- package/dist/op/activities/decide.js +211 -0
- package/dist/op/activities/env-teardown.js +110 -0
- package/dist/op/activities/factory.js +591 -0
- package/dist/op/activities/forge-pull-request.js +82 -0
- package/dist/op/activities/gh-host.js +78 -0
- package/dist/op/activities/guard-validate.js +165 -0
- package/dist/op/activities/http-check.js +40 -0
- package/dist/op/activities/index.js +59 -0
- package/dist/op/activities/lexicon-upgrade.js +629 -0
- package/dist/op/activities/lifecycle.js +109 -0
- package/dist/op/activities/pipeline-audit.js +147 -0
- package/dist/op/activities/policy.js +26 -0
- package/dist/op/activities/predict-behaviour.js +341 -0
- package/dist/op/activities/propose-upgrade.js +165 -0
- package/dist/op/activities/reconcile.d.ts +28 -16
- package/dist/op/activities/reconcile.d.ts.map +1 -1
- package/dist/op/activities/reconcile.js +1011 -0
- package/dist/op/activities/shell.js +118 -0
- package/dist/op/activities/source-release.js +97 -0
- package/dist/op/activities/source-rollback.js +165 -0
- package/dist/op/activities/teardown.js +17 -0
- package/dist/op/activities/util.js +6 -0
- package/dist/op/activities/wait.js +51 -0
- package/dist/op/activities/work-evidence.js +35 -0
- package/dist/op/activities/workflow-audit.js +133 -0
- package/dist/op/activity-contract-registry.js +106 -0
- package/dist/op/activity-contract.js +232 -0
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/activity-profiles.js +129 -0
- package/dist/op/activity-registry.js +105 -0
- package/dist/op/activity-runtime.js +28 -0
- package/dist/op/builders.d.ts +1 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +801 -0
- package/dist/op/change-signal.js +118 -0
- package/dist/op/composites/apply-op.js +151 -0
- package/dist/op/composites/behaviour-op.js +65 -0
- package/dist/op/composites/converge-op.js +141 -0
- package/dist/op/composites/index.js +19 -0
- package/dist/op/composites/lexicon-upgrade-op.js +107 -0
- package/dist/op/composites/pipeline-audit-op.js +50 -0
- package/dist/op/composites/reconcile-op.js +84 -0
- package/dist/op/composites/watch-op.js +69 -0
- package/dist/op/composites/workflow-audit-op.js +57 -0
- package/dist/op/converge-rule.js +205 -0
- package/dist/op/cron.js +146 -0
- package/dist/op/decide-backend.js +181 -0
- package/dist/op/decide-config.js +68 -0
- package/dist/op/decide-read-inputs.js +141 -0
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/discover.js +213 -0
- package/dist/op/duration.js +21 -0
- package/dist/op/emulator-freshness.js +80 -0
- package/dist/op/emulator-lifecycle.js +269 -0
- package/dist/op/factory.js +83 -0
- package/dist/op/gate-approval.js +172 -0
- package/dist/op/gate-name.js +86 -0
- package/dist/op/gate-plan-context.js +167 -0
- package/dist/op/gate-point-run.js +67 -0
- package/dist/op/gate-point.js +111 -0
- package/dist/op/gate-resume-plan.js +155 -0
- package/dist/op/gate-resume.js +31 -0
- package/dist/op/gate-review.js +290 -0
- package/dist/op/gate-run-locator.js +85 -0
- package/dist/op/gate-summary.js +100 -0
- package/dist/op/gate-wait.js +56 -0
- package/dist/op/gate.js +449 -0
- package/dist/op/generate-pipeline.js +124 -0
- package/dist/op/index.js +51 -0
- package/dist/op/lifecycle-receipt-store.js +45 -0
- package/dist/op/local-executor.js +1164 -0
- package/dist/op/local-output.js +140 -0
- package/dist/op/op-ir.js +317 -0
- package/dist/op/op-verb-class.js +131 -0
- package/dist/op/op-waves-notify.js +136 -0
- package/dist/op/op-waves-run.d.ts +1 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +1657 -0
- package/dist/op/op-waves.js +409 -0
- package/dist/op/operator.js +743 -0
- package/dist/op/receipt-store.js +94 -0
- package/dist/op/resource.js +23 -0
- package/dist/op/run-context.js +28 -0
- package/dist/op/run-live.js +256 -0
- package/dist/op/runtime.js +21 -0
- package/dist/op/runtimes/local.js +195 -0
- package/dist/op/source-archive.js +131 -0
- package/dist/op/step-output-ref.js +397 -0
- package/dist/op/steward-beside.js +169 -0
- package/dist/op/steward-points.js +138 -0
- package/dist/op/steward-turn.js +59 -0
- package/dist/op/steward.js +317 -0
- package/dist/op/types.js +25 -0
- package/dist/op/work-lease-decl.js +81 -0
- package/dist/op/work-lease-run.js +393 -0
- package/dist/override-gate.js +284 -0
- package/dist/owner-chain.js +74 -0
- package/dist/ownership.js +92 -0
- package/dist/params.js +61 -0
- package/dist/plan-summary.js +711 -0
- package/dist/point-decision.js +211 -0
- package/dist/pr-forge.js +810 -0
- package/dist/pr-loop.js +203 -0
- package/dist/project-codegen.js +191 -0
- package/dist/project-root.js +74 -0
- package/dist/project-validation.js +50 -0
- package/dist/provenance.js +157 -0
- package/dist/pseudo-parameter.js +40 -0
- package/dist/reconcile.js +450 -0
- package/dist/resource-attributes.js +33 -0
- package/dist/runtime-adapter.js +77 -0
- package/dist/runtime.js +66 -0
- package/dist/secret-materialization.js +153 -0
- package/dist/secret-provenance.js +250 -0
- package/dist/serializer-walker.js +112 -0
- package/dist/serializer.js +1 -0
- package/dist/sort.js +45 -0
- package/dist/stack-output.js +115 -0
- package/dist/telemetry-attribution.js +149 -0
- package/dist/terraform/__fixtures__/build-graph.js +63 -0
- package/dist/terraform/adopt-state.js +40 -0
- package/dist/terraform/aws-resources.js +384 -0
- package/dist/terraform/bridge.js +204 -0
- package/dist/terraform/carve-provider.js +155 -0
- package/dist/terraform/carve.js +138 -0
- package/dist/terraform/data-source-shape.js +57 -0
- package/dist/terraform/emit-source.js +36 -0
- package/dist/terraform/excise.js +123 -0
- package/dist/terraform/graduate.js +128 -0
- package/dist/terraform/graph.js +435 -0
- package/dist/terraform/hcl2json.js +60 -0
- package/dist/terraform/manifest.js +149 -0
- package/dist/terraform/parse.js +81 -0
- package/dist/terraform/providers/aws.js +146 -0
- package/dist/terraform/providers/gcp.js +294 -0
- package/dist/terraform/providers/index.js +17 -0
- package/dist/terraform/providers/kubernetes.js +253 -0
- package/dist/terraform/score.js +151 -0
- package/dist/terraform/state.js +67 -0
- package/dist/terraform/tier-map.js +74 -0
- package/dist/terraform/types.js +13 -0
- package/dist/terraform/unified-diff.js +132 -0
- package/dist/testing.js +295 -0
- package/dist/toml-emit.js +153 -0
- package/dist/toml-parse.js +355 -0
- package/dist/toml-utils.js +60 -0
- package/dist/toml.js +428 -0
- package/dist/ts-loader.d.ts +46 -0
- package/dist/ts-loader.d.ts.map +1 -0
- package/dist/ts-loader.js +103 -0
- package/dist/types.js +1 -0
- package/dist/utils.js +61 -0
- package/dist/validation.js +20 -0
- package/dist/vendor/js-yaml-load.js +1662 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts +7 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.js +119 -0
- package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
- package/dist/workspace/__fixtures__/sessions.d.ts +1 -1
- package/dist/workspace/__fixtures__/sessions.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/sessions.js +91 -0
- package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
- package/dist/workspace/agent-cli.js +99 -0
- package/dist/workspace/agent.schema.json +390 -0
- package/dist/workspace/answers-ledger.js +89 -0
- package/dist/workspace/box-cli.js +142 -0
- package/dist/workspace/box-factory-write.js +196 -0
- package/dist/workspace/box-factory-write.schema.json +342 -0
- package/dist/workspace/box-factory.js +88 -0
- package/dist/workspace/box-intent.js +126 -0
- package/dist/workspace/box-isolation.js +169 -0
- package/dist/workspace/box-listing-write.schema.json +204 -0
- package/dist/workspace/box-listing.js +298 -0
- package/dist/workspace/box-publish.js +352 -0
- package/dist/workspace/box-publish.schema.json +498 -0
- package/dist/workspace/box-services.js +39 -0
- package/dist/workspace/broker-protocol.js +359 -0
- package/dist/workspace/broker-protocol.schema.json +228 -0
- package/dist/workspace/change-set.schema.json +462 -0
- package/dist/workspace/changes-cli.js +56 -0
- package/dist/workspace/changes.js +446 -0
- package/dist/workspace/changes.schema.json +642 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
- package/dist/workspace/chant-migrations.js +113 -0
- package/dist/workspace/check.schema.json +433 -0
- package/dist/workspace/checks/box-isolation.js +62 -0
- package/dist/workspace/checks/boxes.js +491 -0
- package/dist/workspace/checks/diagrams.js +104 -0
- package/dist/workspace/checks/generated.js +419 -0
- package/dist/workspace/checks/ledgers.js +212 -0
- package/dist/workspace/checks/links.js +191 -0
- package/dist/workspace/checks/live.js +100 -0
- package/dist/workspace/checks/pipelines.js +188 -0
- package/dist/workspace/checks/records.js +169 -0
- package/dist/workspace/checks.js +426 -0
- package/dist/workspace/ci-green-cli.js +125 -0
- package/dist/workspace/ci-green-forge.js +83 -0
- package/dist/workspace/ci-green-workflow.d.ts +3 -1
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +202 -0
- package/dist/workspace/ci-green.js +325 -0
- package/dist/workspace/ci-last-green.schema.json +158 -0
- package/dist/workspace/class-data.d.ts +84 -0
- package/dist/workspace/class-data.d.ts.map +1 -0
- package/dist/workspace/class-data.js +238 -0
- package/dist/workspace/compose-graph.js +235 -0
- package/dist/workspace/compose-reports.js +146 -0
- package/dist/workspace/composites.js +264 -0
- package/dist/workspace/composites.schema.json +617 -0
- package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
- package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
- package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
- package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
- package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
- package/dist/workspace/conformance/broker.js +736 -0
- package/dist/workspace/conformance/index.js +673 -0
- package/dist/workspace/conformance/vitest.js +108 -0
- package/dist/workspace/conformance/writer.js +1080 -0
- package/dist/workspace/decide.js +879 -0
- package/dist/workspace/decision-points.schema.json +135 -135
- package/dist/workspace/declaration-write-cli.js +74 -0
- package/dist/workspace/declaration-write.js +238 -0
- package/dist/workspace/declaration.js +938 -0
- package/dist/workspace/declaration.schema.json +1413 -1413
- package/dist/workspace/declared-kinds.js +106 -0
- package/dist/workspace/environments.js +164 -0
- package/dist/workspace/evidence.schema.json +279 -0
- package/dist/workspace/export-cli.js +185 -0
- package/dist/workspace/export.js +499 -0
- package/dist/workspace/factory-rules.js +175 -0
- package/dist/workspace/generated-files.js +92 -0
- package/dist/workspace/glob.js +45 -0
- package/dist/workspace/graph-cache.js +352 -0
- package/dist/workspace/graph-cli.js +348 -0
- package/dist/workspace/graph.schema.json +1338 -0
- package/dist/workspace/identity-gate-rule.js +75 -0
- package/dist/workspace/identity.js +126 -0
- package/dist/workspace/import.js +283 -0
- package/dist/workspace/init.js +620 -0
- package/dist/workspace/intent-cli.js +263 -0
- package/dist/workspace/intent-joins.js +201 -0
- package/dist/workspace/intent-record.js +352 -0
- package/dist/workspace/intent-record.schema.json +864 -0
- package/dist/workspace/intent.js +1582 -0
- package/dist/workspace/intent.schema.json +2420 -0
- package/dist/workspace/json-edit.js +221 -0
- package/dist/workspace/jsonc.js +235 -0
- package/dist/workspace/kind-readers.js +103 -0
- package/dist/workspace/kinds.d.ts +3 -7
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/kinds.js +553 -0
- package/dist/workspace/lexicon-symbols.js +112 -0
- package/dist/workspace/lineage-adopt-cli.js +102 -0
- package/dist/workspace/lineage-adopt.js +360 -0
- package/dist/workspace/lineage-check.js +282 -0
- package/dist/workspace/lineage-cli.js +121 -0
- package/dist/workspace/lineage-hash-index.js +284 -0
- package/dist/workspace/lineage-init.js +507 -0
- package/dist/workspace/lineage-lock.js +387 -0
- package/dist/workspace/lineage-merge.js +45 -0
- package/dist/workspace/lineage-migrations.d.ts.map +1 -1
- package/dist/workspace/lineage-migrations.js +329 -0
- package/dist/workspace/lineage-provenance.js +36 -0
- package/dist/workspace/lineage-update.js +138 -0
- package/dist/workspace/lineage-upgrade-cli.js +131 -0
- package/dist/workspace/lineage-upgrade.js +889 -0
- package/dist/workspace/lineage-vendor.js +171 -0
- package/dist/workspace/lineage-version.js +128 -0
- package/dist/workspace/lineage-versions.js +275 -0
- package/dist/workspace/links.js +330 -0
- package/dist/workspace/ls-generated.js +95 -0
- package/dist/workspace/ls.js +277 -0
- package/dist/workspace/ls.schema.json +333 -0
- package/dist/workspace/member-commands.js +508 -0
- package/dist/workspace/member-handles.js +216 -0
- package/dist/workspace/member-pipeline.js +258 -0
- package/dist/workspace/member-run.js +117 -0
- package/dist/workspace/member-write.schema.json +193 -0
- package/dist/workspace/nested-graph.js +156 -0
- package/dist/workspace/nesting.js +38 -0
- package/dist/workspace/patch.js +301 -0
- package/dist/workspace/patch.schema.json +321 -0
- package/dist/workspace/pin-cli.js +55 -0
- package/dist/workspace/pin-integrity.js +100 -0
- package/dist/workspace/plan-summary.schema.json +155 -0
- package/dist/workspace/point-answer.schema.json +129 -129
- package/dist/workspace/points-cli.js +291 -0
- package/dist/workspace/points-write.schema.json +660 -0
- package/dist/workspace/points.js +521 -0
- package/dist/workspace/points.schema.json +916 -0
- package/dist/workspace/pr-report.schema.json +108 -0
- package/dist/workspace/principal-classes.d.ts +4 -11
- package/dist/workspace/principal-classes.d.ts.map +1 -1
- package/dist/workspace/principal-classes.js +162 -0
- package/dist/workspace/reason-codes.js +326 -0
- package/dist/workspace/record-assets.js +151 -0
- package/dist/workspace/record-decided.js +105 -0
- package/dist/workspace/record-sessions.js +96 -0
- package/dist/workspace/record-source.js +114 -0
- package/dist/workspace/records-amend.schema.json +284 -0
- package/dist/workspace/records-checkout.js +76 -0
- package/dist/workspace/records-cli.js +707 -0
- package/dist/workspace/records-close.js +116 -0
- package/dist/workspace/records-close.schema.json +278 -0
- package/dist/workspace/records-new.schema.json +202 -0
- package/dist/workspace/records-review.schema.json +367 -0
- package/dist/workspace/records-since.js +317 -0
- package/dist/workspace/records-since.schema.json +218 -0
- package/dist/workspace/records-write.js +1229 -0
- package/dist/workspace/records.js +1345 -0
- package/dist/workspace/records.schema.json +604 -0
- package/dist/workspace/reference-kinds/app/package.json +10 -0
- package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/dist/workspace/returns.js +303 -0
- package/dist/workspace/root-refusal.js +75 -0
- package/dist/workspace/run-statement.schema.json +622 -0
- package/dist/workspace/runs-cli.js +584 -0
- package/dist/workspace/runs-write.schema.json +994 -0
- package/dist/workspace/runs.js +708 -0
- package/dist/workspace/runs.schema.json +1257 -0
- package/dist/workspace/runtimes.js +76 -0
- package/dist/workspace/session-kinds.js +83 -0
- package/dist/workspace/signers.schema.json +206 -0
- package/dist/workspace/source-block.js +125 -0
- package/dist/workspace/squash.js +177 -0
- package/dist/workspace/status-gates.js +162 -0
- package/dist/workspace/status-stewards.js +330 -0
- package/dist/workspace/status.js +514 -0
- package/dist/workspace/status.schema.json +998 -0
- package/dist/workspace/steward-index.js +191 -0
- package/dist/workspace/symbols.js +188 -0
- package/dist/workspace/template-manifest.js +227 -0
- package/dist/workspace/template-pins.js +115 -0
- package/dist/workspace/trailer-joins.js +65 -0
- package/dist/workspace/trailers.js +111 -0
- package/dist/workspace/tree.js +136 -0
- package/dist/workspace/trust/attestor.js +63 -0
- package/dist/workspace/trust/dsse.js +108 -0
- package/dist/workspace/trust/evidence-cli.js +175 -0
- package/dist/workspace/trust/evidence.js +161 -0
- package/dist/workspace/trust/gate-seal.js +226 -0
- package/dist/workspace/trust/policy.js +190 -0
- package/dist/workspace/trust/provenance.js +180 -0
- package/dist/workspace/trust/rotation.js +298 -0
- package/dist/workspace/trust/run-commits.js +101 -0
- package/dist/workspace/trust/run-statement.js +182 -0
- package/dist/workspace/trust/seal.js +272 -0
- package/dist/workspace/trust/signers-cli.js +152 -0
- package/dist/workspace/trust/ssh-commit.js +178 -0
- package/dist/workspace/trust/test-repo.js +118 -0
- package/dist/workspace/trust/trust-files.js +193 -0
- package/dist/workspace/trust/verify-cli.js +63 -0
- package/dist/workspace/trust/verify.js +192 -0
- package/dist/workspace/which-chant.js +141 -0
- package/dist/workspace/wip-cli.js +95 -0
- package/dist/workspace/wip-write.schema.json +504 -0
- package/dist/workspace/wip.js +631 -0
- package/dist/workspace/wip.schema.json +334 -0
- package/dist/workspace/work-cli.js +448 -0
- package/dist/workspace/work-evidence.js +122 -0
- package/dist/workspace/work-evidence.schema.json +222 -0
- package/dist/workspace/work-history.schema.json +421 -0
- package/dist/workspace/work-lease.schema.json +246 -0
- package/dist/workspace/work-size.js +77 -0
- package/dist/workspace/work.js +283 -0
- package/dist/workspace/workspace-kinds.schema.json +259 -259
- package/dist/workspace/workspace-principals.schema.json +53 -53
- package/dist/workspace/write-lock-cli.js +105 -0
- package/dist/workspace/write-lock.js +424 -0
- package/dist/workspace/write-lock.schema.json +172 -0
- package/dist/workspace/write-scope.js +484 -0
- package/dist/yaml.js +459 -0
- package/package.json +2 -2
- package/src/build.ts +8 -0
- package/src/change-set.test.ts +48 -0
- package/src/change-set.ts +52 -2
- package/src/ci-jobs.test.ts +49 -0
- package/src/ci-jobs.ts +515 -0
- package/src/cli/commands/check-lexicon-plugin.ts +2 -0
- package/src/cli/commands/lint.ts +3 -0
- package/src/cli/commands/migrate.ts +2 -0
- package/src/cli/compiled-cli.e2e.test.ts +165 -0
- package/src/cli/main.ts +121 -27
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/codegen/pinned-upgrade.ts +2 -0
- package/src/components/discover.ts +2 -0
- package/src/components/pr-pipeline.ts +3 -2
- package/src/components/sandbox/driver.ts +3 -1
- package/src/composite.ts +15 -3
- package/src/config-import.ts +3 -0
- package/src/discovery/collect.ts +15 -1
- package/src/discovery/fold-build-parity.test.ts +71 -0
- package/src/discovery/fold-import.ts +25 -127
- package/src/discovery/fold-project-provenance.test.ts +21 -4
- package/src/discovery/host-composite.ts +101 -0
- package/src/discovery/import.ts +2 -0
- package/src/discovery/index.ts +11 -1
- package/src/discovery/sandbox/driver.ts +3 -1
- package/src/gate-decision-bundle.test.ts +5 -4
- package/src/gate-decision-identity.test.ts +59 -6
- package/src/gate-decision.ts +81 -21
- package/src/lexicon-module.ts +3 -0
- package/src/lifecycle/gate-audit.test.ts +55 -1
- package/src/lifecycle/gate-audit.ts +116 -3
- package/src/lifecycle/gate-ledger.test.ts +20 -1
- package/src/lifecycle/gate-ledger.ts +33 -1
- package/src/lint/config.ts +1 -1
- package/src/lint/discover.ts +28 -8
- package/src/lint/policy-import.ts +4 -1
- package/src/lint/rule-loader.ts +2 -0
- package/src/op/activities/activity-contracts.ts +1 -1
- package/src/op/activities/change-set.ts +11 -3
- package/src/op/activities/lexicon-upgrade.test.ts +2 -0
- package/src/op/activities/reconcile.test.ts +62 -2
- package/src/op/activities/reconcile.ts +46 -22
- package/src/op/builders.ts +1 -1
- package/src/op/discover.ts +3 -0
- package/src/op/op-waves-run.ts +4 -3
- package/src/op/op-waves.test.ts +2 -0
- package/src/op/work-lease-run.test.ts +12 -4
- package/src/ts-loader.test.ts +23 -0
- package/src/ts-loader.ts +122 -0
- package/src/workspace/__fixtures__/contract-repo.ts +17 -1
- package/src/workspace/__fixtures__/sessions.ts +3 -3
- package/src/workspace/change-set.schema.json +5 -3
- package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
- package/src/workspace/ci-green-workflow.test.ts +4 -4
- package/src/workspace/ci-green-workflow.ts +5 -2
- package/src/workspace/class-data.test.ts +64 -0
- package/src/workspace/class-data.ts +236 -0
- package/src/workspace/declaration.ts +1 -1
- package/src/workspace/kinds.ts +7 -36
- package/src/workspace/lineage-migrations.ts +2 -0
- package/src/workspace/points.ts +1 -1
- package/src/workspace/principal-classes.ts +12 -95
- package/src/workspace/records-formats.test.ts +7 -2
- package/src/workspace/records-sessions-write.test.ts +3 -3
- package/src/workspace/status-contract.e2e.test.ts +37 -0
- package/src/workspace/status-contract.test.ts +23 -21
package/src/gate-decision.ts
CHANGED
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
*
|
|
19
19
|
* A gate the declaration at base names under `identity.gates` counts only a
|
|
20
20
|
* sealed approval from its class: {@link identityGateAdmissionAt} reads that
|
|
21
|
-
* rule from a bare clone at base
|
|
22
|
-
*
|
|
21
|
+
* rule from a bare clone at base, with the principal classes the pinned
|
|
22
|
+
* packages supply read as data (#3888), and judges by `admitApprover`, the
|
|
23
|
+
* function chant's `gateAdmission` judges by (#3862); pass its `refuses` to
|
|
23
24
|
* {@link decideGateApproval}.
|
|
24
25
|
*
|
|
25
26
|
* With `spend` (#3784), an approval a wave already applied under is spent and
|
|
@@ -27,14 +28,17 @@
|
|
|
27
28
|
* the lines of `_gates/<op>/applied.jsonl` ({@link parseAppliedGateLines}).
|
|
28
29
|
*
|
|
29
30
|
* The module reads the ledger lines and the review it is handed; reading
|
|
30
|
-
* them is the caller's. It imports no TypeScript, esbuild, zod, lint,
|
|
31
|
-
* codegen module, and none of chant's git ledger
|
|
31
|
+
* them is the caller's. It imports no TypeScript, esbuild, zod, ajv, lint,
|
|
32
|
+
* fold or codegen module, no package's code, and none of chant's git ledger
|
|
33
|
+
* code, which
|
|
32
34
|
* `gate-decision-bundle.test.ts` holds it to. Its rules are chant's own:
|
|
33
35
|
* `./lifecycle/gate-ledger-select.ts` is what `evaluateGate` decides by, and
|
|
34
36
|
* `gate-decision.test.ts` decides the same ledgers both ways.
|
|
35
37
|
*/
|
|
36
38
|
|
|
37
39
|
import { spawnSync } from "node:child_process";
|
|
40
|
+
import { readFileSync } from "node:fs";
|
|
41
|
+
import { join, posix } from "node:path";
|
|
38
42
|
import {
|
|
39
43
|
isPendingGateExpired,
|
|
40
44
|
latestPendingGate,
|
|
@@ -50,7 +54,8 @@ import {
|
|
|
50
54
|
trustConfigProblems,
|
|
51
55
|
} from "./workspace/trust/trust-files";
|
|
52
56
|
import { parseJsonText } from "./workspace/jsonc";
|
|
53
|
-
import { CORE_CLASSES, admitApprover, type ClassGrant, type GateAdmissionRule } from "./workspace/identity-gate-rule";
|
|
57
|
+
import { CORE_CLASSES, admitApprover, type ClassGrant, type GateAdmissionRule, type PrincipalClass } from "./workspace/identity-gate-rule";
|
|
58
|
+
import { diskFiles, findInstalledPackage, mergePinClasses, parseClassDataByHand, readClassFiles, type PinClassRead } from "./workspace/class-data";
|
|
54
59
|
import type { GateResolutionRecord, PendingGateRecord } from "./lifecycle/gate-ledger";
|
|
55
60
|
import type { MergedReview } from "./op/gate-review";
|
|
56
61
|
import type { GateApprovalSource } from "./op/op-waves";
|
|
@@ -207,6 +212,56 @@ export interface IdentityGateAdmission {
|
|
|
207
212
|
refuses(approval: SealedGateApproval): string | null;
|
|
208
213
|
}
|
|
209
214
|
|
|
215
|
+
/** The domain classes the pins of the declaration at base supply, as chant's `loadClassRegistry` reads them, and the pins that could not be read. */
|
|
216
|
+
interface PinnedClasses {
|
|
217
|
+
classes: PrincipalClass[];
|
|
218
|
+
/** Pins whose classes are not known, one line each: a package pin that is not installed, or not at its pinned version. */
|
|
219
|
+
unread: string[];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Read the classes each pin supplies, as chant's `gateAdmission(cwd, gate,
|
|
224
|
+
* base)` reads them: a path pin's `./workspace-principals` file from `base`
|
|
225
|
+
* itself, so a change can't remap a class by editing its own copy of the
|
|
226
|
+
* plugin; a package pin's from the package installed under `packages` (its
|
|
227
|
+
* `node_modules` or a parent's), which must be at the pinned version. Reads
|
|
228
|
+
* data only and imports no package.
|
|
229
|
+
*/
|
|
230
|
+
function pinnedClassesAt(repo: string, base: string, pins: unknown, packages: string): PinnedClasses {
|
|
231
|
+
const reads: PinClassRead[] = [];
|
|
232
|
+
const unread: string[] = [];
|
|
233
|
+
(Array.isArray(pins) ? pins : []).forEach((raw: unknown, i) => {
|
|
234
|
+
const pin = (raw !== null && typeof raw === "object" ? raw : {}) as { package?: unknown; version?: unknown; path?: unknown };
|
|
235
|
+
if (typeof pin.path === "string" && pin.path) {
|
|
236
|
+
const dir = posix.normalize(pin.path);
|
|
237
|
+
const files = (path: string) => showAt(repo, base, dir === "." ? path : posix.join(dir, path));
|
|
238
|
+
reads.push({ pin: i, source: pin.path, read: readClassFiles(files, pin.path, parseClassDataByHand) });
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (typeof pin.package !== "string" || !pin.package) return;
|
|
242
|
+
const dir = findInstalledPackage(pin.package, packages);
|
|
243
|
+
if (!dir) {
|
|
244
|
+
unread.push(`${pin.package} is not installed under ${packages}`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
let installed: unknown;
|
|
248
|
+
try {
|
|
249
|
+
installed = (JSON.parse(readFileSync(join(dir, "package.json"), "utf-8")) as { version?: unknown }).version;
|
|
250
|
+
} catch {
|
|
251
|
+
installed = undefined;
|
|
252
|
+
}
|
|
253
|
+
if (typeof pin.version === "string" && pin.version && installed !== pin.version) {
|
|
254
|
+
unread.push(`${pin.package} is pinned at ${pin.version}, and ${String(installed ?? "an unknown version")} is installed under ${packages}`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
reads.push({ pin: i, source: pin.package, read: readClassFiles(diskFiles(dir), pin.package, parseClassDataByHand) });
|
|
258
|
+
});
|
|
259
|
+
return { classes: mergePinClasses(reads).classes, unread };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/** The core classes whose members no domain class can change: every one but `human`, which is the principals in no other class. */
|
|
263
|
+
const PIN_FREE = new Set(CORE_CLASSES.filter((c) => c.role !== null).map((c) => c.name));
|
|
264
|
+
|
|
210
265
|
/**
|
|
211
266
|
* The `identity.gates` rule for `gate` at `base`, or null when the
|
|
212
267
|
* declaration there names none: what chant's `gateAdmission(cwd, gate, base)`
|
|
@@ -215,34 +270,39 @@ export interface IdentityGateAdmission {
|
|
|
215
270
|
* class, the role grants in `.chant/trust.json` at base put the approver in
|
|
216
271
|
* it. Both judge with the same function ({@link admitApprover}).
|
|
217
272
|
*
|
|
218
|
-
* The classes are the four core ones, then
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
273
|
+
* The classes are the four core ones, then the domain classes the
|
|
274
|
+
* declaration's pins supply, in pin order (#3888), read as chant reads them:
|
|
275
|
+
* a path pin's `./workspace-principals` file at `base`, and a package pin's
|
|
276
|
+
* from the package installed under `packages` (default `repo`) at the
|
|
277
|
+
* pinned version. A bare clone has no `node_modules`, so a caller that reads
|
|
278
|
+
* one passes the directory its packages are installed under. Only data is
|
|
279
|
+
* read; no package is imported. `classes`, when given, stands for every
|
|
280
|
+
* domain class instead and no pin is read.
|
|
281
|
+
*
|
|
282
|
+
* When a pin can't be read (its package is not installed, or not at the
|
|
283
|
+
* pinned version), a gate whose class it could change (a domain class, or
|
|
284
|
+
* `human`) refuses every approval and says which pins were not read; a gate
|
|
285
|
+
* naming `agent`, `runner` or `service`, or no class, is judged as usual.
|
|
223
286
|
* Throws when the declaration at base cannot be parsed.
|
|
224
287
|
*/
|
|
225
288
|
export function identityGateAdmissionAt(
|
|
226
289
|
repo: string,
|
|
227
290
|
base: string,
|
|
228
291
|
gate: string,
|
|
229
|
-
opts: { classes?: readonly ClassGrant[] } = {},
|
|
292
|
+
opts: { classes?: readonly ClassGrant[]; packages?: string } = {},
|
|
230
293
|
): IdentityGateAdmission | null {
|
|
231
294
|
const declaration = declarationAt(repo, base);
|
|
232
295
|
const requirement = declaration === null ? undefined : identityGatesOf(declaration.value).find((g) => g.gate === gate);
|
|
233
296
|
if (!requirement) return null;
|
|
234
297
|
const { signers, roles } = trustAt(repo, base);
|
|
235
298
|
const pins = (declaration!.value as { pins?: unknown }).pins;
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
? { unknownClass: `is not a core class, and this reader does not load the classes the pinned packages in ${declaration!.file} at base supply` }
|
|
244
|
-
: {}),
|
|
245
|
-
};
|
|
299
|
+
const pinned = opts.classes ? { classes: opts.classes, unread: [] } : pinnedClassesAt(repo, base, pins, opts.packages ?? repo);
|
|
300
|
+
const want = requirement.class;
|
|
301
|
+
if (want !== null && !PIN_FREE.has(want) && pinned.unread.length > 0) {
|
|
302
|
+
const reason = `identity.gates.${gate} names the class ${want}, and the pins in ${declaration!.file} at base could not all be read, so no approval can show it is in that class: ${pinned.unread.join("; ")}`;
|
|
303
|
+
return { requirement, refuses: () => reason };
|
|
304
|
+
}
|
|
305
|
+
const rule: GateAdmissionRule = { gate, class: want, signers, roles, classes: [...CORE_CLASSES, ...pinned.classes] };
|
|
246
306
|
return { requirement, refuses: (a) => admitApprover(rule, a) };
|
|
247
307
|
}
|
|
248
308
|
|
package/src/lexicon-module.ts
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
import { createRequire } from "node:module";
|
|
28
28
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
29
29
|
import { pathToFileURL } from "node:url";
|
|
30
|
+
import { ensureTypeScriptLoader } from "./ts-loader";
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* One `lexicons` entry: a package-backed name, or a name plus the module that
|
|
@@ -179,6 +180,7 @@ export async function importLexiconModule(name: string): Promise<Record<string,
|
|
|
179
180
|
const path = modulePaths.get(name);
|
|
180
181
|
if (path === undefined) return undefined;
|
|
181
182
|
try {
|
|
183
|
+
ensureTypeScriptLoader();
|
|
182
184
|
return (await import(path)) as Record<string, unknown>;
|
|
183
185
|
} catch (err) {
|
|
184
186
|
throw new Error(
|
|
@@ -259,6 +261,7 @@ export function resolveFromProject(spec: string, fromDir: string = process.cwd()
|
|
|
259
261
|
*/
|
|
260
262
|
export async function importLexiconPackage(spec: string, fromDir: string = process.cwd()): Promise<Record<string, unknown>> {
|
|
261
263
|
try {
|
|
264
|
+
ensureTypeScriptLoader();
|
|
262
265
|
return (await import(spec)) as Record<string, unknown>;
|
|
263
266
|
} catch (err) {
|
|
264
267
|
const pkg = packageNameOf(spec);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, test, expect } from "vitest";
|
|
2
|
-
import { deriveGateAudit, gateLedgerLines, gateLedgerLinesFromLog, readGateAuditLedgers, isOverrideGate } from "./gate-audit";
|
|
2
|
+
import { readGateAuditDecisions, deriveGateAudit, gateLedgerLines, gateLedgerLinesFromLog, readGateAuditLedgers, isOverrideGate } from "./gate-audit";
|
|
3
3
|
import { memoryGateLedgerPort } from "../op/gate";
|
|
4
4
|
|
|
5
5
|
const D1 = "jcs1-sha256:" + "a".repeat(64);
|
|
@@ -12,6 +12,15 @@ const resolution = (o: Record<string, unknown> = {}) =>
|
|
|
12
12
|
const ledger = (op: string, ...texts: string[]) => ({ op, lines: texts.map((text) => ({ text })) });
|
|
13
13
|
|
|
14
14
|
describe("lifecycle/gate-audit", () => {
|
|
15
|
+
test("a hold's heldBy and approvalMode are surfaced (#3886, #3887)", () => {
|
|
16
|
+
const { entries } = deriveGateAudit({ ledgers: [ledger("tf-apply", pending({ approvalMode: "sealed", heldBy: { hook: "migrate", moment: "before-apply", target: "vpc" } }))] });
|
|
17
|
+
expect(entries[0]).toMatchObject({ approvalMode: "sealed", heldBy: { hook: "migrate", moment: "before-apply", target: "vpc" } });
|
|
18
|
+
expect(entries[0]!.detail).toEqual({});
|
|
19
|
+
const bad = deriveGateAudit({ ledgers: [ledger("tf-apply", pending({ approvalMode: "x", heldBy: { hook: 1 } }))] });
|
|
20
|
+
expect(bad.entries[0]!.heldBy).toBeUndefined();
|
|
21
|
+
expect(bad.entries[0]!.approvalMode).toBeUndefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
15
24
|
test("a pending fact's wave is surfaced (#3839)", () => {
|
|
16
25
|
const { entries } = deriveGateAudit({ ledgers: [ledger("tf-apply", pending({ wave: { number: 2, name: "prod", op: "tg" } }))] });
|
|
17
26
|
expect(entries[0]).toMatchObject({ wave: { number: 2, name: "prod", op: "tg" } });
|
|
@@ -179,4 +188,49 @@ describe("lifecycle/gate-audit", () => {
|
|
|
179
188
|
expect(fromPort.entries.map((e) => e.kind)).toEqual(["approval-requested", "approved"]);
|
|
180
189
|
expect(fromPort.entries.map((e) => e.at)).toEqual(fromText.entries.map((e) => e.at));
|
|
181
190
|
});
|
|
191
|
+
|
|
192
|
+
describe("op-wave decision records (#3810)", () => {
|
|
193
|
+
const outcomes = [
|
|
194
|
+
{ moment: "before-plan", name: "lint", exit: 0, outcome: "passed" },
|
|
195
|
+
{ moment: "after-plan", name: "cost", target: "prod", exit: 2, outcome: "held" },
|
|
196
|
+
{ moment: "before-apply", name: "backup", exit: 1, outcome: "failed" },
|
|
197
|
+
{ moment: "after-apply", name: "skip", exit: 0, outcome: "skipped", reason: "nothing applied" },
|
|
198
|
+
];
|
|
199
|
+
const record = { wave: 1, name: "prod", op: "tf-apply", gate: "wave-1", digest: D1, heldBy: ["cost"], outcomes };
|
|
200
|
+
|
|
201
|
+
test("each outcome becomes a hook entry linked to the approval and the apply", () => {
|
|
202
|
+
const { entries, gaps } = deriveGateAudit({
|
|
203
|
+
ledgers: [ledger("tf-apply", pending(), resolution())],
|
|
204
|
+
applies: [{ ref: "reports/1", at: "2026-10-01T12:00:00.000Z", gate: "wave-1", digest: D1 }],
|
|
205
|
+
decisions: [{ ref: "wave-1.json", at: "2026-10-01T12:05:00.000Z", record }],
|
|
206
|
+
});
|
|
207
|
+
expect(gaps).toEqual([]);
|
|
208
|
+
const hooks = entries.filter((e) => e.kind === "hook");
|
|
209
|
+
expect(hooks.map((h) => h.hook?.outcome)).toEqual(["passed", "held", "failed", "skipped"]);
|
|
210
|
+
expect(hooks[1]!.hook).toMatchObject({ moment: "after-plan", name: "cost", target: "prod", exit: 2 });
|
|
211
|
+
expect(hooks[3]!.hook?.reason).toBe("nothing applied");
|
|
212
|
+
const approved = entries.find((e) => e.kind === "approved")!;
|
|
213
|
+
const applied = entries.find((e) => e.kind === "applied")!;
|
|
214
|
+
for (const h of hooks) expect(h).toMatchObject({ under: approved.id, applied: applied.id, gate: "wave-1", digest: D1, wave: { number: 1, name: "prod" } });
|
|
215
|
+
expect(new Set(hooks.map((h) => h.id)).size).toBe(4);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("text input, no approval on file, and a malformed record", () => {
|
|
219
|
+
const { entries, gaps } = deriveGateAudit({
|
|
220
|
+
ledgers: [],
|
|
221
|
+
decisions: [{ ref: "a.json", at: "2026-10-01T12:00:00.000Z", text: JSON.stringify(record) }, { ref: "b.json", at: "2026-10-01T12:00:00.000Z", text: "nope" }],
|
|
222
|
+
});
|
|
223
|
+
expect(entries.filter((e) => e.kind === "hook")).toHaveLength(4);
|
|
224
|
+
expect(entries[0]).not.toHaveProperty("under");
|
|
225
|
+
expect(gaps.map((g) => g.kind)).toEqual(["malformed-line"]);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("readGateAuditDecisions reads the json files under a directory", async () => {
|
|
229
|
+
const files: Record<string, string> = { "w1.json": JSON.stringify(record), "notes.txt": "x" };
|
|
230
|
+
const port = { list: async () => Object.keys(files), read: async (_d: string, f: string) => files[f] ?? null };
|
|
231
|
+
const got = await readGateAuditDecisions(port, "_wave-decisions/tf", "2026-10-01T12:00:00.000Z");
|
|
232
|
+
expect(got.map((d) => d.ref)).toEqual(["_wave-decisions/tf/w1.json"]);
|
|
233
|
+
expect(deriveGateAudit({ ledgers: [], decisions: got }).entries).toHaveLength(4);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
182
236
|
});
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* | `revoked` | a resolution a commit removed from the file (`subject` says which) |
|
|
22
22
|
* | `applied` | an apply the caller passes in, with the approval it ran under |
|
|
23
23
|
* | `override-spent` | an override an apply the caller passes in cites |
|
|
24
|
+
* | `hook` | a hook outcome in an op-wave decision record the caller passes in |
|
|
24
25
|
*
|
|
25
26
|
* An override gate is, by default, any gate of the op `policy-override`
|
|
26
27
|
* (terragucci writes one gate per root) or named `override-<rule>` (SQL
|
|
@@ -79,6 +80,8 @@ import { canonicalJson } from "../effect-receipt";
|
|
|
79
80
|
import { contentDigest } from "../content-digest";
|
|
80
81
|
import { samePlanDigest } from "./plan-digest";
|
|
81
82
|
import type { GateLedgerPort } from "../op/gate";
|
|
83
|
+
import type { LedgerReadPort } from "./ledger-port";
|
|
84
|
+
import type { GateApprovalSource } from "../op/op-waves";
|
|
82
85
|
|
|
83
86
|
export const GATE_AUDIT_KINDS = [
|
|
84
87
|
"approval-requested",
|
|
@@ -88,6 +91,7 @@ export const GATE_AUDIT_KINDS = [
|
|
|
88
91
|
"revoked",
|
|
89
92
|
"applied",
|
|
90
93
|
"override-spent",
|
|
94
|
+
"hook",
|
|
91
95
|
] as const;
|
|
92
96
|
export type GateAuditKind = (typeof GATE_AUDIT_KINDS)[number];
|
|
93
97
|
|
|
@@ -155,7 +159,7 @@ export interface GateAuditSource {
|
|
|
155
159
|
commit?: string;
|
|
156
160
|
/** The commit that added the line, or for a revocation removed it, when the line came from history. */
|
|
157
161
|
author?: GateLedgerCommit;
|
|
158
|
-
change: "added" | "removed" | "apply";
|
|
162
|
+
change: "added" | "removed" | "apply" | "decision";
|
|
159
163
|
}
|
|
160
164
|
|
|
161
165
|
export interface GateAuditEntry {
|
|
@@ -193,8 +197,16 @@ export interface GateAuditEntry {
|
|
|
193
197
|
description?: string;
|
|
194
198
|
/** Pending facts an op wave wrote for a policy denial or a hold (#3839): the wave they belong to. */
|
|
195
199
|
wave?: { number: number; name: string; op?: string };
|
|
200
|
+
/** Pending facts of a hold (#3886): the hook that holds the wave. */
|
|
201
|
+
heldBy?: { hook: string; moment: string; target?: string };
|
|
202
|
+
/** Pending facts of an op wave (#3861): the approval mode the wave asked under. */
|
|
203
|
+
approvalMode?: GateApprovalSource;
|
|
196
204
|
/** Overrides: the rules the denial named (from the denial line when there is one). */
|
|
197
205
|
rules?: string[];
|
|
206
|
+
/** A hook entry: the hook's moment, name, run, how it came out, and why a moment was skipped (#3810). */
|
|
207
|
+
hook?: { moment: string; name: string; target?: string; outcome: "passed" | "failed" | "held" | "skipped"; exit: number; reason?: string };
|
|
208
|
+
/** A hook entry: the applied entry of the same wave and digest, if the caller passed that apply in. */
|
|
209
|
+
applied?: string;
|
|
198
210
|
/** A revoked entry: what was revoked. */
|
|
199
211
|
subject?: "approval" | "override";
|
|
200
212
|
/** An applied entry: the approval entry it ran under, if one is held. An override-spent entry: the override entry. */
|
|
@@ -212,6 +224,35 @@ export interface GateAuditGap {
|
|
|
212
224
|
detail: string;
|
|
213
225
|
}
|
|
214
226
|
|
|
227
|
+
/**
|
|
228
|
+
* An op-wave decision record (`.chant/op-waves/<name>/wave-<k>.json`, written
|
|
229
|
+
* by `chant run wave`), as far as the audit reads it: the wave's gate and
|
|
230
|
+
* digest, and the `outcomes` of its hooks (#3804, #3811, #3847). Typed
|
|
231
|
+
* structurally so this file imports nothing from `../op/`.
|
|
232
|
+
*/
|
|
233
|
+
export interface WaveDecisionRecord {
|
|
234
|
+
wave: number;
|
|
235
|
+
name: string;
|
|
236
|
+
op: string;
|
|
237
|
+
gate: string;
|
|
238
|
+
digest?: string;
|
|
239
|
+
heldBy?: string[];
|
|
240
|
+
heldOn?: unknown;
|
|
241
|
+
outcomes?: ReadonlyArray<{ moment: string; name: string; target?: string; exit: number; outcome: string; reason?: string }>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* A decision record the caller passes in. The record carries no time and no
|
|
246
|
+
* place, so `ref` (a file path, an artifact, a row) and `at` (when it was
|
|
247
|
+
* written) come from the caller. Give the parsed `record`, or its `text`.
|
|
248
|
+
*/
|
|
249
|
+
export interface GateAuditDecision {
|
|
250
|
+
ref: string;
|
|
251
|
+
at: string;
|
|
252
|
+
record?: unknown;
|
|
253
|
+
text?: string;
|
|
254
|
+
}
|
|
255
|
+
|
|
215
256
|
export interface GateAuditOptions {
|
|
216
257
|
/** Whether a gate is an override gate. Default: op `policy-override`, or a gate named `override-...`. */
|
|
217
258
|
isOverride?: (op: string, gate: string) => boolean;
|
|
@@ -228,6 +269,8 @@ export interface GateAuditOptions {
|
|
|
228
269
|
export interface GateAuditInput extends GateAuditOptions {
|
|
229
270
|
ledgers: readonly GateAuditLedger[];
|
|
230
271
|
applies?: readonly GateAuditApply[];
|
|
272
|
+
/** Op-wave decision records: each hook outcome in them becomes a `hook` entry linked to the wave's approval and apply (#3810). */
|
|
273
|
+
decisions?: readonly GateAuditDecision[];
|
|
231
274
|
}
|
|
232
275
|
|
|
233
276
|
export const POLICY_OVERRIDE_OP = "policy-override";
|
|
@@ -241,13 +284,18 @@ type Row = Record<string, unknown>;
|
|
|
241
284
|
|
|
242
285
|
const KNOWN = new Set([
|
|
243
286
|
"version", "kind", "op", "gate", "resolvedBy", "relayedBy", "timestamp", "note", "url", "planDigest", "environment",
|
|
244
|
-
"approver", "seal", "review", "runId", "expiresAt", "description", "wave", "rules", "pr", "head", "reviewers",
|
|
287
|
+
"approver", "seal", "review", "runId", "expiresAt", "description", "wave", "heldBy", "approvalMode", "rules", "pr", "head", "reviewers",
|
|
245
288
|
]);
|
|
246
289
|
|
|
247
290
|
const waveOf = (v: unknown): { number: number; name: string; op?: string } | undefined => {
|
|
248
291
|
const w = v as { number?: unknown; name?: unknown; op?: unknown } | null;
|
|
249
292
|
return w && typeof w === "object" && typeof w.number === "number" && typeof w.name === "string" ? { number: w.number, name: w.name, ...(typeof w.op === "string" ? { op: w.op } : {}) } : undefined;
|
|
250
293
|
};
|
|
294
|
+
const heldByOf = (v: unknown): { hook: string; moment: string; target?: string } | undefined => {
|
|
295
|
+
const h = v as { hook?: unknown; moment?: unknown; target?: unknown } | null;
|
|
296
|
+
return h && typeof h === "object" && typeof h.hook === "string" && typeof h.moment === "string" ? { hook: h.hook, moment: h.moment, ...(typeof h.target === "string" ? { target: h.target } : {}) } : undefined;
|
|
297
|
+
};
|
|
298
|
+
const modeOf = (v: unknown): GateApprovalSource | undefined => (v === "ledger" || v === "pr-review" || v === "sealed" ? v : undefined);
|
|
251
299
|
const str = (v: unknown): string | undefined => (typeof v === "string" && v !== "" ? v : undefined);
|
|
252
300
|
const strings = (v: unknown): string[] | undefined => (Array.isArray(v) ? v.filter((x): x is string => typeof x === "string") : undefined);
|
|
253
301
|
const time = (iso: string): number => Date.parse(iso) || 0;
|
|
@@ -302,6 +350,23 @@ interface Seen {
|
|
|
302
350
|
/** Whether two digests, either absent, can be the same plan: absent matches anything, as an old line records none. */
|
|
303
351
|
const compatible = (a: string | undefined, b: string | undefined): boolean => a === undefined || b === undefined || samePlanDigest(a, b);
|
|
304
352
|
|
|
353
|
+
function decisionOf(d: GateAuditDecision): WaveDecisionRecord | undefined {
|
|
354
|
+
let v: unknown = d.record;
|
|
355
|
+
if (v === undefined && d.text !== undefined) {
|
|
356
|
+
try {
|
|
357
|
+
v = JSON.parse(d.text);
|
|
358
|
+
} catch {
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
const r = v as Row | null;
|
|
363
|
+
if (!r || typeof r !== "object" || typeof r.wave !== "number" || typeof r.name !== "string" || typeof r.op !== "string" || typeof r.gate !== "string") return undefined;
|
|
364
|
+
const outcomes = Array.isArray(r.outcomes)
|
|
365
|
+
? r.outcomes.filter((o): o is NonNullable<WaveDecisionRecord["outcomes"]>[number] => !!o && typeof o === "object" && typeof (o as Row).moment === "string" && typeof (o as Row).name === "string" && typeof (o as Row).exit === "number" && typeof (o as Row).outcome === "string")
|
|
366
|
+
: undefined;
|
|
367
|
+
return { wave: r.wave, name: r.name, op: r.op, gate: r.gate, ...(str(r.digest) ? { digest: str(r.digest) } : {}), ...(strings(r.heldBy) ? { heldBy: strings(r.heldBy) } : {}), ...(r.heldOn !== undefined ? { heldOn: r.heldOn } : {}), ...(outcomes ? { outcomes } : {}) };
|
|
368
|
+
}
|
|
369
|
+
|
|
305
370
|
/** The entries `input` adds up to, oldest first, and the gaps they show. */
|
|
306
371
|
export function deriveGateAudit(input: GateAuditInput): { entries: GateAuditEntry[]; gaps: GateAuditGap[] } {
|
|
307
372
|
const isOverride = input.isOverride ?? isOverrideGate;
|
|
@@ -359,7 +424,7 @@ export function deriveGateAudit(input: GateAuditInput): { entries: GateAuditEntr
|
|
|
359
424
|
...base,
|
|
360
425
|
kind: override ? "override-requested" : "approval-requested",
|
|
361
426
|
at: String(r.timestamp),
|
|
362
|
-
...drop({ runId: str(r.runId), expiresAt: str(r.expiresAt), description: str(r.description), url: str(r.url), rules: strings(r.rules), wave: waveOf(r.wave) }),
|
|
427
|
+
...drop({ runId: str(r.runId), expiresAt: str(r.expiresAt), description: str(r.description), url: str(r.url), rules: strings(r.rules), wave: waveOf(r.wave), heldBy: heldByOf(r.heldBy), approvalMode: modeOf(r.approvalMode) }),
|
|
363
428
|
detail: extra,
|
|
364
429
|
}));
|
|
365
430
|
continue;
|
|
@@ -450,6 +515,35 @@ export function deriveGateAudit(input: GateAuditInput): { entries: GateAuditEntr
|
|
|
450
515
|
}
|
|
451
516
|
}
|
|
452
517
|
|
|
518
|
+
for (const d of input.decisions ?? []) {
|
|
519
|
+
const rec = decisionOf(d);
|
|
520
|
+
if (!rec) {
|
|
521
|
+
gaps.push({ kind: "malformed-line", detail: `${d.ref} is not an op-wave decision record` });
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
const approval = rec.digest === undefined ? undefined : entries
|
|
525
|
+
.filter((e) => e.kind === "approved" && e.gate === rec.gate && e.op === rec.op && e.digest !== undefined && samePlanDigest(e.digest, rec.digest!))
|
|
526
|
+
.sort((x, y) => time(y.at) - time(x.at))[0];
|
|
527
|
+
const applied = rec.digest === undefined ? undefined : entries.find((e) => e.kind === "applied" && e.gate === rec.gate && e.digest !== undefined && samePlanDigest(e.digest, rec.digest!));
|
|
528
|
+
for (const [i, o] of (rec.outcomes ?? []).entries()) {
|
|
529
|
+
if (o.outcome !== "passed" && o.outcome !== "failed" && o.outcome !== "held" && o.outcome !== "skipped") continue;
|
|
530
|
+
entries.push(keyed({
|
|
531
|
+
id: idOf("hook", d.ref, d.at, i, o),
|
|
532
|
+
kind: "hook",
|
|
533
|
+
at: d.at,
|
|
534
|
+
gate: rec.gate,
|
|
535
|
+
op: rec.op,
|
|
536
|
+
...(rec.digest ? { digest: rec.digest } : {}),
|
|
537
|
+
...(approval ? { under: approval.id } : {}),
|
|
538
|
+
...(applied ? { applied: applied.id } : {}),
|
|
539
|
+
hook: { moment: o.moment, name: o.name, ...(o.target ? { target: o.target } : {}), outcome: o.outcome, exit: o.exit, ...(o.reason ? { reason: o.reason } : {}) },
|
|
540
|
+
wave: { number: rec.wave, name: rec.name, op: rec.op },
|
|
541
|
+
detail: drop({ heldBy: rec.heldBy?.length ? rec.heldBy : undefined, heldOn: o.outcome === "held" ? rec.heldOn : undefined }),
|
|
542
|
+
source: { path: d.ref, op: rec.op, change: "decision" },
|
|
543
|
+
}));
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
453
547
|
entries.sort((x, y) => time(x.at) - time(y.at));
|
|
454
548
|
return { entries, gaps };
|
|
455
549
|
}
|
|
@@ -510,3 +604,22 @@ export async function readGateAuditLedgers(port: Pick<GateLedgerPort, "read">, o
|
|
|
510
604
|
}
|
|
511
605
|
return out;
|
|
512
606
|
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* The thin reader for decision records kept on the ledger branch: every
|
|
610
|
+
* `.json` file directly under `dir` (such as a product's `_wave-decisions/<name>`),
|
|
611
|
+
* as input for {@link GateAuditInput.decisions}. A decision record holds no
|
|
612
|
+
* time, so `at` stamps them all: when the product collected them. Where the
|
|
613
|
+
* records live is the product's business; chant writes them to
|
|
614
|
+
* `.chant/op-waves/<name>/wave-<k>.json` in the job, and a product that
|
|
615
|
+
* collects them elsewhere passes them in directly.
|
|
616
|
+
*/
|
|
617
|
+
export async function readGateAuditDecisions(port: Pick<LedgerReadPort, "read" | "list">, dir: string, at: string): Promise<GateAuditDecision[]> {
|
|
618
|
+
const out: GateAuditDecision[] = [];
|
|
619
|
+
for (const file of (await port.list(dir)).sort()) {
|
|
620
|
+
if (!file.endsWith(".json")) continue;
|
|
621
|
+
const text = await port.read(dir, file);
|
|
622
|
+
if (text !== null) out.push({ ref: `${dir}/${file}`, at, text });
|
|
623
|
+
}
|
|
624
|
+
return out;
|
|
625
|
+
}
|
|
@@ -6,7 +6,7 @@ import { join } from "node:path";
|
|
|
6
6
|
import {
|
|
7
7
|
appendGateResolution, appendPendingGate, readGateResolutions, readGateLedger,
|
|
8
8
|
latestResolutionSince, latestPendingGate, isPendingGateExpired,
|
|
9
|
-
resolveApprovalUrl, isApprovalUrl, latestResolutionForPlan,
|
|
9
|
+
resolveApprovalUrl, isApprovalUrl, latestResolutionForPlan, parseGateLedger,
|
|
10
10
|
type PendingGateRecord, type GateResolutionRecord,
|
|
11
11
|
} from "./gate-ledger";
|
|
12
12
|
import { readBlobFromPath, writeBlobToPath } from "./git";
|
|
@@ -484,3 +484,22 @@ describe("gate ledger newline termination (#3849)", () => {
|
|
|
484
484
|
});
|
|
485
485
|
});
|
|
486
486
|
});
|
|
487
|
+
|
|
488
|
+
describe("pending fact wave and heldBy (#3886, #3887)", () => {
|
|
489
|
+
const line = (o: Record<string, unknown>) =>
|
|
490
|
+
JSON.stringify({ version: 1, kind: "pending", op: "tg", gate: "g", timestamp: "2026-10-01T00:00:00Z", expiresAt: "2026-10-02T00:00:00Z", ...o });
|
|
491
|
+
test("the reader types wave, heldBy and approvalMode", () => {
|
|
492
|
+
const { pending } = parseGateLedger(line({ approvalMode: "pr-review", wave: { number: 2, name: "prod", op: "tg" }, heldBy: { hook: "migrate", moment: "before-apply", target: "vpc" } }));
|
|
493
|
+
const p: PendingGateRecord = pending[0]!;
|
|
494
|
+
expect(p.wave).toEqual({ number: 2, name: "prod", op: "tg" });
|
|
495
|
+
expect(p.heldBy).toEqual({ hook: "migrate", moment: "before-apply", target: "vpc" });
|
|
496
|
+
expect(p.approvalMode).toBe("pr-review");
|
|
497
|
+
});
|
|
498
|
+
test("a wave or heldBy of the wrong shape is dropped, the line is kept", () => {
|
|
499
|
+
const { pending, malformed } = parseGateLedger(line({ wave: { number: "2" }, heldBy: "migrate" }));
|
|
500
|
+
expect(malformed).toBe(0);
|
|
501
|
+
expect(pending).toHaveLength(1);
|
|
502
|
+
expect(pending[0]!.wave).toBeUndefined();
|
|
503
|
+
expect(pending[0]!.heldBy).toBeUndefined();
|
|
504
|
+
});
|
|
505
|
+
});
|
|
@@ -228,6 +228,21 @@ export type GateResolutionInput = Omit<GateResolutionRecord, "version" | "kind">
|
|
|
228
228
|
* ledger by a line a minute. Once `expiresAt` passes, the fact is stale and
|
|
229
229
|
* the next run records a fresh one.
|
|
230
230
|
*/
|
|
231
|
+
export interface PendingGateWave {
|
|
232
|
+
number: number;
|
|
233
|
+
name: string;
|
|
234
|
+
/** The Op waves spec's name. */
|
|
235
|
+
op?: string;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** The hook that holds a wave on a gate (#3886): which hook asked, at which moment, and for which run. */
|
|
239
|
+
export interface PendingGateHeldBy {
|
|
240
|
+
hook: string;
|
|
241
|
+
moment: string;
|
|
242
|
+
/** The run, for a `perRun` hook. */
|
|
243
|
+
target?: string;
|
|
244
|
+
}
|
|
245
|
+
|
|
231
246
|
export interface PendingGateRecord {
|
|
232
247
|
/** Schema version, so an incompatible future shape is detected before being misread. */
|
|
233
248
|
version: 1;
|
|
@@ -296,6 +311,17 @@ export interface PendingGateRecord {
|
|
|
296
311
|
* than inferring it from config. Not the quorum block in `approval`.
|
|
297
312
|
*/
|
|
298
313
|
approvalMode?: GateApprovalSource;
|
|
314
|
+
/**
|
|
315
|
+
* The Op wave this gate belongs to (#3839): a hold on another gate or a
|
|
316
|
+
* policy denial. Absent on a gate that is not a wave's.
|
|
317
|
+
*/
|
|
318
|
+
wave?: PendingGateWave;
|
|
319
|
+
/**
|
|
320
|
+
* The hook that holds the wave on this gate (#3886), on a hold only: its
|
|
321
|
+
* name, the moment it ran at and its run. A reader names the holder from it
|
|
322
|
+
* rather than from `description`, which the hook writes.
|
|
323
|
+
*/
|
|
324
|
+
heldBy?: PendingGateHeldBy;
|
|
299
325
|
/**
|
|
300
326
|
* The open question this gate waits on, on a gate that asks a decision
|
|
301
327
|
* point (#3170). It is answered with `chant workspace points answer <id>`,
|
|
@@ -449,7 +475,13 @@ export function parseGateLedger(
|
|
|
449
475
|
malformed++;
|
|
450
476
|
continue;
|
|
451
477
|
}
|
|
452
|
-
|
|
478
|
+
// #3887: a `wave` or `heldBy` of the wrong shape is dropped, so a reader can trust the type.
|
|
479
|
+
const rec = parsed as PendingGateRecord;
|
|
480
|
+
const w = (parsed as { wave?: unknown }).wave as Partial<PendingGateWave> | null | undefined;
|
|
481
|
+
if (w !== undefined && !(w && typeof w === "object" && typeof w.number === "number" && typeof w.name === "string")) delete rec.wave;
|
|
482
|
+
const h = (parsed as { heldBy?: unknown }).heldBy as Partial<PendingGateHeldBy> | null | undefined;
|
|
483
|
+
if (h !== undefined && !(h && typeof h === "object" && typeof h.hook === "string" && typeof h.moment === "string")) delete rec.heldBy;
|
|
484
|
+
pending.push(rec);
|
|
453
485
|
continue;
|
|
454
486
|
}
|
|
455
487
|
if (typeof parsed.resolvedBy !== "string") {
|
package/src/lint/config.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { Severity, RuleConfig } from "./rule";
|
|
|
6
6
|
import type { PostSynthDiagnostic } from "./post-synth";
|
|
7
7
|
import { moduleDir, getRuntime } from "../runtime-adapter";
|
|
8
8
|
import { canonicalRuleId, type RuleMeta } from "../audit/catalog";
|
|
9
|
-
import strictPreset from "./presets/strict.json";
|
|
9
|
+
import strictPreset from "./presets/strict.json" with { type: "json" };
|
|
10
10
|
|
|
11
11
|
// chant #1117 — the upward config-discovery walk moved to a shared module
|
|
12
12
|
// (`../project-root`) so `chant build`/`lint.policies` use the identical walk
|
package/src/lint/discover.ts
CHANGED
|
@@ -10,17 +10,35 @@ import { join } from "path";
|
|
|
10
10
|
import { createRequire } from "module";
|
|
11
11
|
import type { LintRule } from "./rule";
|
|
12
12
|
import type { PostSynthCheck } from "./post-synth";
|
|
13
|
+
import { ensureTypeScriptLoader } from "../ts-loader";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
let cjsTypeScript = false;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Register tsx so createRequire can load TypeScript files in Node.js ESM
|
|
19
|
+
* context. Does nothing when tsx is not available; then only pre-compiled .js
|
|
20
|
+
* files can be require()'d.
|
|
21
|
+
*
|
|
22
|
+
* From source this runs when the module loads, as it always has: vitest and
|
|
23
|
+
* the source CLI rely on tsx's CommonJS hook being in place from then on. The
|
|
24
|
+
* compiled CLI imports this module on every start and most commands read no
|
|
25
|
+
* rule directory, so there it waits for the first one (#3878).
|
|
26
|
+
*/
|
|
27
|
+
function registerTypeScriptRequire(): void {
|
|
28
|
+
if (cjsTypeScript) return;
|
|
29
|
+
cjsTypeScript = true;
|
|
30
|
+
if (ensureTypeScriptLoader()) return;
|
|
31
|
+
try {
|
|
32
|
+
const _req = createRequire(import.meta.url);
|
|
33
|
+
const { register } = _req("tsx/cjs/api") as { register: () => void };
|
|
34
|
+
register();
|
|
35
|
+
} catch {
|
|
36
|
+
// tsx not available; only pre-compiled .js files can be require()'d
|
|
37
|
+
}
|
|
22
38
|
}
|
|
23
39
|
|
|
40
|
+
if (!import.meta.url.endsWith(".js")) registerTypeScriptRequire();
|
|
41
|
+
|
|
24
42
|
/**
|
|
25
43
|
* Discover lint rules from a directory.
|
|
26
44
|
*
|
|
@@ -32,6 +50,7 @@ try {
|
|
|
32
50
|
* @param importMetaUrl - The caller's import.meta.url (for createRequire)
|
|
33
51
|
*/
|
|
34
52
|
export function discoverLintRules(dir: string, importMetaUrl: string): LintRule[] {
|
|
53
|
+
registerTypeScriptRequire();
|
|
35
54
|
const require = createRequire(importMetaUrl);
|
|
36
55
|
const rules: LintRule[] = [];
|
|
37
56
|
|
|
@@ -62,6 +81,7 @@ export function discoverLintRules(dir: string, importMetaUrl: string): LintRule[
|
|
|
62
81
|
* @param importMetaUrl - The caller's import.meta.url (for createRequire)
|
|
63
82
|
*/
|
|
64
83
|
export function discoverPostSynthChecks(dir: string, importMetaUrl: string): PostSynthCheck[] {
|
|
84
|
+
registerTypeScriptRequire();
|
|
65
85
|
const require = createRequire(importMetaUrl);
|
|
66
86
|
const checks: PostSynthCheck[] = [];
|
|
67
87
|
|
|
@@ -17,12 +17,14 @@
|
|
|
17
17
|
* the *decision* and documents the reasoning, and re-exports these three
|
|
18
18
|
* functions as its public surface) for one structural reason: `./policy.ts`
|
|
19
19
|
* needs to consult it, `./policy-sandbox.ts` needs to call `./policy.ts`, and a
|
|
20
|
-
* flag on a leaf module
|
|
20
|
+
* flag on a leaf module (its one import, `../ts-loader`, is a leaf too) breaks what would otherwise
|
|
21
21
|
* be an import cycle. It also puts the check on the narrowest possible thing —
|
|
22
22
|
* the function that actually executes project code — rather than on a caller
|
|
23
23
|
* that might forget to ask.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
+
import { ensureTypeScriptLoader } from "../ts-loader";
|
|
27
|
+
|
|
26
28
|
/** Whether this process must run project policy modules inside the sandbox boundary instead of here. */
|
|
27
29
|
let armed = false;
|
|
28
30
|
|
|
@@ -66,5 +68,6 @@ export async function importPolicyModule(policyPath: string): Promise<PolicyModu
|
|
|
66
68
|
`Refusing to import the policy module ${policyPath} into the chant process under --sandbox: it is project-authored code and must be imported inside the sandbox boundary (packages/core/src/lint/policy-sandbox.ts's runProjectPolicies).`,
|
|
67
69
|
);
|
|
68
70
|
}
|
|
71
|
+
ensureTypeScriptLoader();
|
|
69
72
|
return (await import(policyPath)) as PolicyModuleNamespace;
|
|
70
73
|
}
|
package/src/lint/rule-loader.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readdirSync, existsSync } from "fs";
|
|
2
2
|
import { dirname, join, resolve } from "path";
|
|
3
3
|
import type { LintRule } from "./rule";
|
|
4
|
+
import { ensureTypeScriptLoader } from "../ts-loader";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Type guard to check if a value conforms to the LintRule interface.
|
|
@@ -82,6 +83,7 @@ export async function loadLocalRules(projectDir: string): Promise<LintRule[]> {
|
|
|
82
83
|
const filePath = resolve(rulesDir, file);
|
|
83
84
|
let mod: Record<string, unknown>;
|
|
84
85
|
try {
|
|
86
|
+
ensureTypeScriptLoader();
|
|
85
87
|
mod = await import(filePath);
|
|
86
88
|
} catch (err) {
|
|
87
89
|
throw new Error(
|