@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
|
@@ -0,0 +1,938 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The workspace declaration, `chant.workspace.json` or `.jsonc` (#2524 D1, D2;
|
|
3
|
+
* ws-051 for example groups).
|
|
4
|
+
*
|
|
5
|
+
* Every read goes through {@link parseDeclaration}: the text is parsed with
|
|
6
|
+
* positions, the declared `minReader` is checked, the result is validated
|
|
7
|
+
* against the JSON Schema shipped beside this file, and then the rules JSON
|
|
8
|
+
* Schema can't say are checked in code: unique names, and the placement rules.
|
|
9
|
+
* Any failure is a {@link WorkspaceReadError} naming the file, line and
|
|
10
|
+
* column. A declaration never reads as empty.
|
|
11
|
+
*
|
|
12
|
+
* Group matches depend on the tree, so their placement is checked when they
|
|
13
|
+
* are expanded ({@link resolveGroups}).
|
|
14
|
+
*
|
|
15
|
+
* Everything under `workspace/` loads only when a `chant workspace` command
|
|
16
|
+
* runs. The level-0 goldens (#2526) fail if a level-0 command loads it.
|
|
17
|
+
*/
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
19
|
+
import { createRequire } from "node:module";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
|
+
import schema from "./declaration.schema.json" with { type: "json" };
|
|
22
|
+
import { expandGlob } from "./glob.js";
|
|
23
|
+
import { EXAMPLES_KIND, holdsChantProject } from "./kinds.js";
|
|
24
|
+
import { parseJsonText, pointerToken } from "./jsonc.js";
|
|
25
|
+
import { joinPath } from "./tree.js";
|
|
26
|
+
export const DECLARATION_SCHEMA_ID = schema.$id;
|
|
27
|
+
export const DECLARATION_FILES = ["chant.workspace.json", "chant.workspace.jsonc"];
|
|
28
|
+
export const DECLARATION_SCHEMA_VERSION = 1;
|
|
29
|
+
/** Names no member or group may take: ledger paths use them (#2524 D7, D17). */
|
|
30
|
+
export const RESERVED_NAMES = ["_workspace", "_members"];
|
|
31
|
+
export const NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,39}$/;
|
|
32
|
+
// ── Errors ───────────────────────────────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Why a workspace could not be read. The list is closed: a reader may switch
|
|
35
|
+
* on it, and a new code is a contract change (#2524 D15).
|
|
36
|
+
*/
|
|
37
|
+
export const WORKSPACE_ERROR_CODES = [
|
|
38
|
+
/** No chant.workspace.json or .jsonc between the directory and the git root. */
|
|
39
|
+
"declaration-missing",
|
|
40
|
+
/** Both chant.workspace.json and chant.workspace.jsonc are present. */
|
|
41
|
+
"declaration-ambiguous",
|
|
42
|
+
/** The file is not valid JSON (or JSONC, for .jsonc). */
|
|
43
|
+
"declaration-unparseable",
|
|
44
|
+
/** The file does not match the declaration schema, or repeats a name. */
|
|
45
|
+
"declaration-invalid",
|
|
46
|
+
/** A member or group match breaks a placement rule (#2524 D2, ws-051). */
|
|
47
|
+
"placement-invalid",
|
|
48
|
+
/** The declaration's minReader is newer than this chant. */
|
|
49
|
+
"reader-too-old",
|
|
50
|
+
/** The declaration pins another chant, which is not installed at the root (#2524 D15, ws-021). */
|
|
51
|
+
"root-chant-required",
|
|
52
|
+
/** `--at` was given outside a git repository. */
|
|
53
|
+
"not-a-git-repository",
|
|
54
|
+
/** `--at` names no commit. */
|
|
55
|
+
"revision-unknown",
|
|
56
|
+
];
|
|
57
|
+
export class WorkspaceReadError extends Error {
|
|
58
|
+
constructor(code, message, location) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.code = code;
|
|
61
|
+
this.location = location;
|
|
62
|
+
this.name = "WorkspaceReadError";
|
|
63
|
+
}
|
|
64
|
+
/** `file:line:column: message`, or the message alone. */
|
|
65
|
+
describe() {
|
|
66
|
+
const l = this.location;
|
|
67
|
+
return l ? `${l.file}:${l.line}:${l.column}: ${this.message}` : this.message;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** The core principal classes (#2524 D5). A pinned package may supply domain classes too (#3080, `principal-classes.ts`). */
|
|
71
|
+
export const PRINCIPAL_CLASSES = ["human", "agent", "runner", "service"];
|
|
72
|
+
/** How a record is written, as the records commands name it (#2548). */
|
|
73
|
+
export const WRITE_VERBS = ["new", "amend", "review", "close"];
|
|
74
|
+
/** The default `ci.green.window`. */
|
|
75
|
+
export const DEFAULT_CI_WINDOW = "24h";
|
|
76
|
+
/** A renderer a diagram is pinned to (#2764): a closed list of tools chant does not run. */
|
|
77
|
+
export const DIAGRAM_TOOLS = ["d2", "mermaid", "graphviz", "excalidraw"];
|
|
78
|
+
/** The gate a ship Op stops at when the block names none (ws-100). */
|
|
79
|
+
export const DEFAULT_SHIP_GATE = "ship";
|
|
80
|
+
/** The environment a ship Op records its releases in when the block names none (ws-100). */
|
|
81
|
+
export const DEFAULT_SHIP_ENV = "box";
|
|
82
|
+
/** What a replicate policy pushes (#3172): work branches, kept attempts, work-in-progress snapshots and the ledger branch. */
|
|
83
|
+
export const REPLICATE_REF_CLASSES = ["work", "kept", "wip", "ledger"];
|
|
84
|
+
/** When chant pushes on its own under a replicate policy (#3172). */
|
|
85
|
+
export const REPLICATE_TRIGGERS = ["save", "release"];
|
|
86
|
+
/** The remote a replicate policy pushes to when it names none. */
|
|
87
|
+
export const DEFAULT_REPLICATE_REMOTE = "origin";
|
|
88
|
+
/** What a check command is (#3146). */
|
|
89
|
+
export const FACTORY_CHECK_KINDS = ["test", "build", "lint", "plan", "conformance"];
|
|
90
|
+
/** The branch prefix a publish target uses when it names none: the work lease's own branch. */
|
|
91
|
+
export const DEFAULT_PUBLISH_BRANCH_PREFIX = "chant/work/";
|
|
92
|
+
/** Where boxes keep state when their host names no stateRoot (#2727). */
|
|
93
|
+
export const DEFAULT_STATE_ROOT = "${XDG_STATE_HOME}/chant/boxes";
|
|
94
|
+
// ── This chant ───────────────────────────────────────────────────────────────
|
|
95
|
+
/** The package whose pin names the root's chant (#2524 D15, ws-021). */
|
|
96
|
+
export const CHANT_PACKAGE = "@intentius/chant";
|
|
97
|
+
let readerVersionCache;
|
|
98
|
+
/**
|
|
99
|
+
* The version of the chant doing the reading. Read as a file, not through
|
|
100
|
+
* `require`: discovery reads the declaration on every walk under a workspace
|
|
101
|
+
* root (#2527), and a CJS require of `package.json` took about a minute per
|
|
102
|
+
* call in a vitest worker once a build had run in it, where a file read takes
|
|
103
|
+
* well under a millisecond.
|
|
104
|
+
*/
|
|
105
|
+
export function readerVersion() {
|
|
106
|
+
readerVersionCache ?? (readerVersionCache = JSON.parse(readFileSync(fileURLToPath(new URL("../../package.json", import.meta.url)), "utf-8")).version);
|
|
107
|
+
return readerVersionCache;
|
|
108
|
+
}
|
|
109
|
+
const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?$/;
|
|
110
|
+
/** Negative when `a` is older than `b`. Build metadata is not allowed, and prereleases sort before their release. */
|
|
111
|
+
export function compareVersions(a, b) {
|
|
112
|
+
const ma = SEMVER.exec(a);
|
|
113
|
+
const mb = SEMVER.exec(b);
|
|
114
|
+
if (!ma || !mb)
|
|
115
|
+
throw new Error(`not a version: ${ma ? b : a}`);
|
|
116
|
+
for (let i = 1; i <= 3; i++) {
|
|
117
|
+
const d = Number(ma[i]) - Number(mb[i]);
|
|
118
|
+
if (d !== 0)
|
|
119
|
+
return d;
|
|
120
|
+
}
|
|
121
|
+
if (ma[4] === mb[4])
|
|
122
|
+
return 0;
|
|
123
|
+
if (ma[4] === undefined)
|
|
124
|
+
return 1;
|
|
125
|
+
if (mb[4] === undefined)
|
|
126
|
+
return -1;
|
|
127
|
+
return ma[4] < mb[4] ? -1 : 1;
|
|
128
|
+
}
|
|
129
|
+
let compiled;
|
|
130
|
+
function validator() {
|
|
131
|
+
if (compiled)
|
|
132
|
+
return compiled;
|
|
133
|
+
const require = createRequire(import.meta.url);
|
|
134
|
+
// ajv is CommonJS; its class is the default export, or that export's own default.
|
|
135
|
+
const mod = require("ajv/dist/2020");
|
|
136
|
+
const Ajv = (mod.default ?? mod);
|
|
137
|
+
compiled = new Ajv({ allErrors: true, strict: true }).compile(schema);
|
|
138
|
+
return compiled;
|
|
139
|
+
}
|
|
140
|
+
/** Readable text for one schema error, keyed on the rule that failed. */
|
|
141
|
+
function explain(e, value) {
|
|
142
|
+
const def = /#\/\$defs\/([A-Za-z]+)\//.exec(e.schemaPath)?.[1];
|
|
143
|
+
if (e.keyword === "pattern") {
|
|
144
|
+
const shown = JSON.stringify(value);
|
|
145
|
+
if (def === "name" && typeof value === "string" && RESERVED_NAMES.includes(value)) {
|
|
146
|
+
return `${shown} is reserved; pick another name`;
|
|
147
|
+
}
|
|
148
|
+
if (def === "name")
|
|
149
|
+
return `${shown} is not a valid name: use lowercase letters, digits and hyphens, starting with a letter or digit, at most 40 characters`;
|
|
150
|
+
if (def === "kindName")
|
|
151
|
+
return `${shown} is not a valid kind or role name`;
|
|
152
|
+
if (def === "dir")
|
|
153
|
+
return `${shown} is not a directory inside the workspace: use a relative path with / separators, and no . or .. segments`;
|
|
154
|
+
if (def === "path")
|
|
155
|
+
return `${shown} is not a path inside the member or workspace: use a relative path with / separators, and no . or .. segments`;
|
|
156
|
+
if (def === "glob")
|
|
157
|
+
return `${shown} is not a glob inside the workspace: use a relative pattern with / separators, and no . or .. segments`;
|
|
158
|
+
if (def === "version")
|
|
159
|
+
return `${shown} is not a version such as 1.2.3`;
|
|
160
|
+
return `${shown} is not allowed here`;
|
|
161
|
+
}
|
|
162
|
+
if (e.keyword === "additionalProperties") {
|
|
163
|
+
return `unknown field ${JSON.stringify(e.params.additionalProperty)}; only fields named x-... may be added`;
|
|
164
|
+
}
|
|
165
|
+
if (e.keyword === "required") {
|
|
166
|
+
const missing = String(e.params.missingProperty);
|
|
167
|
+
if (missing === "because" && e.instancePath.endsWith("/handWritten"))
|
|
168
|
+
return `a hand-written generated file needs "because", saying why it is kept by hand`;
|
|
169
|
+
if (missing === "because")
|
|
170
|
+
return `a member of kind other needs "because", saying why it is there`;
|
|
171
|
+
return `missing required field ${JSON.stringify(missing)}`;
|
|
172
|
+
}
|
|
173
|
+
if (e.keyword === "const" && e.instancePath === "/schema")
|
|
174
|
+
return `schema must be 1, the only declaration format this chant reads`;
|
|
175
|
+
return e.message ?? "is invalid";
|
|
176
|
+
}
|
|
177
|
+
/** Keywords that only summarise errors reported on their own. */
|
|
178
|
+
const SUMMARY_KEYWORDS = new Set(["if", "then", "else", "oneOf", "anyOf"]);
|
|
179
|
+
function valueAt(root, pointer) {
|
|
180
|
+
let v = root;
|
|
181
|
+
for (const token of pointer.split("/").slice(1)) {
|
|
182
|
+
const key = token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
183
|
+
if (v === null || typeof v !== "object")
|
|
184
|
+
return undefined;
|
|
185
|
+
v = v[key];
|
|
186
|
+
}
|
|
187
|
+
return v;
|
|
188
|
+
}
|
|
189
|
+
/** The version the declaration's `@intentius/chant` pin names, and where the pin is. Undefined without one. */
|
|
190
|
+
export function pinnedChant(obj) {
|
|
191
|
+
if (!Array.isArray(obj.pins))
|
|
192
|
+
return undefined;
|
|
193
|
+
const index = obj.pins.findIndex((p) => p !== null && typeof p === "object" && p.package === CHANT_PACKAGE && typeof p.version === "string");
|
|
194
|
+
return index < 0 ? undefined : { version: obj.pins[index].version, index };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Parse and check a declaration's text. `file` is the name used in messages
|
|
198
|
+
* and decides the dialect: a name ending in `.jsonc` allows comments and
|
|
199
|
+
* trailing commas.
|
|
200
|
+
*/
|
|
201
|
+
export function parseDeclaration(text, file, reader = readerVersion(), options = {}) {
|
|
202
|
+
const parsed = parseJsonText(text, { jsonc: file.endsWith(".jsonc") });
|
|
203
|
+
if (!parsed.ok) {
|
|
204
|
+
throw new WorkspaceReadError("declaration-unparseable", parsed.message, { file, ...parsed.location });
|
|
205
|
+
}
|
|
206
|
+
const at = (pointer, key = false) => ({ file, ...parsed.locate(pointer, key) });
|
|
207
|
+
const raw = parsed.value;
|
|
208
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
209
|
+
throw new WorkspaceReadError("declaration-invalid", "the declaration must be a JSON object", at(""));
|
|
210
|
+
}
|
|
211
|
+
const obj = raw;
|
|
212
|
+
// The root's chant reads the declaration (ws-021). A pin to another chant
|
|
213
|
+
// comes before minReader and the schema: that chant may know fields this
|
|
214
|
+
// one doesn't.
|
|
215
|
+
const pin = options.rootChant ? pinnedChant(obj) : undefined;
|
|
216
|
+
if (pin && pin.version !== reader) {
|
|
217
|
+
throw new WorkspaceReadError("root-chant-required", `this declaration pins ${CHANT_PACKAGE} ${pin.version}, and this is chant ${reader}; the root's chant reads it, so install ${CHANT_PACKAGE}@${pin.version} at the workspace root`, at(`/pins/${pin.index}/version`));
|
|
218
|
+
}
|
|
219
|
+
// minReader first: a declaration written for a newer chant may use fields
|
|
220
|
+
// this one doesn't know, and "too old" is the true reason it can't read it.
|
|
221
|
+
if (typeof obj.minReader === "string" && SEMVER.test(obj.minReader) && compareVersions(reader, obj.minReader) < 0) {
|
|
222
|
+
throw new WorkspaceReadError("reader-too-old", `this declaration needs chant ${obj.minReader} or newer to read it, and this is chant ${reader}`, at("/minReader"));
|
|
223
|
+
}
|
|
224
|
+
const validate = validator();
|
|
225
|
+
if (!validate(raw)) {
|
|
226
|
+
const errors = (validate.errors ?? []).filter((e) => !SUMMARY_KEYWORDS.has(e.keyword));
|
|
227
|
+
// The deepest error first: it is the one closest to what needs fixing.
|
|
228
|
+
errors.sort((a, b) => b.instancePath.split("/").length - a.instancePath.split("/").length);
|
|
229
|
+
const first = errors[0] ?? validate.errors[0];
|
|
230
|
+
const isKey = first.keyword === "additionalProperties";
|
|
231
|
+
const pointer = isKey ? `${first.instancePath}/${pointerToken(String(first.params.additionalProperty))}` : first.instancePath;
|
|
232
|
+
const where = first.instancePath === "" ? "" : ` (at ${first.instancePath})`;
|
|
233
|
+
const more = errors.length > 1 ? `; ${errors.length - 1} more problem${errors.length > 2 ? "s" : ""} after this one` : "";
|
|
234
|
+
throw new WorkspaceReadError("declaration-invalid", `${explain(first, valueAt(raw, first.instancePath))}${where}${more}`, at(pointer, isKey));
|
|
235
|
+
}
|
|
236
|
+
const entries = obj.members.map((e, i) => {
|
|
237
|
+
const pointer = `/members/${i}`;
|
|
238
|
+
const suppress = (e.suppress ?? []).map((x) => ({ check: x.check, because: x.because }));
|
|
239
|
+
if (e.kind === EXAMPLES_KIND) {
|
|
240
|
+
const glob = e.glob;
|
|
241
|
+
return {
|
|
242
|
+
type: "group",
|
|
243
|
+
name: e.name,
|
|
244
|
+
kind: EXAMPLES_KIND,
|
|
245
|
+
globs: typeof glob === "string" ? [glob] : [...glob],
|
|
246
|
+
suppress,
|
|
247
|
+
pointer,
|
|
248
|
+
globLocation: parsed.locate(`${pointer}/glob`),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const roles = (e.roles ?? []).map((r) => typeof r === "string" ? { name: r, path: null } : { name: r.name, path: r.path ?? null });
|
|
252
|
+
const generated = (e.generated ?? []).map((g, j) => ({
|
|
253
|
+
path: g.path,
|
|
254
|
+
generator: g.generator,
|
|
255
|
+
sources: [...(g.sources ?? [])],
|
|
256
|
+
handWritten: g.handWritten ? { because: g.handWritten.because } : null,
|
|
257
|
+
pointer: `${pointer}/generated/${j}`,
|
|
258
|
+
}));
|
|
259
|
+
const links = (e.links ?? []).map((l, j) => ({
|
|
260
|
+
member: l.member,
|
|
261
|
+
output: l.output,
|
|
262
|
+
kind: l.kind ?? null,
|
|
263
|
+
protocol: l.protocol ?? null,
|
|
264
|
+
pointer: `${pointer}/links/${j}`,
|
|
265
|
+
}));
|
|
266
|
+
const records = recordKindsOf(e.records, e.dir, e.name, `${pointer}/records`);
|
|
267
|
+
const diagrams = diagramsOf(e.diagrams, e.name, `${pointer}/diagrams`);
|
|
268
|
+
const box = boxOf(e.box, `${pointer}/box`);
|
|
269
|
+
return {
|
|
270
|
+
type: "member",
|
|
271
|
+
name: e.name,
|
|
272
|
+
dir: e.dir,
|
|
273
|
+
kind: e.kind,
|
|
274
|
+
roles,
|
|
275
|
+
generated,
|
|
276
|
+
outputs: e.outputs === undefined ? null : [...e.outputs],
|
|
277
|
+
fields: e.fields === undefined ? null : structuredClone(e.fields),
|
|
278
|
+
links,
|
|
279
|
+
records,
|
|
280
|
+
diagrams,
|
|
281
|
+
box,
|
|
282
|
+
upstream: e.upstream ?? null,
|
|
283
|
+
because: e.because ?? null,
|
|
284
|
+
travel: e.travel === true,
|
|
285
|
+
suppress,
|
|
286
|
+
pointer,
|
|
287
|
+
};
|
|
288
|
+
});
|
|
289
|
+
// Names are unique across members and groups.
|
|
290
|
+
const names = new Map();
|
|
291
|
+
for (const e of entries) {
|
|
292
|
+
const first = names.get(e.name);
|
|
293
|
+
if (first) {
|
|
294
|
+
throw new WorkspaceReadError("declaration-invalid", `the name ${JSON.stringify(e.name)} is already used by the entry at ${first.pointer}`, at(`${e.pointer}/name`));
|
|
295
|
+
}
|
|
296
|
+
names.set(e.name, e);
|
|
297
|
+
}
|
|
298
|
+
// Placement (#2524 D2): one root member at most, no two members in one
|
|
299
|
+
// directory, and only the root member contains other members.
|
|
300
|
+
const members = entries.filter((e) => e.type === "member");
|
|
301
|
+
const byDir = new Map();
|
|
302
|
+
for (const m of members) {
|
|
303
|
+
const other = byDir.get(m.dir);
|
|
304
|
+
if (other) {
|
|
305
|
+
throw new WorkspaceReadError("placement-invalid", `member ${m.name} has the same directory as member ${other.name} (${m.dir})`, at(`${m.pointer}/dir`));
|
|
306
|
+
}
|
|
307
|
+
byDir.set(m.dir, m);
|
|
308
|
+
}
|
|
309
|
+
for (const m of members) {
|
|
310
|
+
const outer = members.find((o) => o !== m && o.dir !== "." && isInside(m.dir, o.dir));
|
|
311
|
+
if (outer) {
|
|
312
|
+
throw new WorkspaceReadError("placement-invalid", `member ${m.name} (${m.dir}) sits inside member ${outer.name} (${outer.dir}); only the root member "." may contain other members`, at(`${m.pointer}/dir`));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// A member lists a generated file once, and never one inside another
|
|
316
|
+
// member's directory: that member owns the file and lists it (#2541).
|
|
317
|
+
for (const m of members) {
|
|
318
|
+
const seen = new Map();
|
|
319
|
+
for (const g of m.generated) {
|
|
320
|
+
const first = seen.get(g.path);
|
|
321
|
+
if (first) {
|
|
322
|
+
throw new WorkspaceReadError("declaration-invalid", `member ${m.name} lists the generated file ${g.path} twice; the first is at ${first.pointer}`, at(`${g.pointer}/path`));
|
|
323
|
+
}
|
|
324
|
+
seen.set(g.path, g);
|
|
325
|
+
const full = m.dir === "." ? g.path : `${m.dir}/${g.path}`;
|
|
326
|
+
const inner = members.find((o) => o !== m && o.dir !== "." && isInside(o.dir, m.dir) && isInside(full, o.dir));
|
|
327
|
+
if (inner) {
|
|
328
|
+
throw new WorkspaceReadError("placement-invalid", `member ${m.name} lists the generated file ${g.path}, which sits inside member ${inner.name} (${inner.dir}); list it there`, at(`${g.pointer}/path`));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// A kind file is declared once, and a name the declaration gives a kind is
|
|
333
|
+
// given once (#2680): readers key the kinds by both.
|
|
334
|
+
const ownRecords = recordKindsOf(obj.records, ".", null, "/records");
|
|
335
|
+
const byPath = new Map();
|
|
336
|
+
const byName = new Map();
|
|
337
|
+
for (const r of [...ownRecords, ...members.flatMap((m) => m.records)]) {
|
|
338
|
+
const first = byPath.get(r.path);
|
|
339
|
+
if (first)
|
|
340
|
+
throw new WorkspaceReadError("declaration-invalid", `the record kind ${r.path} is already declared at ${first.pointer}`, at(`${r.pointer}/kind`));
|
|
341
|
+
byPath.set(r.path, r);
|
|
342
|
+
if (r.name === null)
|
|
343
|
+
continue;
|
|
344
|
+
const named = byName.get(r.name);
|
|
345
|
+
if (named)
|
|
346
|
+
throw new WorkspaceReadError("declaration-invalid", `the record kind name ${JSON.stringify(r.name)} is already given at ${named.pointer}`, at(`${r.pointer}/name`));
|
|
347
|
+
byName.set(r.name, r);
|
|
348
|
+
}
|
|
349
|
+
// A box names each capability once (#2726): a broker reads its scope by name.
|
|
350
|
+
for (const m of members) {
|
|
351
|
+
const seen = new Map();
|
|
352
|
+
for (const c of m.box?.capabilities ?? []) {
|
|
353
|
+
const first = seen.get(c.name);
|
|
354
|
+
if (first)
|
|
355
|
+
throw new WorkspaceReadError("declaration-invalid", `member ${m.name}'s box lists the capability ${c.name} twice; the first is at ${first.pointer}`, at(`${c.pointer}/name`));
|
|
356
|
+
seen.set(c.name, c);
|
|
357
|
+
}
|
|
358
|
+
// Its services name each other only within the block, without a cycle (#2880).
|
|
359
|
+
const problem = m.box ? boxServicesProblem(m.name, m.box.services) : null;
|
|
360
|
+
if (problem)
|
|
361
|
+
throw new WorkspaceReadError("declaration-invalid", problem.message, at(problem.pointer));
|
|
362
|
+
}
|
|
363
|
+
// One factory, building and naming declared members (#3146).
|
|
364
|
+
const factory = factoryProblem(members);
|
|
365
|
+
if (factory)
|
|
366
|
+
throw new WorkspaceReadError("declaration-invalid", factory.message, at(factory.pointer));
|
|
367
|
+
// One replicate policy (#3172): the checkout is the whole repository's, so one remote takes its work in progress.
|
|
368
|
+
const replicating = members.filter((m) => m.box?.replicate);
|
|
369
|
+
if (replicating.length > 1) {
|
|
370
|
+
throw new WorkspaceReadError("declaration-invalid", `members ${replicating[0].name} and ${replicating[1].name} both declare replicate in their box block; a checkout's work in progress goes to one remote, so a workspace has one replicate policy`, at(replicating[1].box.replicate.pointer));
|
|
371
|
+
}
|
|
372
|
+
// A diagram name is given once across the declaration (#2764): a reader keys diagrams by name.
|
|
373
|
+
const ownDiagrams = diagramsOf(obj.diagrams, null, "/diagrams");
|
|
374
|
+
const byDiagramName = new Map();
|
|
375
|
+
for (const d of [...ownDiagrams, ...members.flatMap((m) => m.diagrams)]) {
|
|
376
|
+
const first = byDiagramName.get(d.name);
|
|
377
|
+
if (first) {
|
|
378
|
+
throw new WorkspaceReadError("declaration-invalid", `the diagram name ${JSON.stringify(d.name)} is already used by the diagram at ${first.pointer}`, at(`${d.pointer}/name`));
|
|
379
|
+
}
|
|
380
|
+
byDiagramName.set(d.name, d);
|
|
381
|
+
}
|
|
382
|
+
const hosts = hostsOf(obj, members, at);
|
|
383
|
+
const writeScope = writeScopeOf(obj.writeScope, members, at);
|
|
384
|
+
const agents = agentsOf(obj.agents, members, at);
|
|
385
|
+
const tierSession = factoryTierSessionProblem(members, agents);
|
|
386
|
+
if (tierSession)
|
|
387
|
+
throw new WorkspaceReadError("declaration-invalid", tierSession.message, at(tierSession.pointer));
|
|
388
|
+
const ci = ciOf(obj.ci, at);
|
|
389
|
+
const pins = (obj.pins ?? []).map((p) => ({
|
|
390
|
+
package: p.package ?? null,
|
|
391
|
+
version: p.version ?? null,
|
|
392
|
+
path: p.path ?? null,
|
|
393
|
+
integrity: p.integrity ?? null,
|
|
394
|
+
}));
|
|
395
|
+
const declaration = {
|
|
396
|
+
name: obj.name,
|
|
397
|
+
schema: obj.schema,
|
|
398
|
+
minReader: obj.minReader ?? null,
|
|
399
|
+
entries,
|
|
400
|
+
members,
|
|
401
|
+
groups: entries.filter((e) => e.type === "group"),
|
|
402
|
+
pins,
|
|
403
|
+
checks: { ...(obj.checks ?? {}) },
|
|
404
|
+
quorum: typeof obj.quorum === "number" ? obj.quorum : null,
|
|
405
|
+
records: ownRecords,
|
|
406
|
+
diagrams: ownDiagrams,
|
|
407
|
+
hosts,
|
|
408
|
+
changes: changesOf(obj.changes),
|
|
409
|
+
writeScope,
|
|
410
|
+
agents,
|
|
411
|
+
identity: identityOf(obj.identity),
|
|
412
|
+
ci,
|
|
413
|
+
file,
|
|
414
|
+
};
|
|
415
|
+
written.set(declaration, raw);
|
|
416
|
+
return declaration;
|
|
417
|
+
}
|
|
418
|
+
/** Each parsed declaration's JSON as written, for its x- keys (#3595). */
|
|
419
|
+
const written = new WeakMap();
|
|
420
|
+
/**
|
|
421
|
+
* The `x-` keys of the object at `pointer` in the declaration as written
|
|
422
|
+
* (#3595), in file order: what a reader of `status --json` or `ls --json`
|
|
423
|
+
* gets back on the object the declaration holds them on. Empty when the
|
|
424
|
+
* pointer names no object, and for a declaration not read through
|
|
425
|
+
* {@link parseDeclaration}.
|
|
426
|
+
*/
|
|
427
|
+
export function extensionsAt(declaration, pointer) {
|
|
428
|
+
const value = valueAt(written.get(declaration), pointer);
|
|
429
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
430
|
+
return {};
|
|
431
|
+
return Object.fromEntries(Object.entries(value).filter(([k]) => k.startsWith("x-")));
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* The `writeScope` block, already validated, with the rule the schema can't
|
|
435
|
+
* say (#2548): a member it names is a declared member. Its keys are kept in
|
|
436
|
+
* file order: the core classes and any domain class (#3080).
|
|
437
|
+
*/
|
|
438
|
+
function writeScopeOf(raw, members, at) {
|
|
439
|
+
if (raw === undefined)
|
|
440
|
+
return null;
|
|
441
|
+
const block = raw;
|
|
442
|
+
const out = {};
|
|
443
|
+
for (const [cls, entry] of Object.entries(block)) {
|
|
444
|
+
const pointer = `/writeScope/${cls}`;
|
|
445
|
+
const list = entry.members === undefined || entry.members === "*" ? null : [...entry.members];
|
|
446
|
+
for (const [i, name] of (list ?? []).entries()) {
|
|
447
|
+
if (!members.some((m) => m.name === name)) {
|
|
448
|
+
throw new WorkspaceReadError("declaration-invalid", `writeScope.${cls} names the member ${JSON.stringify(name)}, which the declaration does not declare; declared members: ${members.map((m) => m.name).join(", ") || "none"}`, at(`${pointer}/members/${i}`));
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
const records = entry.records === undefined ? null : Object.fromEntries(Object.entries(entry.records).map(([k, v]) => [k, [...v]]));
|
|
452
|
+
const guarded = (entry.protected ?? []).map((p) => (typeof p === "string" ? { path: p, except: [] } : { path: p.path, except: [...(p.except ?? [])] }));
|
|
453
|
+
out[cls] = { members: list, records, protected: guarded, pointer };
|
|
454
|
+
}
|
|
455
|
+
return out;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* The `agents` list, already validated, with the rules the schema can't say
|
|
459
|
+
* (#2548, ws-101): names are unique, every member a session names is a
|
|
460
|
+
* declared member, and a principal is listed by one session at most.
|
|
461
|
+
*/
|
|
462
|
+
/** The `identity` block, already validated by the schema (#3163). */
|
|
463
|
+
function identityOf(raw) {
|
|
464
|
+
if (raw === undefined)
|
|
465
|
+
return null;
|
|
466
|
+
const block = raw;
|
|
467
|
+
const gates = {};
|
|
468
|
+
for (const [gate, entry] of Object.entries(block.gates ?? {})) {
|
|
469
|
+
gates[gate] = { gate, class: entry.class ?? null, pointer: `/identity/gates/${gate.replace(/~/g, "~0").replace(/\//g, "~1")}` };
|
|
470
|
+
}
|
|
471
|
+
return { attribution: block.attribution ?? "any", gates };
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* The `ci` block, already validated by the schema, with its defaults and the
|
|
475
|
+
* rule the schema can't say (#3573): every phase `require` names is declared.
|
|
476
|
+
*/
|
|
477
|
+
function ciOf(raw, at) {
|
|
478
|
+
if (raw === undefined)
|
|
479
|
+
return null;
|
|
480
|
+
const block = raw;
|
|
481
|
+
if (block.green === undefined)
|
|
482
|
+
return { green: null };
|
|
483
|
+
const g = block.green;
|
|
484
|
+
const phases = Object.entries(g.phases).map(([name, p]) => ({
|
|
485
|
+
name,
|
|
486
|
+
runs: [...(Array.isArray(p) ? p : p.runs)],
|
|
487
|
+
skipped: Array.isArray(p) ? "fail" : (p.skipped ?? "fail"),
|
|
488
|
+
pointer: `/ci/green/phases/${pointerToken(name)}`,
|
|
489
|
+
}));
|
|
490
|
+
for (const [i, name] of g.require.entries()) {
|
|
491
|
+
if (phases.some((p) => p.name === name))
|
|
492
|
+
continue;
|
|
493
|
+
throw new WorkspaceReadError("declaration-invalid", `ci.green.require names the phase ${JSON.stringify(name)}, which ci.green.phases does not declare; declared phases: ${phases.map((p) => p.name).join(", ")}`, at(`/ci/green/require/${i}`));
|
|
494
|
+
}
|
|
495
|
+
return { green: { branch: g.branch, window: g.window ?? DEFAULT_CI_WINDOW, phases, require: [...g.require], pointer: "/ci/green" } };
|
|
496
|
+
}
|
|
497
|
+
function agentsOf(raw, members, at) {
|
|
498
|
+
const agents = (raw ?? []).map((a, i) => {
|
|
499
|
+
// The schema requires exactly one of member and members (ws-101).
|
|
500
|
+
const bound = a.members !== undefined ? [...a.members] : [a.member];
|
|
501
|
+
return {
|
|
502
|
+
name: a.name,
|
|
503
|
+
members: bound,
|
|
504
|
+
member: bound[0],
|
|
505
|
+
principals: [...(a.principals ?? [])],
|
|
506
|
+
pointer: `/agents/${i}`,
|
|
507
|
+
listed: a.members !== undefined,
|
|
508
|
+
};
|
|
509
|
+
});
|
|
510
|
+
const byName = new Map();
|
|
511
|
+
const byPrincipal = new Map();
|
|
512
|
+
for (const { listed, ...a } of agents) {
|
|
513
|
+
const first = byName.get(a.name);
|
|
514
|
+
if (first)
|
|
515
|
+
throw new WorkspaceReadError("declaration-invalid", `the agent name ${JSON.stringify(a.name)} is already used by the agent at ${first.pointer}`, at(`${a.pointer}/name`));
|
|
516
|
+
byName.set(a.name, a);
|
|
517
|
+
for (const [i, name] of a.members.entries()) {
|
|
518
|
+
if (members.some((m) => m.name === name))
|
|
519
|
+
continue;
|
|
520
|
+
throw new WorkspaceReadError("declaration-invalid", `agent ${a.name} is bound to ${JSON.stringify(name)}, which is not a declared member; an agent session is bound to members, not an example group`, at(listed ? `${a.pointer}/members/${i}` : `${a.pointer}/member`));
|
|
521
|
+
}
|
|
522
|
+
for (const [i, p] of a.principals.entries()) {
|
|
523
|
+
const other = byPrincipal.get(p);
|
|
524
|
+
if (other)
|
|
525
|
+
throw new WorkspaceReadError("declaration-invalid", `the principal ${JSON.stringify(p)} is already listed by agent ${other.name}`, at(`${a.pointer}/principals/${i}`));
|
|
526
|
+
byPrincipal.set(p, a);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return [...byName.values()];
|
|
530
|
+
}
|
|
531
|
+
/** The `changes` block, already validated, with its defaults (#2773). */
|
|
532
|
+
function changesOf(block) {
|
|
533
|
+
if (block === undefined)
|
|
534
|
+
return null;
|
|
535
|
+
return { severity: block.severity ?? "warn", ignore: [...(block.ignore ?? [])] };
|
|
536
|
+
}
|
|
537
|
+
/** The `records` list at `pointer`, already validated, with each kind file's path from the workspace root. */
|
|
538
|
+
function recordKindsOf(raw, dir, member, pointer) {
|
|
539
|
+
return (raw ?? []).map((r, i) => ({
|
|
540
|
+
kind: r.kind,
|
|
541
|
+
path: dir === "." ? r.kind : `${dir}/${r.kind}`,
|
|
542
|
+
name: r.name ?? null,
|
|
543
|
+
member,
|
|
544
|
+
pointer: `${pointer}/${i}`,
|
|
545
|
+
}));
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* The `diagrams` list at `pointer`, already validated. `source` and `render`
|
|
549
|
+
* are workspace-root-relative as written: unlike a generated file or a
|
|
550
|
+
* record kind, a diagram's files need not sit inside the declaring member's
|
|
551
|
+
* directory, so there is no member-relative form to resolve (#2764).
|
|
552
|
+
*/
|
|
553
|
+
function diagramsOf(raw, member, pointer) {
|
|
554
|
+
return (raw ?? []).map((d, i) => ({
|
|
555
|
+
name: d.name,
|
|
556
|
+
title: d.title,
|
|
557
|
+
source: d.source ?? null,
|
|
558
|
+
render: d.render ?? null,
|
|
559
|
+
renderer: { tool: d.renderer.tool, version: d.renderer.version, args: [...(d.renderer.args ?? [])] },
|
|
560
|
+
sourceHash: d.sourceHash ?? null,
|
|
561
|
+
member,
|
|
562
|
+
pointer: `${pointer}/${i}`,
|
|
563
|
+
}));
|
|
564
|
+
}
|
|
565
|
+
/** The `box` block at `pointer`, already validated, or null when there is none (#2726, #2727). */
|
|
566
|
+
function boxOf(raw, pointer) {
|
|
567
|
+
if (raw === undefined)
|
|
568
|
+
return null;
|
|
569
|
+
const b = raw;
|
|
570
|
+
const f = b.factory;
|
|
571
|
+
const l = b.listing;
|
|
572
|
+
const r = b.replicate;
|
|
573
|
+
return {
|
|
574
|
+
capabilities: (b.capabilities ?? []).map((c, i) => ({ name: c.name, broker: c.broker ?? null, scope: [...(c.scope ?? [])], pointer: `${pointer}/capabilities/${i}` })),
|
|
575
|
+
// The schema requires host and slot together, and host for ports, state and cookies.
|
|
576
|
+
isolation: b.host === undefined
|
|
577
|
+
? null
|
|
578
|
+
: { host: b.host, slot: b.slot, ports: { ...(b.ports ?? {}) }, state: { ...(b.state ?? {}) }, cookies: [...(b.cookies ?? [])] },
|
|
579
|
+
intent: b.intent ?? null,
|
|
580
|
+
services: (b.services ?? []).map((s, i) => ({
|
|
581
|
+
name: s.name,
|
|
582
|
+
cmd: s.cmd,
|
|
583
|
+
needs: [...(s.needs ?? [])],
|
|
584
|
+
httpPort: s.httpPort ?? null,
|
|
585
|
+
duration: s.duration ?? null,
|
|
586
|
+
health: s.health ?? null,
|
|
587
|
+
optional: s.optional ?? false,
|
|
588
|
+
pointer: `${pointer}/services/${i}`,
|
|
589
|
+
})),
|
|
590
|
+
factory: f === undefined
|
|
591
|
+
? null
|
|
592
|
+
: {
|
|
593
|
+
builds: [...f.builds],
|
|
594
|
+
check: f.check === undefined ? null : typeof f.check === "string" ? { run: f.check, kind: "test" } : { run: f.check.run, kind: f.check.kind ?? "test" },
|
|
595
|
+
checks: f.checks ?? null,
|
|
596
|
+
builders: f.builders ?? null,
|
|
597
|
+
tiers: (f.tiers ?? []).map((t) => ({ tier: t.tier, agent: t.agent, kinds: t.kinds === undefined ? null : [...t.kinds], session: t.session ?? null })),
|
|
598
|
+
publish: f.publish === undefined
|
|
599
|
+
? null
|
|
600
|
+
: {
|
|
601
|
+
forge: f.publish.forge ?? "github",
|
|
602
|
+
repo: f.publish.repo,
|
|
603
|
+
base: f.publish.base ?? null,
|
|
604
|
+
branchPrefix: f.publish.branchPrefix ?? DEFAULT_PUBLISH_BRANCH_PREFIX,
|
|
605
|
+
head: f.publish.head ?? null,
|
|
606
|
+
},
|
|
607
|
+
pointer: `${pointer}/factory`,
|
|
608
|
+
},
|
|
609
|
+
listing: l === undefined ? null : { published: l.published ?? true, title: l.title ?? "", line: l.line ?? "", cover: l.cover ?? null },
|
|
610
|
+
publisher: b.publisher ?? null,
|
|
611
|
+
ship: b.ship === undefined
|
|
612
|
+
? null
|
|
613
|
+
: {
|
|
614
|
+
op: b.ship.op,
|
|
615
|
+
gate: b.ship.gate ?? DEFAULT_SHIP_GATE,
|
|
616
|
+
env: b.ship.env ?? DEFAULT_SHIP_ENV,
|
|
617
|
+
bookkeeping: (b.ship.bookkeeping ?? []).map((p) => p.replace(/^\.\//, "").replace(/\/+$/, "")),
|
|
618
|
+
pointer: `${pointer}/ship`,
|
|
619
|
+
},
|
|
620
|
+
replicate: r === undefined
|
|
621
|
+
? null
|
|
622
|
+
: {
|
|
623
|
+
remote: r.remote ?? DEFAULT_REPLICATE_REMOTE,
|
|
624
|
+
// In the order the closed lists give, so a reader compares them without sorting.
|
|
625
|
+
refs: REPLICATE_REF_CLASSES.filter((c) => (r.refs ?? REPLICATE_REF_CLASSES).includes(c)),
|
|
626
|
+
on: REPLICATE_TRIGGERS.filter((t) => (r.on ?? REPLICATE_TRIGGERS).includes(t)),
|
|
627
|
+
every: r.every ?? null,
|
|
628
|
+
pointer: `${pointer}/replicate`,
|
|
629
|
+
},
|
|
630
|
+
pointer,
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* The rules the schema can't say about the factories (#3146, ws-077): at most
|
|
635
|
+
* one box block declares one, and the members its builds and builders name
|
|
636
|
+
* are declared members.
|
|
637
|
+
*/
|
|
638
|
+
function factoryProblem(members) {
|
|
639
|
+
const declaring = members.filter((m) => m.box?.factory);
|
|
640
|
+
if (declaring.length > 1) {
|
|
641
|
+
return {
|
|
642
|
+
message: `members ${declaring[0].name} and ${declaring[1].name} both declare a factory in their box block; a workspace has one factory, so an orchestrator reads one`,
|
|
643
|
+
pointer: declaring[1].box.factory.pointer,
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
const factory = declaring[0]?.box?.factory;
|
|
647
|
+
if (!factory)
|
|
648
|
+
return null;
|
|
649
|
+
const known = () => members.map((m) => m.name).join(", ");
|
|
650
|
+
const j = factory.builds.findIndex((name) => !members.some((m) => m.name === name));
|
|
651
|
+
if (j >= 0) {
|
|
652
|
+
return { message: `the factory builds ${JSON.stringify(factory.builds[j])}, which is not a declared member; declared members: ${known()}`, pointer: `${factory.pointer}/builds/${j}` };
|
|
653
|
+
}
|
|
654
|
+
if (factory.builders !== null && !members.some((m) => m.name === factory.builders)) {
|
|
655
|
+
return { message: `the factory's builders names ${JSON.stringify(factory.builders)}, which is not a declared member; declared members: ${known()}`, pointer: `${factory.pointer}/builders` };
|
|
656
|
+
}
|
|
657
|
+
// Builder tiers (#3152): their agents are the builders member's, and one entry answers each tier and kind.
|
|
658
|
+
if (factory.tiers.length > 0 && factory.builders === null) {
|
|
659
|
+
return { message: "the factory declares tiers and no builders; tiers name agents the builders member declares, so name it", pointer: `${factory.pointer}/tiers` };
|
|
660
|
+
}
|
|
661
|
+
const answered = new Map();
|
|
662
|
+
for (const [i, t] of factory.tiers.entries()) {
|
|
663
|
+
for (const kind of t.kinds ?? [null]) {
|
|
664
|
+
const key = `${t.tier}\0${kind ?? ""}`;
|
|
665
|
+
const first = answered.get(key);
|
|
666
|
+
if (first !== undefined) {
|
|
667
|
+
const which = kind === null ? "with no kinds" : `for kind ${kind}`;
|
|
668
|
+
return { message: `tiers/${first} and tiers/${i} both name a builder at tier ${t.tier} ${which}; a tier has one builder per kind, so one entry answers it`, pointer: `${factory.pointer}/tiers/${i}` };
|
|
669
|
+
}
|
|
670
|
+
answered.set(key, i);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return null;
|
|
674
|
+
}
|
|
675
|
+
/** The rule the schema can't say about the factory's tiers once the sessions are read (#3152): a session is a declared agent session. */
|
|
676
|
+
function factoryTierSessionProblem(members, agents) {
|
|
677
|
+
const factory = members.find((m) => m.box?.factory)?.box?.factory;
|
|
678
|
+
if (!factory)
|
|
679
|
+
return null;
|
|
680
|
+
for (const [i, t] of factory.tiers.entries()) {
|
|
681
|
+
if (t.session !== null && !agents.some((a) => a.name === t.session)) {
|
|
682
|
+
const known = agents.map((a) => a.name).join(", ") || "none";
|
|
683
|
+
return { message: `tiers/${i} names the session ${JSON.stringify(t.session)}, which is not a declared agent session; declared sessions: ${known}`, pointer: `${factory.pointer}/tiers/${i}/session` };
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* The rules the schema can't say about a box's services (#2880), as a
|
|
690
|
+
* message and the pointer to show, or null when they hold: each name is
|
|
691
|
+
* given once, every `needs` names a service of the same block, the `needs`
|
|
692
|
+
* form no cycle, and at most one service sets `httpPort`. The fly lexicon
|
|
693
|
+
* checks a list it is handed inline with the same rules.
|
|
694
|
+
*/
|
|
695
|
+
export function boxServicesProblem(member, services) {
|
|
696
|
+
const byName = new Map();
|
|
697
|
+
for (const s of services) {
|
|
698
|
+
const first = byName.get(s.name);
|
|
699
|
+
if (first)
|
|
700
|
+
return { message: `member ${member}'s box declares the service ${s.name} twice; the first is at ${first.pointer}`, pointer: `${s.pointer}/name` };
|
|
701
|
+
byName.set(s.name, s);
|
|
702
|
+
}
|
|
703
|
+
let routed;
|
|
704
|
+
for (const s of services) {
|
|
705
|
+
if (s.httpPort === null)
|
|
706
|
+
continue;
|
|
707
|
+
if (routed) {
|
|
708
|
+
return {
|
|
709
|
+
message: `member ${member}'s box gives both ${routed.name} (port ${routed.httpPort}) and ${s.name} (port ${s.httpPort}) an httpPort, and the supervisor routes the sprite's URL to one service`,
|
|
710
|
+
pointer: `${s.pointer}/httpPort`,
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
routed = s;
|
|
714
|
+
}
|
|
715
|
+
for (const s of services) {
|
|
716
|
+
const j = s.needs.findIndex((n) => !byName.has(n));
|
|
717
|
+
if (j >= 0) {
|
|
718
|
+
const known = services.map((x) => x.name).join(", ");
|
|
719
|
+
return { message: `member ${member}'s box service ${s.name} needs ${JSON.stringify(s.needs[j])}, which the block does not declare; declared services: ${known}`, pointer: `${s.pointer}/needs/${j}` };
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
const cycle = serviceCycle(services);
|
|
723
|
+
if (cycle) {
|
|
724
|
+
const s = byName.get(cycle[0]);
|
|
725
|
+
return { message: `member ${member}'s box services need each other in a cycle: ${cycle.join(" -> ")}`, pointer: `${s.pointer}/needs` };
|
|
726
|
+
}
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
/** The first cycle the services' `needs` form, as names ending where it starts, or null. */
|
|
730
|
+
function serviceCycle(services) {
|
|
731
|
+
const byName = new Map(services.map((s) => [s.name, s]));
|
|
732
|
+
const state = new Map();
|
|
733
|
+
const visit = (name, trail) => {
|
|
734
|
+
const st = state.get(name);
|
|
735
|
+
if (st === "done")
|
|
736
|
+
return null;
|
|
737
|
+
if (st === "visiting")
|
|
738
|
+
return [...trail.slice(trail.indexOf(name)), name];
|
|
739
|
+
state.set(name, "visiting");
|
|
740
|
+
for (const dep of byName.get(name)?.needs ?? []) {
|
|
741
|
+
const found = visit(dep, [...trail, name]);
|
|
742
|
+
if (found)
|
|
743
|
+
return found;
|
|
744
|
+
}
|
|
745
|
+
state.set(name, "done");
|
|
746
|
+
return null;
|
|
747
|
+
};
|
|
748
|
+
for (const s of services) {
|
|
749
|
+
const found = visit(s.name, []);
|
|
750
|
+
if (found)
|
|
751
|
+
return found;
|
|
752
|
+
}
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* The hosts, already validated, with the rules the schema can't say (#2727):
|
|
757
|
+
* host names are unique, a box's host is declared, its slot's block fits the
|
|
758
|
+
* host's range and its offsets fit the block. What two boxes resolve to is
|
|
759
|
+
* `chant workspace check`'s question (WSP123), not a read error.
|
|
760
|
+
*/
|
|
761
|
+
function hostsOf(obj, members, at) {
|
|
762
|
+
const hosts = (obj.hosts ?? []).map((h, i) => ({
|
|
763
|
+
name: h.name,
|
|
764
|
+
ports: { ...h.ports },
|
|
765
|
+
stateRoot: h.stateRoot ?? null,
|
|
766
|
+
pointer: `/hosts/${i}`,
|
|
767
|
+
}));
|
|
768
|
+
const invalid = (message, pointer) => new WorkspaceReadError("declaration-invalid", message, at(pointer));
|
|
769
|
+
const byName = new Map();
|
|
770
|
+
for (const h of hosts) {
|
|
771
|
+
const first = byName.get(h.name);
|
|
772
|
+
if (first)
|
|
773
|
+
throw invalid(`the host name ${JSON.stringify(h.name)} is already used by the host at ${first.pointer}`, `${h.pointer}/name`);
|
|
774
|
+
byName.set(h.name, h);
|
|
775
|
+
if (h.ports.from > h.ports.to)
|
|
776
|
+
throw invalid(`host ${h.name}'s port range starts at ${h.ports.from}, after its end ${h.ports.to}`, `${h.pointer}/ports`);
|
|
777
|
+
}
|
|
778
|
+
for (const m of members) {
|
|
779
|
+
const iso = m.box?.isolation;
|
|
780
|
+
if (!iso)
|
|
781
|
+
continue;
|
|
782
|
+
const box = m.box.pointer;
|
|
783
|
+
const host = byName.get(iso.host);
|
|
784
|
+
if (!host) {
|
|
785
|
+
const known = hosts.map((h) => h.name).join(", ") || "none are declared";
|
|
786
|
+
throw invalid(`member ${m.name}'s box names the host ${JSON.stringify(iso.host)}, which hosts does not declare; declared hosts: ${known}`, `${box}/host`);
|
|
787
|
+
}
|
|
788
|
+
const { from, to, perBox } = host.ports;
|
|
789
|
+
const last = from + (iso.slot + 1) * perBox - 1;
|
|
790
|
+
if (last > to) {
|
|
791
|
+
const slots = Math.floor((to - from + 1) / perBox);
|
|
792
|
+
throw invalid(`member ${m.name}'s box has slot ${iso.slot} on host ${host.name}, which needs ports ${from + iso.slot * perBox} to ${last}, past the end of the host's range (${to}); the range holds ${slots} slot${slots === 1 ? "" : "s"}`, `${box}/slot`);
|
|
793
|
+
}
|
|
794
|
+
for (const [port, offset] of Object.entries(iso.ports)) {
|
|
795
|
+
if (offset >= perBox) {
|
|
796
|
+
throw invalid(`member ${m.name}'s box gives port ${port} offset ${offset}, and host ${host.name} gives each box ${perBox} port${perBox === 1 ? "" : "s"} (offsets 0 to ${perBox - 1})`, `${box}/ports/${pointerToken(port)}`);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return hosts;
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* Every record kind the declaration names (#2680), in the order readers use
|
|
804
|
+
* them: the workspace's own first, then each member's, members in file order
|
|
805
|
+
* and each list in its own order.
|
|
806
|
+
*/
|
|
807
|
+
export function declaredRecordKinds(declaration) {
|
|
808
|
+
return [...declaration.records, ...declaration.members.flatMap((m) => m.records)];
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Every diagram artifact the declaration names (#2764), in the order readers
|
|
812
|
+
* use them: the workspace's own first, then each member's, members in file
|
|
813
|
+
* order and each list in its own order.
|
|
814
|
+
*/
|
|
815
|
+
export function declaredDiagrams(declaration) {
|
|
816
|
+
return [...declaration.diagrams, ...declaration.members.flatMap((m) => m.diagrams)];
|
|
817
|
+
}
|
|
818
|
+
/** Whether `path` is `dir` or sits under it. Both are tree-relative; `"."` is the root. */
|
|
819
|
+
export function isInside(path, dir) {
|
|
820
|
+
if (dir === ".")
|
|
821
|
+
return true;
|
|
822
|
+
return path === dir || path.startsWith(`${dir}/`);
|
|
823
|
+
}
|
|
824
|
+
// ── Reading from a tree ──────────────────────────────────────────────────────
|
|
825
|
+
/**
|
|
826
|
+
* Read the declaration in directory `dir` of `tree`. Throws
|
|
827
|
+
* `declaration-missing` when neither name is there and
|
|
828
|
+
* `declaration-ambiguous` when both are.
|
|
829
|
+
*/
|
|
830
|
+
export function readDeclaration(tree, dir = "", options = {}) {
|
|
831
|
+
const present = DECLARATION_FILES.map((name) => joinPath(dir, name)).filter((p) => tree.stat(p) === "file");
|
|
832
|
+
if (present.length === 0) {
|
|
833
|
+
throw new WorkspaceReadError("declaration-missing", `no ${DECLARATION_FILES.join(" or ")} in ${dir || "the workspace root"}${tree.label}`);
|
|
834
|
+
}
|
|
835
|
+
if (present.length > 1) {
|
|
836
|
+
throw new WorkspaceReadError("declaration-ambiguous", `both ${present.join(" and ")} exist${tree.label}; keep one of them`, { file: present[1], line: 1, column: 1 });
|
|
837
|
+
}
|
|
838
|
+
return parseDeclaration(tree.read(present[0]), present[0], readerVersion(), options);
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Walk up from `start` (tree-relative) to the nearest directory holding a
|
|
842
|
+
* declaration, within `tree`. The tree's root is the git root, so this is
|
|
843
|
+
* `findWorkspaceRoot` for a revision. Returns the directory, or undefined.
|
|
844
|
+
*/
|
|
845
|
+
export function findDeclarationDir(tree, start) {
|
|
846
|
+
for (let dir = start;; dir = dir.includes("/") ? dir.slice(0, dir.lastIndexOf("/")) : "") {
|
|
847
|
+
if (DECLARATION_FILES.some((name) => tree.stat(joinPath(dir, name)) === "file"))
|
|
848
|
+
return dir;
|
|
849
|
+
if (dir === "")
|
|
850
|
+
return undefined;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Expand every group's globs in `tree` (rooted at the workspace root) and
|
|
855
|
+
* check where the matches sit (ws-051): a match is never a member's directory
|
|
856
|
+
* and never contains one, it doesn't sit inside a nested workspace, and no
|
|
857
|
+
* two groups claim the same directory. A match may sit inside any other
|
|
858
|
+
* member's directory; that member leaves it to the group.
|
|
859
|
+
*/
|
|
860
|
+
export function resolveGroups(declaration, tree) {
|
|
861
|
+
const at = (g) => ({ file: declaration.file, ...g.globLocation });
|
|
862
|
+
const claimed = new Map();
|
|
863
|
+
const resolved = [];
|
|
864
|
+
for (const group of declaration.groups) {
|
|
865
|
+
const dirs = [...new Set(group.globs.flatMap((g) => expandGlob(tree, g)))].sort();
|
|
866
|
+
const matches = [];
|
|
867
|
+
const skipped = [];
|
|
868
|
+
for (const dir of dirs) {
|
|
869
|
+
if (!holdsChantProject(tree, dir)) {
|
|
870
|
+
skipped.push(dir);
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
const clash = (message) => new WorkspaceReadError("placement-invalid", `group ${group.name} matches ${dir}, ${message}`, at(group));
|
|
874
|
+
for (const m of declaration.members) {
|
|
875
|
+
if (m.dir === ".")
|
|
876
|
+
continue;
|
|
877
|
+
if (m.dir === dir)
|
|
878
|
+
throw clash(`which is member ${m.name}'s directory; a match is never a member`);
|
|
879
|
+
if (isInside(m.dir, dir))
|
|
880
|
+
throw clash(`which contains member ${m.name} (${m.dir})`);
|
|
881
|
+
if (m.kind === "workspace" && isInside(dir, m.dir)) {
|
|
882
|
+
throw clash(`which sits inside the nested workspace ${m.name}; that workspace declares its own examples`);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
const other = claimed.get(dir);
|
|
886
|
+
if (other)
|
|
887
|
+
throw clash(`which group ${other.name} also matches`);
|
|
888
|
+
claimed.set(dir, group);
|
|
889
|
+
matches.push(dir);
|
|
890
|
+
}
|
|
891
|
+
resolved.push({ group, matches, skipped });
|
|
892
|
+
}
|
|
893
|
+
return resolved;
|
|
894
|
+
}
|
|
895
|
+
// ── Ownership ────────────────────────────────────────────────────────────────
|
|
896
|
+
/**
|
|
897
|
+
* Which entry owns `path` (relative to the workspace root): the group whose
|
|
898
|
+
* match holds it, else the member with the deepest directory holding it, else
|
|
899
|
+
* none. A group match wins over the member whose directory it sits in
|
|
900
|
+
* (ws-051). Ledgers (#2538), telemetry attribution (#2558) and the root
|
|
901
|
+
* project's discovery (#2537) all ask this question.
|
|
902
|
+
*/
|
|
903
|
+
export function ownerOf(declaration, groups, path) {
|
|
904
|
+
for (const g of groups) {
|
|
905
|
+
const match = g.matches.find((m) => isInside(path, m));
|
|
906
|
+
if (match)
|
|
907
|
+
return { group: g.group, match };
|
|
908
|
+
}
|
|
909
|
+
let best;
|
|
910
|
+
for (const m of declaration.members) {
|
|
911
|
+
if (!isInside(path, m.dir))
|
|
912
|
+
continue;
|
|
913
|
+
if (!best || best.dir === "." || (m.dir !== "." && m.dir.length > best.dir.length))
|
|
914
|
+
best = m;
|
|
915
|
+
}
|
|
916
|
+
return best ? { member: best } : undefined;
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* The directories that leave the root project once the declaration exists
|
|
920
|
+
* (#2524 D0, D2): every member's directory but the root's, and every group
|
|
921
|
+
* match. The root project's build, lint, Op and audit discovery skip them
|
|
922
|
+
* (#2537); `chant workspace init` prints them before it writes.
|
|
923
|
+
*/
|
|
924
|
+
export function rootExclusions(declaration, groups) {
|
|
925
|
+
const out = [];
|
|
926
|
+
for (const m of declaration.members)
|
|
927
|
+
if (m.dir !== ".")
|
|
928
|
+
out.push({ dir: m.dir, owner: m.name });
|
|
929
|
+
for (const g of groups) {
|
|
930
|
+
for (const dir of g.matches) {
|
|
931
|
+
// A match inside a member's directory already left with that member.
|
|
932
|
+
if (declaration.members.some((m) => m.dir !== "." && isInside(dir, m.dir)))
|
|
933
|
+
continue;
|
|
934
|
+
out.push({ dir, owner: g.group.name });
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
return out.sort((a, b) => (a.dir < b.dir ? -1 : a.dir > b.dir ? 1 : 0));
|
|
938
|
+
}
|