devcontour-harness 0.0.0-stage → 0.1.0-alpha.6
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/LICENSE +21 -0
- package/README.md +183 -2
- package/docs/architecture.md +473 -0
- package/docs/compatibility-versions.md +56 -0
- package/docs/compatibility.md +192 -0
- package/docs/connectors.md +323 -0
- package/docs/contracts.md +603 -0
- package/docs/integrations/hindsight.md +148 -0
- package/docs/quickstart.md +182 -0
- package/docs/release-notes/0.1.0-alpha.6.md +238 -0
- package/docs/review-probes.md +120 -0
- package/docs/review-protocol.md +251 -0
- package/docs/toolchains.md +167 -0
- package/docs/turbo-starter.md +269 -0
- package/docs/upgrade.md +202 -0
- package/examples/README.md +27 -0
- package/examples/external-connector/README.md +19 -0
- package/examples/external-connector/connector.mjs +55 -0
- package/examples/files-only/README.md +28 -0
- package/examples/files-only/context/norms/rules.md +4 -0
- package/examples/files-only/graph.json +23 -0
- package/examples/files-only/policy.json +30 -0
- package/examples/one-vendor/README.md +19 -0
- package/examples/one-vendor/policy.json +27 -0
- package/examples/single-task/README.md +18 -0
- package/examples/single-task/graph.json +27 -0
- package/examples/single-task/policy-same-vendor.json +55 -0
- package/examples/single-task/policy.json +52 -0
- package/examples/single-task/src/.gitkeep +0 -0
- package/examples/single-task/test/run.js +19 -0
- package/examples/toolchains/README.md +32 -0
- package/examples/toolchains/go/bad/label/label.go +9 -0
- package/examples/toolchains/go/good/label/label.go +9 -0
- package/examples/toolchains/go/policy.json +79 -0
- package/examples/toolchains/go/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/go/repo/_gitignore +1 -0
- package/examples/toolchains/go/repo/go.mod +5 -0
- package/examples/toolchains/go/repo/go.sum +2 -0
- package/examples/toolchains/go/repo/label/label.go +9 -0
- package/examples/toolchains/go/repo/label/label_test.go +27 -0
- package/examples/toolchains/go/repo/label/version.go +9 -0
- package/examples/toolchains/go/task.json +25 -0
- package/examples/toolchains/mixed-go/bad/backend/label/label.go +9 -0
- package/examples/toolchains/mixed-go/bad/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-go/good/backend/label/label.go +9 -0
- package/examples/toolchains/mixed-go/good/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-go/policy.json +126 -0
- package/examples/toolchains/mixed-go/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/mixed-go/repo/_gitignore +6 -0
- package/examples/toolchains/mixed-go/repo/backend/go.mod +3 -0
- package/examples/toolchains/mixed-go/repo/backend/label/label.go +9 -0
- package/examples/toolchains/mixed-go/repo/backend/label/label_test.go +30 -0
- package/examples/toolchains/mixed-go/repo/contract/check.mjs +17 -0
- package/examples/toolchains/mixed-go/repo/contract/label.json +9 -0
- package/examples/toolchains/mixed-go/repo/frontend/package.json +15 -0
- package/examples/toolchains/mixed-go/repo/frontend/pnpm-lock.yaml +22 -0
- package/examples/toolchains/mixed-go/repo/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-go/repo/frontend/test/label.test.js +11 -0
- package/examples/toolchains/mixed-go/task.json +25 -0
- package/examples/toolchains/mixed-python/bad/backend/src/fx_backend/__init__.py +6 -0
- package/examples/toolchains/mixed-python/bad/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-python/good/backend/src/fx_backend/__init__.py +6 -0
- package/examples/toolchains/mixed-python/good/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-python/policy.json +121 -0
- package/examples/toolchains/mixed-python/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/mixed-python/repo/_gitignore +6 -0
- package/examples/toolchains/mixed-python/repo/backend/.python-version +1 -0
- package/examples/toolchains/mixed-python/repo/backend/pyproject.toml +19 -0
- package/examples/toolchains/mixed-python/repo/backend/src/fx_backend/__init__.py +6 -0
- package/examples/toolchains/mixed-python/repo/backend/tests/test_label.py +11 -0
- package/examples/toolchains/mixed-python/repo/backend/uv.lock +108 -0
- package/examples/toolchains/mixed-python/repo/contract/check.mjs +17 -0
- package/examples/toolchains/mixed-python/repo/contract/label.json +9 -0
- package/examples/toolchains/mixed-python/repo/frontend/package.json +15 -0
- package/examples/toolchains/mixed-python/repo/frontend/pnpm-lock.yaml +22 -0
- package/examples/toolchains/mixed-python/repo/frontend/src/label.js +4 -0
- package/examples/toolchains/mixed-python/repo/frontend/test/label.test.js +11 -0
- package/examples/toolchains/mixed-python/task.json +25 -0
- package/examples/toolchains/npm/bad/src/label.js +4 -0
- package/examples/toolchains/npm/good/src/label.js +4 -0
- package/examples/toolchains/npm/policy.json +82 -0
- package/examples/toolchains/npm/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/npm/repo/_gitignore +4 -0
- package/examples/toolchains/npm/repo/package-lock.json +22 -0
- package/examples/toolchains/npm/repo/package.json +13 -0
- package/examples/toolchains/npm/repo/src/label.js +4 -0
- package/examples/toolchains/npm/repo/test/label.test.js +13 -0
- package/examples/toolchains/npm/task.json +25 -0
- package/examples/toolchains/pnpm/bad/packages/label/src/label.js +4 -0
- package/examples/toolchains/pnpm/good/packages/label/src/label.js +4 -0
- package/examples/toolchains/pnpm/policy.json +85 -0
- package/examples/toolchains/pnpm/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/pnpm/repo/_gitignore +4 -0
- package/examples/toolchains/pnpm/repo/package.json +10 -0
- package/examples/toolchains/pnpm/repo/packages/checker/check.mjs +5 -0
- package/examples/toolchains/pnpm/repo/packages/checker/package.json +9 -0
- package/examples/toolchains/pnpm/repo/packages/label/package.json +14 -0
- package/examples/toolchains/pnpm/repo/packages/label/src/label.js +4 -0
- package/examples/toolchains/pnpm/repo/packages/label/test/label.test.js +13 -0
- package/examples/toolchains/pnpm/repo/pnpm-lock.yaml +29 -0
- package/examples/toolchains/pnpm/repo/pnpm-workspace.yaml +2 -0
- package/examples/toolchains/pnpm/task.json +25 -0
- package/examples/toolchains/python/bad/src/fx_label/__init__.py +6 -0
- package/examples/toolchains/python/good/src/fx_label/__init__.py +6 -0
- package/examples/toolchains/python/policy.json +80 -0
- package/examples/toolchains/python/repo/.python-version +1 -0
- package/examples/toolchains/python/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/python/repo/_gitignore +5 -0
- package/examples/toolchains/python/repo/pyproject.toml +19 -0
- package/examples/toolchains/python/repo/src/fx_label/__init__.py +6 -0
- package/examples/toolchains/python/repo/tests/test_label.py +13 -0
- package/examples/toolchains/python/repo/uv.lock +108 -0
- package/examples/toolchains/python/task.json +25 -0
- package/examples/toolchains/turbo/bad/packages/label/src/label.js +4 -0
- package/examples/toolchains/turbo/good/packages/label/src/label.js +4 -0
- package/examples/toolchains/turbo/policy.json +110 -0
- package/examples/toolchains/turbo/repo/REQUIREMENTS.md +9 -0
- package/examples/toolchains/turbo/repo/_gitignore +4 -0
- package/examples/toolchains/turbo/repo/package.json +13 -0
- package/examples/toolchains/turbo/repo/packages/checker/check.mjs +5 -0
- package/examples/toolchains/turbo/repo/packages/checker/package.json +9 -0
- package/examples/toolchains/turbo/repo/packages/label/package.json +14 -0
- package/examples/toolchains/turbo/repo/packages/label/src/label.js +4 -0
- package/examples/toolchains/turbo/repo/packages/label/test/label.test.js +13 -0
- package/examples/toolchains/turbo/repo/pnpm-lock.yaml +94 -0
- package/examples/toolchains/turbo/repo/pnpm-workspace.yaml +2 -0
- package/examples/toolchains/turbo/repo/turbo.json +7 -0
- package/examples/toolchains/turbo/task.json +25 -0
- package/examples/turbo-starter/README.md +16 -0
- package/examples/turbo-starter/changes/issued-at-consumer-only.patch +12 -0
- package/examples/turbo-starter/changes/issued-at.patch +130 -0
- package/examples/turbo-starter/cleanup.mjs +58 -0
- package/examples/turbo-starter/graph.json +32 -0
- package/examples/turbo-starter/harness/acceptance/db-isolation.test.mjs +97 -0
- package/examples/turbo-starter/harness/acceptance/env-probe.test.mjs +75 -0
- package/examples/turbo-starter/harness/acceptance/generation.test.mjs +54 -0
- package/examples/turbo-starter/harness/acceptance/issued-at.test.mjs +43 -0
- package/examples/turbo-starter/harness/acceptance/lifecycle-probe.test.mjs +47 -0
- package/examples/turbo-starter/harness/compose-bridge.mjs +593 -0
- package/examples/turbo-starter/harness/compose.acceptance.yml +23 -0
- package/examples/turbo-starter/harness/env/backend.env.template +7 -0
- package/examples/turbo-starter/harness/env/compose.env.template +6 -0
- package/examples/turbo-starter/policy.json +109 -0
- package/examples/turbo-starter/policy.lifecycle.json +114 -0
- package/examples/turbo-starter/setup.mjs +352 -0
- package/examples/two-vendors/policy.json +30 -0
- package/lib/agents/cli-adapter.d.ts +48 -0
- package/lib/agents/cli-adapter.js +386 -0
- package/lib/agents/inspect.d.ts +6 -0
- package/lib/agents/inspect.js +46 -0
- package/lib/agents/probe-server.d.ts +2 -0
- package/lib/agents/probe-server.js +13 -0
- package/lib/agents/review-probe.d.ts +295 -0
- package/lib/agents/review-probe.js +872 -0
- package/lib/agents/runtime-events.d.ts +11 -0
- package/lib/agents/runtime-events.js +21 -0
- package/lib/agents/schemas.d.ts +217 -0
- package/lib/agents/schemas.js +124 -0
- package/lib/agents/usage.d.ts +8 -0
- package/lib/agents/usage.js +83 -0
- package/lib/cli.d.ts +2 -0
- package/lib/cli.js +491 -0
- package/lib/connectors/files.d.ts +108 -0
- package/lib/connectors/files.js +133 -0
- package/lib/contracts/checks.d.ts +307 -0
- package/lib/contracts/checks.js +181 -0
- package/lib/contracts/cli.d.ts +3895 -0
- package/lib/contracts/cli.js +664 -0
- package/lib/contracts/context.d.ts +135 -0
- package/lib/contracts/context.js +129 -0
- package/lib/contracts/digest.d.ts +9 -0
- package/lib/contracts/digest.js +22 -0
- package/lib/contracts/errors.d.ts +81 -0
- package/lib/contracts/errors.js +70 -0
- package/lib/contracts/events.d.ts +827 -0
- package/lib/contracts/events.js +258 -0
- package/lib/contracts/execution.d.ts +3216 -0
- package/lib/contracts/execution.js +872 -0
- package/lib/contracts/failure.d.ts +67 -0
- package/lib/contracts/failure.js +127 -0
- package/lib/contracts/index.d.ts +18 -0
- package/lib/contracts/index.js +18 -0
- package/lib/contracts/policy.d.ts +1080 -0
- package/lib/contracts/policy.js +544 -0
- package/lib/contracts/ports.d.ts +417 -0
- package/lib/contracts/ports.js +1 -0
- package/lib/contracts/primitives.d.ts +63 -0
- package/lib/contracts/primitives.js +73 -0
- package/lib/contracts/profiles.d.ts +336 -0
- package/lib/contracts/profiles.js +109 -0
- package/lib/contracts/published.d.ts +3237 -0
- package/lib/contracts/published.js +34 -0
- package/lib/contracts/result.d.ts +1280 -0
- package/lib/contracts/result.js +311 -0
- package/lib/contracts/review.d.ts +441 -0
- package/lib/contracts/review.js +477 -0
- package/lib/contracts/toolchain.d.ts +96 -0
- package/lib/contracts/toolchain.js +89 -0
- package/lib/contracts/version.d.ts +17 -0
- package/lib/contracts/version.js +17 -0
- package/lib/contracts/work.d.ts +173 -0
- package/lib/contracts/work.js +178 -0
- package/lib/control/base-move.d.ts +44 -0
- package/lib/control/base-move.js +90 -0
- package/lib/control/doctor.d.ts +50 -0
- package/lib/control/doctor.js +113 -0
- package/lib/control/harness.d.ts +1125 -0
- package/lib/control/harness.js +741 -0
- package/lib/control/provenance.d.ts +17 -0
- package/lib/control/provenance.js +25 -0
- package/lib/control/recovery.d.ts +237 -0
- package/lib/control/recovery.js +236 -0
- package/lib/control/review.d.ts +62 -0
- package/lib/control/review.js +178 -0
- package/lib/control/workflow.d.ts +247 -0
- package/lib/control/workflow.js +259 -0
- package/lib/engine/budget.d.ts +345 -0
- package/lib/engine/budget.js +278 -0
- package/lib/engine/classify.d.ts +8 -0
- package/lib/engine/classify.js +32 -0
- package/lib/engine/engine.d.ts +1527 -0
- package/lib/engine/engine.js +2259 -0
- package/lib/engine/failure.d.ts +1 -0
- package/lib/engine/failure.js +3 -0
- package/lib/engine/joint-runner.d.ts +257 -0
- package/lib/engine/joint-runner.js +254 -0
- package/lib/engine/measured.d.ts +15 -0
- package/lib/engine/measured.js +82 -0
- package/lib/engine/prompt.d.ts +66 -0
- package/lib/engine/prompt.js +131 -0
- package/lib/engine/property-recovery.d.ts +50 -0
- package/lib/engine/property-recovery.js +171 -0
- package/lib/engine/repair.d.ts +33 -0
- package/lib/engine/repair.js +82 -0
- package/lib/engine/result.d.ts +9 -0
- package/lib/engine/result.js +218 -0
- package/lib/engine/reuse.d.ts +80 -0
- package/lib/engine/reuse.js +102 -0
- package/lib/engine/runner.d.ts +360 -0
- package/lib/engine/runner.js +1836 -0
- package/lib/engine/standalone.d.ts +6 -0
- package/lib/engine/standalone.js +48 -0
- package/lib/engine/usage.d.ts +87 -0
- package/lib/engine/usage.js +165 -0
- package/lib/environment/isolation.d.ts +110 -0
- package/lib/environment/isolation.js +238 -0
- package/lib/environment/lifecycle.d.ts +40 -0
- package/lib/environment/lifecycle.js +197 -0
- package/lib/environment/live-calls.d.ts +14 -0
- package/lib/environment/live-calls.js +73 -0
- package/lib/environment/os-tools.d.ts +16 -0
- package/lib/environment/os-tools.js +35 -0
- package/lib/environment/process.d.ts +32 -0
- package/lib/environment/process.js +369 -0
- package/lib/environment/redaction.d.ts +22 -0
- package/lib/environment/redaction.js +102 -0
- package/lib/environment/resources.d.ts +31 -0
- package/lib/environment/resources.js +120 -0
- package/lib/index.d.ts +65 -0
- package/lib/index.js +67 -0
- package/lib/integrations/connector/commands.d.ts +358 -0
- package/lib/integrations/connector/commands.js +428 -0
- package/lib/integrations/connector/config.d.ts +215 -0
- package/lib/integrations/connector/config.js +214 -0
- package/lib/integrations/connector/delivery.d.ts +107 -0
- package/lib/integrations/connector/delivery.js +591 -0
- package/lib/integrations/connector/fake.d.ts +291 -0
- package/lib/integrations/connector/fake.js +786 -0
- package/lib/integrations/connector/history.d.ts +124 -0
- package/lib/integrations/connector/history.js +497 -0
- package/lib/integrations/connector/index.d.ts +16 -0
- package/lib/integrations/connector/index.js +16 -0
- package/lib/integrations/connector/redact.d.ts +19 -0
- package/lib/integrations/connector/redact.js +91 -0
- package/lib/integrations/connector/registry.d.ts +15 -0
- package/lib/integrations/connector/registry.js +43 -0
- package/lib/integrations/connector/snapshot.d.ts +131 -0
- package/lib/integrations/connector/snapshot.js +422 -0
- package/lib/integrations/connector/source.d.ts +37 -0
- package/lib/integrations/connector/source.js +73 -0
- package/lib/integrations/connector/steps.d.ts +71 -0
- package/lib/integrations/connector/steps.js +188 -0
- package/lib/integrations/connector/store.d.ts +140 -0
- package/lib/integrations/connector/store.js +277 -0
- package/lib/integrations/connector/summary.d.ts +38 -0
- package/lib/integrations/connector/summary.js +59 -0
- package/lib/integrations/connector/testing-worker.d.ts +1 -0
- package/lib/integrations/connector/testing-worker.js +81 -0
- package/lib/integrations/connector/testing.d.ts +205 -0
- package/lib/integrations/connector/testing.js +1615 -0
- package/lib/integrations/connector/transport.d.ts +240 -0
- package/lib/integrations/connector/transport.js +28 -0
- package/lib/integrations/memory/context.d.ts +120 -0
- package/lib/integrations/memory/context.js +239 -0
- package/lib/integrations/memory/index.d.ts +8 -0
- package/lib/integrations/memory/index.js +8 -0
- package/lib/integrations/memory/provider.d.ts +79 -0
- package/lib/integrations/memory/provider.js +22 -0
- package/lib/integrations/memory/sink.d.ts +56 -0
- package/lib/integrations/memory/sink.js +116 -0
- package/lib/integrations/memory/testing.d.ts +44 -0
- package/lib/integrations/memory/testing.js +61 -0
- package/lib/integrations/relay-v1/index.d.ts +122 -0
- package/lib/integrations/relay-v1/index.js +860 -0
- package/lib/integrations/relay-v2/index.d.ts +145 -0
- package/lib/integrations/relay-v2/index.js +752 -0
- package/lib/integrations/relay-v2/process.d.ts +32 -0
- package/lib/integrations/relay-v2/process.js +112 -0
- package/lib/integrations/relay-v2/protocol.d.ts +172 -0
- package/lib/integrations/relay-v2/protocol.js +142 -0
- package/lib/package.d.ts +2 -0
- package/lib/package.js +3 -0
- package/lib/profiles/resolve.d.ts +190 -0
- package/lib/profiles/resolve.js +273 -0
- package/lib/storage/document.d.ts +1234 -0
- package/lib/storage/document.js +80 -0
- package/lib/storage/sqlite.d.ts +35 -0
- package/lib/storage/sqlite.js +260 -0
- package/lib/testing/index.d.ts +5 -0
- package/lib/testing/index.js +5 -0
- package/lib/testing/store-contract.d.ts +8 -0
- package/lib/testing/store-contract.js +167 -0
- package/lib/toolchains/index.d.ts +9 -0
- package/lib/toolchains/index.js +9 -0
- package/lib/toolchains/inspect.d.ts +105 -0
- package/lib/toolchains/inspect.js +831 -0
- package/lib/toolchains/manifests.d.ts +67 -0
- package/lib/toolchains/manifests.js +238 -0
- package/lib/toolchains/probe.d.ts +28 -0
- package/lib/toolchains/probe.js +54 -0
- package/lib/toolchains/recipes.d.ts +33 -0
- package/lib/toolchains/recipes.js +51 -0
- package/lib/validate.d.ts +36 -0
- package/lib/validate.js +175 -0
- package/lib/verification/acceptance.d.ts +284 -0
- package/lib/verification/acceptance.js +670 -0
- package/lib/verification/checks.d.ts +72 -0
- package/lib/verification/checks.js +190 -0
- package/lib/verification/confirm.d.ts +125 -0
- package/lib/verification/confirm.js +411 -0
- package/lib/verification/corpus.d.ts +1303 -0
- package/lib/verification/corpus.js +744 -0
- package/lib/verification/dependencies.d.ts +66 -0
- package/lib/verification/dependencies.js +144 -0
- package/lib/verification/gates.d.ts +160 -0
- package/lib/verification/gates.js +600 -0
- package/lib/verification/joint.d.ts +63 -0
- package/lib/verification/joint.js +121 -0
- package/lib/verification/proof.d.ts +54 -0
- package/lib/verification/proof.js +96 -0
- package/lib/verification/property.d.ts +86 -0
- package/lib/verification/property.js +214 -0
- package/lib/verification/requirements.d.ts +25 -0
- package/lib/verification/requirements.js +69 -0
- package/lib/verification/self-check.d.ts +29 -0
- package/lib/verification/self-check.js +99 -0
- package/lib/verification/spike.d.ts +79 -0
- package/lib/verification/spike.js +124 -0
- package/package.json +100 -4
- package/profiles/expo-mobile.json +15 -0
- package/profiles/go-api.json +15 -0
- package/profiles/go-gotestsum.json +21 -0
- package/profiles/mobile-maestro.json +29 -0
- package/profiles/nest-api.json +26 -0
- package/profiles/next-product.json +72 -0
- package/profiles/node-checks.json +77 -0
- package/profiles/npm-ci.json +22 -0
- package/profiles/pnpm-frozen.json +24 -0
- package/profiles/python-api.json +32 -0
- package/profiles/python-uv.json +26 -0
- package/profiles/react-native.json +50 -0
- package/profiles/react-vite-admin.json +71 -0
- package/schemas/context-snapshot.schema.json +231 -0
- package/schemas/contract-document.schema.json +385 -0
- package/schemas/execution-document.schema.json +3695 -0
- package/schemas/execution-policy.schema.json +2196 -0
- package/schemas/joint-verification.schema.json +617 -0
- package/schemas/result-envelope.schema.json +1652 -0
- package/schemas/review-record.schema.json +177 -0
- package/schemas/run-event.schema.json +2458 -0
- package/schemas/run-result.schema.json +1570 -0
- package/schemas/stack-profile.schema.json +535 -0
- package/schemas/work-graph.schema.json +381 -0
- package/schemas/work-order.schema.json +256 -0
- package/skills/harness/SKILL.md +64 -0
- package/templates/AGENTS.md +13 -0
- package/templates/controller-mode/AGENTS.controller.md +58 -0
- package/templates/controller-mode/README.md +44 -0
- package/templates/graph.json +22 -0
- package/templates/policy.json +28 -0
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { API_VERSION, STATE_VERSION } from "./version.js";
|
|
3
|
+
import { digestSchema, gitShaSchema, idSchema, isoTimeSchema, runtimeNameSchema, } from "./primitives.js";
|
|
4
|
+
import { errorCodes } from "./errors.js";
|
|
5
|
+
import { controlStateSchema, controllerLeaseSchema, workStatusSchema } from "./execution.js";
|
|
6
|
+
import { runEventSchema } from "./events.js";
|
|
7
|
+
import { deliveryStateSchema, resultEnvelopeSchema } from "./result.js";
|
|
8
|
+
import { reviewRecordSchema } from "./review.js";
|
|
9
|
+
import { sourceRefSchema } from "./work.js";
|
|
10
|
+
import { profilePinSchema, resolvedProfileSchema } from "./profiles.js";
|
|
11
|
+
import { toolchainReportSchema } from "./toolchain.js";
|
|
12
|
+
const state = {
|
|
13
|
+
name: '--state',
|
|
14
|
+
value: 'dir',
|
|
15
|
+
required: true,
|
|
16
|
+
description: 'Каталог состояния исполнения',
|
|
17
|
+
};
|
|
18
|
+
const graph = {
|
|
19
|
+
name: '--graph',
|
|
20
|
+
value: 'path',
|
|
21
|
+
required: true,
|
|
22
|
+
description: 'WorkGraph JSON',
|
|
23
|
+
};
|
|
24
|
+
const policy = {
|
|
25
|
+
name: '--policy',
|
|
26
|
+
value: 'path',
|
|
27
|
+
required: true,
|
|
28
|
+
description: 'ExecutionPolicy JSON',
|
|
29
|
+
};
|
|
30
|
+
const context = {
|
|
31
|
+
name: '--context',
|
|
32
|
+
value: 'path',
|
|
33
|
+
required: false,
|
|
34
|
+
description: 'ContextSnapshot JSON; без него — файловый ContextSource каталога графа',
|
|
35
|
+
};
|
|
36
|
+
const author = {
|
|
37
|
+
name: '--author',
|
|
38
|
+
value: 'id',
|
|
39
|
+
required: true,
|
|
40
|
+
description: 'Автор предложения: codex, claude, fixture или external (человек/инструмент вне harness); по нему применяется правило вендора',
|
|
41
|
+
};
|
|
42
|
+
const work = {
|
|
43
|
+
name: '--work',
|
|
44
|
+
value: 'id',
|
|
45
|
+
required: true,
|
|
46
|
+
description: 'ID поручения',
|
|
47
|
+
};
|
|
48
|
+
const source = {
|
|
49
|
+
name: '--source',
|
|
50
|
+
value: 'path',
|
|
51
|
+
required: true,
|
|
52
|
+
description: 'Конфигурация коннектора задач (provider relay-v1-http | relay-v2-cli)',
|
|
53
|
+
};
|
|
54
|
+
export const cliCommands = {
|
|
55
|
+
validate: {
|
|
56
|
+
description: 'Проверить граф, политику, их связь и (если задан) снимок контекста без вызова моделей и записи состояния',
|
|
57
|
+
writes: false,
|
|
58
|
+
idempotency: 'Чистая функция входов',
|
|
59
|
+
args: [graph, policy, context],
|
|
60
|
+
refusals: [],
|
|
61
|
+
},
|
|
62
|
+
'review-plan': {
|
|
63
|
+
description: 'Техническое ревью плана (графа) с конкретным digest; новый раунд сохраняет историю находок предмета',
|
|
64
|
+
writes: true,
|
|
65
|
+
idempotency: 'Повтор с тем же digest и тем же автором, уже согласованный последним раундом, возвращает этот раунд без вызова модели; иначе — новый раунд в пределах maxAttempts. Автор, не допускаемый правилом вендора, — REVIEWER_SAME_VENDOR до вызова модели',
|
|
66
|
+
args: [
|
|
67
|
+
state,
|
|
68
|
+
graph,
|
|
69
|
+
policy,
|
|
70
|
+
context,
|
|
71
|
+
author,
|
|
72
|
+
{
|
|
73
|
+
name: '--source',
|
|
74
|
+
value: 'path',
|
|
75
|
+
required: false,
|
|
76
|
+
description: 'Конфигурация коннектора задач: внешние предпосылки графа допускаются по решению источника (trusts) и доступности SHA в target ref; без неё доверенных receipt нет',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
refusals: [
|
|
80
|
+
'REVIEW_REJECTED',
|
|
81
|
+
'ATTEMPTS_EXHAUSTED',
|
|
82
|
+
'BUDGET_EXHAUSTED',
|
|
83
|
+
'BUDGET_UNKNOWN',
|
|
84
|
+
'NOT_READY',
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
'review-contract': {
|
|
88
|
+
description: 'Техническое ревью контракта с конкретным digest',
|
|
89
|
+
writes: true,
|
|
90
|
+
idempotency: 'Как review-plan, предмет — ID контракта',
|
|
91
|
+
args: [
|
|
92
|
+
state,
|
|
93
|
+
{ name: '--contract', value: 'path', required: true, description: 'ContractDocument JSON' },
|
|
94
|
+
policy,
|
|
95
|
+
author,
|
|
96
|
+
],
|
|
97
|
+
refusals: ['REVIEW_REJECTED', 'ATTEMPTS_EXHAUSTED', 'BUDGET_EXHAUSTED', 'BUDGET_UNKNOWN'],
|
|
98
|
+
},
|
|
99
|
+
approve: {
|
|
100
|
+
description: 'Согласование оператором (approvalMode: operator) конкретного digest графа или контракта, уже прошедшего ревью',
|
|
101
|
+
writes: true,
|
|
102
|
+
idempotency: 'Повтор для того же digest ничего не меняет',
|
|
103
|
+
args: [
|
|
104
|
+
state,
|
|
105
|
+
{
|
|
106
|
+
name: '--digest',
|
|
107
|
+
value: 'digest',
|
|
108
|
+
required: true,
|
|
109
|
+
description: 'Digest из ReviewRecord последнего раунда',
|
|
110
|
+
},
|
|
111
|
+
{ name: '--subject', value: 'id', required: true, description: 'ID графа или контракта' },
|
|
112
|
+
],
|
|
113
|
+
refusals: ['APPROVAL_STALE', 'APPROVAL_REQUIRED', 'REVIEW_REJECTED'],
|
|
114
|
+
},
|
|
115
|
+
run: {
|
|
116
|
+
description: 'Зарегистрировать согласованный граф (идемпотентно по connector, ref, revision, digest) и вести работу до простоя',
|
|
117
|
+
writes: true,
|
|
118
|
+
idempotency: 'Тот же граф той же редакции продолжает прежнюю работу; другой digest для той же редакции источника — REVISION_CONFLICT',
|
|
119
|
+
args: [
|
|
120
|
+
state,
|
|
121
|
+
{ ...graph, required: false, description: 'WorkGraph JSON; не нужен с --source' },
|
|
122
|
+
policy,
|
|
123
|
+
context,
|
|
124
|
+
{
|
|
125
|
+
name: '--source',
|
|
126
|
+
value: 'path',
|
|
127
|
+
required: false,
|
|
128
|
+
description: 'Конфигурация коннектора (relay-v1-http | relay-v2-cli): перед запуском задачи перечитываются, semantic digest сверяется с закреплённым снимком и eligibility — до любого вызова runtime; результат доставляется в исходную задачу',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: '--sink',
|
|
132
|
+
value: 'sink',
|
|
133
|
+
required: false,
|
|
134
|
+
description: 'Получатель результата, `file:<каталог>`',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: '--once',
|
|
138
|
+
value: 'flag',
|
|
139
|
+
required: false,
|
|
140
|
+
description: 'Один шаг очереди вместо работы до простоя',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: '--author',
|
|
144
|
+
value: 'id',
|
|
145
|
+
required: false,
|
|
146
|
+
description: 'Автор графа для ревью плана; по умолчанию external',
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
refusals: [
|
|
150
|
+
'APPROVAL_REQUIRED',
|
|
151
|
+
'APPROVAL_STALE',
|
|
152
|
+
'PAUSED',
|
|
153
|
+
'CONTROLLER_BUSY',
|
|
154
|
+
'REVISION_CONFLICT',
|
|
155
|
+
'GATE_FAILED',
|
|
156
|
+
'REVIEW_REJECTED',
|
|
157
|
+
'SCOPE_VIOLATION',
|
|
158
|
+
'BUDGET_EXHAUSTED',
|
|
159
|
+
'BUDGET_UNKNOWN',
|
|
160
|
+
'ATTEMPTS_EXHAUSTED',
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
status: {
|
|
164
|
+
description: 'Состояние очереди, графов и поручений с причинами блокировки',
|
|
165
|
+
writes: false,
|
|
166
|
+
idempotency: 'Только чтение',
|
|
167
|
+
args: [
|
|
168
|
+
state,
|
|
169
|
+
{ name: '--graph', value: 'id', required: false, description: 'Только этот граф' },
|
|
170
|
+
],
|
|
171
|
+
refusals: ['NOT_FOUND'],
|
|
172
|
+
},
|
|
173
|
+
events: {
|
|
174
|
+
description: 'События строго после номера, по возрастанию',
|
|
175
|
+
writes: false,
|
|
176
|
+
idempotency: 'Только чтение',
|
|
177
|
+
args: [
|
|
178
|
+
state,
|
|
179
|
+
{ name: '--after', value: 'number', required: false, description: 'Номер, по умолчанию 0' },
|
|
180
|
+
{ name: '--limit', value: 'number', required: false, description: '1–500, по умолчанию 100' },
|
|
181
|
+
],
|
|
182
|
+
refusals: ['NOT_FOUND'],
|
|
183
|
+
},
|
|
184
|
+
pause: {
|
|
185
|
+
description: 'Пауза оператора: новые claims запрещены, активные попытки продолжаются',
|
|
186
|
+
writes: true,
|
|
187
|
+
idempotency: 'Повтор ничего не меняет',
|
|
188
|
+
args: [state],
|
|
189
|
+
refusals: ['NOT_FOUND'],
|
|
190
|
+
},
|
|
191
|
+
resume: {
|
|
192
|
+
description: 'Снять паузу — решение человека: паузу оператора, штатной остановки и отказа runtime (с её классами отказов); паузу операции reconfigure не снимает',
|
|
193
|
+
writes: true,
|
|
194
|
+
idempotency: 'Повтор без паузы ничего не меняет',
|
|
195
|
+
args: [state],
|
|
196
|
+
refusals: ['NOT_FOUND', 'PAUSED'],
|
|
197
|
+
},
|
|
198
|
+
cancel: {
|
|
199
|
+
description: 'Отменить поручение: активная попытка теряет владение, поручение становится cancelled; это не retry',
|
|
200
|
+
writes: true,
|
|
201
|
+
idempotency: 'Повтор для отменённого ничего не меняет',
|
|
202
|
+
args: [
|
|
203
|
+
state,
|
|
204
|
+
work,
|
|
205
|
+
{ name: '--reason', value: 'text', required: false, description: 'Причина' },
|
|
206
|
+
],
|
|
207
|
+
refusals: ['NOT_FOUND'],
|
|
208
|
+
},
|
|
209
|
+
retry: {
|
|
210
|
+
description: 'Новая попытка неуспешного (failed) поручения в пределах maxAttempts и бюджета; --reset сбрасывает счётчик попыток с причиной, учёт расходов не сбрасывается',
|
|
211
|
+
writes: true,
|
|
212
|
+
idempotency: 'Повтор для уже готового к выдаче поручения ничего не меняет',
|
|
213
|
+
args: [
|
|
214
|
+
state,
|
|
215
|
+
work,
|
|
216
|
+
{
|
|
217
|
+
name: '--reset',
|
|
218
|
+
value: 'flag',
|
|
219
|
+
required: false,
|
|
220
|
+
description: 'Сбросить счётчик попыток; требует --reason',
|
|
221
|
+
},
|
|
222
|
+
{ name: '--reason', value: 'text', required: false, description: 'Причина сброса' },
|
|
223
|
+
],
|
|
224
|
+
refusals: ['NOT_FOUND', 'ATTEMPTS_EXHAUSTED', 'BUDGET_EXHAUSTED', 'BUDGET_UNKNOWN'],
|
|
225
|
+
},
|
|
226
|
+
result: {
|
|
227
|
+
description: 'Машинный результат последней завершённой попытки поручения и состояние доставки',
|
|
228
|
+
writes: false,
|
|
229
|
+
idempotency: 'Только чтение',
|
|
230
|
+
args: [state, work],
|
|
231
|
+
refusals: ['NOT_FOUND'],
|
|
232
|
+
},
|
|
233
|
+
deliver: {
|
|
234
|
+
description: 'Повторить доставку результата получателю с тем же ключом; модели, gates и интеграция не вызываются',
|
|
235
|
+
writes: true,
|
|
236
|
+
idempotency: 'Доставленный результат повторно не доставляется',
|
|
237
|
+
args: [
|
|
238
|
+
state,
|
|
239
|
+
work,
|
|
240
|
+
{
|
|
241
|
+
name: '--sink',
|
|
242
|
+
value: 'sink',
|
|
243
|
+
required: true,
|
|
244
|
+
description: 'Получатель, `file:<каталог>`',
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
refusals: ['NOT_FOUND', 'REVISION_CONFLICT'],
|
|
248
|
+
},
|
|
249
|
+
cleanup: {
|
|
250
|
+
description: 'Довести незавершённую очистку закончившейся попытки: повторить teardown по сохранённым receipt окружений и убрать её рабочие деревья; модели, gates и Git-приёмка не вызываются',
|
|
251
|
+
writes: true,
|
|
252
|
+
idempotency: 'Повтор после успешной очистки отвечает nothing-pending и ничего не меняет',
|
|
253
|
+
args: [
|
|
254
|
+
state,
|
|
255
|
+
{ name: '--run', value: 'id', required: true, description: 'ID попытки (runId)' },
|
|
256
|
+
],
|
|
257
|
+
refusals: ['NOT_FOUND', 'NOT_READY'],
|
|
258
|
+
},
|
|
259
|
+
profile: {
|
|
260
|
+
description: 'Разрешить профиль стека (встроенный ID или ./file.json репозитория): слои, gates, закрепление; только чтение манифестов, без команд проекта',
|
|
261
|
+
writes: false,
|
|
262
|
+
idempotency: 'Чистая функция файлов профиля',
|
|
263
|
+
args: [
|
|
264
|
+
{
|
|
265
|
+
name: '--profile',
|
|
266
|
+
value: 'text',
|
|
267
|
+
required: true,
|
|
268
|
+
description: 'Встроенный ID профиля или относительный ./file.json',
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: '--repository',
|
|
272
|
+
value: 'dir',
|
|
273
|
+
required: false,
|
|
274
|
+
description: 'Корень репозитория для локального профиля',
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
refusals: [],
|
|
278
|
+
},
|
|
279
|
+
doctor: {
|
|
280
|
+
description: 'Версии, наличие runtime и их capabilities, OS-sandbox, совместимость каталога состояния; без live-вызова модели',
|
|
281
|
+
writes: false,
|
|
282
|
+
idempotency: 'Только чтение',
|
|
283
|
+
args: [
|
|
284
|
+
{ ...state, required: false },
|
|
285
|
+
{ ...policy, required: false },
|
|
286
|
+
],
|
|
287
|
+
refusals: [],
|
|
288
|
+
},
|
|
289
|
+
'source-check': {
|
|
290
|
+
description: 'Коннектор задач: подключение, идентичность и capabilities backend, совпадение проекта, проверка mapping; без мутаций, записи истории и создания состояния',
|
|
291
|
+
writes: false,
|
|
292
|
+
idempotency: 'Только чтение получателя',
|
|
293
|
+
args: [
|
|
294
|
+
source,
|
|
295
|
+
{ ...state, required: false },
|
|
296
|
+
{
|
|
297
|
+
...policy,
|
|
298
|
+
required: false,
|
|
299
|
+
description: 'ExecutionPolicy JSON для сверки gates/ролей mapping',
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
refusals: ['NOT_READY'],
|
|
303
|
+
},
|
|
304
|
+
'source-snapshot': {
|
|
305
|
+
description: 'Коннектор задач: согласованное чтение задач, предпросмотр и закрепление снимка (graph/context/manifest) для review-plan и approve',
|
|
306
|
+
writes: true,
|
|
307
|
+
idempotency: 'Неизменная постановка — тот же semantic digest, тот же граф и контекст; новых записей у получателя нет',
|
|
308
|
+
args: [
|
|
309
|
+
source,
|
|
310
|
+
state,
|
|
311
|
+
{
|
|
312
|
+
...policy,
|
|
313
|
+
required: false,
|
|
314
|
+
description: 'ExecutionPolicy JSON: её секреты маскируются в диагностике',
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
name: '--out',
|
|
318
|
+
value: 'dir',
|
|
319
|
+
required: false,
|
|
320
|
+
description: 'Каталог graph.json, context.json, manifest.json',
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
refusals: ['NOT_READY'],
|
|
324
|
+
},
|
|
325
|
+
'source-status': {
|
|
326
|
+
description: 'Коннектор задач: локально принято / доставлено / конфликт / неизвестный исход и независимое чтение получателя',
|
|
327
|
+
writes: false,
|
|
328
|
+
idempotency: 'Только чтение',
|
|
329
|
+
args: [source, state],
|
|
330
|
+
refusals: ['NOT_FOUND'],
|
|
331
|
+
},
|
|
332
|
+
'source-deliver': {
|
|
333
|
+
description: 'Коннектор задач: доставить или продолжить доставку принятых результатов с тем же ключом операции; модели, gates и Git не вызываются',
|
|
334
|
+
writes: true,
|
|
335
|
+
idempotency: 'Подтверждённая доставка не повторяется; неизвестный исход не отправляется повторно до source-reconcile',
|
|
336
|
+
args: [
|
|
337
|
+
source,
|
|
338
|
+
state,
|
|
339
|
+
{ ...work, required: false, description: 'ID поручения; без него — все с результатом' },
|
|
340
|
+
],
|
|
341
|
+
refusals: ['NOT_FOUND', 'CONTROLLER_BUSY', 'REVISION_CONFLICT'],
|
|
342
|
+
},
|
|
343
|
+
'source-reconcile': {
|
|
344
|
+
description: 'Коннектор задач: разобрать неизвестный исход или конфликт операции доставки по фактам получателя; неоднозначность — только явным решением',
|
|
345
|
+
writes: true,
|
|
346
|
+
idempotency: 'Разобранная операция не меняется; мутаций без решения и фактов нет',
|
|
347
|
+
args: [
|
|
348
|
+
source,
|
|
349
|
+
state,
|
|
350
|
+
{
|
|
351
|
+
name: '--operation',
|
|
352
|
+
value: 'digest',
|
|
353
|
+
required: true,
|
|
354
|
+
description: 'Ключ операции из source-status',
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
name: '--decision',
|
|
358
|
+
value: 'text',
|
|
359
|
+
required: false,
|
|
360
|
+
description: 'resend (записи у получателя нет), adopt:<id> (одна из нескольких записей с маркером), recheck (CAS-конфликт без изменения постановки)',
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
refusals: ['NOT_FOUND', 'CONTROLLER_BUSY'],
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
/* ------------------------------------------------------------------ */
|
|
367
|
+
/* Данные ответов */
|
|
368
|
+
/* ------------------------------------------------------------------ */
|
|
369
|
+
const blocker = z.strictObject({
|
|
370
|
+
code: z.enum(Object.keys(errorCodes)),
|
|
371
|
+
message: z.string().max(4000),
|
|
372
|
+
});
|
|
373
|
+
export const validateDataSchema = z.strictObject({
|
|
374
|
+
graphId: idSchema,
|
|
375
|
+
graphDigest: digestSchema,
|
|
376
|
+
policyDigest: digestSchema,
|
|
377
|
+
contextDigest: digestSchema.optional(),
|
|
378
|
+
orders: z.number().int().positive(),
|
|
379
|
+
});
|
|
380
|
+
export const statusDataSchema = z.strictObject({
|
|
381
|
+
stateVersion: z.literal(STATE_VERSION),
|
|
382
|
+
control: controlStateSchema,
|
|
383
|
+
controller: controllerLeaseSchema.optional(),
|
|
384
|
+
graphs: z.array(z.strictObject({
|
|
385
|
+
id: idSchema,
|
|
386
|
+
digest: digestSchema,
|
|
387
|
+
source: sourceRefSchema,
|
|
388
|
+
approved: z.boolean(),
|
|
389
|
+
})),
|
|
390
|
+
works: z.array(z.strictObject({
|
|
391
|
+
id: idSchema,
|
|
392
|
+
graphId: idSchema,
|
|
393
|
+
status: workStatusSchema,
|
|
394
|
+
attempt: z.number().int().min(0),
|
|
395
|
+
activeRunId: z.string().optional(),
|
|
396
|
+
resultSha: gitShaSchema.optional(),
|
|
397
|
+
/** Почему поручение сейчас не выдаётся; пусто — может быть выдано. */
|
|
398
|
+
blockers: z.array(blocker),
|
|
399
|
+
})),
|
|
400
|
+
/**
|
|
401
|
+
* Бюджеты по сохранённым записям вызовов: общий, групп с незавершённой
|
|
402
|
+
* работой и незавершённых поручений. Нет поля — бюджеты не заданы.
|
|
403
|
+
* `remainingUsd`/`remainingMs` — `null`, когда расход не известен полностью.
|
|
404
|
+
*/
|
|
405
|
+
budgets: z
|
|
406
|
+
.strictObject({
|
|
407
|
+
onUnknown: z.enum(['stop', 'continue']),
|
|
408
|
+
budgets: z.array(z.strictObject({
|
|
409
|
+
scope: z.strictObject({
|
|
410
|
+
kind: z.enum(['work', 'group', 'total']),
|
|
411
|
+
id: z.string().max(200).optional(),
|
|
412
|
+
}),
|
|
413
|
+
state: z.enum(['within', 'exceeded', 'undetermined']),
|
|
414
|
+
limit: z.strictObject({
|
|
415
|
+
usd: z.number().positive().optional(),
|
|
416
|
+
timeMs: z.number().int().positive().optional(),
|
|
417
|
+
}),
|
|
418
|
+
reportedUsd: z.number().min(0),
|
|
419
|
+
estimatedUsd: z.number().min(0),
|
|
420
|
+
unknownCalls: z.number().int().min(0),
|
|
421
|
+
unfinishedCalls: z.number().int().min(0),
|
|
422
|
+
abandonedCalls: z.number().int().min(0),
|
|
423
|
+
errorCalls: z.number().int().min(0),
|
|
424
|
+
uncoveredRuns: z.number().int().min(0),
|
|
425
|
+
durationMs: z.number().min(0),
|
|
426
|
+
remainingUsd: z.number().min(0).nullable(),
|
|
427
|
+
remainingMs: z.number().min(0).nullable(),
|
|
428
|
+
reason: z.string().optional(),
|
|
429
|
+
})),
|
|
430
|
+
})
|
|
431
|
+
.optional(),
|
|
432
|
+
});
|
|
433
|
+
export const eventsDataSchema = z.strictObject({
|
|
434
|
+
events: z.array(runEventSchema),
|
|
435
|
+
/** Номер для следующего `--after`. */
|
|
436
|
+
next: z.number().int().min(0),
|
|
437
|
+
});
|
|
438
|
+
export const runDataSchema = z.strictObject({
|
|
439
|
+
graphId: idSchema,
|
|
440
|
+
digest: digestSchema,
|
|
441
|
+
/** Граф уже был зарегистрирован этой редакцией: работа продолжена. */
|
|
442
|
+
resumed: z.boolean(),
|
|
443
|
+
works: z.array(z.strictObject({
|
|
444
|
+
id: idSchema,
|
|
445
|
+
status: workStatusSchema,
|
|
446
|
+
runId: z.string().optional(),
|
|
447
|
+
resultSha: gitShaSchema.optional(),
|
|
448
|
+
blockers: z.array(blocker),
|
|
449
|
+
})),
|
|
450
|
+
/**
|
|
451
|
+
* Задание технической очереди графа (режим agent): сохранённая стадия,
|
|
452
|
+
* статус, использованные восстановления и причина остановки.
|
|
453
|
+
*/
|
|
454
|
+
workflow: z
|
|
455
|
+
.strictObject({
|
|
456
|
+
key: digestSchema,
|
|
457
|
+
kind: idSchema,
|
|
458
|
+
id: idSchema,
|
|
459
|
+
stage: z.number().int().min(0),
|
|
460
|
+
status: z.enum(['queued', 'running', 'failed', 'stale', 'completed']),
|
|
461
|
+
attempts: z.number().int().min(0),
|
|
462
|
+
repairs: z.number().int().min(0),
|
|
463
|
+
repairBudget: z.number().int().min(0),
|
|
464
|
+
error: z.string().optional(),
|
|
465
|
+
history: z.array(z.strictObject({ at: isoTimeSchema, stage: z.number().int().min(0), event: z.string() })),
|
|
466
|
+
})
|
|
467
|
+
.optional(),
|
|
468
|
+
});
|
|
469
|
+
export const controlDataSchema = z.strictObject({
|
|
470
|
+
control: controlStateSchema,
|
|
471
|
+
changed: z.boolean(),
|
|
472
|
+
});
|
|
473
|
+
export const workActionDataSchema = z.strictObject({
|
|
474
|
+
workId: idSchema,
|
|
475
|
+
status: workStatusSchema,
|
|
476
|
+
attempt: z.number().int().min(0),
|
|
477
|
+
changed: z.boolean(),
|
|
478
|
+
});
|
|
479
|
+
export const approveDataSchema = z.strictObject({
|
|
480
|
+
subject: idSchema,
|
|
481
|
+
digest: digestSchema,
|
|
482
|
+
at: isoTimeSchema,
|
|
483
|
+
changed: z.boolean(),
|
|
484
|
+
});
|
|
485
|
+
export const doctorDataSchema = z.strictObject({
|
|
486
|
+
harness: z.string(),
|
|
487
|
+
apiVersion: z.literal(API_VERSION),
|
|
488
|
+
node: z.string(),
|
|
489
|
+
platform: z.string(),
|
|
490
|
+
runtimes: z.array(z.strictObject({
|
|
491
|
+
runtime: runtimeNameSchema,
|
|
492
|
+
available: z.boolean(),
|
|
493
|
+
version: z.string().optional(),
|
|
494
|
+
structuredOutput: z.boolean(),
|
|
495
|
+
cancellation: z.boolean(),
|
|
496
|
+
reason: z.string().optional(),
|
|
497
|
+
})),
|
|
498
|
+
sandbox: z.strictObject({ os: z.boolean(), reason: z.string().optional() }),
|
|
499
|
+
state: z
|
|
500
|
+
.strictObject({
|
|
501
|
+
stateVersion: z.number().int(),
|
|
502
|
+
compatible: z.boolean(),
|
|
503
|
+
writer: z.string().optional(),
|
|
504
|
+
engineVersions: z
|
|
505
|
+
.strictObject({ controller: z.string().optional(), attempts: z.array(z.string()) })
|
|
506
|
+
.optional(),
|
|
507
|
+
})
|
|
508
|
+
.optional(),
|
|
509
|
+
/** Диагностика toolchain репозиториев политики; есть, когда задана политика. */
|
|
510
|
+
toolchains: z.array(toolchainReportSchema).optional(),
|
|
511
|
+
problems: z.array(z.string()),
|
|
512
|
+
});
|
|
513
|
+
export const profileDataSchema = z.strictObject({
|
|
514
|
+
pin: profilePinSchema,
|
|
515
|
+
profile: resolvedProfileSchema,
|
|
516
|
+
});
|
|
517
|
+
export const versionDataSchema = z.strictObject({
|
|
518
|
+
harness: z.string(),
|
|
519
|
+
apiVersion: z.literal(API_VERSION),
|
|
520
|
+
});
|
|
521
|
+
const providerSchema = z.enum(['relay-v1-http', 'relay-v2-cli']);
|
|
522
|
+
const ownershipSchema = z.strictObject({
|
|
523
|
+
stateDir: z.string(),
|
|
524
|
+
store: z.string(),
|
|
525
|
+
note: z.string(),
|
|
526
|
+
});
|
|
527
|
+
export const sourceCheckDataSchema = z.strictObject({
|
|
528
|
+
provider: providerSchema,
|
|
529
|
+
projectId: z.string(),
|
|
530
|
+
connector: idSchema,
|
|
531
|
+
connected: z.boolean(),
|
|
532
|
+
projectMatches: z.boolean(),
|
|
533
|
+
identity: z
|
|
534
|
+
.strictObject({ capabilities: z.array(z.string()), build: z.record(z.string(), z.string()) })
|
|
535
|
+
.optional(),
|
|
536
|
+
history: z.strictObject({ enabled: z.boolean(), capability: z.boolean() }),
|
|
537
|
+
mapping: z.array(z.strictObject({ ref: z.string(), key: z.string().optional(), problems: z.array(z.string()) })),
|
|
538
|
+
ownership: ownershipSchema,
|
|
539
|
+
problems: z.array(z.string()),
|
|
540
|
+
});
|
|
541
|
+
export const sourceSnapshotDataSchema = z.strictObject({
|
|
542
|
+
connector: idSchema,
|
|
543
|
+
graphId: idSchema,
|
|
544
|
+
graphDigest: digestSchema,
|
|
545
|
+
contextDigest: digestSchema,
|
|
546
|
+
/** Semantic digest набора задач (`graph.source.revision`); не Git SHA. */
|
|
547
|
+
revision: digestSchema,
|
|
548
|
+
created: z.boolean(),
|
|
549
|
+
eligible: z.boolean(),
|
|
550
|
+
problems: z.array(z.string()),
|
|
551
|
+
truncated: z.array(z.string()),
|
|
552
|
+
tasks: z.array(z.strictObject({
|
|
553
|
+
identity: z.string(),
|
|
554
|
+
key: z.string(),
|
|
555
|
+
orderId: idSchema,
|
|
556
|
+
semanticDigest: digestSchema,
|
|
557
|
+
casRevision: z.number().int(),
|
|
558
|
+
column: z.string(),
|
|
559
|
+
})),
|
|
560
|
+
files: z.strictObject({ graph: z.string(), context: z.string(), manifest: z.string() }),
|
|
561
|
+
});
|
|
562
|
+
const operationViewSchema = z.strictObject({
|
|
563
|
+
key: digestSchema,
|
|
564
|
+
runId: z.string(),
|
|
565
|
+
outcome: z.string(),
|
|
566
|
+
status: z.enum(['intent', 'in-progress', 'delivered', 'conflict', 'uncertain', 'failed']),
|
|
567
|
+
reason: z.string().optional(),
|
|
568
|
+
currentRevision: z.string().optional(),
|
|
569
|
+
steps: z.array(z.strictObject({
|
|
570
|
+
n: z.number().int(),
|
|
571
|
+
kind: z.string(),
|
|
572
|
+
status: z.string(),
|
|
573
|
+
marker: z.string(),
|
|
574
|
+
})),
|
|
575
|
+
lease: z.strictObject({ owner: z.string(), expiresAt: isoTimeSchema }).optional(),
|
|
576
|
+
});
|
|
577
|
+
export const sourceStatusDataSchema = z.strictObject({
|
|
578
|
+
connector: idSchema,
|
|
579
|
+
provider: providerSchema,
|
|
580
|
+
projectId: z.string(),
|
|
581
|
+
snapshot: z.strictObject({ revision: digestSchema, graphId: idSchema }).optional(),
|
|
582
|
+
ownership: ownershipSchema,
|
|
583
|
+
tasks: z.array(z.strictObject({
|
|
584
|
+
index: z.number().int(),
|
|
585
|
+
ref: z.string(),
|
|
586
|
+
key: z.string().optional(),
|
|
587
|
+
identity: z.string().optional(),
|
|
588
|
+
workId: idSchema,
|
|
589
|
+
local: z.strictObject({
|
|
590
|
+
status: z.string(),
|
|
591
|
+
attempt: z.number().int().optional(),
|
|
592
|
+
resultSha: gitShaSchema.optional(),
|
|
593
|
+
}),
|
|
594
|
+
deliveries: z.array(z.strictObject({ status: z.string(), key: z.string(), operation: z.string().optional() })),
|
|
595
|
+
operations: z.array(operationViewSchema),
|
|
596
|
+
remote: z.union([
|
|
597
|
+
z.strictObject({
|
|
598
|
+
reachable: z.literal(true),
|
|
599
|
+
column: z.string(),
|
|
600
|
+
casRevision: z.number().int(),
|
|
601
|
+
semanticDigest: digestSchema,
|
|
602
|
+
matchesSnapshot: z.boolean(),
|
|
603
|
+
criteria: z.array(z.strictObject({ id: z.string(), title: z.string(), completed: z.boolean() })),
|
|
604
|
+
markers: z.record(z.string(), z.number().int()),
|
|
605
|
+
}),
|
|
606
|
+
z.strictObject({ reachable: z.literal(false), error: z.string() }),
|
|
607
|
+
]),
|
|
608
|
+
})),
|
|
609
|
+
});
|
|
610
|
+
export const sourceDeliverDataSchema = z.strictObject({
|
|
611
|
+
connector: idSchema,
|
|
612
|
+
deliveries: z.array(z.strictObject({
|
|
613
|
+
workId: idSchema,
|
|
614
|
+
outcome: z.string(),
|
|
615
|
+
delivery: z.array(deliveryStateSchema),
|
|
616
|
+
})),
|
|
617
|
+
});
|
|
618
|
+
export const sourceReconcileDataSchema = z.strictObject({
|
|
619
|
+
operation: digestSchema,
|
|
620
|
+
workId: idSchema,
|
|
621
|
+
before: z.string(),
|
|
622
|
+
after: z.string(),
|
|
623
|
+
resolved: z.boolean(),
|
|
624
|
+
facts: z.array(z.string()),
|
|
625
|
+
delivery: z.array(deliveryStateSchema).optional(),
|
|
626
|
+
});
|
|
627
|
+
export const cleanupDataSchema = z.discriminatedUnion('status', [
|
|
628
|
+
z.strictObject({ status: z.literal('nothing-pending') }),
|
|
629
|
+
/** Очищено: receipts окружений, по которым повторён teardown. */
|
|
630
|
+
z.strictObject({ status: z.literal('cleaned'), receipts: z.array(z.string()) }),
|
|
631
|
+
]);
|
|
632
|
+
/** Схема `data` каждой команды. */
|
|
633
|
+
export const cliDataSchemas = {
|
|
634
|
+
validate: validateDataSchema,
|
|
635
|
+
'review-plan': reviewRecordSchema,
|
|
636
|
+
'review-contract': reviewRecordSchema,
|
|
637
|
+
approve: approveDataSchema,
|
|
638
|
+
run: runDataSchema,
|
|
639
|
+
status: statusDataSchema,
|
|
640
|
+
events: eventsDataSchema,
|
|
641
|
+
pause: controlDataSchema,
|
|
642
|
+
resume: controlDataSchema,
|
|
643
|
+
cancel: workActionDataSchema,
|
|
644
|
+
retry: workActionDataSchema,
|
|
645
|
+
result: resultEnvelopeSchema,
|
|
646
|
+
deliver: resultEnvelopeSchema,
|
|
647
|
+
cleanup: cleanupDataSchema,
|
|
648
|
+
profile: profileDataSchema,
|
|
649
|
+
doctor: doctorDataSchema,
|
|
650
|
+
'source-check': sourceCheckDataSchema,
|
|
651
|
+
'source-snapshot': sourceSnapshotDataSchema,
|
|
652
|
+
'source-status': sourceStatusDataSchema,
|
|
653
|
+
'source-deliver': sourceDeliverDataSchema,
|
|
654
|
+
'source-reconcile': sourceReconcileDataSchema,
|
|
655
|
+
version: versionDataSchema,
|
|
656
|
+
};
|
|
657
|
+
export const cliErrorSchema = z.strictObject({
|
|
658
|
+
code: z.enum(Object.keys(errorCodes)),
|
|
659
|
+
class: z.enum(['input', 'refused', 'infrastructure']),
|
|
660
|
+
message: z.string(),
|
|
661
|
+
issues: z.array(z.strictObject({ path: z.array(z.union([z.string(), z.number()])), message: z.string() })),
|
|
662
|
+
});
|
|
663
|
+
/** Входной документ контракта для `review-contract` — см. `checks.ts`. */
|
|
664
|
+
export { contractDocumentSchema } from "./checks.js";
|