@intentius/chant 0.101.0 → 0.104.0
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/dist/agents/checks.d.ts.map +1 -1
- package/dist/attrref.d.ts.map +1 -1
- package/dist/audit/core.d.ts +2 -0
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/nginx.d.ts.map +1 -1
- package/dist/audit/prior-art.d.ts +48 -0
- package/dist/audit/prior-art.d.ts.map +1 -1
- package/dist/behaviour-kinds.d.ts.map +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/change-set.d.ts +232 -0
- package/dist/change-set.d.ts.map +1 -0
- package/dist/cli/commands/audit.d.ts +7 -0
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/carve-emit.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.d.ts +16 -0
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/import.d.ts +8 -0
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +19 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts +9 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
- package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.d.ts +11 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -0
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.d.ts +33 -0
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +16 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/pr.d.ts +31 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -0
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/lsp/server.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/tools/build.d.ts.map +1 -1
- package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
- package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
- package/dist/cli/mcp/tools/import.d.ts.map +1 -1
- package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
- package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
- package/dist/cli/mcp/tools/search.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts +4 -3
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +74 -3
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/codegen/naming.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.d.ts +67 -3
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/registry.d.ts.map +1 -1
- package/dist/components/auto-release.d.ts +16 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability.d.ts +53 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/changed-files.d.ts +31 -0
- package/dist/components/changed-files.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +9 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +24 -0
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/driver.d.ts +13 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-output.d.ts +6 -0
- package/dist/components/fan-out-output.d.ts.map +1 -1
- package/dist/components/fan-out-record.d.ts +41 -0
- package/dist/components/fan-out-record.d.ts.map +1 -0
- package/dist/components/fan-out-run.d.ts +65 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts +2 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out.d.ts +6 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/gated-wave-pipeline.d.ts +50 -0
- package/dist/components/gated-wave-pipeline.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layers.d.ts +25 -0
- package/dist/components/layers.d.ts.map +1 -0
- package/dist/components/pr-pipeline.d.ts +61 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -0
- package/dist/components/pr-run.d.ts +119 -0
- package/dist/components/pr-run.d.ts.map +1 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/verbs/process-runner.d.ts.map +1 -1
- package/dist/components/verbs/r2-sync.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
- package/dist/components/verbs/shell.d.ts.map +1 -1
- package/dist/components/verbs/sign.d.ts.map +1 -1
- package/dist/components/verbs/verify.d.ts.map +1 -1
- package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
- package/dist/components/verbs/wrangler.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +49 -0
- package/dist/components/wave-plan.d.ts.map +1 -0
- package/dist/composite.d.ts.map +1 -1
- package/dist/config.d.ts +19 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/declarable.d.ts +16 -0
- package/dist/declarable.d.ts.map +1 -1
- package/dist/discovery/cache.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +15 -5
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +16 -0
- package/dist/discovery/param-deps.d.ts.map +1 -1
- package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
- package/dist/discovery/specifier-resolve.d.ts +37 -0
- package/dist/discovery/specifier-resolve.d.ts.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/fold/fold.d.ts +3 -1
- package/dist/fold/fold.d.ts.map +1 -1
- package/dist/gated-waves.d.ts +147 -0
- package/dist/gated-waves.d.ts.map +1 -0
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-layout.d.ts.map +1 -1
- package/dist/import/base-parser.d.ts.map +1 -1
- package/dist/import/embedded.d.ts +7 -0
- package/dist/import/embedded.d.ts.map +1 -1
- package/dist/import/parser-options.d.ts +14 -0
- package/dist/import/parser-options.d.ts.map +1 -0
- package/dist/import/parser.d.ts +17 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kubectl-context.d.ts.map +1 -1
- package/dist/lexicon-output.d.ts.map +1 -1
- package/dist/lexicon-schema.d.ts +3 -3
- package/dist/lexicon.d.ts +103 -3
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/assert-live.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +22 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +46 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/member-ledger.d.ts.map +1 -1
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lifecycle/work-lease.d.ts +61 -2
- package/dist/lifecycle/work-lease.d.ts.map +1 -1
- package/dist/lint/config.d.ts +8 -8
- package/dist/lint/engine.d.ts +6 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lint/post-synth.d.ts +18 -0
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +137 -11
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/apply.d.ts +79 -9
- package/dist/op/activities/apply.d.ts.map +1 -1
- package/dist/op/activities/change-set.d.ts +62 -0
- package/dist/op/activities/change-set.d.ts.map +1 -0
- package/dist/op/activities/decide.d.ts +2 -0
- package/dist/op/activities/decide.d.ts.map +1 -1
- package/dist/op/activities/factory.d.ts +137 -0
- package/dist/op/activities/factory.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +5 -1
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
- package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
- package/dist/op/activity-contract.d.ts +1 -1
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-profiles.d.ts.map +1 -1
- package/dist/op/builders.d.ts +11 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/apply-op.d.ts +12 -5
- package/dist/op/composites/apply-op.d.ts.map +1 -1
- package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
- package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts +5 -1
- package/dist/op/decide-backend.d.ts.map +1 -1
- package/dist/op/decide-read-inputs.d.ts +4 -2
- package/dist/op/decide-read-inputs.d.ts.map +1 -1
- package/dist/op/emulator-lifecycle.d.ts +21 -2
- package/dist/op/emulator-lifecycle.d.ts.map +1 -1
- package/dist/op/factory.d.ts +83 -0
- package/dist/op/factory.d.ts.map +1 -0
- package/dist/op/gate-approval.d.ts +5 -1
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-wait.d.ts.map +1 -1
- package/dist/op/gate.d.ts +19 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/index.d.ts +6 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +6 -0
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/op-ir.d.ts +2 -0
- package/dist/op/op-ir.d.ts.map +1 -1
- package/dist/op/op-verb-class.d.ts.map +1 -1
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/run-context.d.ts +39 -0
- package/dist/op/run-context.d.ts.map +1 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/source-archive.d.ts.map +1 -1
- package/dist/op/steward-beside.d.ts.map +1 -1
- package/dist/op/steward-points.d.ts.map +1 -1
- package/dist/op/steward.d.ts.map +1 -1
- package/dist/op/types.d.ts +16 -3
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts +24 -4
- package/dist/op/work-lease-run.d.ts.map +1 -1
- package/dist/plan-summary.d.ts +207 -0
- package/dist/plan-summary.d.ts.map +1 -0
- package/dist/pr-forge.d.ts +105 -0
- package/dist/pr-forge.d.ts.map +1 -0
- package/dist/pr-loop.d.ts +178 -0
- package/dist/pr-loop.d.ts.map +1 -0
- package/dist/project-root.d.ts.map +1 -1
- package/dist/provenance.d.ts +21 -0
- package/dist/provenance.d.ts.map +1 -1
- package/dist/pseudo-parameter.d.ts.map +1 -1
- package/dist/reconcile.d.ts.map +1 -1
- package/dist/secret-materialization.d.ts.map +1 -1
- package/dist/telemetry-attribution.d.ts +31 -0
- package/dist/telemetry-attribution.d.ts.map +1 -1
- package/dist/terraform/emit-source.d.ts.map +1 -1
- package/dist/terraform/hcl2json.d.ts +45 -0
- package/dist/terraform/hcl2json.d.ts.map +1 -0
- package/dist/terraform/parse.d.ts +4 -40
- package/dist/terraform/parse.d.ts.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
- package/dist/workspace/agent-cli.d.ts +5 -0
- package/dist/workspace/agent-cli.d.ts.map +1 -1
- package/dist/workspace/box-cli.d.ts +12 -0
- package/dist/workspace/box-cli.d.ts.map +1 -0
- package/dist/workspace/box-factory.d.ts +97 -0
- package/dist/workspace/box-factory.d.ts.map +1 -0
- package/dist/workspace/box-listing.d.ts +85 -0
- package/dist/workspace/box-listing.d.ts.map +1 -0
- package/dist/workspace/box-publish.d.ts +147 -0
- package/dist/workspace/box-publish.d.ts.map +1 -0
- package/dist/workspace/broker-protocol.d.ts +190 -0
- package/dist/workspace/broker-protocol.d.ts.map +1 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
- package/dist/workspace/checks/boxes.d.ts.map +1 -1
- package/dist/workspace/checks.d.ts +5 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/compose-graph.d.ts +10 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/composites.d.ts +2 -2
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
- package/dist/workspace/conformance/broker.d.ts +202 -0
- package/dist/workspace/conformance/broker.d.ts.map +1 -0
- package/dist/workspace/conformance/index.d.ts +68 -6
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/vitest.d.ts +19 -3
- package/dist/workspace/conformance/vitest.d.ts.map +1 -1
- package/dist/workspace/conformance/writer.d.ts +462 -0
- package/dist/workspace/conformance/writer.d.ts.map +1 -0
- package/dist/workspace/decide.d.ts +126 -12
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/decision-points.schema.json +11 -4
- package/dist/workspace/declaration.d.ts +156 -4
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +383 -5
- package/dist/workspace/environments.d.ts +36 -10
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/factory-rules.d.ts +180 -0
- package/dist/workspace/factory-rules.d.ts.map +1 -0
- package/dist/workspace/generated-files.d.ts.map +1 -1
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/identity.d.ts +111 -0
- package/dist/workspace/identity.d.ts.map +1 -0
- package/dist/workspace/init.d.ts +21 -0
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/intent-cli.d.ts +7 -4
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-record.d.ts +36 -2
- package/dist/workspace/intent-record.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts +249 -8
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/json-edit.d.ts +24 -0
- package/dist/workspace/json-edit.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +11 -0
- package/dist/workspace/jsonc.d.ts.map +1 -1
- package/dist/workspace/kinds.d.ts +66 -4
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/lexicon-symbols.d.ts +29 -0
- package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
- package/dist/workspace/lineage-hash-index.d.ts.map +1 -1
- package/dist/workspace/lineage-lock.d.ts +2 -2
- package/dist/workspace/lineage-lock.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.d.ts +31 -2
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/point-answer.schema.json +42 -2
- package/dist/workspace/points-cli.d.ts +10 -3
- package/dist/workspace/points-cli.d.ts.map +1 -1
- package/dist/workspace/points.d.ts +66 -5
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/principal-classes.d.ts +114 -0
- package/dist/workspace/principal-classes.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +53 -4
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/record-assets.d.ts.map +1 -1
- package/dist/workspace/record-sessions.d.ts +5 -7
- package/dist/workspace/record-sessions.d.ts.map +1 -1
- package/dist/workspace/records-checkout.d.ts +54 -0
- package/dist/workspace/records-checkout.d.ts.map +1 -0
- package/dist/workspace/records-cli.d.ts +34 -1
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +7 -3
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-since.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +68 -7
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +43 -9
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/runs-cli.d.ts +296 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -0
- package/dist/workspace/runs.d.ts +544 -0
- package/dist/workspace/runs.d.ts.map +1 -0
- package/dist/workspace/session-kinds.d.ts +1 -1
- package/dist/workspace/session-kinds.d.ts.map +1 -1
- package/dist/workspace/source-block.d.ts +1 -1
- package/dist/workspace/source-block.d.ts.map +1 -1
- package/dist/workspace/squash.d.ts +80 -0
- package/dist/workspace/squash.d.ts.map +1 -0
- package/dist/workspace/status-gates.d.ts +17 -3
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +64 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/symbols.d.ts +63 -0
- package/dist/workspace/symbols.d.ts.map +1 -0
- package/dist/workspace/trailer-joins.d.ts +46 -0
- package/dist/workspace/trailer-joins.d.ts.map +1 -0
- package/dist/workspace/trailers.d.ts +89 -0
- package/dist/workspace/trailers.d.ts.map +1 -0
- package/dist/workspace/trust/attestor.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/run-commits.d.ts +46 -0
- package/dist/workspace/trust/run-commits.d.ts.map +1 -0
- package/dist/workspace/trust/run-statement.d.ts +128 -0
- package/dist/workspace/trust/run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/seal.d.ts +38 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/test-repo.d.ts.map +1 -1
- package/dist/workspace/trust/verify-cli.d.ts +1 -1
- package/dist/workspace/trust/verify.d.ts +16 -2
- package/dist/workspace/trust/verify.d.ts.map +1 -1
- package/dist/workspace/wip-cli.d.ts +21 -0
- package/dist/workspace/wip-cli.d.ts.map +1 -0
- package/dist/workspace/wip.d.ts +268 -0
- package/dist/workspace/wip.d.ts.map +1 -0
- package/dist/workspace/work-cli.d.ts +39 -3
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-evidence.d.ts +1 -1
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work-size.d.ts +55 -0
- package/dist/workspace/work-size.d.ts.map +1 -0
- package/dist/workspace/work.d.ts +26 -1
- package/dist/workspace/work.d.ts.map +1 -1
- package/dist/workspace/workspace-kinds.schema.json +122 -0
- package/dist/workspace/workspace-principals.schema.json +60 -0
- package/dist/workspace/write-lock-cli.d.ts +60 -0
- package/dist/workspace/write-lock-cli.d.ts.map +1 -0
- package/dist/workspace/write-lock.d.ts +152 -0
- package/dist/workspace/write-lock.d.ts.map +1 -0
- package/dist/workspace/write-scope.d.ts +83 -19
- package/dist/workspace/write-scope.d.ts.map +1 -1
- package/dist/yaml.d.ts +21 -39
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +7 -2
- package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
- package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
- package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
- package/src/__fixtures__/change-set/warden.plan.json +44 -0
- package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
- package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
- package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
- package/src/audit/core.test.ts +15 -0
- package/src/audit/core.ts +8 -2
- package/src/audit/discover.test.ts +11 -0
- package/src/audit/discover.ts +7 -2
- package/src/audit/prior-art.ts +15 -0
- package/src/change-set-bundle.test.ts +57 -0
- package/src/change-set.test.ts +215 -0
- package/src/change-set.ts +445 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
- package/src/cli/commands/audit-opt-in.test.ts +54 -0
- package/src/cli/commands/audit.ts +29 -2
- package/src/cli/commands/build.test.ts +19 -0
- package/src/cli/commands/build.ts +3 -2
- package/src/cli/commands/carve-emit-state.test.ts +4 -0
- package/src/cli/commands/carve-emit.ts +5 -19
- package/src/cli/commands/check-lexicon.test.ts +62 -1
- package/src/cli/commands/check-lexicon.ts +36 -6
- package/src/cli/commands/import-live.test.ts +18 -0
- package/src/cli/commands/import-parser-options.test.ts +133 -0
- package/src/cli/commands/import.ts +21 -3
- package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
- package/src/cli/commands/init.test.ts +8 -1
- package/src/cli/commands/init.ts +23 -8
- package/src/cli/commands/lint.test.ts +37 -0
- package/src/cli/commands/onboard.test.ts +53 -3
- package/src/cli/commands/onboard.ts +52 -4
- package/src/cli/commands/pinned-upgrade.ts +73 -33
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
- package/src/cli/handlers/build.ts +13 -1
- package/src/cli/handlers/change-set.test.ts +56 -0
- package/src/cli/handlers/change-set.ts +44 -0
- package/src/cli/handlers/components.ts +2 -2
- package/src/cli/handlers/dev.ts +8 -6
- package/src/cli/handlers/fan-out.test.ts +221 -2
- package/src/cli/handlers/fan-out.ts +165 -75
- package/src/cli/handlers/graph.ts +3 -0
- package/src/cli/handlers/lifecycle.test.ts +67 -0
- package/src/cli/handlers/lifecycle.ts +6 -5
- package/src/cli/handlers/misc.ts +2 -0
- package/src/cli/handlers/operator.test.ts +21 -0
- package/src/cli/handlers/operator.ts +121 -6
- package/src/cli/handlers/pr.ts +373 -0
- package/src/cli/handlers/run.test.ts +111 -0
- package/src/cli/handlers/run.ts +86 -24
- package/src/cli/handlers/scenario.ts +2 -2
- package/src/cli/main.test.ts +21 -0
- package/src/cli/main.ts +246 -30
- package/src/cli/mcp/never-over-mcp.test.ts +101 -0
- package/src/cli/mcp/op-tools.ts +24 -2
- package/src/cli/mcp/workspace-tools.test.ts +5 -2
- package/src/cli/mcp/workspace-tools.ts +62 -7
- package/src/cli/registry.ts +74 -3
- package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
- package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
- package/src/codegen/pinned-upgrade.test.ts +104 -0
- package/src/codegen/pinned-upgrade.ts +250 -56
- package/src/codegen/testdata/postgres-tags.json +242 -0
- package/src/components/auto-release.ts +1 -1
- package/src/components/capability.ts +55 -0
- package/src/components/changed-files.ts +66 -0
- package/src/components/cli-support.ts +28 -5
- package/src/components/component.schema.json +17 -0
- package/src/components/component.ts +25 -0
- package/src/components/deploy-units.ts +3 -0
- package/src/components/driver.test.ts +52 -0
- package/src/components/driver.ts +31 -13
- package/src/components/fan-out-output.ts +42 -1
- package/src/components/fan-out-record.ts +69 -0
- package/src/components/fan-out-run.test.ts +17 -0
- package/src/components/fan-out-run.ts +304 -1
- package/src/components/fan-out-support.ts +3 -0
- package/src/components/fan-out-waves.test.ts +375 -0
- package/src/components/fan-out.ts +18 -17
- package/src/components/gated-wave-pipeline.ts +82 -0
- package/src/components/index.ts +1 -0
- package/src/components/layers.ts +30 -0
- package/src/components/pr-pipeline.ts +91 -0
- package/src/components/pr-run.test.ts +205 -0
- package/src/components/pr-run.ts +280 -0
- package/src/components/promote.ts +5 -0
- package/src/components/verbs/shell.test.ts +11 -0
- package/src/components/verbs/shell.ts +7 -3
- package/src/components/wave-plan.ts +124 -0
- package/src/config.test.ts +21 -0
- package/src/config.ts +15 -0
- package/src/declarable.test.ts +21 -0
- package/src/declarable.ts +19 -0
- package/src/discovery/fold-composite.test.ts +41 -5
- package/src/discovery/fold-import.test.ts +129 -0
- package/src/discovery/fold-import.ts +643 -131
- package/src/discovery/fold-package-composite.test.ts +264 -0
- package/src/discovery/fold-specifiers.test.ts +191 -0
- package/src/discovery/param-deps.test.ts +66 -1
- package/src/discovery/param-deps.ts +45 -0
- package/src/discovery/sandbox/bundle.ts +1 -1
- package/src/discovery/specifier-resolve.ts +344 -0
- package/src/fold/fold.test.ts +39 -1
- package/src/fold/fold.ts +83 -9
- package/src/fold-provenance.test.ts +140 -0
- package/src/gated-waves-bundle.test.ts +62 -0
- package/src/gated-waves.test.ts +118 -0
- package/src/gated-waves.ts +240 -0
- package/src/graph-ir.test.ts +83 -0
- package/src/graph-ir.ts +29 -0
- package/src/import/embedded.test.ts +20 -0
- package/src/import/embedded.ts +13 -0
- package/src/import/parser-options.ts +46 -0
- package/src/import/parser.ts +20 -0
- package/src/index.ts +1 -0
- package/src/lexicon.ts +106 -3
- package/src/lifecycle/gate-ledger.ts +23 -0
- package/src/lifecycle/git.ts +102 -16
- package/src/lifecycle/observe.test.ts +18 -0
- package/src/lifecycle/observe.ts +6 -4
- package/src/lifecycle/snapshot.ts +2 -2
- package/src/lifecycle/work-lease.test.ts +1 -1
- package/src/lifecycle/work-lease.ts +93 -2
- package/src/lint/engine.test.ts +55 -0
- package/src/lint/engine.ts +30 -4
- package/src/lint/output-docs.test.ts +59 -56
- package/src/lint/post-synth.test.ts +19 -0
- package/src/lint/post-synth.ts +19 -1
- package/src/meta/declared-imports.test.ts +1 -1
- package/src/op/activities/activity-contracts.ts +84 -0
- package/src/op/activities/apply.test.ts +189 -5
- package/src/op/activities/apply.ts +230 -8
- package/src/op/activities/change-set.ts +114 -0
- package/src/op/activities/decide.ts +3 -0
- package/src/op/activities/factory.ts +675 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/lexicon-upgrade.test.ts +160 -6
- package/src/op/activities/lexicon-upgrade.ts +154 -51
- package/src/op/activity-contract.test.ts +21 -1
- package/src/op/activity-contract.ts +19 -9
- package/src/op/builders.ts +23 -0
- package/src/op/composites/apply-op.ts +12 -5
- package/src/op/composites/composites.test.ts +30 -3
- package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
- package/src/op/composites/lexicon-upgrade-op.ts +29 -8
- package/src/op/decide-backend.ts +5 -1
- package/src/op/decide-read-inputs.ts +33 -5
- package/src/op/emulator-lifecycle.test.ts +23 -0
- package/src/op/emulator-lifecycle.ts +52 -14
- package/src/op/factory.e2e.test.ts +232 -0
- package/src/op/factory.ts +118 -0
- package/src/op/gate-approval.test.ts +74 -0
- package/src/op/gate-approval.ts +5 -1
- package/src/op/gate.ts +31 -5
- package/src/op/index.ts +11 -1
- package/src/op/local-executor.test.ts +15 -0
- package/src/op/local-executor.ts +40 -12
- package/src/op/local-output.ts +1 -1
- package/src/op/op-ir.test.ts +9 -0
- package/src/op/op-ir.ts +4 -0
- package/src/op/op-verb-class.ts +3 -0
- package/src/op/operator.ts +4 -0
- package/src/op/run-context.test.ts +141 -0
- package/src/op/run-context.ts +51 -0
- package/src/op/runtimes/local.test.ts +14 -0
- package/src/op/runtimes/local.ts +2 -0
- package/src/op/steward-beside.ts +2 -0
- package/src/op/types.ts +16 -3
- package/src/op/work-lease-run.test.ts +47 -0
- package/src/op/work-lease-run.ts +76 -11
- package/src/plan-summary.test.ts +263 -0
- package/src/plan-summary.ts +845 -0
- package/src/pr-forge.test.ts +237 -0
- package/src/pr-forge.ts +332 -0
- package/src/pr-loop-bundle.test.ts +46 -0
- package/src/pr-loop.test.ts +171 -0
- package/src/pr-loop.ts +324 -0
- package/src/provenance.ts +35 -0
- package/src/telemetry-attribution.test.ts +23 -1
- package/src/telemetry-attribution.ts +51 -0
- package/src/terraform/hcl2json.test.ts +21 -0
- package/src/terraform/hcl2json.ts +81 -0
- package/src/terraform/parse.ts +11 -74
- package/src/workspace/agent-cli.ts +7 -3
- package/src/workspace/agent.schema.json +22 -0
- package/src/workspace/app-kind.test.ts +196 -0
- package/src/workspace/box-cli.ts +113 -0
- package/src/workspace/box-factory.test.ts +323 -0
- package/src/workspace/box-factory.ts +136 -0
- package/src/workspace/box-listing-write.schema.json +204 -0
- package/src/workspace/box-listing.test.ts +234 -0
- package/src/workspace/box-listing.ts +324 -0
- package/src/workspace/box-publish.schema.json +498 -0
- package/src/workspace/box-publish.test.ts +204 -0
- package/src/workspace/box-publish.ts +420 -0
- package/src/workspace/box-ship.test.ts +96 -0
- package/src/workspace/broker-protocol.schema.json +186 -0
- package/src/workspace/broker-protocol.test.ts +122 -0
- package/src/workspace/broker-protocol.ts +317 -0
- package/src/workspace/builder-tiers.test.ts +146 -0
- package/src/workspace/change-set.schema.json +460 -0
- package/src/workspace/changes.schema.json +12 -20
- package/src/workspace/changes.ts +4 -1
- package/src/workspace/chant-migrations.e2e.test.ts +17 -5
- package/src/workspace/checks/boxes.test.ts +5 -0
- package/src/workspace/checks.ts +39 -8
- package/src/workspace/component-environments.test.ts +105 -0
- package/src/workspace/compose-graph.ts +7 -0
- package/src/workspace/composites.schema.json +23 -4
- package/src/workspace/composites.test.ts +8 -8
- package/src/workspace/composites.ts +13 -2
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
- package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/src/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
- package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
- package/src/workspace/conformance/broker.test.ts +122 -0
- package/src/workspace/conformance/broker.ts +792 -0
- package/src/workspace/conformance/conformance.e2e.test.ts +36 -3
- package/src/workspace/conformance/index.mjs +51 -3
- package/src/workspace/conformance/index.ts +107 -15
- package/src/workspace/conformance/vitest.ts +76 -2
- package/src/workspace/conformance/writer-conformance.e2e.test.ts +177 -0
- package/src/workspace/conformance/writer.test.ts +186 -0
- package/src/workspace/conformance/writer.ts +1191 -0
- package/src/workspace/decide.test.ts +208 -4
- package/src/workspace/decide.ts +433 -73
- package/src/workspace/decision-points.schema.json +11 -4
- package/src/workspace/declaration.schema.json +383 -5
- package/src/workspace/declaration.ts +315 -10
- package/src/workspace/environments.ts +66 -14
- package/src/workspace/factory-rules.test.ts +62 -0
- package/src/workspace/factory-rules.ts +218 -0
- package/src/workspace/graph-cli.ts +6 -3
- package/src/workspace/graph.schema.json +314 -0
- package/src/workspace/identity.test.ts +219 -0
- package/src/workspace/identity.ts +186 -0
- package/src/workspace/init.ts +82 -2
- package/src/workspace/intent-cli.ts +84 -13
- package/src/workspace/intent-patch-id.test.ts +162 -0
- package/src/workspace/intent-record.schema.json +336 -1
- package/src/workspace/intent-record.ts +96 -16
- package/src/workspace/intent-reviews.test.ts +76 -0
- package/src/workspace/intent-squash.test.ts +213 -0
- package/src/workspace/intent-why.test.ts +274 -0
- package/src/workspace/intent.schema.json +950 -9
- package/src/workspace/intent.test.ts +11 -2
- package/src/workspace/intent.ts +722 -65
- package/src/workspace/json-edit.test.ts +121 -0
- package/src/workspace/json-edit.ts +142 -0
- package/src/workspace/jsonc.ts +20 -0
- package/src/workspace/kinds.ts +201 -39
- package/src/workspace/lexicon-symbols.test.ts +148 -0
- package/src/workspace/lexicon-symbols.ts +125 -0
- package/src/workspace/lineage-upgrade.test.ts +63 -0
- package/src/workspace/lineage-upgrade.ts +146 -5
- package/src/workspace/plan-summary.schema.json +155 -0
- package/src/workspace/point-answer.schema.json +42 -2
- package/src/workspace/points-cli.ts +42 -16
- package/src/workspace/points-write.schema.json +163 -4
- package/src/workspace/points.schema.json +157 -2
- package/src/workspace/points.test.ts +13 -1
- package/src/workspace/points.ts +118 -12
- package/src/workspace/pr-report.schema.json +95 -0
- package/src/workspace/principal-classes.test.ts +175 -0
- package/src/workspace/principal-classes.ts +307 -0
- package/src/workspace/profiles.test.ts +159 -0
- package/src/workspace/read-contract.test.ts +2 -2
- package/src/workspace/reason-codes.test.ts +23 -3
- package/src/workspace/reason-codes.ts +61 -4
- package/src/workspace/record-sessions.ts +9 -8
- package/src/workspace/records-amend.schema.json +80 -0
- package/src/workspace/records-checkout.ts +106 -0
- package/src/workspace/records-cli.ts +123 -17
- package/src/workspace/records-close.schema.json +79 -0
- package/src/workspace/records-close.ts +31 -7
- package/src/workspace/records-concurrent.e2e.test.ts +135 -0
- package/src/workspace/records-concurrent.test.ts +145 -0
- package/src/workspace/records-formats.test.ts +46 -10
- package/src/workspace/records-new.schema.json +9 -0
- package/src/workspace/records-review.schema.json +80 -0
- package/src/workspace/records-sessions-write.test.ts +69 -0
- package/src/workspace/records-sessions.test.ts +22 -0
- package/src/workspace/records-uncommitted.test.ts +171 -0
- package/src/workspace/records-write.ts +219 -30
- package/src/workspace/records.schema.json +88 -1
- package/src/workspace/records.ts +76 -8
- package/src/workspace/reference-kinds/app/package.json +10 -0
- package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/src/workspace/run-statement.schema.json +622 -0
- package/src/workspace/runs-cli.ts +710 -0
- package/src/workspace/runs-statement.test.ts +239 -0
- package/src/workspace/runs-write.schema.json +994 -0
- package/src/workspace/runs.schema.json +1257 -0
- package/src/workspace/runs.test.ts +281 -0
- package/src/workspace/runs.ts +970 -0
- package/src/workspace/session-kinds.ts +3 -3
- package/src/workspace/squash.ts +198 -0
- package/src/workspace/status-contract.test.ts +10 -2
- package/src/workspace/status-gates.ts +25 -9
- package/src/workspace/status.schema.json +252 -4
- package/src/workspace/status.ts +110 -1
- package/src/workspace/symbols.ts +191 -0
- package/src/workspace/trailer-joins.test.ts +171 -0
- package/src/workspace/trailer-joins.ts +82 -0
- package/src/workspace/trailers.ts +148 -0
- package/src/workspace/trust/run-commits.ts +115 -0
- package/src/workspace/trust/run-statement.ts +226 -0
- package/src/workspace/trust/seal.ts +58 -1
- package/src/workspace/trust/verify-cli.ts +6 -5
- package/src/workspace/trust/verify.ts +39 -6
- package/src/workspace/wip-cli.ts +97 -0
- package/src/workspace/wip-write.schema.json +504 -0
- package/src/workspace/wip.schema.json +334 -0
- package/src/workspace/wip.test.ts +294 -0
- package/src/workspace/wip.ts +753 -0
- package/src/workspace/work-cli.e2e.test.ts +28 -1
- package/src/workspace/work-cli.ts +136 -8
- package/src/workspace/work-evidence.schema.json +5 -0
- package/src/workspace/work-history.schema.json +73 -1
- package/src/workspace/work-history.test.ts +48 -5
- package/src/workspace/work-kind-fields.test.ts +154 -0
- package/src/workspace/work-lease.schema.json +14 -1
- package/src/workspace/work-size.test.ts +77 -0
- package/src/workspace/work-size.ts +93 -0
- package/src/workspace/work.ts +82 -0
- package/src/workspace/workspace-kinds.schema.json +122 -0
- package/src/workspace/workspace-principals.schema.json +60 -0
- package/src/workspace/write-lock-cli.ts +131 -0
- package/src/workspace/write-lock.schema.json +172 -0
- package/src/workspace/write-lock.test.ts +189 -0
- package/src/workspace/write-lock.ts +474 -0
- package/src/workspace/write-scope.test.ts +144 -3
- package/src/workspace/write-scope.ts +192 -45
- package/src/yaml.test.ts +111 -1
- package/src/yaml.ts +141 -549
|
@@ -25,59 +25,78 @@
|
|
|
25
25
|
* detection only (ws-002).
|
|
26
26
|
*
|
|
27
27
|
* A principal's class comes from the role grants in the trust policy at base,
|
|
28
|
-
* through {@link principalClass} alone (the agent, runner and service roles
|
|
28
|
+
* through {@link principalClass} alone (the agent, runner and service roles,
|
|
29
|
+
* then the role each domain class a pinned package supplies names, #3080),
|
|
29
30
|
* or from naming an agent session. Claiming a session only ever narrows what
|
|
30
31
|
* a writer may do, so an unverified `CHANT_AGENT` or trailer is safe to honour.
|
|
32
|
+
*
|
|
33
|
+
* A writeScope key no pinned package supplies fails closed: a writer judged
|
|
34
|
+
* `human` might be in that class, so it is refused with
|
|
35
|
+
* `write-scope-class-unknown` until the plugin is installed at the pinned
|
|
36
|
+
* version or the entry is removed.
|
|
31
37
|
*/
|
|
32
38
|
|
|
33
39
|
import { execFileSync } from "node:child_process";
|
|
34
40
|
import { posix, relative, sep } from "node:path";
|
|
41
|
+
import { isDeepStrictEqual } from "node:util";
|
|
42
|
+
// @ts-ignore — picomatch has no types declaration
|
|
43
|
+
import picomatch from "picomatch";
|
|
35
44
|
import {
|
|
36
|
-
PRINCIPAL_CLASSES,
|
|
37
45
|
readDeclaration,
|
|
38
46
|
WorkspaceReadError,
|
|
39
47
|
type AgentDeclaration,
|
|
40
48
|
type ClassScope,
|
|
41
49
|
type Declaration,
|
|
42
50
|
type PrincipalClass,
|
|
51
|
+
type ProtectedPath,
|
|
43
52
|
type WriteVerb,
|
|
44
53
|
} from "./declaration";
|
|
54
|
+
import {
|
|
55
|
+
classesOf,
|
|
56
|
+
coreClassRegistry,
|
|
57
|
+
loadClassRegistry,
|
|
58
|
+
principalClass as classOf,
|
|
59
|
+
roleGrants,
|
|
60
|
+
unknownScopeClasses,
|
|
61
|
+
type ClassRegistry,
|
|
62
|
+
} from "./principal-classes";
|
|
45
63
|
import type { ReasonCode } from "./reason-codes";
|
|
64
|
+
import { parseJsonText } from "./jsonc";
|
|
46
65
|
import { memberHolding } from "./record-assets";
|
|
47
66
|
import { gitRoot } from "./record-source";
|
|
48
67
|
import { normalisePrincipal, parseFrontMatter } from "./records";
|
|
68
|
+
import type { WorkspaceTree } from "./tree";
|
|
49
69
|
import { emptyPolicy, type TrustPolicy } from "./trust/policy";
|
|
50
70
|
import { commitProvenance, policyAtBase, resolveBase } from "./trust/provenance";
|
|
71
|
+
import { AGENT_TRAILER } from "./trailers";
|
|
51
72
|
import { locateWorkspace } from "./which-chant";
|
|
52
73
|
|
|
53
74
|
/** The environment variable naming the agent session a write is made in. */
|
|
54
75
|
export const AGENT_ENV = "CHANT_AGENT";
|
|
55
76
|
|
|
56
|
-
/** The commit trailer naming the agent session a commit was made in. */
|
|
57
|
-
export
|
|
77
|
+
/** The commit trailer naming the agent session a commit was made in, one of chant's trailers (`trailers.ts`). */
|
|
78
|
+
export { AGENT_TRAILER };
|
|
58
79
|
|
|
59
80
|
/** Why a write is outside its writer's scope. Closed. */
|
|
60
|
-
export const WRITE_SCOPE_CODES = ["write-scope-member", "write-scope-kind", "agent-unknown"] as const satisfies readonly ReasonCode[];
|
|
81
|
+
export const WRITE_SCOPE_CODES = ["write-scope-member", "write-scope-kind", "write-scope-class-unknown", "agent-unknown"] as const satisfies readonly ReasonCode[];
|
|
61
82
|
export type WriteScopeCode = (typeof WRITE_SCOPE_CODES)[number];
|
|
62
83
|
|
|
63
|
-
/** The classes a role grant puts a principal in, in the order they are tried. Human is the rest. */
|
|
64
|
-
const ROLE_CLASSES = ["agent", "runner", "service"] as const satisfies readonly PrincipalClass[];
|
|
65
|
-
|
|
66
84
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* possibly the declaration, #2547) is decided in one place: the policy.
|
|
85
|
+
* What `check --changes` reports a path with: the record-write codes, and a
|
|
86
|
+
* write to a protected path (#3146), which a record write never is. Closed.
|
|
70
87
|
*/
|
|
71
|
-
export
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
export const SCOPE_FINDING_CODES = [...WRITE_SCOPE_CODES, "write-scope-protected"] as const satisfies readonly ReasonCode[];
|
|
89
|
+
export type ScopeFindingCode = (typeof SCOPE_FINDING_CODES)[number];
|
|
90
|
+
|
|
91
|
+
export { classesOf, roleGrants };
|
|
74
92
|
|
|
75
|
-
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
/**
|
|
94
|
+
* The class a principal is in: the first of agent, runner and service whose
|
|
95
|
+
* role it holds at base, then the first domain class in `classes` whose role
|
|
96
|
+
* it holds (#3080), or human.
|
|
97
|
+
*/
|
|
98
|
+
export function principalClass(policy: TrustPolicy, principal: string | null, classes: ClassRegistry = coreClassRegistry()): PrincipalClass {
|
|
99
|
+
return classOf(policy, principal, classes);
|
|
81
100
|
}
|
|
82
101
|
|
|
83
102
|
/** Who is writing, as the scope judges it. */
|
|
@@ -104,7 +123,12 @@ export class WriteScopeError extends Error {
|
|
|
104
123
|
* the declaration declares none by that name), in the session that lists
|
|
105
124
|
* `principal`, or else in the class `principal`'s roles give it.
|
|
106
125
|
*/
|
|
107
|
-
export function resolveWriter(
|
|
126
|
+
export function resolveWriter(
|
|
127
|
+
declaration: Declaration | null,
|
|
128
|
+
policy: TrustPolicy,
|
|
129
|
+
given: { agent?: string | null; principal?: string | null },
|
|
130
|
+
classes: ClassRegistry = coreClassRegistry(),
|
|
131
|
+
): Writer {
|
|
108
132
|
const principal = given.principal ?? null;
|
|
109
133
|
const agents = declaration?.agents ?? [];
|
|
110
134
|
if (given.agent !== undefined && given.agent !== null) {
|
|
@@ -125,19 +149,40 @@ export function resolveWriter(declaration: Declaration | null, policy: TrustPoli
|
|
|
125
149
|
const agent = agents.find((a) => a.principals.some((p) => normalisePrincipal(p) === name));
|
|
126
150
|
if (agent) return { principal, class: "agent", agent };
|
|
127
151
|
}
|
|
128
|
-
return { principal, class: principalClass(policy, principal), agent: null };
|
|
152
|
+
return { principal, class: principalClass(policy, principal, classes), agent: null };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Refuse `writer` when the declaration's writeScope names a class `classes`
|
|
157
|
+
* doesn't know and the writer is judged human (#3080): nothing says which
|
|
158
|
+
* role puts a principal in the unknown class, so this writer may be in it.
|
|
159
|
+
* A writer in another class is judged by that class, which comes first.
|
|
160
|
+
*/
|
|
161
|
+
export function unknownClassVerdict(declaration: Declaration | null, writer: Writer, classes: ClassRegistry): { ok: true } | { ok: false; code: "write-scope-class-unknown"; message: string } {
|
|
162
|
+
if (writer.class !== "human") return OK;
|
|
163
|
+
const unknown = unknownScopeClasses(declaration?.writeScope ?? null, classes);
|
|
164
|
+
if (unknown.length === 0) return OK;
|
|
165
|
+
const list = unknown.map((c) => `writeScope.${c}`).join(", ");
|
|
166
|
+
return {
|
|
167
|
+
ok: false,
|
|
168
|
+
code: "write-scope-class-unknown",
|
|
169
|
+
message: `${who(writer)} may be in ${unknown.length === 1 ? "a class" : "classes"} no pinned package supplies (${list}), so its scope can't be told; install the package that supplies ${unknown.length === 1 ? "it" : "them"} at the pinned version, or remove the entry (known classes: ${classes.names().join(", ")})`,
|
|
170
|
+
};
|
|
129
171
|
}
|
|
130
172
|
|
|
131
173
|
/** The scope that applies to `writer`, or null when its class is not restricted. An agent is always restricted to its member. */
|
|
132
174
|
export function scopeOf(declaration: Declaration | null, writer: Writer): ClassScope | null {
|
|
133
175
|
const entry = declaration?.writeScope?.[writer.class];
|
|
134
|
-
if (writer.class === "agent") return { members: null, records: entry?.records ?? null, pointer: entry?.pointer ?? "/agents" };
|
|
176
|
+
if (writer.class === "agent") return { members: null, records: entry?.records ?? null, protected: entry?.protected ?? [], pointer: entry?.pointer ?? "/agents" };
|
|
135
177
|
return entry ?? null;
|
|
136
178
|
}
|
|
137
179
|
|
|
138
|
-
export type ScopeVerdict = { ok: true } | { ok: false; code: Exclude<
|
|
180
|
+
export type ScopeVerdict = { ok: true } | { ok: false; code: Exclude<ScopeFindingCode, "agent-unknown">; message: string };
|
|
139
181
|
|
|
140
|
-
|
|
182
|
+
/** A record write's verdict: never write-scope-protected, since protected paths judge files that aren't records. */
|
|
183
|
+
export type RecordVerdict = { ok: true } | { ok: false; code: Exclude<WriteScopeCode, "agent-unknown">; message: string };
|
|
184
|
+
|
|
185
|
+
const OK = { ok: true } as const;
|
|
141
186
|
|
|
142
187
|
function who(writer: Writer): string {
|
|
143
188
|
if (writer.agent) return `agent session ${writer.agent.name}, bound to member ${writer.agent.member},`;
|
|
@@ -164,7 +209,7 @@ export interface ScopedKind {
|
|
|
164
209
|
}
|
|
165
210
|
|
|
166
211
|
/** Whether `writer` may write a record of `kind` with `verb`. A delete is never in a restricted scope. */
|
|
167
|
-
export function judgeRecord(declaration: Declaration | null, writer: Writer, kind: ScopedKind, verb: WriteVerb | "delete"):
|
|
212
|
+
export function judgeRecord(declaration: Declaration | null, writer: Writer, kind: ScopedKind, verb: WriteVerb | "delete"): RecordVerdict {
|
|
168
213
|
const scope = scopeOf(declaration, writer);
|
|
169
214
|
if (scope === null) return OK;
|
|
170
215
|
// The workspace's own kinds are in every member's reach; a member's kinds only in its own.
|
|
@@ -194,17 +239,97 @@ export function judgeRecord(declaration: Declaration | null, writer: Writer, kin
|
|
|
194
239
|
};
|
|
195
240
|
}
|
|
196
241
|
|
|
197
|
-
/**
|
|
198
|
-
|
|
242
|
+
/**
|
|
243
|
+
* The protected entry of `entries` that covers `path` (#3146, ws-077): one
|
|
244
|
+
* whose glob matches the path or a directory above it. Null when none does.
|
|
245
|
+
*/
|
|
246
|
+
export function protectedEntry(entries: readonly ProtectedPath[], path: string): ProtectedPath | null {
|
|
247
|
+
if (entries.length === 0) return null;
|
|
248
|
+
const parts = path.split("/");
|
|
249
|
+
const prefixes = parts.map((_, i) => parts.slice(0, i + 1).join("/"));
|
|
250
|
+
for (const entry of entries) {
|
|
251
|
+
const match = picomatch(entry.path, { dot: true }) as (p: string) => boolean;
|
|
252
|
+
if (prefixes.some((p) => match(p))) return entry;
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** What an array item an `except` pointer covers is compared as, so the items after it keep their places. */
|
|
258
|
+
const REMOVED = Symbol("except");
|
|
259
|
+
|
|
260
|
+
/** Remove every value `pointer` matches from `value`, in place; a `*` token matches every key or index at its level. */
|
|
261
|
+
function removeAtPointer(value: unknown, tokens: readonly string[]): void {
|
|
262
|
+
if (tokens.length === 0 || value === null || typeof value !== "object") return;
|
|
263
|
+
const [head, ...rest] = tokens;
|
|
264
|
+
const container = value as Record<string, unknown>;
|
|
265
|
+
const names = head === "*" ? Object.keys(container) : Object.prototype.hasOwnProperty.call(container, head) ? [head] : [];
|
|
266
|
+
for (const name of names) {
|
|
267
|
+
if (rest.length > 0) removeAtPointer(container[name], rest);
|
|
268
|
+
else if (Array.isArray(value)) (value as unknown[])[Number(name)] = REMOVED;
|
|
269
|
+
else delete container[name];
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Whether JSON text `before` and `after` differ only in what `except`
|
|
275
|
+
* allows: a top-level key, or, for an entry starting with `/`, the values a
|
|
276
|
+
* JSON Pointer matches, where a `*` token matches every key or array index
|
|
277
|
+
* at its level (`/members/*\/box/listing`, #3308). Comments and trailing
|
|
278
|
+
* commas are read, so a `.jsonc` declaration is judged too. False when either
|
|
279
|
+
* is missing or isn't a JSON object.
|
|
280
|
+
*/
|
|
281
|
+
export function onlyKeysChanged(before: string | null, after: string | null, except: readonly string[]): boolean {
|
|
282
|
+
if (before === null || after === null || except.length === 0) return false;
|
|
283
|
+
const strip = (text: string): Record<string, unknown> | null => {
|
|
284
|
+
const parsed = parseJsonText(text, { jsonc: true });
|
|
285
|
+
if (!parsed.ok) return null;
|
|
286
|
+
const value = parsed.value;
|
|
287
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
|
|
288
|
+
const copy = structuredClone(value) as Record<string, unknown>;
|
|
289
|
+
for (const entry of except) {
|
|
290
|
+
if (entry.startsWith("/")) removeAtPointer(copy, entry.slice(1).split("/").map((t) => t.replace(/~1/g, "/").replace(/~0/g, "~")));
|
|
291
|
+
else delete copy[entry];
|
|
292
|
+
}
|
|
293
|
+
return copy;
|
|
294
|
+
};
|
|
295
|
+
const a = strip(before);
|
|
296
|
+
const b = strip(after);
|
|
297
|
+
return a !== null && b !== null && isDeepStrictEqual(a, b);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** A file's text before and after a write, read only when a protected entry with `except` needs it. */
|
|
301
|
+
export interface PathChange {
|
|
302
|
+
before(): string | null;
|
|
303
|
+
after(): string | null;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Whether `writer` may write the file at `path`, from the workspace root:
|
|
308
|
+
* the path is in a member the writer may write, and no protected entry of
|
|
309
|
+
* its scope covers it, unless the entry's `except` allows the change (#3146).
|
|
310
|
+
* Without `change`, a write to a path an `except` entry covers is judged as a
|
|
311
|
+
* change outside the allowed keys.
|
|
312
|
+
*/
|
|
313
|
+
export function judgePath(declaration: Declaration | null, writer: Writer, path: string, change?: PathChange): ScopeVerdict {
|
|
199
314
|
const scope = scopeOf(declaration, writer);
|
|
200
315
|
if (scope === null) return OK;
|
|
201
316
|
const member = memberHolding(path, declaration?.members ?? []);
|
|
202
|
-
if (memberAllowed(writer, scope, member))
|
|
203
|
-
|
|
317
|
+
if (!memberAllowed(writer, scope, member)) {
|
|
318
|
+
const where = member === null ? "is in no member" : `is in member ${member}`;
|
|
319
|
+
return {
|
|
320
|
+
ok: false,
|
|
321
|
+
code: "write-scope-member",
|
|
322
|
+
message: `${who(writer)} may not write ${path}, which ${where}: ${writer.class === "agent" ? "an agent session writes only its own member" : `writeScope.${writer.class}.members leaves it out`}`,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
const guarded = protectedEntry(scope.protected, path);
|
|
326
|
+
if (guarded === null) return OK;
|
|
327
|
+
if (guarded.except.length > 0 && change && onlyKeysChanged(change.before(), change.after(), guarded.except)) return OK;
|
|
328
|
+
const allowance = guarded.except.length > 0 ? `, outside what its except allows (${guarded.except.join(", ")})` : "";
|
|
204
329
|
return {
|
|
205
330
|
ok: false,
|
|
206
|
-
code: "write-scope-
|
|
207
|
-
message: `${who(writer)} may not write ${path}
|
|
331
|
+
code: "write-scope-protected",
|
|
332
|
+
message: `${who(writer)} may not write ${path}${allowance}: writeScope.${writer.class}.protected lists ${guarded.path}`,
|
|
208
333
|
};
|
|
209
334
|
}
|
|
210
335
|
|
|
@@ -220,12 +345,14 @@ export interface ScopeSource {
|
|
|
220
345
|
/** The workspace root from the git root, "." for the git root, or null without a declaration. */
|
|
221
346
|
root: string | null;
|
|
222
347
|
policy: TrustPolicy;
|
|
348
|
+
/** The principal classes: the core four and those the declaration's pins supply, path pins read where the declaration was (#3080). */
|
|
349
|
+
classes: ClassRegistry;
|
|
223
350
|
}
|
|
224
351
|
|
|
225
|
-
function readAt(cwd: string, at?: string): { declaration: Declaration; rootOnDisk: string; root: string } | null {
|
|
352
|
+
function readAt(cwd: string, at?: string): { declaration: Declaration; rootOnDisk: string; root: string; tree: WorkspaceTree } | null {
|
|
226
353
|
try {
|
|
227
354
|
const located = locateWorkspace(cwd, at);
|
|
228
|
-
return { declaration: readDeclaration(located.tree), rootOnDisk: located.rootOnDisk, root: located.root };
|
|
355
|
+
return { declaration: readDeclaration(located.tree), rootOnDisk: located.rootOnDisk, root: located.root, tree: located.tree };
|
|
229
356
|
} catch (err) {
|
|
230
357
|
if (err instanceof WorkspaceReadError) return null;
|
|
231
358
|
throw err;
|
|
@@ -242,12 +369,16 @@ export function scopeSource(cwd: string): ScopeSource {
|
|
|
242
369
|
const top = gitRoot(cwd);
|
|
243
370
|
const base = top ? resolveBase(top) : null;
|
|
244
371
|
const policy = top && base ? policyAtBase(top, base) : emptyPolicy(null);
|
|
372
|
+
const withClasses = (read: NonNullable<ReturnType<typeof readAt>>) => {
|
|
373
|
+
const { tree, ...rest } = read;
|
|
374
|
+
return { ...rest, classes: loadClassRegistry(read.declaration.pins, read.rootOnDisk, { tree }).registry };
|
|
375
|
+
};
|
|
245
376
|
if (base?.commit) {
|
|
246
377
|
const atBase = readAt(cwd, base.commit);
|
|
247
|
-
if (atBase) return { ...atBase, from: "base", policy };
|
|
378
|
+
if (atBase) return { ...withClasses(atBase), from: "base", policy };
|
|
248
379
|
}
|
|
249
380
|
const here = readAt(cwd);
|
|
250
|
-
return here ? { ...here, from: "working-tree", policy } : { declaration: null, from: null, rootOnDisk: null, root: null, policy };
|
|
381
|
+
return here ? { ...withClasses(here), from: "working-tree", policy } : { declaration: null, from: null, rootOnDisk: null, root: null, policy, classes: coreClassRegistry() };
|
|
251
382
|
}
|
|
252
383
|
|
|
253
384
|
const toPosix = (p: string) => (sep === "/" ? p : p.split(sep).join("/"));
|
|
@@ -271,16 +402,20 @@ export function scopedKind(source: ScopeSource, kindName: string, kindFile: stri
|
|
|
271
402
|
* Refuse a record write outside the writer's scope (#2548): throws a
|
|
272
403
|
* {@link WriteScopeError}. `agent` is the session the write names
|
|
273
404
|
* (`CHANT_AGENT`), and `principal` who the write names as its author.
|
|
405
|
+
* Returns what it read at base, for the identity rule (#3163).
|
|
274
406
|
*/
|
|
275
407
|
export function refuseRecordWrite(
|
|
276
408
|
cwd: string,
|
|
277
409
|
write: { kindName: string; kindFile: string; recordsDir: string; verb: WriteVerb; agent?: string | null; principal?: string | null },
|
|
278
|
-
):
|
|
410
|
+
): ScopeSource {
|
|
279
411
|
const source = scopeSource(cwd);
|
|
280
|
-
if (source.declaration === null && (write.agent === undefined || write.agent === null)) return;
|
|
281
|
-
const writer = resolveWriter(source.declaration, source.policy, { agent: write.agent, principal: write.principal });
|
|
412
|
+
if (source.declaration === null && (write.agent === undefined || write.agent === null)) return source;
|
|
413
|
+
const writer = resolveWriter(source.declaration, source.policy, { agent: write.agent, principal: write.principal }, source.classes);
|
|
414
|
+
const unknown = unknownClassVerdict(source.declaration, writer, source.classes);
|
|
415
|
+
if (!unknown.ok) throw new WriteScopeError(unknown.code, unknown.message);
|
|
282
416
|
const verdict = judgeRecord(source.declaration, writer, scopedKind(source, write.kindName, write.kindFile, write.recordsDir), write.verb);
|
|
283
417
|
if (!verdict.ok) throw new WriteScopeError(verdict.code, verdict.message);
|
|
418
|
+
return source;
|
|
284
419
|
}
|
|
285
420
|
|
|
286
421
|
// ── The check over a range ───────────────────────────────────────────────────
|
|
@@ -301,9 +436,9 @@ export interface ScopeCommit {
|
|
|
301
436
|
}
|
|
302
437
|
|
|
303
438
|
export interface ScopeFinding {
|
|
304
|
-
/** `finding:<code>:<commit>:<path>`, or `finding
|
|
439
|
+
/** `finding:<code>:<commit>:<path>`, or `finding:<code>:<commit>` for agent-unknown and write-scope-class-unknown, which judge the whole commit. */
|
|
305
440
|
id: string;
|
|
306
|
-
code:
|
|
441
|
+
code: ScopeFindingCode;
|
|
307
442
|
commit: string;
|
|
308
443
|
/** From the workspace root, or null for a finding on the whole commit. */
|
|
309
444
|
path: string | null;
|
|
@@ -318,7 +453,7 @@ export interface ScopeFinding {
|
|
|
318
453
|
export interface ScopeReport {
|
|
319
454
|
/** The commit the declaration and the trust policy were read at. */
|
|
320
455
|
base: string;
|
|
321
|
-
/** The classes with a writeScope entry, and agent when any session is declared. */
|
|
456
|
+
/** The classes with a writeScope entry, and agent when any session is declared: core first, then domain classes in pin order, then any no pinned package supplies. */
|
|
322
457
|
restricted: PrincipalClass[];
|
|
323
458
|
agents: string[];
|
|
324
459
|
commits: ScopeCommit[];
|
|
@@ -384,13 +519,17 @@ export async function checkWriteScope(q: {
|
|
|
384
519
|
prefix: string;
|
|
385
520
|
declaration: Declaration;
|
|
386
521
|
kinds: CheckKind[];
|
|
522
|
+
/** The principal classes the declaration's pins supply at base (#3080). Without it, the core four. */
|
|
523
|
+
classes?: ClassRegistry;
|
|
387
524
|
}): Promise<ScopeReport | null> {
|
|
388
525
|
const { top, base, head, prefix, declaration } = q;
|
|
526
|
+
const classes = q.classes ?? coreClassRegistry();
|
|
389
527
|
if (declaration.writeScope === null && declaration.agents.length === 0) return null;
|
|
390
528
|
const policy = policyAtBase(top, { commit: base, from: "flag" });
|
|
391
529
|
const { activeAttestors } = await import("./trust/attestor");
|
|
392
530
|
const attestors = await activeAttestors();
|
|
393
|
-
const
|
|
531
|
+
const scoped = (c: string) => declaration.writeScope?.[c] !== undefined || (c === "agent" && declaration.agents.length > 0);
|
|
532
|
+
const restricted = [...classes.names().filter(scoped), ...unknownScopeClasses(declaration.writeScope, classes)];
|
|
394
533
|
const report: ScopeReport = { base, restricted, agents: declaration.agents.map((a) => a.name), commits: [], findings: [] };
|
|
395
534
|
const list = git(top, ["rev-list", "--reverse", "--no-merges", `${base}..${head}`]).split("\n").filter(Boolean);
|
|
396
535
|
for (const commit of list) {
|
|
@@ -410,7 +549,7 @@ export async function checkWriteScope(q: {
|
|
|
410
549
|
}
|
|
411
550
|
let writer: Writer;
|
|
412
551
|
try {
|
|
413
|
-
writer = resolveWriter(declaration, policy, { agent: named, principal });
|
|
552
|
+
writer = resolveWriter(declaration, policy, { agent: named, principal }, classes);
|
|
414
553
|
} catch (err) {
|
|
415
554
|
if (!(err instanceof WriteScopeError)) throw err;
|
|
416
555
|
report.commits.push({ commit, subject, principal, attested, class: "agent", agent: named, paths: paths.length });
|
|
@@ -418,6 +557,11 @@ export async function checkWriteScope(q: {
|
|
|
418
557
|
continue;
|
|
419
558
|
}
|
|
420
559
|
report.commits.push({ commit, subject, principal, attested, class: writer.class, agent: writer.agent?.name ?? null, paths: paths.length });
|
|
560
|
+
const unknown = unknownClassVerdict(declaration, writer, classes);
|
|
561
|
+
if (!unknown.ok) {
|
|
562
|
+
report.findings.push({ id: `finding:${unknown.code}:${commit}`, code: unknown.code, commit, path: null, principal, class: writer.class, agent: null, verb: null, message: `${commit.slice(0, 8)}: ${unknown.message}` });
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
421
565
|
if (scopeOf(declaration, writer) === null) continue;
|
|
422
566
|
for (const p of paths) {
|
|
423
567
|
const inWorkspace = prefix === "" ? p.path : p.path.slice(prefix.length + 1);
|
|
@@ -428,7 +572,10 @@ export async function checkWriteScope(q: {
|
|
|
428
572
|
verb = p.status === "A" ? "new" : p.status === "D" ? "delete" : modifiedVerb(top, commit, p.path, kind);
|
|
429
573
|
verdict = judgeRecord(declaration, writer, kind.scoped, verb);
|
|
430
574
|
} else {
|
|
431
|
-
verdict = judgePath(declaration, writer, inWorkspace
|
|
575
|
+
verdict = judgePath(declaration, writer, inWorkspace, {
|
|
576
|
+
before: () => (p.status === "A" ? null : show(top, `${commit}^`, p.path)),
|
|
577
|
+
after: () => (p.status === "D" ? null : show(top, commit, p.path)),
|
|
578
|
+
});
|
|
432
579
|
}
|
|
433
580
|
if (verdict.ok) continue;
|
|
434
581
|
report.findings.push({
|
package/src/yaml.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "vitest";
|
|
2
2
|
import { load as jsYamlLoad } from "js-yaml";
|
|
3
|
-
import { emitYAML, parseYAML, parseYAMLDocument, parseScalar, splitYAMLDocuments, YAMLParseError } from "./yaml";
|
|
3
|
+
import { emitYAML, emitYAMLEntry, parseYAML, parseYAMLDocument, parseScalar, splitYAMLDocuments, YAMLParseError } from "./yaml";
|
|
4
4
|
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
// emitYAML
|
|
@@ -781,3 +781,113 @@ describe("parseYAML — anchors, aliases and merge keys (#2991)", () => {
|
|
|
781
781
|
expect(() => parseYAML("a: &v 1\nb:\n <<: *v\n")).toThrow(YAMLParseError);
|
|
782
782
|
});
|
|
783
783
|
});
|
|
784
|
+
|
|
785
|
+
// #3006: parseYAML is js-yaml with chant's schema. Before it, an inline
|
|
786
|
+
// comment stayed in the value and a flow collection that was not JSON came
|
|
787
|
+
// back as a string, without a warning.
|
|
788
|
+
describe("parseYAML — comments and flow collections (#3006)", () => {
|
|
789
|
+
const same = (src: string): void => {
|
|
790
|
+
expect(parseYAMLDocument(src)).toEqual(jsYamlLoad(src));
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
test("an inline comment is not part of the value", () => {
|
|
794
|
+
expect(parseYAML("replicas: 1 # comment\n")).toEqual({ replicas: 1 });
|
|
795
|
+
expect(parseYAML("image: nginx:1.27 # pinned\nport: 80\t# tab\n")).toEqual({ image: "nginx:1.27", port: 80 });
|
|
796
|
+
same("items:\n - a # one\n - name: b # two\n url: http://x/#frag\n");
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
test("a # inside a quoted or plain scalar is kept", () => {
|
|
800
|
+
expect(parseYAML("a: 'x # y'\nb: \"x # y\"\nc: x#y\n")).toEqual({ a: "x # y", b: "x # y", c: "x#y" });
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
test("flow sequences and mappings that are not JSON", () => {
|
|
804
|
+
expect(parseYAML("args: [--foo, --bar]\n")).toEqual({ args: ["--foo", "--bar"] });
|
|
805
|
+
same("weekdays: [saturday, sunday]\ndays: ['1:7']\nmeta: { name: gw, labels: { app: x } }\n");
|
|
806
|
+
same("times:\n - { start_time: \"00:00\", end_time: \"24:00\" }\n");
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
test("a flow collection spanning lines", () => {
|
|
810
|
+
same("args: [\n --foo,\n --bar\n]\nmeta: {\n a: 1,\n b: [x, y]\n}\n");
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
test("a nested sequence on one line, as Grafana writes object matchers", () => {
|
|
814
|
+
expect(parseYAML("matchers:\n - - severity\n - =\n - page\n")).toEqual({ matchers: [["severity", "=", "page"]] });
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
test("a folded scalar keeps the line breaks of its more-indented lines (#2925)", () => {
|
|
818
|
+
same("msg: >\n a\n indented\n b\n");
|
|
819
|
+
});
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
describe("parseYAML — what chant keeps from its old parser (#3006)", () => {
|
|
823
|
+
test("yes and no are booleans; on and off stay strings", () => {
|
|
824
|
+
expect(parseYAML("a: yes\nb: no\nc: on\nd: off\n")).toEqual({ a: true, b: false, c: "on", d: "off" });
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
test("a date stays a string", () => {
|
|
828
|
+
expect(parseYAML("date: 2024-01-01\nat: 2024-01-01T00:00:00Z\n")).toEqual({ date: "2024-01-01", at: "2024-01-01T00:00:00Z" });
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
test("a local tag on a scalar or sequence reads as its text", () => {
|
|
832
|
+
expect(parseYAML("s: !reference [.base, script]\nr: !Ref MyApi\n")).toEqual({
|
|
833
|
+
s: "!reference [.base, script]",
|
|
834
|
+
r: "!Ref MyApi",
|
|
835
|
+
});
|
|
836
|
+
expect(parseYAML(emitYAMLEntry("s", { tag: "!reference", value: [".base", "script"] }))).toEqual({
|
|
837
|
+
s: "!reference [.base, script]",
|
|
838
|
+
});
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
test("a duplicate key takes the last value", () => {
|
|
842
|
+
expect(parseYAML("a: 1\na: 2\n")).toEqual({ a: 2 });
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
test("a `---`-separated stream reads as one mapping, as before", () => {
|
|
846
|
+
expect(parseYAML("a: 1\n---\nb: 2\n")).toEqual({ a: 1, b: 2 });
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
test("a scalar document is an error naming its line", () => {
|
|
850
|
+
expect(() => parseYAML("# header\njust text\n")).toThrow(/YAML line 2:/);
|
|
851
|
+
expect(parseYAML("")).toEqual({});
|
|
852
|
+
expect(parseYAML("# only a comment\n")).toEqual({});
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
test("a merged block is a copy, not shared with its anchor", () => {
|
|
856
|
+
const doc = parseYAML("a: &a\n x: { n: 1 }\nb:\n <<: *a\n") as { a: { x: { n: number } }; b: { x: { n: number } } };
|
|
857
|
+
doc.b.x.n = 2;
|
|
858
|
+
expect(doc.a.x.n).toBe(1);
|
|
859
|
+
});
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
describe("emitYAMLEntry (#3006)", () => {
|
|
863
|
+
test("an inline value gets a space after the colon", () => {
|
|
864
|
+
expect(emitYAMLEntry("jobs", {})).toBe("jobs: {}");
|
|
865
|
+
expect(emitYAMLEntry("stages", [])).toBe("stages: []");
|
|
866
|
+
expect(emitYAMLEntry("name", "x")).toBe("name: x");
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
test("a block value follows on the next line", () => {
|
|
870
|
+
expect(emitYAMLEntry("stages", ["a", "b"])).toBe("stages:\n - a\n - b");
|
|
871
|
+
expect(emitYAMLEntry("b", { c: 1 }, 1)).toBe(" b:\n c: 1");
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
test("what it writes parses back", () => {
|
|
875
|
+
const doc = { on: {}, env: { A: "1" }, stages: [], jobs: { build: { script: ["make"] } } };
|
|
876
|
+
const text = Object.entries(doc).map(([k, v]) => emitYAMLEntry(k, v)).join("\n");
|
|
877
|
+
expect(parseYAML(text)).toEqual(doc);
|
|
878
|
+
});
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
describe("emitYAML quotes strings a parser would read as something else (#3006)", () => {
|
|
882
|
+
const values = ["foo:", "- x", "? x", "|x", ">x", "@x", "`x", "%x", ",x", "]x", "}x", "True", "NULL", "~", ".inf", "-.inf", ".NaN", " lead", "trail ", "-1", "+1", ".5", "Yes"];
|
|
883
|
+
|
|
884
|
+
for (const v of values) {
|
|
885
|
+
test(`round-trips ${JSON.stringify(v)}`, () => {
|
|
886
|
+
expect(parseYAML(`k: ${emitYAML(v, 0)}\n`).k).toBe(v);
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
test("strings that were safe stay plain", () => {
|
|
891
|
+
for (const v of ["--flag", "-x", "a:b", "http://a/b", "on"]) expect(emitYAML(v, 0)).toBe(v);
|
|
892
|
+
});
|
|
893
|
+
});
|