@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
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #3147 — the work kind's fields that replace studio's x-factory on work
|
|
3
|
+
* items: a contract link read with the contract's state, a builder tier from
|
|
4
|
+
* the tiers the kind declares, decision-point answers joined by the item's id
|
|
5
|
+
* (from the tree, and from the lifecycle ledger where a steward asked them),
|
|
6
|
+
* the box's intent as a source, an attempt limit, and result.lease.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFileSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { afterAll, beforeAll, describe, expect, test } from "vitest";
|
|
12
|
+
import { cleanScratch, contract, git, REPO, repo } from "./__fixtures__/contract-repo";
|
|
13
|
+
import { writeBlobToPath } from "../lifecycle/git";
|
|
14
|
+
import { answersLedgerDir } from "./answers-ledger";
|
|
15
|
+
import { parseFrontMatter } from "./records";
|
|
16
|
+
import { queryRecords } from "./records-cli";
|
|
17
|
+
import { newRecord } from "./records-write";
|
|
18
|
+
import recordsSchema from "./records.schema.json";
|
|
19
|
+
|
|
20
|
+
const REF = join(REPO, "reference-workspace");
|
|
21
|
+
const ref = (path: string) => readFileSync(join(REF, path), "utf-8");
|
|
22
|
+
const records = contract(recordsSchema);
|
|
23
|
+
|
|
24
|
+
const DECISION = (() => {
|
|
25
|
+
const fm = parseFrontMatter(ref("decisions/ref-001-how-the-app-is-deployed.md"));
|
|
26
|
+
if (!fm.ok) throw new Error(fm.message);
|
|
27
|
+
return fm.value;
|
|
28
|
+
})();
|
|
29
|
+
|
|
30
|
+
function decision(id: string, state = "decided"): string {
|
|
31
|
+
const proposed = state === "proposed";
|
|
32
|
+
const data = { ...DECISION, id, title: `Record ${id}`, state, supersedes: [], evidence: [], constrains: ["member:app"], ...(proposed ? { choice: null, decided_by: null, decided_on: null } : {}) };
|
|
33
|
+
return `---\n${JSON.stringify(data, null, 2)}\n---\n\n# ${id}\n`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function work(id: string, fields: Record<string, unknown> = {}): string {
|
|
37
|
+
const data = { schema: 1, id, title: `Work ${id}`, state: "open", implements: [], needs: [], constrains: ["member:app"], evidence: [], opened_on: "2026-10-03", source: { kind: "workspace", member: "app" }, supersedes: [], ...fields };
|
|
38
|
+
return `---\n${JSON.stringify(data, null, 2)}\n---\n\n# ${id}\n`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The reference slice-tier answer, about `item`, under the id `id`. */
|
|
42
|
+
function answer(id: string, item: string, extra: Record<string, unknown> = {}): string {
|
|
43
|
+
const fm = parseFrontMatter(ref("answers/slice-tier-01eb5382958d.md"));
|
|
44
|
+
if (!fm.ok) throw new Error(fm.message);
|
|
45
|
+
const data = { ...fm.value, id, constrains: [item], ...extra };
|
|
46
|
+
return `---\n${JSON.stringify(data, null, 2)}\n---\n\n# ${id}\n`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The reference work kind, with a contract kind: here the decision kind's shape, kept in contracts/.
|
|
50
|
+
const KIND = ref("work/work.kind.mjs").replace(
|
|
51
|
+
' answers: "../answers/answer.kind.mjs",\n',
|
|
52
|
+
' answers: "../answers/answer.kind.mjs",\n contract: { field: "contract", kind: "../contracts/decision.kind.mjs" },\n',
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
let root: string;
|
|
56
|
+
|
|
57
|
+
beforeAll(async () => {
|
|
58
|
+
expect(KIND).toContain("../contracts/decision.kind.mjs");
|
|
59
|
+
root = repo({
|
|
60
|
+
"chant.workspace.json": JSON.stringify({ name: "box", schema: 1, members: [{ name: "app", dir: "app", kind: "other", because: "the app" }] }),
|
|
61
|
+
"app/server.mjs": "export const port = 8080;\n",
|
|
62
|
+
"decisions/decision.kind.mjs": ref("decisions/decision.kind.mjs"),
|
|
63
|
+
"decisions/decision.schema.json": ref("decisions/decision.schema.json"),
|
|
64
|
+
"decisions/points.json": ref("decisions/points.json"),
|
|
65
|
+
"decisions/intent-001-what-to-build.md": decision("intent-001"),
|
|
66
|
+
"contracts/decision.kind.mjs": ref("decisions/decision.kind.mjs"),
|
|
67
|
+
"contracts/decision.schema.json": ref("decisions/decision.schema.json"),
|
|
68
|
+
"contracts/con-001-notes.md": decision("con-001"),
|
|
69
|
+
"contracts/con-002-draft.md": decision("con-002", "proposed"),
|
|
70
|
+
"answers/answer.kind.mjs": ref("answers/answer.kind.mjs"),
|
|
71
|
+
"answers/answer.schema.json": ref("answers/answer.schema.json"),
|
|
72
|
+
"answers/slice-tier-0123456789ab.md": answer("slice-tier-0123456789ab", "W-001"),
|
|
73
|
+
"work/work.kind.mjs": KIND,
|
|
74
|
+
"work/work.schema.json": ref("work/work.schema.json"),
|
|
75
|
+
"work/W-001-built.md": work("W-001", { contract: "con-001", tier: "small", max_attempts: 5, result: { lease: "6f0c11aa" } }),
|
|
76
|
+
"work/W-002-draft.md": work("W-002", { contract: "con-002", tier: "huge" }),
|
|
77
|
+
"work/W-003-missing.md": work("W-003", { contract: "con-404" }),
|
|
78
|
+
"work/W-004-plain.md": work("W-004"),
|
|
79
|
+
"work/W-005-intent.md": work("W-005", {
|
|
80
|
+
implements: ["intent-001"],
|
|
81
|
+
source: { intent: { decision: "intent-001", question: "What should the box build?", answer: "A notes app", by: "morgan", at: "2026-10-03T09:00:00Z" } },
|
|
82
|
+
}),
|
|
83
|
+
});
|
|
84
|
+
git(root, "add", "-A");
|
|
85
|
+
git(root, "commit", "-q", "-m", "the box");
|
|
86
|
+
// A question a steward asked in its turn sits on the lifecycle ledger, never in the checkout (#2786).
|
|
87
|
+
await writeBlobToPath(answersLedgerDir("answer"), "understand-0123456789ab.md", answer("understand-0123456789ab", "W-001", { point: "understand", answer: "proceed", answered_by: ["morgan"] }), "ask understand", { cwd: join(root, "answers") });
|
|
88
|
+
});
|
|
89
|
+
afterAll(cleanScratch);
|
|
90
|
+
|
|
91
|
+
describe("the work kind's fields (#3147)", () => {
|
|
92
|
+
test("contract links with the contract's state, tier and contract warnings, and answers joined by id from the tree and the ledger", async () => {
|
|
93
|
+
const doc = await queryRecords({ kind: "work/work.kind.mjs", cwd: root });
|
|
94
|
+
records.expectValid(doc);
|
|
95
|
+
if ("error" in doc) throw new Error(doc.error.message);
|
|
96
|
+
expect(doc.summary).toMatchObject({ total: 5, valid: 5, invalid: 0 });
|
|
97
|
+
const by = Object.fromEntries(doc.records.map((r) => [r.id, r]));
|
|
98
|
+
const codes = (id: string) => by[id].warnings.map((w: { code: string }) => w.code);
|
|
99
|
+
|
|
100
|
+
expect(by["W-001"].contract).toEqual({ id: "con-001", state: "decided" });
|
|
101
|
+
expect(codes("W-001")).toEqual([]);
|
|
102
|
+
expect(by["W-002"].contract).toEqual({ id: "con-002", state: "proposed" });
|
|
103
|
+
expect(codes("W-002")).toEqual(["work-contract-undecided", "work-tier-unknown"]);
|
|
104
|
+
expect(by["W-003"].contract).toEqual({ id: "con-404", state: null });
|
|
105
|
+
expect(codes("W-003")).toEqual(["work-contract-unknown"]);
|
|
106
|
+
expect(by["W-004"].contract).toBeNull();
|
|
107
|
+
|
|
108
|
+
// The item carries neither answer; the read joins both by its id.
|
|
109
|
+
expect(by["W-001"].answers).toEqual([
|
|
110
|
+
{ id: "slice-tier-0123456789ab", point: "slice-tier", state: "answered", answer: "small", answeredBy: [] },
|
|
111
|
+
{ id: "understand-0123456789ab", point: "understand", state: "answered", answer: "proceed", answeredBy: ["morgan"] },
|
|
112
|
+
]);
|
|
113
|
+
expect(by["W-002"].answers).toEqual([]);
|
|
114
|
+
expect(by["W-005"].data).toMatchObject({ source: { intent: { decision: "intent-001", answer: "A notes app", by: "morgan" } } });
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("at a revision, answers come from that tree only: the ledger is not part of it", async () => {
|
|
118
|
+
const doc = await queryRecords({ kind: "work/work.kind.mjs", cwd: root, at: "HEAD" });
|
|
119
|
+
records.expectValid(doc);
|
|
120
|
+
if ("error" in doc) throw new Error(doc.error.message);
|
|
121
|
+
expect(doc.records.find((r) => r.id === "W-001")!.answers!.map((a) => a.id)).toEqual(["slice-tier-0123456789ab"]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("the schema keeps only the lease under result, and an intent source needs its decision, answer and who decided", async () => {
|
|
125
|
+
const fields = (over: Record<string, unknown>) =>
|
|
126
|
+
JSON.stringify({ schema: 1, title: "More", state: "open", implements: [], needs: [], constrains: ["member:app"], evidence: [], opened_on: "2026-10-03", source: { kind: "workspace", member: "app" }, supersedes: [], ...over });
|
|
127
|
+
const kind = "work/work.kind.mjs";
|
|
128
|
+
const ok = await newRecord({ kind, fields: fields({ result: { lease: "6f0c" }, max_attempts: 2, tier: "large", contract: "con-001" }), dryRun: true, cwd: root });
|
|
129
|
+
expect("error" in ok ? ok.error : null).toBeNull();
|
|
130
|
+
for (const over of [
|
|
131
|
+
{ result: { lease: "6f0c", agent: "builder" } },
|
|
132
|
+
{ max_attempts: 0 },
|
|
133
|
+
{ source: { intent: { decision: "intent-001", answer: "A notes app" } } },
|
|
134
|
+
{ source: { intent: { decision: "intent-001", by: "morgan" } } },
|
|
135
|
+
]) {
|
|
136
|
+
const doc = await newRecord({ kind, fields: fields(over), dryRun: true, cwd: root });
|
|
137
|
+
expect("error" in doc && doc.error.code, JSON.stringify(over)).toBe("record-schema-invalid");
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("a kind that lists a tier twice, or names an attempt limit below one, is kind-invalid", async () => {
|
|
142
|
+
for (const [from, to] of [
|
|
143
|
+
['tiers: ["small", "medium", "large"]', 'tiers: ["small", "small"]'],
|
|
144
|
+
['max: 3', 'max: 0'],
|
|
145
|
+
]) {
|
|
146
|
+
const dir = repo({
|
|
147
|
+
"work/work.kind.mjs": ref("work/work.kind.mjs").replace(from, to),
|
|
148
|
+
"work/work.schema.json": ref("work/work.schema.json"),
|
|
149
|
+
});
|
|
150
|
+
const doc = await queryRecords({ kind: "work/work.kind.mjs", cwd: dir });
|
|
151
|
+
expect("error" in doc && doc.error.code, to).toBe("kind-invalid");
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://intentius.io/chant/schemas/workspace/work-lease/v1/work-lease.schema.json",
|
|
4
4
|
"title": "chant workspace work output",
|
|
5
|
-
"description": "What `chant workspace work claim|renew|release <id> --holder <name> --json` prints (#2732, ws-055): the work lease it wrote, the reason it was refused, or the reason the command could not run. Version 1 of the write contract for work leases. The lease is the ref refs/chant/lease/[_members/<member>/]work/<id>; each write also appends to _leases/<id>.jsonl on chant/lifecycle. Readers ignore fields they do not know; a field is only ever added within a version. The refusal and error codes are closed lists, each in the one closed list of `reason-codes.ts`.",
|
|
5
|
+
"description": "What `chant workspace work claim|renew|release <id> --holder <name> --json` prints (#2732, ws-055): the work lease it wrote, the reason it was refused, or the reason the command could not run. Version 1 of the write contract for work leases. The lease is the ref refs/chant/lease/[_members/<member>/]work/<id>; each write also appends to _leases/<id>.jsonl on chant/lifecycle. Readers ignore fields they do not know; a field is only ever added within a version. The refusal and error codes are closed lists, each in the one closed list of `reason-codes.ts`. A release's --outcome is one of the closed list `$defs/outcome` (#3147); any other value is refused with write-usage-invalid.",
|
|
6
6
|
"oneOf": [
|
|
7
7
|
{
|
|
8
8
|
"$ref": "#/$defs/result"
|
|
@@ -15,6 +15,19 @@
|
|
|
15
15
|
}
|
|
16
16
|
],
|
|
17
17
|
"$defs": {
|
|
18
|
+
"outcome": {
|
|
19
|
+
"description": "How a work lease ended, as a release records it on _leases/<id>.jsonl (#3147). Closed: a new outcome is a contract change. done: the work was finished. not_done: a build ran and did not finish, or the run failed; counts as an attempt. abandoned: an expired lease closed out by someone other than its holder; counts as an attempt. gated: the run stopped at a gate. waiting: the run stopped on a decision point's open question. dropped: the item was dropped, such as by a refuse at the understand point. redraft and ask: the understand point sent the item back to its author. Only not_done and abandoned count toward an item's attempt limit.",
|
|
20
|
+
"enum": [
|
|
21
|
+
"done",
|
|
22
|
+
"not_done",
|
|
23
|
+
"abandoned",
|
|
24
|
+
"gated",
|
|
25
|
+
"waiting",
|
|
26
|
+
"dropped",
|
|
27
|
+
"redraft",
|
|
28
|
+
"ask"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
18
31
|
"lease": {
|
|
19
32
|
"type": "object",
|
|
20
33
|
"required": [
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The slice-tier point's sizes and the understand point (#3150): chant
|
|
3
|
+
* measures a work item the same way for every orchestrator, the decide
|
|
4
|
+
* activity reads the sizes with the item, and the reference workspace
|
|
5
|
+
* declares understand.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { cpSync, readFileSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { afterAll, describe, expect, test } from "vitest";
|
|
11
|
+
import { readInputs } from "../op/decide-read-inputs";
|
|
12
|
+
import { cleanScratch, git, REPO, scratchDir } from "./__fixtures__/contract-repo";
|
|
13
|
+
import { parsePoints } from "./points";
|
|
14
|
+
import { DEFAULT_TIER_LIMITS, fitsTier, measureWorkItem, sizeFields } from "./work-size";
|
|
15
|
+
|
|
16
|
+
afterAll(cleanScratch);
|
|
17
|
+
|
|
18
|
+
const SIZES = ["work-item.criteria", "work-item.files", "work-item.words", "work-item.fits_small", "work-item.fits_medium"];
|
|
19
|
+
|
|
20
|
+
describe("measuring a work item (#3150)", () => {
|
|
21
|
+
test("criteria, backticked paths and words from the ask, the body without headings and the criteria", () => {
|
|
22
|
+
const data = {
|
|
23
|
+
source: { ask: { said: "Make `app/server.ts` answer on `/healthz` and note it in `README.md`.", by: "alice" } },
|
|
24
|
+
acceptance: [{ id: "AC-1", text: "`app/server.ts` answers 200" }, { id: "AC-2", text: "the README says so" }],
|
|
25
|
+
};
|
|
26
|
+
const body = "# Heading words are not counted\n\nThe body names `app/server.ts` again and `docs/`.\n";
|
|
27
|
+
const size = measureWorkItem(data, body);
|
|
28
|
+
// `docs/` and `/healthz` have no part on both sides of a slash, so they are not paths.
|
|
29
|
+
expect(size).toEqual({ criteria: 2, files: 2, words: 24 });
|
|
30
|
+
expect(measureWorkItem({ source: { intent: { answer: "a garden planner" } } }, "")).toEqual({ criteria: 0, files: 0, words: 3 });
|
|
31
|
+
expect(measureWorkItem(null, "")).toEqual({ criteria: 0, files: 0, words: 0 });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("fits_<tier> for each tier with limits, against the defaults or the kind's own", () => {
|
|
35
|
+
expect(sizeFields({ criteria: 11, files: 2, words: 40 })).toEqual({ criteria: 11, files: 2, words: 40, fits_small: false, fits_medium: true });
|
|
36
|
+
expect(sizeFields({ criteria: 1, files: 1, words: 400 })).toMatchObject({ fits_small: false, fits_medium: false });
|
|
37
|
+
expect(sizeFields({ criteria: 1, files: 1, words: 40 }, { tiny: { words: 30 } })).toEqual({ criteria: 1, files: 1, words: 40, fits_tiny: false });
|
|
38
|
+
expect(fitsTier({ criteria: 10, files: 5, words: 150 }, DEFAULT_TIER_LIMITS.small)).toBe(true);
|
|
39
|
+
expect(fitsTier({ criteria: 0, files: 0, words: 0 }, undefined)).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe("the reference workspace (#3150)", () => {
|
|
44
|
+
const ref = join(REPO, "reference-workspace");
|
|
45
|
+
|
|
46
|
+
test("declares understand: four answers, a table that proceeds on an open item, then people", () => {
|
|
47
|
+
const points = parsePoints(readFileSync(join(ref, "decisions", "points.json"), "utf-8"), "points.json");
|
|
48
|
+
const u = points.understand;
|
|
49
|
+
expect(Object.keys(u.question.criteria ?? {})).toEqual(["proceed", "redraft", "ask", "refuse"]);
|
|
50
|
+
expect(Object.keys(u.inputs)).toEqual(["work-item.state", "work-item.title", "work-item.source.ask.said", "work-item.source.ask.by", "work-item.source.ask.via", "work-item.acceptance"]);
|
|
51
|
+
expect(u.deciders.map((d) => d.kind)).toEqual(["table", "quorum"]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("the decide activity reads a work item's sizes with it, and the work kind's limits win", async () => {
|
|
55
|
+
const copy = (): string => {
|
|
56
|
+
const root = scratchDir("chant-work-size-");
|
|
57
|
+
cpSync(ref, root, { recursive: true, filter: (src) => !/[\\/](node_modules|dist)$/.test(src) });
|
|
58
|
+
git(root, "init", "-q");
|
|
59
|
+
git(root, "add", "-A");
|
|
60
|
+
git(root, "commit", "-q", "-m", "the workspace");
|
|
61
|
+
return root;
|
|
62
|
+
};
|
|
63
|
+
let root = copy();
|
|
64
|
+
const read = await readInputs(SIZES, { "work-item": "W-001" }, root);
|
|
65
|
+
expect(read.missing).toEqual([]);
|
|
66
|
+
expect(read.inputs).toMatchObject({ "work-item.criteria": 2, "work-item.fits_small": true, "work-item.fits_medium": true });
|
|
67
|
+
expect(typeof read.inputs["work-item.words"]).toBe("number");
|
|
68
|
+
|
|
69
|
+
// A fresh copy: a kind file is loaded once per path.
|
|
70
|
+
root = copy();
|
|
71
|
+
const kind = join(root, "work", "work.kind.mjs");
|
|
72
|
+
writeFileSync(kind, readFileSync(kind, "utf-8").replace('tier: { field: "tier", tiers: ["small", "medium", "large"] }', 'tier: { field: "tier", tiers: ["small", "medium", "large"], limits: { small: { criteria: 1 } } }'));
|
|
73
|
+
const narrow = await readInputs(SIZES, { "work-item": "W-001" }, root);
|
|
74
|
+
expect(narrow.inputs["work-item.fits_small"]).toBe(false);
|
|
75
|
+
expect(narrow.missing).toEqual(["work-item.fits_medium"]);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How much a work item holds, for the `slice-tier` decision point (#3150).
|
|
3
|
+
*
|
|
4
|
+
* The point picks the smallest builder tier that can build an item, from five
|
|
5
|
+
* inputs every orchestrator must compute the same way, so chant computes
|
|
6
|
+
* them. They are read through the `work-item` output like any other field:
|
|
7
|
+
*
|
|
8
|
+
* work-item.criteria the item's acceptance criteria, counted
|
|
9
|
+
* work-item.files distinct paths the item names in backticks
|
|
10
|
+
* work-item.words words in the item's text
|
|
11
|
+
* work-item.fits_<tier> whether criteria, files and words are each within
|
|
12
|
+
* that tier's limits (`fits_small`, `fits_medium`)
|
|
13
|
+
*
|
|
14
|
+
* The item's text is what a person asked (`source.ask.said`, or the answer
|
|
15
|
+
* to the box's intent, `source.intent.answer`), the record's Markdown body
|
|
16
|
+
* with its heading lines left out, and each acceptance criterion's text. A
|
|
17
|
+
* path is a backticked token with a `/` between two parts, such as
|
|
18
|
+
* `app/server.ts` or `design/screens/`, or a file name with an extension of
|
|
19
|
+
* one to five letters, such as `README.md`. Words are runs of non-blank
|
|
20
|
+
* characters.
|
|
21
|
+
*
|
|
22
|
+
* The limits are the work kind's `work.tier.limits`, else
|
|
23
|
+
* {@link DEFAULT_TIER_LIMITS}: small holds at most 10 criteria, 5 files and
|
|
24
|
+
* 150 words, medium 20, 10 and 300. A tier with no limits, such as large,
|
|
25
|
+
* has no `fits_` input; an item that fits neither small nor medium is large.
|
|
26
|
+
* These are the sizing defaults studio's factory used (arugula-salad/studio
|
|
27
|
+
* `queue.mjs` `sizing()`), so a point's answers keep their meaning.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/** A field of `value` by dotted path, or undefined. */
|
|
31
|
+
function fieldOf(value: unknown, path: string): unknown {
|
|
32
|
+
let at: unknown = value;
|
|
33
|
+
for (const part of path.split(".")) {
|
|
34
|
+
if (at === null || typeof at !== "object" || !Object.prototype.hasOwnProperty.call(at, part)) return undefined;
|
|
35
|
+
at = (at as Record<string, unknown>)[part];
|
|
36
|
+
}
|
|
37
|
+
return at;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** What one tier may hold. A limit left out is not checked. */
|
|
41
|
+
export interface TierLimit {
|
|
42
|
+
criteria?: number;
|
|
43
|
+
files?: number;
|
|
44
|
+
words?: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The limits when the work kind declares none. */
|
|
48
|
+
export const DEFAULT_TIER_LIMITS: Readonly<Record<string, TierLimit>> = Object.freeze({
|
|
49
|
+
small: { criteria: 10, files: 5, words: 150 },
|
|
50
|
+
medium: { criteria: 20, files: 10, words: 300 },
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export interface WorkItemSize {
|
|
54
|
+
criteria: number;
|
|
55
|
+
files: number;
|
|
56
|
+
words: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const HEADING = /^\s*#/;
|
|
60
|
+
const PATH_LIKE = /^[\w@.-]+(\/[\w@.*-]+)+\/?$|^[\w@-][\w@.-]*\.[a-z]{1,5}$/i;
|
|
61
|
+
const str = (v: unknown): string => (typeof v === "string" ? v : "");
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Measure a work item from its front matter (`data`) and Markdown body.
|
|
65
|
+
* `acceptanceField` is the work kind's `work.acceptance.field`, `acceptance`
|
|
66
|
+
* when it names none.
|
|
67
|
+
*/
|
|
68
|
+
export function measureWorkItem(data: Record<string, unknown> | null, body: string, acceptanceField = "acceptance"): WorkItemSize {
|
|
69
|
+
const d = data ?? {};
|
|
70
|
+
const acceptance = Array.isArray(d[acceptanceField]) ? (d[acceptanceField] as unknown[]) : [];
|
|
71
|
+
const said = str(fieldOf(d, "source.ask.said")) || str(fieldOf(d, "source.intent.answer"));
|
|
72
|
+
const bodyLines = body.split("\n").filter((l) => !HEADING.test(l));
|
|
73
|
+
const criteriaText = acceptance.map((c) => (typeof c === "string" ? c : str((c as { text?: unknown } | null)?.text)));
|
|
74
|
+
const text = [said, ...bodyLines, ...criteriaText].join("\n");
|
|
75
|
+
const files = new Set([...text.matchAll(/`([^`\s]+)`/g)].map((m) => m[1]).filter((t) => PATH_LIKE.test(t)));
|
|
76
|
+
return { criteria: acceptance.length, files: files.size, words: text.split(/\s+/).filter(Boolean).length };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Whether `size` is within `limit`: each limit given is at least the measure. */
|
|
80
|
+
export function fitsTier(size: WorkItemSize, limit: TierLimit | undefined): boolean {
|
|
81
|
+
if (!limit) return false;
|
|
82
|
+
return (["criteria", "files", "words"] as const).every((k) => limit[k] === undefined || size[k] <= limit[k]!);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The slice-tier inputs' fields for a measured item: `criteria`, `files`,
|
|
87
|
+
* `words` and `fits_<tier>` for each tier `limits` names.
|
|
88
|
+
*/
|
|
89
|
+
export function sizeFields(size: WorkItemSize, limits: Readonly<Record<string, TierLimit>> = DEFAULT_TIER_LIMITS): Record<string, number | boolean> {
|
|
90
|
+
const out: Record<string, number | boolean> = { criteria: size.criteria, files: size.files, words: size.words };
|
|
91
|
+
for (const [tier, limit] of Object.entries(limits)) out[`fits_${tier}`] = fitsTier(size, limit);
|
|
92
|
+
return out;
|
|
93
|
+
}
|
package/src/workspace/work.ts
CHANGED
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
* - `implements`: each decision it names, with that decision's state;
|
|
18
18
|
* - `acceptance`, for a kind with acceptance criteria (#2772): how many of the
|
|
19
19
|
* record's criteria passing evidence of the expected verification meets;
|
|
20
|
+
* - `contract`, for a kind with a contract link (#3147): the contract record
|
|
21
|
+
* the item builds, with its state, read from the contract kind at the same
|
|
22
|
+
* revision;
|
|
20
23
|
*
|
|
21
24
|
* and each decision `implementedBy`, the work records naming it. The
|
|
22
25
|
* warnings are closed codes. `work-done-gap-open` is not raised here: it
|
|
@@ -48,6 +51,12 @@ export const WORK_WARNING_CODES = [
|
|
|
48
51
|
"work-acceptance-unmet",
|
|
49
52
|
/** A passing `manual` verdict on a criterion names the record's implementer, so it does not count: a manual verdict comes from someone else (#2772). */
|
|
50
53
|
"work-acceptance-self-verified",
|
|
54
|
+
/** The record names a contract no record of the kind's contract kind has (#3147). */
|
|
55
|
+
"work-contract-unknown",
|
|
56
|
+
/** The record names a contract whose state is not approved, such as a draft (#3147). */
|
|
57
|
+
"work-contract-undecided",
|
|
58
|
+
/** The record names a builder tier its kind's `work.tier.tiers` does not list (#3147). */
|
|
59
|
+
"work-tier-unknown",
|
|
51
60
|
] as const satisfies readonly ReasonCode[];
|
|
52
61
|
export type WorkWarningCode = (typeof WORK_WARNING_CODES)[number];
|
|
53
62
|
|
|
@@ -58,6 +67,49 @@ export interface WorkLink {
|
|
|
58
67
|
state: string | null;
|
|
59
68
|
}
|
|
60
69
|
|
|
70
|
+
/**
|
|
71
|
+
* One decision-point answer about a work item (#3147), as `records --json`
|
|
72
|
+
* joins it from the answer kind the work kind names: the answer records whose
|
|
73
|
+
* `constrains` names the item's id. The item never copies them.
|
|
74
|
+
*/
|
|
75
|
+
export interface WorkAnswer {
|
|
76
|
+
/** The answer record's id, such as understand-0123456789ab. */
|
|
77
|
+
id: string;
|
|
78
|
+
/** The decision point it answers. */
|
|
79
|
+
point: string | null;
|
|
80
|
+
/** escalated, proposed or answered. */
|
|
81
|
+
state: string | null;
|
|
82
|
+
/** The answer, or null while there is none. */
|
|
83
|
+
answer: string | boolean | null;
|
|
84
|
+
/** The people who answered or confirmed it, empty when a table or model did. */
|
|
85
|
+
answeredBy: string[];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The answers about each work item: every answer record whose `constrains`
|
|
90
|
+
* names the item's id, in path order, by item id.
|
|
91
|
+
*/
|
|
92
|
+
export function workAnswers(answerRecords: readonly RecordEntry[], ids: Iterable<string>): Map<string, WorkAnswer[]> {
|
|
93
|
+
const out = new Map<string, WorkAnswer[]>();
|
|
94
|
+
for (const id of ids) out.set(id, []);
|
|
95
|
+
for (const a of answerRecords) {
|
|
96
|
+
if (a.id === null || a.data === null) continue;
|
|
97
|
+
for (const target of idList(a.data, "constrains")) {
|
|
98
|
+
const list = out.get(target);
|
|
99
|
+
if (!list || list.some((x) => x.id === a.id)) continue;
|
|
100
|
+
const answer = a.data.answer;
|
|
101
|
+
list.push({
|
|
102
|
+
id: a.id,
|
|
103
|
+
point: typeof a.data.point === "string" ? a.data.point : null,
|
|
104
|
+
state: a.state,
|
|
105
|
+
answer: typeof answer === "string" || typeof answer === "boolean" ? answer : null,
|
|
106
|
+
answeredBy: idList(a.data, "answered_by"),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
|
|
61
113
|
/** A decision as a work read lists it: its state and the work records implementing it. */
|
|
62
114
|
export interface DecisionWork {
|
|
63
115
|
id: string;
|
|
@@ -174,6 +226,16 @@ export async function applyWork(loaded: LoadedRecordKind, entries: RecordEntry[]
|
|
|
174
226
|
for (const e of entries) if (e.id !== null && !byId.has(e.id)) byId.set(e.id, e);
|
|
175
227
|
const closed = new Set(kind.closedStates);
|
|
176
228
|
|
|
229
|
+
// The contract kind a work item names its contract in (#3147), read at the same revision.
|
|
230
|
+
let contracts: { kind: LoadedRecordKind; byId: Map<string, RecordEntry> } | undefined;
|
|
231
|
+
if (work.contract) {
|
|
232
|
+
const contractKind = await loadRecordKind(work.contract.kind, dirname(loaded.file));
|
|
233
|
+
const contractRead = await readRecords(contractKind, { root: options.root, source: options.source });
|
|
234
|
+
const contractById = new Map<string, RecordEntry>();
|
|
235
|
+
for (const c of contractRead.records) if (c.id !== null && !contractById.has(c.id)) contractById.set(c.id, c);
|
|
236
|
+
contracts = { kind: contractKind, byId: contractById };
|
|
237
|
+
}
|
|
238
|
+
|
|
177
239
|
// Records in a needs cycle: those that reach themselves.
|
|
178
240
|
const inCycle = new Set<string>();
|
|
179
241
|
for (const start of byId.keys()) {
|
|
@@ -242,6 +304,26 @@ export async function applyWork(loaded: LoadedRecordKind, entries: RecordEntry[]
|
|
|
242
304
|
});
|
|
243
305
|
}
|
|
244
306
|
}
|
|
307
|
+
if (contracts && work.contract) {
|
|
308
|
+
const named = e.data[work.contract.field];
|
|
309
|
+
if (typeof named === "string" && named !== "") {
|
|
310
|
+
const c = contracts.byId.get(named);
|
|
311
|
+
e.contract = { id: named, state: c?.state ?? null };
|
|
312
|
+
if (!c) {
|
|
313
|
+
e.warnings.push({ code: "work-contract-unknown", message: `names the contract ${named}, which no record in ${work.contract.kind} has` });
|
|
314
|
+
} else if (!isDecided(contracts.kind.kind, c.state)) {
|
|
315
|
+
e.warnings.push({ code: "work-contract-undecided", message: `names the contract ${named}, which is ${c.state ?? "in no state"}: the work may build a contract nobody approved` });
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
e.contract = null;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (work.tier) {
|
|
322
|
+
const tier = e.data[work.tier.field];
|
|
323
|
+
if (typeof tier === "string" && !work.tier.tiers.includes(tier)) {
|
|
324
|
+
e.warnings.push({ code: "work-tier-unknown", message: `names the builder tier ${tier}, which the kind's tiers (${work.tier.tiers.join(", ")}) do not list` });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
245
327
|
if (e.state !== null && closed.has(e.state) && typeof e.data[work.closedOn] !== "string") {
|
|
246
328
|
e.warnings.push({ code: "work-closed-without-date", message: `${e.id ?? e.path} is ${e.state} and has no ${work.closedOn}` });
|
|
247
329
|
}
|
|
@@ -75,6 +75,9 @@
|
|
|
75
75
|
},
|
|
76
76
|
"graph": {
|
|
77
77
|
"$ref": "#/$defs/graph"
|
|
78
|
+
},
|
|
79
|
+
"fields": {
|
|
80
|
+
"$ref": "#/$defs/fields"
|
|
78
81
|
}
|
|
79
82
|
},
|
|
80
83
|
"patternProperties": {
|
|
@@ -123,6 +126,34 @@
|
|
|
123
126
|
}
|
|
124
127
|
},
|
|
125
128
|
"additionalProperties": false
|
|
129
|
+
},
|
|
130
|
+
"anyJsonKey": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"description": "The directory passes when a file directly in it, whose name matches one of in, parses as JSON and has a value at one of pointers, each a JSON Pointer such as /scripts/start (#3151). A file that is not JSON is no evidence either way. Added by chant 0.103.0.",
|
|
133
|
+
"required": [
|
|
134
|
+
"in",
|
|
135
|
+
"pointers"
|
|
136
|
+
],
|
|
137
|
+
"properties": {
|
|
138
|
+
"in": {
|
|
139
|
+
"type": "array",
|
|
140
|
+
"minItems": 1,
|
|
141
|
+
"uniqueItems": true,
|
|
142
|
+
"items": {
|
|
143
|
+
"$ref": "#/$defs/fileName"
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"pointers": {
|
|
147
|
+
"type": "array",
|
|
148
|
+
"minItems": 1,
|
|
149
|
+
"uniqueItems": true,
|
|
150
|
+
"items": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"pattern": "^(/[^/]+)+$"
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"additionalProperties": false
|
|
126
157
|
}
|
|
127
158
|
},
|
|
128
159
|
"additionalProperties": false
|
|
@@ -154,6 +185,97 @@
|
|
|
154
185
|
"^x-": true
|
|
155
186
|
},
|
|
156
187
|
"additionalProperties": false
|
|
188
|
+
},
|
|
189
|
+
"fields": {
|
|
190
|
+
"type": "object",
|
|
191
|
+
"description": "The fields a member entry of this kind may set under its own fields block, each with a type and, optionally, a default (#3151). chant workspace check fails a member whose fields name one the kind doesn't declare or give a value of the wrong type (WSP005), and chant workspace status --json prints every declared field with the defaults filled in. Added by chant 0.103.0; an older chant can't read a kinds file that uses it.",
|
|
192
|
+
"minProperties": 1,
|
|
193
|
+
"propertyNames": {
|
|
194
|
+
"$ref": "#/$defs/fieldName"
|
|
195
|
+
},
|
|
196
|
+
"additionalProperties": {
|
|
197
|
+
"oneOf": [
|
|
198
|
+
{
|
|
199
|
+
"$ref": "#/$defs/scalarField"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"$ref": "#/$defs/objectField"
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"fieldName": {
|
|
208
|
+
"type": "string",
|
|
209
|
+
"pattern": "^[a-z][A-Za-z0-9]{0,39}$"
|
|
210
|
+
},
|
|
211
|
+
"scalarField": {
|
|
212
|
+
"type": "object",
|
|
213
|
+
"required": [
|
|
214
|
+
"type",
|
|
215
|
+
"description"
|
|
216
|
+
],
|
|
217
|
+
"properties": {
|
|
218
|
+
"type": {
|
|
219
|
+
"enum": [
|
|
220
|
+
"string",
|
|
221
|
+
"integer",
|
|
222
|
+
"boolean"
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
"description": {
|
|
226
|
+
"type": "string",
|
|
227
|
+
"minLength": 1
|
|
228
|
+
},
|
|
229
|
+
"default": {
|
|
230
|
+
"oneOf": [
|
|
231
|
+
{
|
|
232
|
+
"type": "string"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"type": "integer"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"type": "boolean"
|
|
239
|
+
}
|
|
240
|
+
],
|
|
241
|
+
"description": "The value a member that doesn't set the field gets. Its type is the field's. Without it the field reads as null when unset."
|
|
242
|
+
},
|
|
243
|
+
"pattern": {
|
|
244
|
+
"type": "string",
|
|
245
|
+
"minLength": 1,
|
|
246
|
+
"description": "For a string field: a regular expression the value must match."
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
"additionalProperties": false
|
|
250
|
+
},
|
|
251
|
+
"objectField": {
|
|
252
|
+
"type": "object",
|
|
253
|
+
"required": [
|
|
254
|
+
"type",
|
|
255
|
+
"description",
|
|
256
|
+
"properties"
|
|
257
|
+
],
|
|
258
|
+
"properties": {
|
|
259
|
+
"type": {
|
|
260
|
+
"const": "object"
|
|
261
|
+
},
|
|
262
|
+
"description": {
|
|
263
|
+
"type": "string",
|
|
264
|
+
"minLength": 1
|
|
265
|
+
},
|
|
266
|
+
"properties": {
|
|
267
|
+
"type": "object",
|
|
268
|
+
"minProperties": 1,
|
|
269
|
+
"propertyNames": {
|
|
270
|
+
"$ref": "#/$defs/fieldName"
|
|
271
|
+
},
|
|
272
|
+
"additionalProperties": {
|
|
273
|
+
"$ref": "#/$defs/scalarField"
|
|
274
|
+
},
|
|
275
|
+
"description": "The object's own fields, each a string, integer or boolean field. A member sets any of them; the rest take their defaults."
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
"additionalProperties": false
|
|
157
279
|
}
|
|
158
280
|
}
|
|
159
281
|
}
|