@intentius/chant 0.124.13 → 0.124.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/chant +11 -0
- package/dist/agents/checks.js +326 -0
- package/dist/agents/discover.js +885 -0
- package/dist/agents/importer.js +17 -0
- package/dist/agents/index.js +12 -0
- package/dist/agents/types.js +19 -0
- package/dist/apply.js +151 -0
- package/dist/attrref.js +70 -0
- package/dist/audit/catalog.js +350 -0
- package/dist/audit/core.js +252 -0
- package/dist/audit/discover.js +633 -0
- package/dist/audit/fetch.js +666 -0
- package/dist/audit/lineage.js +91 -0
- package/dist/audit/nginx.js +366 -0
- package/dist/audit/prior-art.js +132 -0
- package/dist/audit/proof.js +321 -0
- package/dist/audit/report-html.js +194 -0
- package/dist/audit/report-model.js +198 -0
- package/dist/audit/report.js +102 -0
- package/dist/audit/rules-doc.js +144 -0
- package/dist/audit/secrets.js +405 -0
- package/dist/audit/terraform-state.js +140 -0
- package/dist/audit/wrangler.js +262 -0
- package/dist/behaviour-delta.js +401 -0
- package/dist/behaviour-engine.js +357 -0
- package/dist/behaviour-graph.js +83 -0
- package/dist/behaviour-http.js +188 -0
- package/dist/behaviour-kinds.js +172 -0
- package/dist/behaviour-overlay.js +50 -0
- package/dist/behaviour-predict.js +188 -0
- package/dist/behaviour-request.js +194 -0
- package/dist/behaviour.js +1325 -0
- package/dist/build-params.js +108 -0
- package/dist/build.d.ts +6 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +669 -0
- package/dist/builder.js +44 -0
- package/dist/cdk/advise.js +30 -0
- package/dist/cdk/assembly.js +122 -0
- package/dist/cdk/graph.js +444 -0
- package/dist/cdk/tier-map.js +64 -0
- package/dist/cdk/types.js +24 -0
- package/dist/change-set.d.ts +24 -2
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +361 -0
- package/dist/child-project.js +21 -0
- package/dist/ci-jobs.d.ts +227 -0
- package/dist/ci-jobs.d.ts.map +1 -0
- package/dist/ci-jobs.js +448 -0
- package/dist/claimed-fields.js +135 -0
- package/dist/cli/build-options.js +70 -0
- package/dist/cli/build-params-cli.js +139 -0
- package/dist/cli/command-group.js +123 -0
- package/dist/cli/commands/audit-agents.js +326 -0
- package/dist/cli/commands/audit.js +571 -0
- package/dist/cli/commands/build.js +920 -0
- package/dist/cli/commands/carve-apply.js +153 -0
- package/dist/cli/commands/carve-bridge.js +201 -0
- package/dist/cli/commands/carve-emit.js +332 -0
- package/dist/cli/commands/carve-status.js +119 -0
- package/dist/cli/commands/carve.js +204 -0
- package/dist/cli/commands/check-lexicon-docs.js +79 -0
- package/dist/cli/commands/check-lexicon-examples.js +177 -0
- package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
- package/dist/cli/commands/check-lexicon-mcp.js +82 -0
- package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-plugin.js +104 -0
- package/dist/cli/commands/check-lexicon.js +766 -0
- package/dist/cli/commands/describe.js +85 -0
- package/dist/cli/commands/diff.js +175 -0
- package/dist/cli/commands/doctor.js +350 -0
- package/dist/cli/commands/import-agents.js +155 -0
- package/dist/cli/commands/import.js +670 -0
- package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
- package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
- package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
- package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
- package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
- package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
- package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
- package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
- package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
- package/dist/cli/commands/init-lexicon.js +172 -0
- package/dist/cli/commands/init.js +381 -0
- package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
- package/dist/cli/commands/lexicon-surface-diff.js +145 -0
- package/dist/cli/commands/licenses.js +125 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +948 -0
- package/dist/cli/commands/list.js +63 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +423 -0
- package/dist/cli/commands/onboard.js +403 -0
- package/dist/cli/commands/pinned-upgrade.js +191 -0
- package/dist/cli/commands/update.js +194 -0
- package/dist/cli/commands/vendor.js +217 -0
- package/dist/cli/conflict-check.js +104 -0
- package/dist/cli/debug.js +8 -0
- package/dist/cli/format.js +104 -0
- package/dist/cli/handlers/build.js +267 -0
- package/dist/cli/handlers/carve-apply.js +30 -0
- package/dist/cli/handlers/carve-bridge.js +28 -0
- package/dist/cli/handlers/carve-emit.js +50 -0
- package/dist/cli/handlers/carve-status.js +26 -0
- package/dist/cli/handlers/carve.js +40 -0
- package/dist/cli/handlers/change-set.js +46 -0
- package/dist/cli/handlers/components.js +730 -0
- package/dist/cli/handlers/dev.js +113 -0
- package/dist/cli/handlers/emulator.js +233 -0
- package/dist/cli/handlers/explain.js +54 -0
- package/dist/cli/handlers/fan-out.js +422 -0
- package/dist/cli/handlers/gate-resume.js +275 -0
- package/dist/cli/handlers/generate.js +84 -0
- package/dist/cli/handlers/graph.js +969 -0
- package/dist/cli/handlers/init.js +102 -0
- package/dist/cli/handlers/lifecycle.js +1727 -0
- package/dist/cli/handlers/lint.js +62 -0
- package/dist/cli/handlers/migrate.js +48 -0
- package/dist/cli/handlers/misc.js +391 -0
- package/dist/cli/handlers/operator.js +1162 -0
- package/dist/cli/handlers/override-approve.js +102 -0
- package/dist/cli/handlers/pr.js +503 -0
- package/dist/cli/handlers/promote.js +342 -0
- package/dist/cli/handlers/run-generate.js +206 -0
- package/dist/cli/handlers/run-wave.js +66 -0
- package/dist/cli/handlers/run.js +1191 -0
- package/dist/cli/handlers/scenario.js +325 -0
- package/dist/cli/handlers/search.js +924 -0
- package/dist/cli/handlers/serve.js +32 -0
- package/dist/cli/handlers/vendor.js +154 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/is-entry-point.js +23 -0
- package/dist/cli/lsp/capabilities.js +28 -0
- package/dist/cli/lsp/diagnostics.js +34 -0
- package/dist/cli/lsp/server.js +329 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +2540 -0
- package/dist/cli/mcp/lifecycle-tools.js +80 -0
- package/dist/cli/mcp/op-tools.js +306 -0
- package/dist/cli/mcp/resource-handlers.js +258 -0
- package/dist/cli/mcp/resources/context.js +85 -0
- package/dist/cli/mcp/server.js +353 -0
- package/dist/cli/mcp/tools/build.js +111 -0
- package/dist/cli/mcp/tools/composites.js +95 -0
- package/dist/cli/mcp/tools/explain.js +166 -0
- package/dist/cli/mcp/tools/import.js +49 -0
- package/dist/cli/mcp/tools/lint.js +41 -0
- package/dist/cli/mcp/tools/scaffold.js +111 -0
- package/dist/cli/mcp/tools/search.js +112 -0
- package/dist/cli/mcp/types.js +1 -0
- package/dist/cli/mcp/workspace-plugins.js +91 -0
- package/dist/cli/mcp/workspace-tools.d.ts +1 -1
- package/dist/cli/mcp/workspace-tools.js +564 -0
- package/dist/cli/mcp-config.js +70 -0
- package/dist/cli/plugins.js +313 -0
- package/dist/cli/registry.js +23 -0
- package/dist/cli/reporters/stylish.js +329 -0
- package/dist/cli/version.js +15 -0
- package/dist/cli/watch.js +79 -0
- package/dist/codegen/bound-property-types.js +82 -0
- package/dist/codegen/coverage.js +119 -0
- package/dist/codegen/docs-file-markers.js +60 -0
- package/dist/codegen/docs-pages.js +115 -0
- package/dist/codegen/docs-rule-scanning.js +164 -0
- package/dist/codegen/docs-rules.js +76 -0
- package/dist/codegen/docs-sections.js +117 -0
- package/dist/codegen/docs-sidebar.js +65 -0
- package/dist/codegen/docs-types.js +4 -0
- package/dist/codegen/docs.js +356 -0
- package/dist/codegen/fetch.js +340 -0
- package/dist/codegen/generate-post-synth-barrel.js +63 -0
- package/dist/codegen/generate-registry.js +71 -0
- package/dist/codegen/generate-runtime-index.js +56 -0
- package/dist/codegen/generate-typescript.js +119 -0
- package/dist/codegen/generate.js +115 -0
- package/dist/codegen/json-patch.js +141 -0
- package/dist/codegen/json-schema-to-ts.js +344 -0
- package/dist/codegen/json-schema.js +246 -0
- package/dist/codegen/lexicon-regen.js +412 -0
- package/dist/codegen/naming.js +217 -0
- package/dist/codegen/okf-lexicon.js +245 -0
- package/dist/codegen/package.js +150 -0
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.js +494 -0
- package/dist/codegen/registry.js +60 -0
- package/dist/codegen/rehype-base-url.mjs +68 -0
- package/dist/codegen/rolling-upgrade.js +217 -0
- package/dist/codegen/surface-snapshot.js +537 -0
- package/dist/codegen/testdata/postgres-tags.json +242 -0
- package/dist/codegen/topo-sort.js +36 -0
- package/dist/codegen/typecheck.js +115 -0
- package/dist/codegen/validate.js +200 -0
- package/dist/codegen/version-bump.js +35 -0
- package/dist/components/auto-release.js +143 -0
- package/dist/components/builders.js +47 -0
- package/dist/components/capability-plugin-loader.js +175 -0
- package/dist/components/capability-plugin-schema.js +46 -0
- package/dist/components/capability-plugin.js +99 -0
- package/dist/components/capability.js +60 -0
- package/dist/components/changed-files.js +72 -0
- package/dist/components/cli-support.js +427 -0
- package/dist/components/component.js +120 -0
- package/dist/components/component.schema.json +271 -0
- package/dist/components/config-defaults.js +130 -0
- package/dist/components/deploy-units.js +60 -0
- package/dist/components/discover.d.ts.map +1 -1
- package/dist/components/discover.js +189 -0
- package/dist/components/driver-output.js +86 -0
- package/dist/components/driver.js +728 -0
- package/dist/components/fan-out-output.js +165 -0
- package/dist/components/fan-out-record.js +94 -0
- package/dist/components/fan-out-run.js +373 -0
- package/dist/components/fan-out-support.js +60 -0
- package/dist/components/fan-out.js +273 -0
- package/dist/components/gate-plan.js +41 -0
- package/dist/components/gated-wave-pipeline.js +46 -0
- package/dist/components/index.js +24 -0
- package/dist/components/layers.js +28 -0
- package/dist/components/manifest-persistence.js +108 -0
- package/dist/components/pilots/alb-ecs.pilot.js +59 -0
- package/dist/components/pilots/dynamodb.pilot.js +51 -0
- package/dist/components/pilots/jar-emr.pilot.js +65 -0
- package/dist/components/pilots/lambda.pilot.js +52 -0
- package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
- package/dist/components/pilots/project.js +12 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +135 -0
- package/dist/components/pr-run.js +363 -0
- package/dist/components/presets/ecs-fargate.js +72 -0
- package/dist/components/presets/index.js +28 -0
- package/dist/components/presets/lambda.js +34 -0
- package/dist/components/presets/single-host-compose.js +41 -0
- package/dist/components/promote.js +549 -0
- package/dist/components/registry.js +34 -0
- package/dist/components/run-progress.js +33 -0
- package/dist/components/sandbox/driver.d.ts.map +1 -1
- package/dist/components/sandbox/driver.js +93 -0
- package/dist/components/sandbox/run.js +115 -0
- package/dist/components/starter-plugin.js +104 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
- package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
- package/dist/components/verbs/bom-writer.js +287 -0
- package/dist/components/verbs/build-archive.js +188 -0
- package/dist/components/verbs/build.js +142 -0
- package/dist/components/verbs/cloud-executor.js +110 -0
- package/dist/components/verbs/component-bom.js +125 -0
- package/dist/components/verbs/ensure-secret.js +50 -0
- package/dist/components/verbs/index.js +61 -0
- package/dist/components/verbs/license-policy.js +75 -0
- package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
- package/dist/components/verbs/process-runner.js +78 -0
- package/dist/components/verbs/r2-sync.js +93 -0
- package/dist/components/verbs/reproducibility.js +62 -0
- package/dist/components/verbs/run-agent.js +577 -0
- package/dist/components/verbs/sbom-generator.js +119 -0
- package/dist/components/verbs/sbom.js +97 -0
- package/dist/components/verbs/shell.js +32 -0
- package/dist/components/verbs/sign.js +221 -0
- package/dist/components/verbs/stub.js +28 -0
- package/dist/components/verbs/tool-sbom-generator.js +154 -0
- package/dist/components/verbs/verify.js +112 -0
- package/dist/components/verbs/vex.js +131 -0
- package/dist/components/verbs/vuln-gate.js +152 -0
- package/dist/components/verbs/vuln-scan.js +288 -0
- package/dist/components/verbs/wait-verify.js +106 -0
- package/dist/components/verbs/wrangler.js +179 -0
- package/dist/components/wave-plan.js +102 -0
- package/dist/composite.d.ts +10 -2
- package/dist/composite.d.ts.map +1 -1
- package/dist/composite.js +313 -0
- package/dist/config-import.d.ts.map +1 -1
- package/dist/config-import.js +22 -0
- package/dist/config-sandbox.js +122 -0
- package/dist/config-static.js +206 -0
- package/dist/config.js +605 -0
- package/dist/content-digest.js +23 -0
- package/dist/declarable.js +114 -0
- package/dist/deep-observation.js +437 -0
- package/dist/detectLexicon.js +54 -0
- package/dist/discovery/cache.js +70 -0
- package/dist/discovery/collect.d.ts +2 -1
- package/dist/discovery/collect.d.ts.map +1 -1
- package/dist/discovery/collect.js +223 -0
- package/dist/discovery/cycles.js +95 -0
- package/dist/discovery/entity-wire-codec.js +391 -0
- package/dist/discovery/entity-wire.js +42 -0
- package/dist/discovery/files.js +121 -0
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/fold-import.js +4073 -0
- package/dist/discovery/fold-rank.js +292 -0
- package/dist/discovery/graph.js +115 -0
- package/dist/discovery/host-composite.d.ts +35 -0
- package/dist/discovery/host-composite.d.ts.map +1 -0
- package/dist/discovery/host-composite.js +93 -0
- package/dist/discovery/import.d.ts.map +1 -1
- package/dist/discovery/import.js +65 -0
- package/dist/discovery/index.d.ts +9 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +333 -0
- package/dist/discovery/param-deps.js +487 -0
- package/dist/discovery/resolve.js +39 -0
- package/dist/discovery/sandbox/bundle.js +214 -0
- package/dist/discovery/sandbox/child-errors.js +26 -0
- package/dist/discovery/sandbox/config-run.js +100 -0
- package/dist/discovery/sandbox/config-wire.js +183 -0
- package/dist/discovery/sandbox/driver.d.ts.map +1 -1
- package/dist/discovery/sandbox/driver.js +333 -0
- package/dist/discovery/sandbox/fork.js +229 -0
- package/dist/discovery/sandbox/policy-run.js +142 -0
- package/dist/discovery/sandbox/policy-wire.js +152 -0
- package/dist/discovery/sandbox/run.js +77 -0
- package/dist/discovery/specifier-resolve.js +320 -0
- package/dist/discovery/walk.js +284 -0
- package/dist/effect-receipt.js +340 -0
- package/dist/env.js +55 -0
- package/dist/errors.js +62 -0
- package/dist/fold/fold.js +1434 -0
- package/dist/fold/foldable-helpers.js +229 -0
- package/dist/fold/subset.js +696 -0
- package/dist/fold-provenance.js +414 -0
- package/dist/gate-decision.d.ts +20 -9
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/gate-decision.js +313 -0
- package/dist/gate-resume-run.js +154 -0
- package/dist/gated-waves.js +165 -0
- package/dist/governance.js +43 -0
- package/dist/graph-declared.js +45 -0
- package/dist/graph-detail.js +207 -0
- package/dist/graph-dot.js +54 -0
- package/dist/graph-effective.js +107 -0
- package/dist/graph-ir.js +623 -0
- package/dist/graph-layout.js +184 -0
- package/dist/graph-lens.js +105 -0
- package/dist/graph-mermaid.js +83 -0
- package/dist/graph-ops.js +39 -0
- package/dist/graph-refs.js +156 -0
- package/dist/held-elsewhere.js +87 -0
- package/dist/identity.js +251 -0
- package/dist/import/base-parser.js +34 -0
- package/dist/import/embedded.js +255 -0
- package/dist/import/generator.js +1 -0
- package/dist/import/ir-utils.js +85 -0
- package/dist/import/parser-options.js +45 -0
- package/dist/import/parser.js +1 -0
- package/dist/index.js +118 -0
- package/dist/intrinsic-interpolation.js +73 -0
- package/dist/intrinsic.js +31 -0
- package/dist/join-key.js +35 -0
- package/dist/kubectl-context.js +150 -0
- package/dist/lexicon-config.js +58 -0
- package/dist/lexicon-integrity.js +47 -0
- package/dist/lexicon-manifest.js +70 -0
- package/dist/lexicon-module.d.ts.map +1 -1
- package/dist/lexicon-module.js +241 -0
- package/dist/lexicon-output.js +218 -0
- package/dist/lexicon-plugin-helpers.js +104 -0
- package/dist/lexicon-schema.js +136 -0
- package/dist/lexicon.js +130 -0
- package/dist/lifecycle/affected.js +224 -0
- package/dist/lifecycle/assert-live.js +110 -0
- package/dist/lifecycle/build-ledger-store.js +160 -0
- package/dist/lifecycle/build-ledger.js +155 -0
- package/dist/lifecycle/change-set.js +356 -0
- package/dist/lifecycle/converge-ledger.js +161 -0
- package/dist/lifecycle/deep-diff.js +233 -0
- package/dist/lifecycle/deep-observe.js +147 -0
- package/dist/lifecycle/digest.js +143 -0
- package/dist/lifecycle/disruption.js +135 -0
- package/dist/lifecycle/gate-applied.js +113 -0
- package/dist/lifecycle/gate-audit.d.ts +69 -2
- package/dist/lifecycle/gate-audit.d.ts.map +1 -1
- package/dist/lifecycle/gate-audit.js +415 -0
- package/dist/lifecycle/gate-ledger-select.js +89 -0
- package/dist/lifecycle/gate-ledger.d.ts +24 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.js +201 -0
- package/dist/lifecycle/gate-origin.js +117 -0
- package/dist/lifecycle/gate-pending.js +58 -0
- package/dist/lifecycle/git.js +1182 -0
- package/dist/lifecycle/identity.js +58 -0
- package/dist/lifecycle/index.js +26 -0
- package/dist/lifecycle/lease.js +283 -0
- package/dist/lifecycle/ledger-port.js +1 -0
- package/dist/lifecycle/legacy-digest.js +91 -0
- package/dist/lifecycle/live-diff.js +274 -0
- package/dist/lifecycle/local-note.js +15 -0
- package/dist/lifecycle/member-ledger.js +122 -0
- package/dist/lifecycle/observation-baseline.js +155 -0
- package/dist/lifecycle/observe.js +375 -0
- package/dist/lifecycle/oras-referrer-lookup.js +82 -0
- package/dist/lifecycle/override-ledger.js +54 -0
- package/dist/lifecycle/plan-digest.js +110 -0
- package/dist/lifecycle/plan-ledger.js +129 -0
- package/dist/lifecycle/receipt-plan.js +192 -0
- package/dist/lifecycle/release-ledger.js +155 -0
- package/dist/lifecycle/release-read.js +64 -0
- package/dist/lifecycle/replay.js +193 -0
- package/dist/lifecycle/rollback.js +102 -0
- package/dist/lifecycle/run-ledger.js +183 -0
- package/dist/lifecycle/scenario-eval.js +204 -0
- package/dist/lifecycle/scenario.js +214 -0
- package/dist/lifecycle/snapshot.js +239 -0
- package/dist/lifecycle/status.js +447 -0
- package/dist/lifecycle/symptoms.js +117 -0
- package/dist/lifecycle/teardown.js +255 -0
- package/dist/lifecycle/types.js +1 -0
- package/dist/lifecycle/unobserved-gate.js +33 -0
- package/dist/lifecycle/wave-plans.js +68 -0
- package/dist/lifecycle/work-item-id.js +36 -0
- package/dist/lifecycle/work-lease.js +393 -0
- package/dist/lint/component-checks.js +87 -0
- package/dist/lint/config.js +483 -0
- package/dist/lint/declarative.js +122 -0
- package/dist/lint/discover.d.ts.map +1 -1
- package/dist/lint/discover.js +138 -0
- package/dist/lint/engine.js +246 -0
- package/dist/lint/knowledge-checks.js +64 -0
- package/dist/lint/named-checks.js +22 -0
- package/dist/lint/output-checks.js +87 -0
- package/dist/lint/output-docs.js +163 -0
- package/dist/lint/parser.js +33 -0
- package/dist/lint/pipeline-change-gate.js +70 -0
- package/dist/lint/policy-import.d.ts +1 -1
- package/dist/lint/policy-import.d.ts.map +1 -1
- package/dist/lint/policy-import.js +62 -0
- package/dist/lint/policy-sandbox.js +86 -0
- package/dist/lint/policy.js +122 -0
- package/dist/lint/post-synth.js +87 -0
- package/dist/lint/presets/relaxed.json +26 -0
- package/dist/lint/presets/strict.json +24 -24
- package/dist/lint/receipt-checks.js +83 -0
- package/dist/lint/rule-loader.d.ts.map +1 -1
- package/dist/lint/rule-loader.js +89 -0
- package/dist/lint/rule-registry.js +86 -0
- package/dist/lint/rule.js +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
- package/dist/lint/rules/comp/index.js +33 -0
- package/dist/lint/rules/comp/support.js +129 -0
- package/dist/lint/rules/composite-scope.js +51 -0
- package/dist/lint/rules/cor017-composite-name-match.js +93 -0
- package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
- package/dist/lint/rules/cor021-env-literal-name.js +100 -0
- package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
- package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
- package/dist/lint/rules/declarable-naming-convention.js +62 -0
- package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
- package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
- package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
- package/dist/lint/rules/evl004-spread-non-const.js +94 -0
- package/dist/lint/rules/evl005-resource-block-body.js +41 -0
- package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
- package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
- package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
- package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
- package/dist/lint/rules/export-required.js +115 -0
- package/dist/lint/rules/file-declarable-limit.js +88 -0
- package/dist/lint/rules/flat-declarations.js +62 -0
- package/dist/lint/rules/index.js +90 -0
- package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
- package/dist/lint/rules/no-redundant-type-import.js +76 -0
- package/dist/lint/rules/no-redundant-value-cast.js +41 -0
- package/dist/lint/rules/no-string-ref.js +59 -0
- package/dist/lint/rules/no-unused-declarable-import.js +75 -0
- package/dist/lint/rules/no-unused-declarable.js +142 -0
- package/dist/lint/rules/op/index.js +28 -0
- package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
- package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
- package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
- package/dist/lint/rules/op/support.js +11 -0
- package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
- package/dist/lint/rules/property-kind.js +56 -0
- package/dist/lint/rules/single-concern-file.js +71 -0
- package/dist/lint/rules/sys001-no-literal-key.js +60 -0
- package/dist/lint/selectors.js +168 -0
- package/dist/lint/suppressions.js +129 -0
- package/dist/lint/typescript.js +17 -0
- package/dist/live-endpoint.js +113 -0
- package/dist/live-read-session.js +76 -0
- package/dist/lsp/lexicon-providers.js +163 -0
- package/dist/lsp/types.js +5 -0
- package/dist/managed-fields.js +293 -0
- package/dist/mcp/types.js +4 -0
- package/dist/notify-verify.js +0 -1
- package/dist/notify.js +0 -1
- package/dist/notify.schema.json +72 -0
- package/dist/observation.js +266 -0
- package/dist/okf-read.js +134 -0
- package/dist/okf.js +275 -0
- package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
- package/dist/op/activities/activity-contracts.d.ts +1 -1
- package/dist/op/activities/activity-contracts.js +313 -0
- package/dist/op/activities/apply.js +582 -0
- package/dist/op/activities/build.js +18 -0
- package/dist/op/activities/change-coverage.js +40 -0
- package/dist/op/activities/change-set.d.ts +8 -3
- package/dist/op/activities/change-set.d.ts.map +1 -1
- package/dist/op/activities/change-set.js +67 -0
- package/dist/op/activities/converge.js +492 -0
- package/dist/op/activities/decide.js +211 -0
- package/dist/op/activities/env-teardown.js +110 -0
- package/dist/op/activities/factory.js +591 -0
- package/dist/op/activities/forge-pull-request.js +82 -0
- package/dist/op/activities/gh-host.js +78 -0
- package/dist/op/activities/guard-validate.js +165 -0
- package/dist/op/activities/http-check.js +40 -0
- package/dist/op/activities/index.js +59 -0
- package/dist/op/activities/lexicon-upgrade.js +629 -0
- package/dist/op/activities/lifecycle.js +109 -0
- package/dist/op/activities/pipeline-audit.js +147 -0
- package/dist/op/activities/policy.js +26 -0
- package/dist/op/activities/predict-behaviour.js +341 -0
- package/dist/op/activities/propose-upgrade.js +165 -0
- package/dist/op/activities/reconcile.d.ts +28 -16
- package/dist/op/activities/reconcile.d.ts.map +1 -1
- package/dist/op/activities/reconcile.js +1011 -0
- package/dist/op/activities/shell.js +118 -0
- package/dist/op/activities/source-release.js +97 -0
- package/dist/op/activities/source-rollback.js +165 -0
- package/dist/op/activities/teardown.js +17 -0
- package/dist/op/activities/util.js +6 -0
- package/dist/op/activities/wait.js +51 -0
- package/dist/op/activities/work-evidence.js +35 -0
- package/dist/op/activities/workflow-audit.js +133 -0
- package/dist/op/activity-contract-registry.js +106 -0
- package/dist/op/activity-contract.js +232 -0
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/activity-profiles.js +129 -0
- package/dist/op/activity-registry.js +105 -0
- package/dist/op/activity-runtime.js +28 -0
- package/dist/op/builders.d.ts +1 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +801 -0
- package/dist/op/change-signal.js +118 -0
- package/dist/op/composites/apply-op.js +151 -0
- package/dist/op/composites/behaviour-op.js +65 -0
- package/dist/op/composites/converge-op.js +141 -0
- package/dist/op/composites/index.js +19 -0
- package/dist/op/composites/lexicon-upgrade-op.js +107 -0
- package/dist/op/composites/pipeline-audit-op.js +50 -0
- package/dist/op/composites/reconcile-op.js +84 -0
- package/dist/op/composites/watch-op.js +69 -0
- package/dist/op/composites/workflow-audit-op.js +57 -0
- package/dist/op/converge-rule.js +205 -0
- package/dist/op/cron.js +146 -0
- package/dist/op/decide-backend.js +181 -0
- package/dist/op/decide-config.js +68 -0
- package/dist/op/decide-read-inputs.js +141 -0
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/discover.js +213 -0
- package/dist/op/duration.js +21 -0
- package/dist/op/emulator-freshness.js +80 -0
- package/dist/op/emulator-lifecycle.js +269 -0
- package/dist/op/factory.js +83 -0
- package/dist/op/gate-approval.js +172 -0
- package/dist/op/gate-name.js +86 -0
- package/dist/op/gate-plan-context.js +167 -0
- package/dist/op/gate-point-run.js +67 -0
- package/dist/op/gate-point.js +111 -0
- package/dist/op/gate-resume-plan.js +155 -0
- package/dist/op/gate-resume.js +31 -0
- package/dist/op/gate-review.js +290 -0
- package/dist/op/gate-run-locator.js +85 -0
- package/dist/op/gate-summary.js +100 -0
- package/dist/op/gate-wait.js +56 -0
- package/dist/op/gate.js +449 -0
- package/dist/op/generate-pipeline.js +124 -0
- package/dist/op/index.js +51 -0
- package/dist/op/lifecycle-receipt-store.js +45 -0
- package/dist/op/local-executor.js +1164 -0
- package/dist/op/local-output.js +140 -0
- package/dist/op/op-ir.js +317 -0
- package/dist/op/op-verb-class.js +131 -0
- package/dist/op/op-waves-notify.js +136 -0
- package/dist/op/op-waves-run.d.ts +1 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +1657 -0
- package/dist/op/op-waves.js +409 -0
- package/dist/op/operator.js +743 -0
- package/dist/op/receipt-store.js +94 -0
- package/dist/op/resource.js +23 -0
- package/dist/op/run-context.js +28 -0
- package/dist/op/run-live.js +256 -0
- package/dist/op/runtime.js +21 -0
- package/dist/op/runtimes/local.js +195 -0
- package/dist/op/source-archive.js +131 -0
- package/dist/op/step-output-ref.js +397 -0
- package/dist/op/steward-beside.js +169 -0
- package/dist/op/steward-points.js +138 -0
- package/dist/op/steward-turn.js +59 -0
- package/dist/op/steward.js +317 -0
- package/dist/op/types.js +25 -0
- package/dist/op/work-lease-decl.js +81 -0
- package/dist/op/work-lease-run.js +393 -0
- package/dist/override-gate.js +284 -0
- package/dist/owner-chain.js +74 -0
- package/dist/ownership.js +92 -0
- package/dist/params.js +61 -0
- package/dist/plan-summary.js +711 -0
- package/dist/point-decision.js +211 -0
- package/dist/pr-forge.js +810 -0
- package/dist/pr-loop.js +203 -0
- package/dist/project-codegen.js +191 -0
- package/dist/project-root.js +74 -0
- package/dist/project-validation.js +50 -0
- package/dist/provenance.js +157 -0
- package/dist/pseudo-parameter.js +40 -0
- package/dist/reconcile.js +450 -0
- package/dist/resource-attributes.js +33 -0
- package/dist/runtime-adapter.js +77 -0
- package/dist/runtime.js +66 -0
- package/dist/secret-materialization.js +153 -0
- package/dist/secret-provenance.js +250 -0
- package/dist/serializer-walker.js +112 -0
- package/dist/serializer.js +1 -0
- package/dist/sort.js +45 -0
- package/dist/stack-output.js +115 -0
- package/dist/telemetry-attribution.js +149 -0
- package/dist/terraform/__fixtures__/build-graph.js +63 -0
- package/dist/terraform/adopt-state.js +40 -0
- package/dist/terraform/aws-resources.js +384 -0
- package/dist/terraform/bridge.js +204 -0
- package/dist/terraform/carve-provider.js +155 -0
- package/dist/terraform/carve.js +138 -0
- package/dist/terraform/data-source-shape.js +57 -0
- package/dist/terraform/emit-source.js +36 -0
- package/dist/terraform/excise.js +123 -0
- package/dist/terraform/graduate.js +128 -0
- package/dist/terraform/graph.js +435 -0
- package/dist/terraform/hcl2json.js +60 -0
- package/dist/terraform/manifest.js +149 -0
- package/dist/terraform/parse.js +81 -0
- package/dist/terraform/providers/aws.js +146 -0
- package/dist/terraform/providers/gcp.js +294 -0
- package/dist/terraform/providers/index.js +17 -0
- package/dist/terraform/providers/kubernetes.js +253 -0
- package/dist/terraform/score.js +151 -0
- package/dist/terraform/state.js +67 -0
- package/dist/terraform/tier-map.js +74 -0
- package/dist/terraform/types.js +13 -0
- package/dist/terraform/unified-diff.js +132 -0
- package/dist/testing.js +295 -0
- package/dist/toml-emit.js +153 -0
- package/dist/toml-parse.js +355 -0
- package/dist/toml-utils.js +60 -0
- package/dist/toml.js +428 -0
- package/dist/ts-loader.d.ts +46 -0
- package/dist/ts-loader.d.ts.map +1 -0
- package/dist/ts-loader.js +103 -0
- package/dist/types.js +1 -0
- package/dist/utils.js +61 -0
- package/dist/validation.js +20 -0
- package/dist/vendor/js-yaml-load.js +1662 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts +7 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.js +119 -0
- package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
- package/dist/workspace/__fixtures__/sessions.d.ts +1 -1
- package/dist/workspace/__fixtures__/sessions.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/sessions.js +91 -0
- package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
- package/dist/workspace/agent-cli.js +99 -0
- package/dist/workspace/agent.schema.json +390 -0
- package/dist/workspace/answers-ledger.js +89 -0
- package/dist/workspace/box-cli.js +142 -0
- package/dist/workspace/box-factory-write.js +196 -0
- package/dist/workspace/box-factory-write.schema.json +342 -0
- package/dist/workspace/box-factory.js +88 -0
- package/dist/workspace/box-intent.js +126 -0
- package/dist/workspace/box-isolation.js +169 -0
- package/dist/workspace/box-listing-write.schema.json +204 -0
- package/dist/workspace/box-listing.js +298 -0
- package/dist/workspace/box-publish.js +352 -0
- package/dist/workspace/box-publish.schema.json +498 -0
- package/dist/workspace/box-services.js +39 -0
- package/dist/workspace/broker-protocol.js +359 -0
- package/dist/workspace/broker-protocol.schema.json +228 -0
- package/dist/workspace/change-set.schema.json +462 -0
- package/dist/workspace/changes-cli.js +56 -0
- package/dist/workspace/changes.js +446 -0
- package/dist/workspace/changes.schema.json +642 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
- package/dist/workspace/chant-migrations.js +113 -0
- package/dist/workspace/check.schema.json +433 -0
- package/dist/workspace/checks/box-isolation.js +62 -0
- package/dist/workspace/checks/boxes.js +491 -0
- package/dist/workspace/checks/diagrams.js +104 -0
- package/dist/workspace/checks/generated.js +419 -0
- package/dist/workspace/checks/ledgers.js +212 -0
- package/dist/workspace/checks/links.js +191 -0
- package/dist/workspace/checks/live.js +100 -0
- package/dist/workspace/checks/pipelines.js +188 -0
- package/dist/workspace/checks/records.js +169 -0
- package/dist/workspace/checks.js +426 -0
- package/dist/workspace/ci-green-cli.js +125 -0
- package/dist/workspace/ci-green-forge.js +83 -0
- package/dist/workspace/ci-green-workflow.d.ts +3 -1
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +202 -0
- package/dist/workspace/ci-green.js +325 -0
- package/dist/workspace/ci-last-green.schema.json +158 -0
- package/dist/workspace/class-data.d.ts +84 -0
- package/dist/workspace/class-data.d.ts.map +1 -0
- package/dist/workspace/class-data.js +238 -0
- package/dist/workspace/compose-graph.js +235 -0
- package/dist/workspace/compose-reports.js +146 -0
- package/dist/workspace/composites.js +264 -0
- package/dist/workspace/composites.schema.json +617 -0
- package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
- package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
- package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
- package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
- package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
- package/dist/workspace/conformance/broker.js +736 -0
- package/dist/workspace/conformance/index.js +673 -0
- package/dist/workspace/conformance/vitest.js +108 -0
- package/dist/workspace/conformance/writer.js +1080 -0
- package/dist/workspace/decide.js +879 -0
- package/dist/workspace/decision-points.schema.json +135 -135
- package/dist/workspace/declaration-write-cli.js +74 -0
- package/dist/workspace/declaration-write.js +238 -0
- package/dist/workspace/declaration.js +938 -0
- package/dist/workspace/declaration.schema.json +1413 -1413
- package/dist/workspace/declared-kinds.js +106 -0
- package/dist/workspace/environments.js +164 -0
- package/dist/workspace/evidence.schema.json +279 -0
- package/dist/workspace/export-cli.js +185 -0
- package/dist/workspace/export.js +499 -0
- package/dist/workspace/factory-rules.js +175 -0
- package/dist/workspace/generated-files.js +92 -0
- package/dist/workspace/glob.js +45 -0
- package/dist/workspace/graph-cache.js +352 -0
- package/dist/workspace/graph-cli.js +348 -0
- package/dist/workspace/graph.schema.json +1338 -0
- package/dist/workspace/identity-gate-rule.js +75 -0
- package/dist/workspace/identity.js +126 -0
- package/dist/workspace/import.js +283 -0
- package/dist/workspace/init.js +620 -0
- package/dist/workspace/intent-cli.js +263 -0
- package/dist/workspace/intent-joins.js +201 -0
- package/dist/workspace/intent-record.js +352 -0
- package/dist/workspace/intent-record.schema.json +864 -0
- package/dist/workspace/intent.js +1582 -0
- package/dist/workspace/intent.schema.json +2420 -0
- package/dist/workspace/json-edit.js +221 -0
- package/dist/workspace/jsonc.js +235 -0
- package/dist/workspace/kind-readers.js +103 -0
- package/dist/workspace/kinds.d.ts +3 -7
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/kinds.js +553 -0
- package/dist/workspace/lexicon-symbols.js +112 -0
- package/dist/workspace/lineage-adopt-cli.js +102 -0
- package/dist/workspace/lineage-adopt.js +360 -0
- package/dist/workspace/lineage-check.js +282 -0
- package/dist/workspace/lineage-cli.js +121 -0
- package/dist/workspace/lineage-hash-index.js +284 -0
- package/dist/workspace/lineage-init.js +507 -0
- package/dist/workspace/lineage-lock.js +387 -0
- package/dist/workspace/lineage-merge.js +45 -0
- package/dist/workspace/lineage-migrations.d.ts.map +1 -1
- package/dist/workspace/lineage-migrations.js +329 -0
- package/dist/workspace/lineage-provenance.js +36 -0
- package/dist/workspace/lineage-update.js +138 -0
- package/dist/workspace/lineage-upgrade-cli.js +131 -0
- package/dist/workspace/lineage-upgrade.js +889 -0
- package/dist/workspace/lineage-vendor.js +171 -0
- package/dist/workspace/lineage-version.js +128 -0
- package/dist/workspace/lineage-versions.js +275 -0
- package/dist/workspace/links.js +330 -0
- package/dist/workspace/ls-generated.js +95 -0
- package/dist/workspace/ls.js +277 -0
- package/dist/workspace/ls.schema.json +333 -0
- package/dist/workspace/member-commands.js +508 -0
- package/dist/workspace/member-handles.js +216 -0
- package/dist/workspace/member-pipeline.js +258 -0
- package/dist/workspace/member-run.js +117 -0
- package/dist/workspace/member-write.schema.json +193 -0
- package/dist/workspace/nested-graph.js +156 -0
- package/dist/workspace/nesting.js +38 -0
- package/dist/workspace/patch.js +301 -0
- package/dist/workspace/patch.schema.json +321 -0
- package/dist/workspace/pin-cli.js +55 -0
- package/dist/workspace/pin-integrity.js +100 -0
- package/dist/workspace/plan-summary.schema.json +155 -0
- package/dist/workspace/point-answer.schema.json +129 -129
- package/dist/workspace/points-cli.js +291 -0
- package/dist/workspace/points-write.schema.json +660 -0
- package/dist/workspace/points.js +521 -0
- package/dist/workspace/points.schema.json +916 -0
- package/dist/workspace/pr-report.schema.json +108 -0
- package/dist/workspace/principal-classes.d.ts +4 -11
- package/dist/workspace/principal-classes.d.ts.map +1 -1
- package/dist/workspace/principal-classes.js +162 -0
- package/dist/workspace/reason-codes.js +326 -0
- package/dist/workspace/record-assets.js +151 -0
- package/dist/workspace/record-decided.js +105 -0
- package/dist/workspace/record-sessions.js +96 -0
- package/dist/workspace/record-source.js +114 -0
- package/dist/workspace/records-amend.schema.json +284 -0
- package/dist/workspace/records-checkout.js +76 -0
- package/dist/workspace/records-cli.js +707 -0
- package/dist/workspace/records-close.js +116 -0
- package/dist/workspace/records-close.schema.json +278 -0
- package/dist/workspace/records-new.schema.json +202 -0
- package/dist/workspace/records-review.schema.json +367 -0
- package/dist/workspace/records-since.js +317 -0
- package/dist/workspace/records-since.schema.json +218 -0
- package/dist/workspace/records-write.js +1229 -0
- package/dist/workspace/records.js +1345 -0
- package/dist/workspace/records.schema.json +604 -0
- package/dist/workspace/reference-kinds/app/package.json +10 -0
- package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/dist/workspace/returns.js +303 -0
- package/dist/workspace/root-refusal.js +75 -0
- package/dist/workspace/run-statement.schema.json +622 -0
- package/dist/workspace/runs-cli.js +584 -0
- package/dist/workspace/runs-write.schema.json +994 -0
- package/dist/workspace/runs.js +708 -0
- package/dist/workspace/runs.schema.json +1257 -0
- package/dist/workspace/runtimes.js +76 -0
- package/dist/workspace/session-kinds.js +83 -0
- package/dist/workspace/signers.schema.json +206 -0
- package/dist/workspace/source-block.js +125 -0
- package/dist/workspace/squash.js +177 -0
- package/dist/workspace/status-gates.js +162 -0
- package/dist/workspace/status-stewards.js +330 -0
- package/dist/workspace/status.js +514 -0
- package/dist/workspace/status.schema.json +998 -0
- package/dist/workspace/steward-index.js +191 -0
- package/dist/workspace/symbols.js +188 -0
- package/dist/workspace/template-manifest.js +227 -0
- package/dist/workspace/template-pins.js +115 -0
- package/dist/workspace/trailer-joins.js +65 -0
- package/dist/workspace/trailers.js +111 -0
- package/dist/workspace/tree.js +136 -0
- package/dist/workspace/trust/attestor.js +63 -0
- package/dist/workspace/trust/dsse.js +108 -0
- package/dist/workspace/trust/evidence-cli.js +175 -0
- package/dist/workspace/trust/evidence.js +161 -0
- package/dist/workspace/trust/gate-seal.js +226 -0
- package/dist/workspace/trust/policy.js +190 -0
- package/dist/workspace/trust/provenance.js +180 -0
- package/dist/workspace/trust/rotation.js +298 -0
- package/dist/workspace/trust/run-commits.js +101 -0
- package/dist/workspace/trust/run-statement.js +182 -0
- package/dist/workspace/trust/seal.js +272 -0
- package/dist/workspace/trust/signers-cli.js +152 -0
- package/dist/workspace/trust/ssh-commit.js +178 -0
- package/dist/workspace/trust/test-repo.js +118 -0
- package/dist/workspace/trust/trust-files.js +193 -0
- package/dist/workspace/trust/verify-cli.js +63 -0
- package/dist/workspace/trust/verify.js +192 -0
- package/dist/workspace/which-chant.js +141 -0
- package/dist/workspace/wip-cli.js +95 -0
- package/dist/workspace/wip-write.schema.json +504 -0
- package/dist/workspace/wip.js +631 -0
- package/dist/workspace/wip.schema.json +334 -0
- package/dist/workspace/work-cli.js +448 -0
- package/dist/workspace/work-evidence.js +122 -0
- package/dist/workspace/work-evidence.schema.json +222 -0
- package/dist/workspace/work-history.schema.json +421 -0
- package/dist/workspace/work-lease.schema.json +246 -0
- package/dist/workspace/work-size.js +77 -0
- package/dist/workspace/work.js +283 -0
- package/dist/workspace/workspace-kinds.schema.json +259 -259
- package/dist/workspace/workspace-principals.schema.json +53 -53
- package/dist/workspace/write-lock-cli.js +105 -0
- package/dist/workspace/write-lock.js +424 -0
- package/dist/workspace/write-lock.schema.json +172 -0
- package/dist/workspace/write-scope.js +484 -0
- package/dist/yaml.js +459 -0
- package/package.json +2 -2
- package/src/build.ts +8 -0
- package/src/change-set.test.ts +48 -0
- package/src/change-set.ts +52 -2
- package/src/ci-jobs.test.ts +49 -0
- package/src/ci-jobs.ts +515 -0
- package/src/cli/commands/check-lexicon-plugin.ts +2 -0
- package/src/cli/commands/lint.ts +3 -0
- package/src/cli/commands/migrate.ts +2 -0
- package/src/cli/compiled-cli.e2e.test.ts +165 -0
- package/src/cli/main.ts +121 -27
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/codegen/pinned-upgrade.ts +2 -0
- package/src/components/discover.ts +2 -0
- package/src/components/pr-pipeline.ts +3 -2
- package/src/components/sandbox/driver.ts +3 -1
- package/src/composite.ts +15 -3
- package/src/config-import.ts +3 -0
- package/src/discovery/collect.ts +15 -1
- package/src/discovery/fold-build-parity.test.ts +71 -0
- package/src/discovery/fold-import.ts +25 -127
- package/src/discovery/fold-project-provenance.test.ts +21 -4
- package/src/discovery/host-composite.ts +101 -0
- package/src/discovery/import.ts +2 -0
- package/src/discovery/index.ts +11 -1
- package/src/discovery/sandbox/driver.ts +3 -1
- package/src/gate-decision-bundle.test.ts +5 -4
- package/src/gate-decision-identity.test.ts +59 -6
- package/src/gate-decision.ts +81 -21
- package/src/lexicon-module.ts +3 -0
- package/src/lifecycle/gate-audit.test.ts +55 -1
- package/src/lifecycle/gate-audit.ts +116 -3
- package/src/lifecycle/gate-ledger.test.ts +20 -1
- package/src/lifecycle/gate-ledger.ts +33 -1
- package/src/lint/config.ts +1 -1
- package/src/lint/discover.ts +28 -8
- package/src/lint/policy-import.ts +4 -1
- package/src/lint/rule-loader.ts +2 -0
- package/src/op/activities/activity-contracts.ts +1 -1
- package/src/op/activities/change-set.ts +11 -3
- package/src/op/activities/lexicon-upgrade.test.ts +2 -0
- package/src/op/activities/reconcile.test.ts +62 -2
- package/src/op/activities/reconcile.ts +46 -22
- package/src/op/builders.ts +1 -1
- package/src/op/discover.ts +3 -0
- package/src/op/op-waves-run.ts +4 -3
- package/src/op/op-waves.test.ts +2 -0
- package/src/op/work-lease-run.test.ts +12 -4
- package/src/ts-loader.test.ts +23 -0
- package/src/ts-loader.ts +122 -0
- package/src/workspace/__fixtures__/contract-repo.ts +17 -1
- package/src/workspace/__fixtures__/sessions.ts +3 -3
- package/src/workspace/change-set.schema.json +5 -3
- package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
- package/src/workspace/ci-green-workflow.test.ts +4 -4
- package/src/workspace/ci-green-workflow.ts +5 -2
- package/src/workspace/class-data.test.ts +64 -0
- package/src/workspace/class-data.ts +236 -0
- package/src/workspace/declaration.ts +1 -1
- package/src/workspace/kinds.ts +7 -36
- package/src/workspace/lineage-migrations.ts +2 -0
- package/src/workspace/points.ts +1 -1
- package/src/workspace/principal-classes.ts +12 -95
- package/src/workspace/records-formats.test.ts +7 -2
- package/src/workspace/records-sessions-write.test.ts +3 -3
- package/src/workspace/status-contract.e2e.test.ts +37 -0
- package/src/workspace/status-contract.test.ts +23 -21
|
@@ -0,0 +1,879 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Answers to decision points as records (ws-058, #2739).
|
|
3
|
+
*
|
|
4
|
+
* {@link askPoint} asks a point's deciders for one set of inputs and records
|
|
5
|
+
* the answer in the answer kind's records directory, {@link answerPoint}
|
|
6
|
+
* records people's answer to an open question, with an optional note, and
|
|
7
|
+
* {@link retractAnswer} takes an answer back (#3351). Each writes one Markdown
|
|
8
|
+
* record or none, never commits, and goes through the checks every records write goes
|
|
9
|
+
* through (`records-write.ts`): the record is read back with the kind's schema
|
|
10
|
+
* before it is written, and no other record may become invalid.
|
|
11
|
+
*
|
|
12
|
+
* - A table's answer is `answered`.
|
|
13
|
+
* - A model's answer at or above its threshold is `proposed`, whatever its
|
|
14
|
+
* confidence, with the probabilities, confidence and threshold, until a
|
|
15
|
+
* person confirms it. Below the threshold the question is `escalated`.
|
|
16
|
+
* - A question no decider before the quorum answered is `escalated`: open for
|
|
17
|
+
* people, with every decider's reason and any model's answer.
|
|
18
|
+
*
|
|
19
|
+
* The same point, declaration and inputs are answered once: the record's id is
|
|
20
|
+
* the point's name and the first 12 hex digits of the inputs hash. Asking again
|
|
21
|
+
* returns the record that is there when it is proposed or answered. An
|
|
22
|
+
* escalated one is asked again, since a backend may answer now, and rewritten
|
|
23
|
+
* only when the chain no longer escalates.
|
|
24
|
+
*
|
|
25
|
+
* An ad-hoc point (#3403) has no candidates of its own: each ask gives the
|
|
26
|
+
* question's text and candidates, the record keeps them as `asked`, and they
|
|
27
|
+
* are part of the inputs hash, so a question asked with other options is
|
|
28
|
+
* another question. People's answer is checked against them.
|
|
29
|
+
*
|
|
30
|
+
* An answer never changes in place. People may retract it (ws-084): the
|
|
31
|
+
* question is escalated to them again, and the answer, who gave it, when, and
|
|
32
|
+
* its note move into the record's `retractions` with who retracted it, when
|
|
33
|
+
* and why. Asking a retracted question again returns it as it stands, since
|
|
34
|
+
* people took it back from the deciders; people answer it again.
|
|
35
|
+
*
|
|
36
|
+
* Each write holds the working tree's write lock (#3173, ws-089) from the first read
|
|
37
|
+
* to the write, so two answers to one question are never both taken from the
|
|
38
|
+
* same reading of it.
|
|
39
|
+
*
|
|
40
|
+
* chant never calls a model (ws-052): the model call is the caller's
|
|
41
|
+
* {@link ModelAsk}, such as the decide Op activity (#2740), or a backend's
|
|
42
|
+
* response the caller already has (`points ask --response`).
|
|
43
|
+
*/
|
|
44
|
+
import { writeFileSync } from "node:fs";
|
|
45
|
+
import { noteWrites, withWriteLock, WriteLockError, WRITE_LOCK_CODES } from "./write-lock.js";
|
|
46
|
+
import { gitRoot } from "./record-source.js";
|
|
47
|
+
import { loadRecordKind, normalisePrincipal, RECORD_REASON_CODES, RecordReadError } from "./records.js";
|
|
48
|
+
import { declaredKindFiles } from "./records-cli.js";
|
|
49
|
+
import { abs, LOAD_ERROR_CODES, open, pick, readAll, RecordWriteError, renderRecord, resolveWriteKind, schemaOrder, validateWrite, } from "./records-write.js";
|
|
50
|
+
import { answerId, askedOf, askedQuestion, candidates, DeciderFailed, inputsHash, parseAsked, pointOf, pointsFileOf, pointVersion, quorumOf, readPointsThrough, runChain, } from "./points.js";
|
|
51
|
+
import { WorkspaceReadError } from "./declaration.js";
|
|
52
|
+
import { policyAtBase, resolveBase } from "./trust/provenance.js";
|
|
53
|
+
import { emptyPolicy } from "./trust/policy.js";
|
|
54
|
+
import { AGENT_ROLE } from "./records-cli.js";
|
|
55
|
+
import { currentStewardTurn } from "../op/steward-turn.js";
|
|
56
|
+
import { IdentityError, refuseUnidentified } from "./identity.js";
|
|
57
|
+
import { scopeSource } from "./write-scope.js";
|
|
58
|
+
import { RefCASConflictError } from "../lifecycle/git.js";
|
|
59
|
+
import { readLedgerAnswers, refreshLedger, withLedgerAnswers, writeLedgerAnswer } from "./answers-ledger.js";
|
|
60
|
+
import { currentGateOrigin, isModelAuthored } from "../lifecycle/gate-origin.js";
|
|
61
|
+
/** The version of the write documents `points ask`, `points answer` and `points retract` print. */
|
|
62
|
+
export const POINTS_WRITE_CONTRACT_VERSION = 1;
|
|
63
|
+
export const POINTS_WRITE_SCHEMA_ID = "https://intentius.io/chant/schemas/workspace/points-write/v1/points-write.schema.json";
|
|
64
|
+
/** Why `points ask`, `points answer` or `points retract` wrote nothing. Closed: a reader may switch on it. */
|
|
65
|
+
export const POINTS_WRITE_ERROR_CODES = [
|
|
66
|
+
...LOAD_ERROR_CODES,
|
|
67
|
+
"write-usage-invalid",
|
|
68
|
+
"write-input-invalid",
|
|
69
|
+
/** No record kind with an answers block is declared, or given with --kind. */
|
|
70
|
+
"points-undeclared",
|
|
71
|
+
/** The points file the answer kind names can't be read or is not valid. */
|
|
72
|
+
"points-invalid",
|
|
73
|
+
/** No points file declares the point. */
|
|
74
|
+
"point-unknown",
|
|
75
|
+
/** The inputs are not a JSON object of the point's declared inputs. */
|
|
76
|
+
"point-inputs-invalid",
|
|
77
|
+
/** A model decider declared unreachable "fail" could not answer. */
|
|
78
|
+
"point-decider-failed",
|
|
79
|
+
/** The answer is not one of the question's candidates. */
|
|
80
|
+
"answer-not-candidate",
|
|
81
|
+
/** Too few people who count toward the point's quorum answered. */
|
|
82
|
+
"quorum-not-met",
|
|
83
|
+
"record-not-found",
|
|
84
|
+
"record-closed",
|
|
85
|
+
"record-id-taken",
|
|
86
|
+
/** The answer was given during a steward's turn (#2749): a steward never answers a question, its own or another's. */
|
|
87
|
+
"answer-in-steward-turn",
|
|
88
|
+
/** The answer or retraction came over MCP or ACP, and the question constrains a gate that is never resolved there (#3817). */
|
|
89
|
+
"answer-never-over-mcp",
|
|
90
|
+
/** An answerer is named by a bare name, and identity.attribution at base is identified (#3163). */
|
|
91
|
+
"principal-unidentified",
|
|
92
|
+
/** `points retract` names a question that has no answer: escalated or proposed (#3351). */
|
|
93
|
+
"answer-not-answered",
|
|
94
|
+
/** The answer kind's schema copy has no `note`, `retractions`, `relayed_by` or `asked` field for what the write was given (#3351, #3402, #3403). */
|
|
95
|
+
"answer-field-unsupported",
|
|
96
|
+
/** An ad-hoc point was asked without its question and candidates, a declared point with them, or they don't fit the point's question type (#3403). */
|
|
97
|
+
"point-candidates-invalid",
|
|
98
|
+
...WRITE_LOCK_CODES,
|
|
99
|
+
...RECORD_REASON_CODES,
|
|
100
|
+
];
|
|
101
|
+
export class PointsWriteError extends Error {
|
|
102
|
+
constructor(code, message) {
|
|
103
|
+
super(message);
|
|
104
|
+
this.code = code;
|
|
105
|
+
this.name = "PointsWriteError";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** The record's `retractions`, as views. */
|
|
109
|
+
function retractionsOf(d) {
|
|
110
|
+
if (!Array.isArray(d.retractions))
|
|
111
|
+
return [];
|
|
112
|
+
const str = (v) => (typeof v === "string" ? v : null);
|
|
113
|
+
const strs = (v) => (Array.isArray(v) ? v.filter((x) => typeof x === "string") : []);
|
|
114
|
+
return d.retractions
|
|
115
|
+
.filter((r) => r !== null && typeof r === "object" && !Array.isArray(r))
|
|
116
|
+
.map((r) => ({
|
|
117
|
+
answer: typeof r.answer === "string" || typeof r.answer === "boolean" ? r.answer : null,
|
|
118
|
+
decider: r.decider !== null && typeof r.decider === "object" && !Array.isArray(r.decider) ? r.decider : {},
|
|
119
|
+
answeredBy: strs(r.answered_by),
|
|
120
|
+
answeredOn: str(r.answered_on),
|
|
121
|
+
answerNote: str(r.answer_note),
|
|
122
|
+
answerRelayedBy: str(r.answer_relayed_by),
|
|
123
|
+
by: strs(r.by),
|
|
124
|
+
on: str(r.on),
|
|
125
|
+
note: str(r.note),
|
|
126
|
+
}));
|
|
127
|
+
}
|
|
128
|
+
/** The harness a steward's question names in its source block (#2749). */
|
|
129
|
+
export const STEWARD_HARNESS = "chant-steward";
|
|
130
|
+
/** The steward that asked, from a record's source block, or null. */
|
|
131
|
+
export function askedByOf(data) {
|
|
132
|
+
const source = data.source;
|
|
133
|
+
if (source === null || typeof source !== "object" || Array.isArray(source))
|
|
134
|
+
return null;
|
|
135
|
+
const s = source;
|
|
136
|
+
if (s.harness !== STEWARD_HARNESS)
|
|
137
|
+
return null;
|
|
138
|
+
const client = s.client;
|
|
139
|
+
const steward = client && typeof client.name === "string" ? client.name : null;
|
|
140
|
+
if (steward === null)
|
|
141
|
+
return null;
|
|
142
|
+
const session = s.session;
|
|
143
|
+
const run = typeof session === "string" ? session : session && typeof session === "object" && typeof session.id === "string" ? session.id : null;
|
|
144
|
+
return { steward, run };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* One answer record as a {@link QuestionView}, or null when its front matter
|
|
148
|
+
* can't be read. `point` is its point as declared now, when there is one, and
|
|
149
|
+
* `ledger` where the record is held when it is on the lifecycle ledger.
|
|
150
|
+
*/
|
|
151
|
+
export function questionView(entry, point, ledger = null) {
|
|
152
|
+
const d = entry.data;
|
|
153
|
+
if (d === null || entry.id === null)
|
|
154
|
+
return null;
|
|
155
|
+
const str = (v) => (typeof v === "string" ? v : null);
|
|
156
|
+
const num = (v) => (typeof v === "number" ? v : null);
|
|
157
|
+
const state = ["escalated", "proposed", "answered"].find((s) => s === entry.state) ?? "escalated";
|
|
158
|
+
const decider = d.decider !== null && typeof d.decider === "object" && !Array.isArray(d.decider) ? d.decider : {};
|
|
159
|
+
const escalations = Array.isArray(d.escalations) ? d.escalations : [];
|
|
160
|
+
const answer = typeof d.answer === "string" || typeof d.answer === "boolean" ? d.answer : null;
|
|
161
|
+
let model = null;
|
|
162
|
+
if (decider.kind === "model") {
|
|
163
|
+
model = { answer, confidence: num(d.confidence), threshold: num(d.threshold), model: str(decider.model), backend: str(decider.backend), observed: true, reason: str(d.reason) };
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const lean = [...escalations].reverse().find((e) => e.kind === "model" && e.answer !== undefined && e.answer !== null);
|
|
167
|
+
if (lean) {
|
|
168
|
+
model = {
|
|
169
|
+
answer: lean.answer ?? null,
|
|
170
|
+
confidence: lean.confidence ?? null,
|
|
171
|
+
threshold: lean.threshold ?? null,
|
|
172
|
+
model: lean.model ?? null,
|
|
173
|
+
backend: lean.backend ?? null,
|
|
174
|
+
observed: false,
|
|
175
|
+
reason: typeof lean.model_reason === "string" ? lean.model_reason : null,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const constrains = Array.isArray(d.constrains) ? d.constrains.filter((c) => typeof c === "string") : [];
|
|
180
|
+
return {
|
|
181
|
+
id: entry.id,
|
|
182
|
+
path: entry.path,
|
|
183
|
+
point: str(d.point) ?? "",
|
|
184
|
+
title: str(d.title) ?? "",
|
|
185
|
+
subject: constrains[0] ?? null,
|
|
186
|
+
state,
|
|
187
|
+
open: state !== "answered",
|
|
188
|
+
questionType: str(d.question_type) ?? "",
|
|
189
|
+
candidates: Array.isArray(d.candidates) ? d.candidates : [],
|
|
190
|
+
inputs: d.inputs !== null && typeof d.inputs === "object" && !Array.isArray(d.inputs) ? d.inputs : {},
|
|
191
|
+
inputsHash: str(d.inputs_hash) ?? "",
|
|
192
|
+
pointVersion: str(d.point_version) ?? "",
|
|
193
|
+
current: point ? pointVersion(point) === d.point_version : null,
|
|
194
|
+
answer,
|
|
195
|
+
decider,
|
|
196
|
+
probabilities: d.probabilities !== null && typeof d.probabilities === "object" ? d.probabilities : null,
|
|
197
|
+
confidence: num(d.confidence),
|
|
198
|
+
threshold: num(d.threshold),
|
|
199
|
+
reason: decider.kind === "model" ? str(d.reason) : null,
|
|
200
|
+
model,
|
|
201
|
+
escalations,
|
|
202
|
+
answeredBy: Array.isArray(d.answered_by) ? d.answered_by.filter((b) => typeof b === "string") : [],
|
|
203
|
+
askedOn: str(d.asked_on),
|
|
204
|
+
answeredOn: str(d.answered_on),
|
|
205
|
+
note: str(d.note),
|
|
206
|
+
relayedBy: str(d.relayed_by),
|
|
207
|
+
retractions: retractionsOf(d),
|
|
208
|
+
asked: askedOf(d) ?? null,
|
|
209
|
+
askedBy: askedByOf(d),
|
|
210
|
+
ledger,
|
|
211
|
+
valid: entry.valid,
|
|
212
|
+
warnings: entry.warnings,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function failure(verb, err) {
|
|
216
|
+
if (err instanceof PointsWriteError || err instanceof RecordWriteError || err instanceof RecordReadError || err instanceof IdentityError || err instanceof WriteLockError) {
|
|
217
|
+
return { $schema: POINTS_WRITE_SCHEMA_ID, contract: POINTS_WRITE_CONTRACT_VERSION, verb, error: { code: err.code, message: err.message } };
|
|
218
|
+
}
|
|
219
|
+
if (err instanceof WorkspaceReadError) {
|
|
220
|
+
return { $schema: POINTS_WRITE_SCHEMA_ID, contract: POINTS_WRITE_CONTRACT_VERSION, verb, error: { code: "points-undeclared", message: `the declaration can't be read: ${err.code}: ${err.message}` } };
|
|
221
|
+
}
|
|
222
|
+
throw err;
|
|
223
|
+
}
|
|
224
|
+
// ── Finding the answer kind and the point ───────────────────────────────────
|
|
225
|
+
/**
|
|
226
|
+
* The answer kinds a write can go through: the one `kind` names (a file, or a
|
|
227
|
+
* declared kind's name), or every declared kind with an answers block.
|
|
228
|
+
*/
|
|
229
|
+
export async function answerKindFiles(cwd, kind) {
|
|
230
|
+
if (kind !== undefined)
|
|
231
|
+
return [resolveWriteKind(kind, cwd)];
|
|
232
|
+
const out = [];
|
|
233
|
+
for (const k of declaredKindFiles(cwd)) {
|
|
234
|
+
try {
|
|
235
|
+
if ((await loadRecordKind(k.file)).kind.answers)
|
|
236
|
+
out.push(k.file);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
// A kind that can't be loaded is check's to report (WSP115); a write names its kind with --kind.
|
|
240
|
+
if (!(err instanceof RecordReadError))
|
|
241
|
+
throw err;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return out;
|
|
245
|
+
}
|
|
246
|
+
async function openAnswers(kindFile, cwd) {
|
|
247
|
+
const o = await open(kindFile, cwd);
|
|
248
|
+
if (!o.loaded.kind.answers)
|
|
249
|
+
throw new PointsWriteError("points-undeclared", `the ${o.loaded.kind.name} kind has no answers block, so it holds no answers to decision points`);
|
|
250
|
+
const pointsFile = pointsFileOf(o.loaded, o.root);
|
|
251
|
+
const read = readPointsThrough(o.source, pointsFile);
|
|
252
|
+
if ("error" in read)
|
|
253
|
+
throw new PointsWriteError("points-invalid", read.error);
|
|
254
|
+
return { o, points: read.points, pointsFile };
|
|
255
|
+
}
|
|
256
|
+
const today = () => new Date().toISOString().slice(0, 10);
|
|
257
|
+
const show = (answer, type) => (type === "noul" ? (answer ? "yes" : "no") : String(answer));
|
|
258
|
+
/** A record's title: the point's title, or an ad-hoc question's own text (#3403), what it is about, and where it stands. */
|
|
259
|
+
function titleFor(point, subject, state, answer, asked) {
|
|
260
|
+
const outcome = state === "escalated" ? "open for people" : state === "proposed" ? `${show(answer, point.question.type)}, proposed` : show(answer, point.question.type);
|
|
261
|
+
return `${asked ? asked.question : point.title}${subject ? ` (${subject})` : ""}: ${outcome}`;
|
|
262
|
+
}
|
|
263
|
+
function body(point, title, asked) {
|
|
264
|
+
const q = askedQuestion(point, asked);
|
|
265
|
+
const describe = (c) => (q.type === "score" ? "" : (q.criteria?.[String(c)] ?? ""));
|
|
266
|
+
const options = candidates(q).map((c) => `- ${show(c, q.type)}${describe(c) ? `: ${describe(c)}` : ""}`);
|
|
267
|
+
return ["", `# ${title}`, "", q.instructions.trim(), "", ...options, ""].join("\n");
|
|
268
|
+
}
|
|
269
|
+
/** The first kind whose points file declares `name`. */
|
|
270
|
+
async function findPoint(kinds, name, cwd) {
|
|
271
|
+
if (kinds.length === 0)
|
|
272
|
+
throw new PointsWriteError("points-undeclared", "no record kind with an answers block is declared: name one with --kind, or declare one in chant.workspace.json");
|
|
273
|
+
const declared = [];
|
|
274
|
+
for (const k of kinds) {
|
|
275
|
+
const opened = await openAnswers(k, cwd);
|
|
276
|
+
const point = pointOf(opened.points, name);
|
|
277
|
+
if (point)
|
|
278
|
+
return { ...opened, point };
|
|
279
|
+
declared.push(...Object.keys(opened.points));
|
|
280
|
+
}
|
|
281
|
+
throw new PointsWriteError("point-unknown", `no points file declares ${JSON.stringify(name)}${declared.length ? ` (the points are ${declared.join(", ")})` : ""}`);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* An ad-hoc point's question and candidates from the ask (#3403), or
|
|
285
|
+
* undefined for a declared point. Refused when an ad-hoc point has none, a
|
|
286
|
+
* declared point is given them, they don't fit the question type, or the
|
|
287
|
+
* answer kind's schema copy has no `asked` field to keep them in.
|
|
288
|
+
*/
|
|
289
|
+
function checkAsked(name, point, given, loaded) {
|
|
290
|
+
if (!point.adhoc) {
|
|
291
|
+
if (given !== undefined)
|
|
292
|
+
throw new PointsWriteError("point-candidates-invalid", `${name} declares its candidates, so the ask gives none: --candidates is for an ad-hoc point`);
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
if (given === undefined)
|
|
296
|
+
throw new PointsWriteError("point-candidates-invalid", `${name} is an ad-hoc point, so each ask gives the question and its candidates: --candidates <file|-|json>`);
|
|
297
|
+
const parsed = parseAsked(point, given);
|
|
298
|
+
if ("problems" in parsed)
|
|
299
|
+
throw new PointsWriteError("point-candidates-invalid", `the candidates for ${name}, a ${point.question.type} question: ${parsed.problems.join("; ")}`);
|
|
300
|
+
if (!answerFields(loaded.schema).asked) {
|
|
301
|
+
throw new PointsWriteError("answer-field-unsupported", `the ${loaded.kind.name} kind's schema has no asked field, so an ad-hoc question's text and candidates can't be kept: copy point-answer.schema.json from @intentius/chant anew`);
|
|
302
|
+
}
|
|
303
|
+
return parsed.asked;
|
|
304
|
+
}
|
|
305
|
+
function checkInputs(name, point, inputs) {
|
|
306
|
+
if (inputs === null || typeof inputs !== "object" || Array.isArray(inputs))
|
|
307
|
+
throw new PointsWriteError("point-inputs-invalid", `the inputs to ${name} must be a JSON object`);
|
|
308
|
+
const declared = Object.keys(point.inputs);
|
|
309
|
+
const unknown = Object.keys(inputs).filter((k) => !declared.includes(k));
|
|
310
|
+
if (unknown.length > 0) {
|
|
311
|
+
throw new PointsWriteError("point-inputs-invalid", `${name} reads ${declared.join(", ")}, and the inputs also give ${unknown.join(", ")}`);
|
|
312
|
+
}
|
|
313
|
+
return inputs;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Write `text` as the record at `path`, after reading it back with every
|
|
317
|
+
* other record: into the working tree, or onto the ledger. Returns the
|
|
318
|
+
* record's warnings and, for a ledger write, where it went.
|
|
319
|
+
*/
|
|
320
|
+
async function write(o, before, path, text, create, dryRun, target) {
|
|
321
|
+
const warnings = await validateWrite(o, before, path, text, target.source);
|
|
322
|
+
const held = target.ledger.byPath.get(path);
|
|
323
|
+
if (target.onLedger) {
|
|
324
|
+
if (dryRun)
|
|
325
|
+
return { warnings, ledger: held?.ledger ?? null };
|
|
326
|
+
try {
|
|
327
|
+
const { ledger } = await writeLedgerAnswer(target.ledger, path, text, target.message, held?.sha ?? null);
|
|
328
|
+
return { warnings, ledger };
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
if (err instanceof RefCASConflictError)
|
|
332
|
+
throw new PointsWriteError("record-id-taken", `${path} was written on chant/lifecycle by another ask or answer at the same time: ask again to read it`);
|
|
333
|
+
throw err;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (!dryRun) {
|
|
337
|
+
try {
|
|
338
|
+
writeFileSync(abs(o, path), text, create ? { flag: "wx" } : undefined);
|
|
339
|
+
noteWrites(o.root, [{ path, text }], target.who);
|
|
340
|
+
}
|
|
341
|
+
catch (err) {
|
|
342
|
+
if (err.code === "EEXIST")
|
|
343
|
+
throw new PointsWriteError("record-id-taken", `${path} was written by another ask at the same time: ask again to read it`);
|
|
344
|
+
throw err;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return { warnings, ledger: null };
|
|
348
|
+
}
|
|
349
|
+
/** The kind's answers on the ledger, and its records read with them laid over the tree. */
|
|
350
|
+
async function readWithLedger(o) {
|
|
351
|
+
const ledger = await readLedgerAnswers({ file: o.loaded.file, name: o.loaded.kind.name, dirRel: o.dirRel });
|
|
352
|
+
const source = withLedgerAnswers(o.source, ledger);
|
|
353
|
+
return { ledger, source, before: await readAll(o, source) };
|
|
354
|
+
}
|
|
355
|
+
function recordData(o, fields) {
|
|
356
|
+
const clean = Object.fromEntries(Object.entries(fields).filter(([, v]) => v !== undefined));
|
|
357
|
+
// The schema's properties order, so a record reads question, then answer, then when.
|
|
358
|
+
return pick(clean, schemaOrder(clean, { properties: o.loaded.schema.properties }));
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Whether an answer kind's schema copy takes the model's reason (#3345): at
|
|
362
|
+
* the top level, and in an escalation entry as `model_reason`. A workspace
|
|
363
|
+
* whose copy of point-answer.schema.json predates them keeps no reason rather
|
|
364
|
+
* than failing the write; copying the schema anew turns them on.
|
|
365
|
+
*/
|
|
366
|
+
export function reasonFields(schema) {
|
|
367
|
+
const has = (o, key) => o !== null && typeof o === "object" && Object.prototype.hasOwnProperty.call(o, key);
|
|
368
|
+
const defs = (schema.definitions ?? schema.$defs);
|
|
369
|
+
return { top: has(schema.properties, "reason"), escalation: has(defs?.escalation?.properties, "model_reason") };
|
|
370
|
+
}
|
|
371
|
+
/** Escalations without `model_reason` when the kind's schema does not take it. */
|
|
372
|
+
function keepReasons(escalations, takes) {
|
|
373
|
+
return takes.escalation ? escalations : escalations.map(({ model_reason: _, ...e }) => e);
|
|
374
|
+
}
|
|
375
|
+
function resultFields(result, takes) {
|
|
376
|
+
const escalations = result.escalations.length > 0 ? keepReasons(result.escalations, takes) : undefined;
|
|
377
|
+
if (result.status === "proposed") {
|
|
378
|
+
const reason = takes.top ? result.reason : undefined;
|
|
379
|
+
return { state: "proposed", answer: result.answer, decider: result.decider, probabilities: result.probabilities, confidence: result.confidence, threshold: result.threshold, reason, escalations };
|
|
380
|
+
}
|
|
381
|
+
if (result.status === "answered")
|
|
382
|
+
return { state: "answered", answer: result.answer, decider: result.decider, escalations };
|
|
383
|
+
return { state: "escalated", decider: result.decider, escalations };
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Ask a point for these inputs, and record the answer: `points ask`. Returns
|
|
387
|
+
* the record that is there when the same point, declaration and inputs were
|
|
388
|
+
* answered or proposed before.
|
|
389
|
+
*/
|
|
390
|
+
export async function askPoint(opts) {
|
|
391
|
+
try {
|
|
392
|
+
return await withWriteLock(opts.cwd, { verb: "points ask", by: opts.steward?.name ?? null }, opts.dryRun, () => askPointLocked(opts));
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
return failure("ask", err);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
async function askPointLocked(opts) {
|
|
399
|
+
try {
|
|
400
|
+
// A steward's turn (#2749): named by the caller, or this process's, as when an Op shells out to `points ask`.
|
|
401
|
+
const turn = opts.steward ? undefined : currentStewardTurn();
|
|
402
|
+
const steward = opts.steward ?? (turn ? { name: turn.steward, ...(turn.run ? { run: turn.run } : {}) } : undefined);
|
|
403
|
+
const toLedger = opts.store !== undefined ? opts.store === "ledger" : steward !== undefined;
|
|
404
|
+
const kinds = await answerKindFiles(opts.cwd, opts.kind);
|
|
405
|
+
const { o, point } = await findPoint(kinds, opts.point, opts.cwd);
|
|
406
|
+
const inputs = checkInputs(opts.point, point, opts.inputs);
|
|
407
|
+
const asked = checkAsked(opts.point, point, opts.candidates, o.loaded);
|
|
408
|
+
const version = pointVersion(point);
|
|
409
|
+
const hash = inputsHash(opts.point, version, inputs, asked);
|
|
410
|
+
const id = answerId(opts.point, hash);
|
|
411
|
+
if (toLedger && !opts.dryRun)
|
|
412
|
+
await refreshLedger(o.loaded.file);
|
|
413
|
+
const { ledger, source: read, before } = await readWithLedger(o);
|
|
414
|
+
const existing = before.find((e) => e.id === id);
|
|
415
|
+
const heldAt = (entry) => ledger.byPath.get(entry.path)?.ledger ?? null;
|
|
416
|
+
const done = (entry, extra) => ({
|
|
417
|
+
$schema: POINTS_WRITE_SCHEMA_ID,
|
|
418
|
+
contract: POINTS_WRITE_CONTRACT_VERSION,
|
|
419
|
+
verb: "ask",
|
|
420
|
+
kind: o.view,
|
|
421
|
+
id,
|
|
422
|
+
path: entry.path,
|
|
423
|
+
reused: extra.reused,
|
|
424
|
+
written: extra.written,
|
|
425
|
+
dryRun: !!opts.dryRun,
|
|
426
|
+
question: questionView(entry, point, extra.ledger !== undefined ? extra.ledger : heldAt(entry)),
|
|
427
|
+
...(extra.text !== undefined ? { text: extra.text } : {}),
|
|
428
|
+
});
|
|
429
|
+
if (existing && existing.data !== null && (existing.state === "answered" || existing.state === "proposed"))
|
|
430
|
+
return done(existing, { reused: true, written: false });
|
|
431
|
+
// People took a retracted question back from the deciders (ws-084): they answer it again, and asking returns it as it stands.
|
|
432
|
+
if (existing && existing.data !== null && Array.isArray(existing.data.retractions) && existing.data.retractions.length > 0)
|
|
433
|
+
return done(existing, { reused: true, written: false });
|
|
434
|
+
let result;
|
|
435
|
+
try {
|
|
436
|
+
result = await runChain(opts.point, { ...point, question: askedQuestion(point, asked) }, inputs, opts.ask);
|
|
437
|
+
}
|
|
438
|
+
catch (err) {
|
|
439
|
+
if (err instanceof DeciderFailed)
|
|
440
|
+
throw new PointsWriteError("point-decider-failed", err.message);
|
|
441
|
+
throw err;
|
|
442
|
+
}
|
|
443
|
+
// A standing escalation is kept while the chain still escalates.
|
|
444
|
+
if (existing && existing.data !== null && result.status === "escalated")
|
|
445
|
+
return done(existing, { reused: true, written: false });
|
|
446
|
+
const on = opts.on ?? today();
|
|
447
|
+
const state = result.status;
|
|
448
|
+
const answer = result.status === "escalated" ? undefined : result.answer;
|
|
449
|
+
const title = titleFor(point, opts.subject, state, answer, asked);
|
|
450
|
+
const modelId = result.status === "proposed" ? result.decider.model : undefined;
|
|
451
|
+
const client = steward ? { name: steward.name } : opts.client;
|
|
452
|
+
const source = {
|
|
453
|
+
via: opts.via ?? "cli",
|
|
454
|
+
...(steward ? { harness: STEWARD_HARNESS } : {}),
|
|
455
|
+
...(client ? { client } : {}),
|
|
456
|
+
...(modelId ? { model: modelId } : {}),
|
|
457
|
+
...(steward?.run ? { session: { id: steward.run } } : {}),
|
|
458
|
+
};
|
|
459
|
+
const data = recordData(o, {
|
|
460
|
+
id,
|
|
461
|
+
title,
|
|
462
|
+
point: opts.point,
|
|
463
|
+
point_version: version,
|
|
464
|
+
question_type: point.question.type,
|
|
465
|
+
candidates: candidates(askedQuestion(point, asked)),
|
|
466
|
+
asked,
|
|
467
|
+
inputs,
|
|
468
|
+
inputs_hash: hash,
|
|
469
|
+
constrains: opts.subject !== undefined ? [opts.subject] : existing?.data?.constrains,
|
|
470
|
+
...resultFields(result, reasonFields(o.loaded.schema)),
|
|
471
|
+
asked_on: on,
|
|
472
|
+
answered_on: state === "answered" ? on : undefined,
|
|
473
|
+
source,
|
|
474
|
+
});
|
|
475
|
+
const path = existing ? existing.path : o.dirRel === "." ? `${id}.md` : `${o.dirRel}/${id}.md`;
|
|
476
|
+
const text = renderRecord(data, body(point, title, asked));
|
|
477
|
+
// A steward's question goes on the ledger, and one already held there stays there (#2786).
|
|
478
|
+
const onLedger = toLedger || ledger.byPath.has(path);
|
|
479
|
+
const message = `Decision point ${opts.point}: ${state}${opts.subject ? ` (${opts.subject})` : ""}${steward ? `, asked by ${steward.name}` : ""}`;
|
|
480
|
+
const wrote = await write(o, before, path, text, !existing, !!opts.dryRun, { source: read, ledger, onLedger, message, who: { verb: "points ask", by: steward?.name ?? null } });
|
|
481
|
+
const entry = { ...(existing ?? emptyEntry(path)), id, path, state, data, valid: true, reasons: [], warnings: wrote.warnings };
|
|
482
|
+
return done(entry, { reused: false, written: !opts.dryRun, ledger: wrote.ledger, ...(opts.dryRun ? { text } : {}) });
|
|
483
|
+
}
|
|
484
|
+
catch (err) {
|
|
485
|
+
return failure("ask", err);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function emptyEntry(path) {
|
|
489
|
+
return { id: null, path, state: null, valid: true, reasons: [], supersededBy: null, remediatedBy: [], data: null, assets: [], warnings: [], digest: "" };
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Whether an answer kind's schema copy takes the fields of #3351 (`note` on an
|
|
493
|
+
* answer, and `retractions`), of #3402 (`relayed_by`) and of #3403 (`asked`).
|
|
494
|
+
* A copy of point-answer.schema.json from before them refuses a note, a
|
|
495
|
+
* retraction, a relay or an ad-hoc ask with `answer-field-unsupported`, rather
|
|
496
|
+
* than dropping what a person wrote or the question an agent asked.
|
|
497
|
+
*/
|
|
498
|
+
export function answerFields(schema) {
|
|
499
|
+
const props = schema.properties;
|
|
500
|
+
const has = (key) => props !== undefined && props !== null && typeof props === "object" && Object.prototype.hasOwnProperty.call(props, key);
|
|
501
|
+
return { note: has("note"), retractions: has("retractions"), relayedBy: has("relayed_by"), asked: has("asked") };
|
|
502
|
+
}
|
|
503
|
+
/** A note as given, trimmed, or undefined when it is empty. */
|
|
504
|
+
const noteOf = (note) => {
|
|
505
|
+
const t = note?.trim();
|
|
506
|
+
return t ? t : undefined;
|
|
507
|
+
};
|
|
508
|
+
/** The trust policy at base, for the quorum: who holds the agent role and each role a quorum names. */
|
|
509
|
+
function policyFor(root) {
|
|
510
|
+
if (!gitRoot(root))
|
|
511
|
+
return emptyPolicy(null);
|
|
512
|
+
try {
|
|
513
|
+
return policyAtBase(root, resolveBase(root));
|
|
514
|
+
}
|
|
515
|
+
catch {
|
|
516
|
+
return emptyPolicy(null);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Count `by` toward a point's quorum: distinct people, after normalising,
|
|
521
|
+
* leaving out anyone holding the agent role in the trust policy at base, and,
|
|
522
|
+
* when the quorum names roles, anyone holding none of them.
|
|
523
|
+
*/
|
|
524
|
+
export function tallyQuorum(by, quorum, policy,
|
|
525
|
+
/** The steward that asked the question (#2749): it never counts toward the answer. */
|
|
526
|
+
steward) {
|
|
527
|
+
const holders = (role) => new Set((policy.roles[role] ?? []).map(normalisePrincipal));
|
|
528
|
+
const agents = holders(AGENT_ROLE);
|
|
529
|
+
const asker = steward !== undefined ? normalisePrincipal(steward) : undefined;
|
|
530
|
+
const counted = [];
|
|
531
|
+
const seen = new Set();
|
|
532
|
+
const left = [];
|
|
533
|
+
for (const name of by) {
|
|
534
|
+
const p = normalisePrincipal(name);
|
|
535
|
+
if (p === "" || seen.has(p))
|
|
536
|
+
continue;
|
|
537
|
+
seen.add(p);
|
|
538
|
+
if (asker !== undefined && p === asker) {
|
|
539
|
+
left.push({ name, why: "is the steward that asked" });
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
if (agents.has(p)) {
|
|
543
|
+
left.push({ name, why: "holds the agent role" });
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
if (quorum.roles && !quorum.roles.some((r) => holders(r).has(p))) {
|
|
547
|
+
left.push({ name, why: `holds none of the roles ${quorum.roles.join(", ")}` });
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
counted.push(name);
|
|
551
|
+
}
|
|
552
|
+
return { counted, left, met: counted.length >= quorum.count };
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* A steward waits on a question and never answers or retracts one (#2749), as
|
|
556
|
+
* it never clears a gate: the write has to come from a person, through hud or
|
|
557
|
+
* a shell, not from the steward's own turn or a process it started.
|
|
558
|
+
*/
|
|
559
|
+
function refuseStewardTurn(id, does) {
|
|
560
|
+
const turn = currentStewardTurn();
|
|
561
|
+
if (turn) {
|
|
562
|
+
throw new PointsWriteError("answer-in-steward-turn", `this is the steward ${turn.steward}'s turn, and a steward never ${does} a decision point: a person ${does === "answers" ? "answers" : "retracts the answer to"} ${id} through hud or \`chant workspace points ${does === "answers" ? "answer" : "retract"}\` at a shell`);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
/** The answer record with this id, in the answer kind `kind` names or the first declared one that has it, read with the ledger's answers laid over the tree. */
|
|
566
|
+
async function findQuestion(cwd, kind, id) {
|
|
567
|
+
const kinds = await answerKindFiles(cwd, kind);
|
|
568
|
+
if (kinds.length === 0)
|
|
569
|
+
throw new PointsWriteError("points-undeclared", "no record kind with an answers block is declared: name one with --kind, or declare one in chant.workspace.json");
|
|
570
|
+
for (const k of kinds) {
|
|
571
|
+
const opened = await openAnswers(k, cwd);
|
|
572
|
+
// A question a steward asked is on the ledger (#2786), and people's answer goes back there. So is
|
|
573
|
+
// one a CI job asked with --store ledger (#3815), from a checkout that is gone: fetch the
|
|
574
|
+
// branch first, so a clone that never ran the job finds the question.
|
|
575
|
+
await refreshLedger(opened.o.loaded.file);
|
|
576
|
+
const read = await readWithLedger(opened.o);
|
|
577
|
+
const target = read.before.find((e) => e.id === id);
|
|
578
|
+
if (target && target.data !== null)
|
|
579
|
+
return { opened, before: read.before, read, target: target };
|
|
580
|
+
}
|
|
581
|
+
throw new PointsWriteError("record-not-found", `no answer record has id ${id}`);
|
|
582
|
+
}
|
|
583
|
+
/** A model-authored channel's name, as a person reads it. */
|
|
584
|
+
const channelName = (origin) => (origin === "acp" ? "ACP" : "MCP");
|
|
585
|
+
/**
|
|
586
|
+
* Count `by` toward the point's quorum, or refuse with `quorum-not-met`.
|
|
587
|
+
*
|
|
588
|
+
* Over MCP or ACP (#3817) the names are the model's to choose, as a gate's
|
|
589
|
+
* approver is (`lifecycle/gate-origin.ts`), so the answer is an agent's and
|
|
590
|
+
* nobody it names counts: a person answers at a shell or through hud.
|
|
591
|
+
*/
|
|
592
|
+
function meetQuorum(name, by, quorum, root, steward, verb, origin) {
|
|
593
|
+
const overModel = isModelAuthored(origin);
|
|
594
|
+
const tally = overModel
|
|
595
|
+
? { counted: [], left: by.map((n) => ({ name: n, why: `was named over ${channelName(origin)}, where an answer is an agent's` })), met: false }
|
|
596
|
+
: tallyQuorum(by, quorum, policyFor(root), steward);
|
|
597
|
+
if (!tally.met) {
|
|
598
|
+
const got = tally.counted.length;
|
|
599
|
+
const left = tally.left.length ? `; not counted: ${tally.left.map((l) => `${l.name}, who ${l.why}`).join("; ")}` : "";
|
|
600
|
+
const remedy = overModel ? `: a person ${verb === "answer" ? "answers" : "retracts it"} at a shell with \`chant workspace points ${verb}\`, or through hud` : "";
|
|
601
|
+
throw new PointsWriteError("quorum-not-met", `${name} needs ${quorum.count} ${quorum.count === 1 ? "person" : "people"}${quorum.roles ? ` holding ${quorum.roles.join(" or ")}` : ""} to ${verb === "answer" ? "answer" : "retract an answer"}, and ${got} ${got === 1 ? "counts" : "count"}${got ? ` (${tally.counted.join(", ")})` : ""}${left}${remedy}`);
|
|
602
|
+
}
|
|
603
|
+
return tally;
|
|
604
|
+
}
|
|
605
|
+
/** The gates a question's `constrains` names, as `gate:<op>/<gate>` with an optional `@<env>` (`op/gate-point.ts`'s `gateSubject`). */
|
|
606
|
+
function constrainedGates(d) {
|
|
607
|
+
const out = [];
|
|
608
|
+
for (const c of Array.isArray(d.constrains) ? d.constrains : []) {
|
|
609
|
+
if (typeof c !== "string" || !c.startsWith("gate:"))
|
|
610
|
+
continue;
|
|
611
|
+
const rest = c.slice("gate:".length);
|
|
612
|
+
const at = rest.lastIndexOf("@");
|
|
613
|
+
const named = at > 0 ? rest.slice(0, at) : rest;
|
|
614
|
+
const slash = named.indexOf("/");
|
|
615
|
+
if (slash > 0 && slash < named.length - 1)
|
|
616
|
+
out.push({ op: named.slice(0, slash), gate: named.slice(slash + 1) });
|
|
617
|
+
}
|
|
618
|
+
return out;
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Refuse an answer or retraction over MCP or ACP to a question that
|
|
622
|
+
* constrains a gate never resolved there (#3817, #3485): the gate-only op
|
|
623
|
+
* names chant knows, a pending fact on the gate ledger that says so (as
|
|
624
|
+
* terragucci's records do), or the Op's own `neverOverMcp`. `op-approve`
|
|
625
|
+
* refuses the same gates.
|
|
626
|
+
*/
|
|
627
|
+
async function refuseNeverOverMcp(id, d, root, origin, does) {
|
|
628
|
+
if (!isModelAuthored(origin))
|
|
629
|
+
return;
|
|
630
|
+
const gates = constrainedGates(d);
|
|
631
|
+
if (gates.length === 0)
|
|
632
|
+
return;
|
|
633
|
+
const { isNeverOverMcpGateOp } = await import("../op/gate-name.js");
|
|
634
|
+
const { readGateLedger } = await import("../lifecycle/gate-ledger.js");
|
|
635
|
+
let configs;
|
|
636
|
+
for (const { op, gate } of gates) {
|
|
637
|
+
let never = isNeverOverMcpGateOp(op);
|
|
638
|
+
if (!never) {
|
|
639
|
+
const { pending } = await readGateLedger(op, { cwd: root }).catch(() => ({ pending: [] }));
|
|
640
|
+
never = pending.some((p) => p.gate === gate && p.neverOverMcp === true);
|
|
641
|
+
}
|
|
642
|
+
if (!never) {
|
|
643
|
+
if (configs === undefined) {
|
|
644
|
+
const { discoverOps } = await import("../op/discover.js");
|
|
645
|
+
configs = await discoverOps({ cwd: root }).then((r) => r.ops).catch(() => new Map());
|
|
646
|
+
}
|
|
647
|
+
never = Boolean(configs.get(op)?.config.neverOverMcp);
|
|
648
|
+
}
|
|
649
|
+
if (never) {
|
|
650
|
+
throw new PointsWriteError("answer-never-over-mcp", `${id} constrains gate "${gate}" on "${op}", which is never resolved over ${channelName(origin)}, so its question is not ${does === "answers" ? "answered" : "retracted"} there either: a person ${does === "answers" ? "answers" : "retracts the answer to"} it at a shell with \`chant workspace points ${does === "answers" ? "answer" : "retract"} ${id}\`, or through hud`);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* People answer an open question: `points answer`. A proposed question the
|
|
656
|
+
* people answer as the model did is confirmed, and keeps the model as its
|
|
657
|
+
* decider; any other answer is the quorum's, and a model's proposal moves into
|
|
658
|
+
* the escalations. The question becomes `answered`, with the people's note
|
|
659
|
+
* when they give one (#3351).
|
|
660
|
+
*/
|
|
661
|
+
export async function answerPoint(opts) {
|
|
662
|
+
try {
|
|
663
|
+
return await withWriteLock(opts.cwd, { verb: "points answer", by: (opts.by ?? []).join(", ") || null }, opts.dryRun, () => answerPointLocked(opts));
|
|
664
|
+
}
|
|
665
|
+
catch (err) {
|
|
666
|
+
return failure("answer", err);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
async function answerPointLocked(opts) {
|
|
670
|
+
try {
|
|
671
|
+
refuseStewardTurn(opts.id, "answers");
|
|
672
|
+
// #3163: under identity.attribution "identified" at base, each answerer is a forge identity or a signer.
|
|
673
|
+
refuseUnidentified(scopeSource(opts.cwd), opts.by, "--by");
|
|
674
|
+
// #3402: and so is whoever relayed the answer.
|
|
675
|
+
const relayedBy = noteOf(opts.relayedBy);
|
|
676
|
+
if (relayedBy !== undefined)
|
|
677
|
+
refuseUnidentified(scopeSource(opts.cwd), [relayedBy], "--relayed-by");
|
|
678
|
+
const found = await findQuestion(opts.cwd, opts.kind, opts.id);
|
|
679
|
+
const { opened, before, target } = found;
|
|
680
|
+
const ledger = found.read.ledger;
|
|
681
|
+
const { o } = opened;
|
|
682
|
+
const d = target.data;
|
|
683
|
+
if (target.state === "answered") {
|
|
684
|
+
throw new PointsWriteError("record-closed", `${opts.id} is answered, and an answer never changes in place: retract it with \`points retract ${opts.id}\` and answer again, ask again with other inputs, or change the point, which asks the question anew`);
|
|
685
|
+
}
|
|
686
|
+
const note = noteOf(opts.note);
|
|
687
|
+
if (note !== undefined && !answerFields(o.loaded.schema).note) {
|
|
688
|
+
throw new PointsWriteError("answer-field-unsupported", `the ${o.loaded.kind.name} kind's schema has no note field, so ${opts.id} can't keep the note: copy point-answer.schema.json from @intentius/chant anew`);
|
|
689
|
+
}
|
|
690
|
+
if (relayedBy !== undefined && !answerFields(o.loaded.schema).relayedBy) {
|
|
691
|
+
throw new PointsWriteError("answer-field-unsupported", `the ${o.loaded.kind.name} kind's schema has no relayed_by field, so ${opts.id} can't record who relayed the answer: copy point-answer.schema.json from @intentius/chant anew`);
|
|
692
|
+
}
|
|
693
|
+
const name = String(d.point);
|
|
694
|
+
const point = pointOf(opened.points, name);
|
|
695
|
+
if (!point)
|
|
696
|
+
throw new PointsWriteError("point-unknown", `${opts.id} answers ${name}, which ${opened.pointsFile} no longer declares`);
|
|
697
|
+
// An ad-hoc question is answered from the candidates it was asked with (#3403).
|
|
698
|
+
const asked = askedOf(d);
|
|
699
|
+
const allowed = asked ? candidates(askedQuestion(point, asked)) : Array.isArray(d.candidates) ? d.candidates : candidates(point.question);
|
|
700
|
+
const type = String(d.question_type);
|
|
701
|
+
const value = type === "noul" && typeof opts.answer === "string" ? { true: true, yes: true, false: false, no: false }[opts.answer.toLowerCase()] : opts.answer;
|
|
702
|
+
if (value === undefined || !allowed.includes(value)) {
|
|
703
|
+
throw new PointsWriteError("answer-not-candidate", `${opts.id} takes one of ${allowed.map((c) => JSON.stringify(c)).join(", ")}, not ${JSON.stringify(opts.answer)}`);
|
|
704
|
+
}
|
|
705
|
+
const origin = opts.origin ?? currentGateOrigin();
|
|
706
|
+
await refuseNeverOverMcp(opts.id, d, o.root, origin, "answers");
|
|
707
|
+
const quorum = quorumOf(point);
|
|
708
|
+
const tally = meetQuorum(name, opts.by, quorum, o.root, askedByOf(d)?.steward, "answer", origin);
|
|
709
|
+
const on = opts.on ?? today();
|
|
710
|
+
const decider = d.decider;
|
|
711
|
+
const confirmed = target.state === "proposed" && decider.kind === "model" && d.answer === value;
|
|
712
|
+
const escalations = Array.isArray(d.escalations) ? [...d.escalations] : [];
|
|
713
|
+
let fields;
|
|
714
|
+
if (confirmed) {
|
|
715
|
+
fields = { ...d, state: "answered", answered_by: tally.counted, answered_on: on, note, relayed_by: relayedBy };
|
|
716
|
+
}
|
|
717
|
+
else {
|
|
718
|
+
if (target.state === "proposed" && decider.kind === "model") {
|
|
719
|
+
escalations.push({
|
|
720
|
+
kind: "model",
|
|
721
|
+
backend: String(decider.backend),
|
|
722
|
+
model: String(decider.model),
|
|
723
|
+
answer: d.answer,
|
|
724
|
+
...(d.probabilities ? { probabilities: d.probabilities } : {}),
|
|
725
|
+
...(typeof d.confidence === "number" ? { confidence: d.confidence } : {}),
|
|
726
|
+
...(typeof d.threshold === "number" ? { threshold: d.threshold } : {}),
|
|
727
|
+
reason: `proposed ${show(d.answer, type)}, and people answered ${show(value, type)}`,
|
|
728
|
+
// The model's own reason moves with its proposal (#3345).
|
|
729
|
+
...(typeof d.reason === "string" && reasonFields(o.loaded.schema).escalation ? { model_reason: d.reason } : {}),
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
const rest = Object.fromEntries(Object.entries(d).filter(([k]) => k !== "probabilities" && k !== "confidence" && k !== "threshold" && k !== "reason"));
|
|
733
|
+
fields = {
|
|
734
|
+
...rest,
|
|
735
|
+
state: "answered",
|
|
736
|
+
answer: value,
|
|
737
|
+
decider: { kind: "quorum", count: quorum.count, ...(quorum.roles ? { roles: quorum.roles } : {}), by: tally.counted },
|
|
738
|
+
escalations: escalations.length > 0 ? escalations : undefined,
|
|
739
|
+
answered_by: tally.counted,
|
|
740
|
+
answered_on: on,
|
|
741
|
+
note,
|
|
742
|
+
relayed_by: relayedBy,
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
const subject = Array.isArray(d.constrains) && typeof d.constrains[0] === "string" ? d.constrains[0] : undefined;
|
|
746
|
+
fields.title = titleFor(point, subject, "answered", value, asked);
|
|
747
|
+
const data = recordData(o, fields);
|
|
748
|
+
const text = renderRecord(data, body(point, String(fields.title), asked));
|
|
749
|
+
const onLedger = ledger.byPath.has(target.path);
|
|
750
|
+
const message = `Decision point ${name}: answered ${show(value, type)} by ${tally.counted.join(", ")}${relayedBy ? `, relayed by ${relayedBy}` : ""}`;
|
|
751
|
+
const wrote = await write(o, before, target.path, text, false, !!opts.dryRun, { source: found.read.source, ledger, onLedger, message, who: { verb: "points answer", by: tally.counted.join(", ") } });
|
|
752
|
+
const entry = { ...target, state: "answered", data, valid: true, reasons: [], warnings: wrote.warnings };
|
|
753
|
+
return {
|
|
754
|
+
$schema: POINTS_WRITE_SCHEMA_ID,
|
|
755
|
+
contract: POINTS_WRITE_CONTRACT_VERSION,
|
|
756
|
+
verb: "answer",
|
|
757
|
+
kind: o.view,
|
|
758
|
+
id: opts.id,
|
|
759
|
+
path: target.path,
|
|
760
|
+
reused: false,
|
|
761
|
+
written: !opts.dryRun,
|
|
762
|
+
dryRun: !!opts.dryRun,
|
|
763
|
+
question: questionView(entry, point, onLedger ? (wrote.ledger ?? ledger.byPath.get(target.path)?.ledger ?? null) : null),
|
|
764
|
+
...(opts.dryRun ? { text } : {}),
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
catch (err) {
|
|
768
|
+
return failure("answer", err);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* People take an answer back: `points retract` (#3351, ws-084). The answer
|
|
773
|
+
* never changes in place. The question is escalated to the point's quorum
|
|
774
|
+
* again, open for people, and the answer as it was (its value, decider, who
|
|
775
|
+
* gave it, when, and its note) moves into the record's `retractions`, with who
|
|
776
|
+
* retracted it, when and why. A model's confirmed proposal also moves into the
|
|
777
|
+
* escalations, as when people answer otherwise. Retracting needs the point's
|
|
778
|
+
* quorum, counted as an answer is, and is refused in a steward's turn. People
|
|
779
|
+
* answer the question again with `points answer`.
|
|
780
|
+
*/
|
|
781
|
+
export async function retractAnswer(opts) {
|
|
782
|
+
try {
|
|
783
|
+
return await withWriteLock(opts.cwd, { verb: "points retract", by: (opts.by ?? []).join(", ") || null }, opts.dryRun, () => retractAnswerLocked(opts));
|
|
784
|
+
}
|
|
785
|
+
catch (err) {
|
|
786
|
+
return failure("retract", err);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
async function retractAnswerLocked(opts) {
|
|
790
|
+
try {
|
|
791
|
+
refuseStewardTurn(opts.id, "retracts");
|
|
792
|
+
refuseUnidentified(scopeSource(opts.cwd), opts.by, "--by");
|
|
793
|
+
const found = await findQuestion(opts.cwd, opts.kind, opts.id);
|
|
794
|
+
const { opened, before, target } = found;
|
|
795
|
+
const ledger = found.read.ledger;
|
|
796
|
+
const { o } = opened;
|
|
797
|
+
const d = target.data;
|
|
798
|
+
if (target.state !== "answered") {
|
|
799
|
+
throw new PointsWriteError("answer-not-answered", `${opts.id} is ${target.state ?? "not answered"}, so there is no answer to retract: answer it with \`points answer ${opts.id}\``);
|
|
800
|
+
}
|
|
801
|
+
if (!answerFields(o.loaded.schema).retractions) {
|
|
802
|
+
throw new PointsWriteError("answer-field-unsupported", `the ${o.loaded.kind.name} kind's schema has no retractions field, so ${opts.id} can't keep the answer it would retract: copy point-answer.schema.json from @intentius/chant anew`);
|
|
803
|
+
}
|
|
804
|
+
const name = String(d.point);
|
|
805
|
+
const point = pointOf(opened.points, name);
|
|
806
|
+
if (!point)
|
|
807
|
+
throw new PointsWriteError("point-unknown", `${opts.id} answers ${name}, which ${opened.pointsFile} no longer declares, so no quorum can take the answer back: ask the point as it is declared now`);
|
|
808
|
+
const origin = opts.origin ?? currentGateOrigin();
|
|
809
|
+
await refuseNeverOverMcp(opts.id, d, o.root, origin, "retracts");
|
|
810
|
+
const quorum = quorumOf(point);
|
|
811
|
+
const tally = meetQuorum(name, opts.by, quorum, o.root, askedByOf(d)?.steward, "retract", origin);
|
|
812
|
+
const on = opts.on ?? today();
|
|
813
|
+
const type = String(d.question_type);
|
|
814
|
+
const decider = d.decider !== null && typeof d.decider === "object" && !Array.isArray(d.decider) ? d.decider : { kind: "quorum" };
|
|
815
|
+
const answer = d.answer;
|
|
816
|
+
const note = noteOf(opts.note);
|
|
817
|
+
const retraction = {
|
|
818
|
+
answer,
|
|
819
|
+
decider,
|
|
820
|
+
answered_by: Array.isArray(d.answered_by) && d.answered_by.length > 0 ? d.answered_by : undefined,
|
|
821
|
+
answered_on: typeof d.answered_on === "string" ? d.answered_on : undefined,
|
|
822
|
+
answer_note: typeof d.note === "string" ? d.note : undefined,
|
|
823
|
+
answer_relayed_by: typeof d.relayed_by === "string" ? d.relayed_by : undefined,
|
|
824
|
+
by: tally.counted,
|
|
825
|
+
on,
|
|
826
|
+
note,
|
|
827
|
+
};
|
|
828
|
+
const escalations = Array.isArray(d.escalations) ? [...d.escalations] : [];
|
|
829
|
+
if (decider.kind === "model") {
|
|
830
|
+
// The confirmed proposal goes back among the deciders that did not settle the question.
|
|
831
|
+
escalations.push({
|
|
832
|
+
kind: "model",
|
|
833
|
+
backend: String(decider.backend),
|
|
834
|
+
model: String(decider.model),
|
|
835
|
+
answer,
|
|
836
|
+
...(d.probabilities ? { probabilities: d.probabilities } : {}),
|
|
837
|
+
...(typeof d.confidence === "number" ? { confidence: d.confidence } : {}),
|
|
838
|
+
...(typeof d.threshold === "number" ? { threshold: d.threshold } : {}),
|
|
839
|
+
reason: `proposed ${show(answer, type)}, which people confirmed and then retracted`,
|
|
840
|
+
...(typeof d.reason === "string" && reasonFields(o.loaded.schema).escalation ? { model_reason: d.reason } : {}),
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
const gone = new Set(["answer", "answered_by", "answered_on", "note", "relayed_by", "probabilities", "confidence", "threshold", "reason"]);
|
|
844
|
+
const rest = Object.fromEntries(Object.entries(d).filter(([k]) => !gone.has(k)));
|
|
845
|
+
const prior = Array.isArray(d.retractions) ? d.retractions : [];
|
|
846
|
+
const subject = Array.isArray(d.constrains) && typeof d.constrains[0] === "string" ? d.constrains[0] : undefined;
|
|
847
|
+
const asked = askedOf(d);
|
|
848
|
+
const title = titleFor(point, subject, "escalated", undefined, asked);
|
|
849
|
+
const data = recordData(o, {
|
|
850
|
+
...rest,
|
|
851
|
+
title,
|
|
852
|
+
state: "escalated",
|
|
853
|
+
decider: { kind: "quorum", count: quorum.count, ...(quorum.roles ? { roles: quorum.roles } : {}) },
|
|
854
|
+
escalations: escalations.length > 0 ? escalations : undefined,
|
|
855
|
+
retractions: [...prior, Object.fromEntries(Object.entries(retraction).filter(([, v]) => v !== undefined))],
|
|
856
|
+
});
|
|
857
|
+
const text = renderRecord(data, body(point, title, asked));
|
|
858
|
+
const onLedger = ledger.byPath.has(target.path);
|
|
859
|
+
const message = `Decision point ${name}: ${show(answer, type)} retracted by ${tally.counted.join(", ")}`;
|
|
860
|
+
const wrote = await write(o, before, target.path, text, false, !!opts.dryRun, { source: found.read.source, ledger, onLedger, message, who: { verb: "points retract", by: tally.counted.join(", ") } });
|
|
861
|
+
const entry = { ...target, state: "escalated", data, valid: true, reasons: [], warnings: wrote.warnings };
|
|
862
|
+
return {
|
|
863
|
+
$schema: POINTS_WRITE_SCHEMA_ID,
|
|
864
|
+
contract: POINTS_WRITE_CONTRACT_VERSION,
|
|
865
|
+
verb: "retract",
|
|
866
|
+
kind: o.view,
|
|
867
|
+
id: opts.id,
|
|
868
|
+
path: target.path,
|
|
869
|
+
reused: false,
|
|
870
|
+
written: !opts.dryRun,
|
|
871
|
+
dryRun: !!opts.dryRun,
|
|
872
|
+
question: questionView(entry, point, onLedger ? (wrote.ledger ?? ledger.byPath.get(target.path)?.ledger ?? null) : null),
|
|
873
|
+
...(opts.dryRun ? { text } : {}),
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
catch (err) {
|
|
877
|
+
return failure("retract", err);
|
|
878
|
+
}
|
|
879
|
+
}
|