devcontour-harness 0.0.0-stage → 0.1.0-alpha.12
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 +268 -2
- package/docs/architecture.md +496 -0
- package/docs/compatibility-versions.md +60 -0
- package/docs/compatibility.md +192 -0
- package/docs/connectors.md +323 -0
- package/docs/contracts.md +630 -0
- package/docs/integrations/hindsight.md +148 -0
- package/docs/quickstart.md +185 -0
- package/docs/release-notes/0.1.0-alpha.10.md +50 -0
- package/docs/release-notes/0.1.0-alpha.11.md +44 -0
- package/docs/release-notes/0.1.0-alpha.12.md +66 -0
- package/docs/release-notes/0.1.0-alpha.6.md +238 -0
- package/docs/release-notes/0.1.0-alpha.7.md +71 -0
- package/docs/release-notes/0.1.0-alpha.8.md +73 -0
- package/docs/release-notes/0.1.0-alpha.9.md +55 -0
- package/docs/review-probes.md +199 -0
- package/docs/review-protocol.md +251 -0
- package/docs/standalone.md +271 -0
- package/docs/toolchains.md +167 -0
- package/docs/turbo-starter.md +269 -0
- package/docs/upgrade.md +219 -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 +393 -0
- package/lib/agents/inspect.d.ts +60 -0
- package/lib/agents/inspect.js +296 -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 +345 -0
- package/lib/agents/review-probe.js +1037 -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/catalog/bytes.d.ts +9 -0
- package/lib/catalog/bytes.js +14 -0
- package/lib/catalog/harness.d.ts +3 -0
- package/lib/catalog/harness.js +11 -0
- package/lib/catalog/index.d.ts +5 -0
- package/lib/catalog/index.js +5 -0
- package/lib/catalog/operations.d.ts +24 -0
- package/lib/catalog/operations.js +74 -0
- package/lib/catalog/page.d.ts +46 -0
- package/lib/catalog/page.js +128 -0
- package/lib/catalog/shared.d.ts +37 -0
- package/lib/catalog/shared.js +67 -0
- package/lib/cli.d.ts +2 -0
- package/lib/cli.js +673 -0
- package/lib/connectors/files.d.ts +108 -0
- package/lib/connectors/files.js +133 -0
- package/lib/contracts/catalog.d.ts +31 -0
- package/lib/contracts/catalog.js +18 -0
- package/lib/contracts/checks.d.ts +307 -0
- package/lib/contracts/checks.js +181 -0
- package/lib/contracts/cli.d.ts +4665 -0
- package/lib/contracts/cli.js +840 -0
- package/lib/contracts/context.d.ts +135 -0
- package/lib/contracts/context.js +129 -0
- package/lib/contracts/diagnosis.d.ts +108 -0
- package/lib/contracts/diagnosis.js +69 -0
- package/lib/contracts/digest.d.ts +9 -0
- package/lib/contracts/digest.js +22 -0
- package/lib/contracts/errors.d.ts +89 -0
- package/lib/contracts/errors.js +74 -0
- package/lib/contracts/events.d.ts +827 -0
- package/lib/contracts/events.js +258 -0
- package/lib/contracts/execution.d.ts +3423 -0
- package/lib/contracts/execution.js +936 -0
- package/lib/contracts/failure.d.ts +38 -0
- package/lib/contracts/failure.js +53 -0
- package/lib/contracts/index.d.ts +22 -0
- package/lib/contracts/index.js +22 -0
- package/lib/contracts/planning.d.ts +433 -0
- package/lib/contracts/planning.js +159 -0
- package/lib/contracts/policy.d.ts +1075 -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 +340 -0
- package/lib/contracts/profiles.js +109 -0
- package/lib/contracts/project.d.ts +69 -0
- package/lib/contracts/project.js +47 -0
- package/lib/contracts/published.d.ts +3467 -0
- package/lib/contracts/published.js +40 -0
- package/lib/contracts/repair-policy.d.ts +31 -0
- package/lib/contracts/repair-policy.js +77 -0
- package/lib/contracts/result.d.ts +1284 -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 +171 -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 +182 -0
- package/lib/control/workflow.d.ts +256 -0
- package/lib/control/workflow.js +277 -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 +41 -0
- package/lib/engine/engine.d.ts +1564 -0
- package/lib/engine/engine.js +2283 -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 +194 -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 +1844 -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 +40 -0
- package/lib/environment/process.js +375 -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/explain/diagnose.d.ts +25 -0
- package/lib/explain/diagnose.js +60 -0
- package/lib/explain/state.d.ts +18 -0
- package/lib/explain/state.js +305 -0
- package/lib/index.d.ts +72 -0
- package/lib/index.js +74 -0
- package/lib/init/policy.d.ts +40 -0
- package/lib/init/policy.js +73 -0
- package/lib/init/project.d.ts +52 -0
- package/lib/init/project.js +412 -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/planning/check.d.ts +26 -0
- package/lib/planning/check.js +174 -0
- package/lib/planning/facts.d.ts +13 -0
- package/lib/planning/facts.js +47 -0
- package/lib/planning/graph.d.ts +20 -0
- package/lib/planning/graph.js +114 -0
- package/lib/planning/index.d.ts +6 -0
- package/lib/planning/index.js +6 -0
- package/lib/planning/issues.d.ts +19 -0
- package/lib/planning/issues.js +210 -0
- package/lib/planning/request.d.ts +19 -0
- package/lib/planning/request.js +57 -0
- package/lib/planning/standalone.d.ts +16 -0
- package/lib/planning/standalone.js +19 -0
- package/lib/planning/stub.d.ts +2 -0
- package/lib/planning/stub.js +5 -0
- package/lib/profiles/resolve.d.ts +266 -0
- package/lib/profiles/resolve.js +322 -0
- package/lib/projections/chain.d.ts +35 -0
- package/lib/projections/chain.js +72 -0
- package/lib/projections/clip.d.ts +6 -0
- package/lib/projections/clip.js +23 -0
- package/lib/projections/enums.d.ts +7 -0
- package/lib/projections/enums.js +19 -0
- package/lib/projections/index.d.ts +8 -0
- package/lib/projections/index.js +9 -0
- package/lib/projections/next.d.ts +28 -0
- package/lib/projections/next.js +75 -0
- package/lib/projections/progress.d.ts +27 -0
- package/lib/projections/progress.js +37 -0
- package/lib/projections/queue.d.ts +21 -0
- package/lib/projections/queue.js +18 -0
- package/lib/projections/stop.d.ts +98 -0
- package/lib/projections/stop.js +532 -0
- package/lib/setup/files.d.ts +45 -0
- package/lib/setup/files.js +280 -0
- package/lib/storage/document.d.ts +1286 -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 +37 -0
- package/lib/validate.js +182 -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 +182 -0
- package/lib/verification/gates.js +641 -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 +104 -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 +3881 -0
- package/schemas/execution-policy.schema.json +2196 -0
- package/schemas/joint-verification.schema.json +617 -0
- package/schemas/plan-draft.schema.json +217 -0
- package/schemas/project-manifest.schema.json +167 -0
- package/schemas/result-envelope.schema.json +1654 -0
- package/schemas/review-record.schema.json +177 -0
- package/schemas/run-event.schema.json +2458 -0
- package/schemas/run-result.schema.json +1572 -0
- package/schemas/stack-profile.schema.json +535 -0
- package/schemas/stop-diagnosis.schema.json +169 -0
- package/schemas/work-graph.schema.json +381 -0
- package/schemas/work-order.schema.json +256 -0
- package/skills/harness/SKILL.md +247 -0
- package/skills/harness-setup/SKILL.md +356 -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/plan-draft.json +35 -0
- package/templates/policy.json +28 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
# Архитектура devcontour-harness
|
|
2
|
+
|
|
3
|
+
Harness — headless-движок исполнения инженерных поручений. Он получает
|
|
4
|
+
согласованный граф поручений, выдаёт попытки исполнителю в изолированном
|
|
5
|
+
worktree, прогоняет обязательные проверки, получает независимое ревью,
|
|
6
|
+
интегрирует результат с текущей принятой веткой, повторяет проверки и ревью на
|
|
7
|
+
integration SHA и продвигает целевую ветку только compare-and-swap. Итог —
|
|
8
|
+
машинный результат с SHA, доказательствами и ограничениями.
|
|
9
|
+
|
|
10
|
+
Harness не хранит продуктовых задач, памяти, досок или релизов и не содержит
|
|
11
|
+
UI. Он используется двумя способами одного и того же движка:
|
|
12
|
+
|
|
13
|
+
1. **Самостоятельно** — библиотека или CLI, файловое поручение и контекст,
|
|
14
|
+
локальное состояние запусков, результат в JSON. Агент пользователя
|
|
15
|
+
подготавливает проект (`init`), составляет план (`plan-request`,
|
|
16
|
+
`plan-check`) и объясняет остановки (`explain`) без ручных служебных JSON.
|
|
17
|
+
2. **Внутри хоста** (например, DevContour) — хост подключает свои адаптеры
|
|
18
|
+
хранения, источника поручений и получателя результата; правила исполнения и
|
|
19
|
+
технической приёмки остаются в пакете.
|
|
20
|
+
|
|
21
|
+
## Процесс
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
Постановка и закреплённый контекст
|
|
25
|
+
|
|
|
26
|
+
v
|
|
27
|
+
План / контракты -> отдельное техническое ревью (digest)
|
|
28
|
+
|
|
|
29
|
+
v
|
|
30
|
+
Согласованный граф -> claim -> реализация в worktree
|
|
31
|
+
|
|
|
32
|
+
v
|
|
33
|
+
Candidate SHA -> обязательные gates -> независимое ревью
|
|
34
|
+
|
|
|
35
|
+
v
|
|
36
|
+
Интеграция с текущей принятой веткой
|
|
37
|
+
|
|
|
38
|
+
v
|
|
39
|
+
Integration SHA -> gates и потребители -> независимое ревью
|
|
40
|
+
|
|
|
41
|
+
v
|
|
42
|
+
Проверка владения, входов и evidence -> CAS target ref -> принятие
|
|
43
|
+
|
|
|
44
|
+
v
|
|
45
|
+
RunResult (SHA, evidence, ограничения) -> ResultSink
|
|
46
|
+
|
|
47
|
+
Замечания -> ограниченная следующая попытка
|
|
48
|
+
Неустранимый отказ / лимит / отмена -> остановка с причиной
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Модули
|
|
52
|
+
|
|
53
|
+
| Модуль | Ответственность |
|
|
54
|
+
| -------------- | ------------------------------------------------------------------------------------- |
|
|
55
|
+
| `contracts` | Версионируемые входы/выходы, схемы, коды ошибок, события, описания портов |
|
|
56
|
+
| `engine` | Переходы исполнения, DAG, владение, техническое согласование и приёмка, повторы |
|
|
57
|
+
| `agents` | Адаптеры Codex/Claude, роли, свежие сессии, выбор reviewer, нормализация ответов |
|
|
58
|
+
| `environment` | Подготовка среды, снимки зависимостей, sandbox, инструменты, ресурсы, cleanup |
|
|
59
|
+
| `verification` | Gates, ревью и probes, evidence, корпус, свойства, совместная проверка |
|
|
60
|
+
| `storage` | Транзакционный порт `ExecutionStore` и самостоятельная SQLite-реализация |
|
|
61
|
+
| `connectors` | `WorkSource`, `ContextSource`, `ResultSink`; встроенные файловые реализации |
|
|
62
|
+
| `control` | Команды и чтение состояния/событий для библиотеки и CLI |
|
|
63
|
+
| `profiles` | Разрешение профилей стека (только чтение манифестов), закрепление, сборка политики |
|
|
64
|
+
| `toolchains` | Требования профиля к инструментам: манифесты, рецепты, проверка версий |
|
|
65
|
+
| `integrations` | Опциональные подключения Relay v1/v2 и памяти; по умолчанию выключены |
|
|
66
|
+
| `testing` | Контрактные проверки для собственных реализаций `ExecutionStore` |
|
|
67
|
+
| `init` | `harness init`: обнаружение проверок проекта, политика, план безопасной записи файлов |
|
|
68
|
+
| `setup` | Безопасная подготовка файлов: проверка назначения, план и create-only запись |
|
|
69
|
+
| `planning` | Запрос планирования и факты проекта, проверка draft, сборка `WorkGraph` |
|
|
70
|
+
| `explain` | Объяснение остановки по состоянию: причина, действующая сторона, следующее действие |
|
|
71
|
+
| `projections` | Чистые проекции для отображения: корни цепочек, прогресс, остановка очереди, усечение |
|
|
72
|
+
| `catalog` | Каталог агентских операций, байтовые пределы и постраничная выдача ответов |
|
|
73
|
+
|
|
74
|
+
Таблица перечисляет каталоги `src/`. Git-операции — worktrees, snapshots,
|
|
75
|
+
проверка области, candidate/integration, CAS и recovery — отдельного каталога
|
|
76
|
+
не образуют: они в `engine` (`runner.ts`, `joint-runner.ts`), `control`
|
|
77
|
+
(`base-move.ts`) и `verification`. Поставляемые skills лежат в корневом
|
|
78
|
+
каталоге пакета `skills/`, шаблоны — в `templates/`; исполняемые гарантии
|
|
79
|
+
остаются в движке.
|
|
80
|
+
|
|
81
|
+
Модули `setup`, `planning`, `explain`, `projections`, `catalog` и разрешение
|
|
82
|
+
профилей с `layerSchema` — общие операции и для самостоятельного проекта, и для
|
|
83
|
+
хоста. Хост вызывает их из пакета и не держит своих копий этих алгоритмов; у
|
|
84
|
+
него остаются продуктовые правила, согласования, память, UI и своё хранилище.
|
|
85
|
+
Подробно — [самостоятельный проект](standalone.md) и [договоры](contracts.md).
|
|
86
|
+
|
|
87
|
+
`contracts` — лист графа зависимостей: он не импортирует других модулей,
|
|
88
|
+
процессов, файловой системы и сети. Линтер проверяет это правило как ошибку.
|
|
89
|
+
|
|
90
|
+
## Направление зависимостей
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
Файлы ---------> WorkSource / ContextSource ---+
|
|
94
|
+
|
|
|
95
|
+
Хост ----------> его адаптеры ----------------> Harness
|
|
96
|
+
|
|
|
97
|
+
Внешняя память -> внешние адаптеры -----------+
|
|
98
|
+
|
|
|
99
|
+
+-------------------+-------------------+
|
|
100
|
+
v v v
|
|
101
|
+
Runtime adapters Git / проверки ExecutionStore
|
|
102
|
+
| |
|
|
103
|
+
+-----------> RunResult / events <------+
|
|
104
|
+
|
|
|
105
|
+
v
|
|
106
|
+
ResultSink
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Хост зависит от harness; harness не зависит от хоста. Обратные импорты,
|
|
110
|
+
чтение соседнего checkout и загрузка его модулей через subprocess запрещены;
|
|
111
|
+
пакет работает, когда исходников хоста на машине нет. UI-зависимости не входят в
|
|
112
|
+
runtime-граф пакета.
|
|
113
|
+
|
|
114
|
+
## Одна транзакция исполнения
|
|
115
|
+
|
|
116
|
+
Решения движка — claim, продление и проверка владения, запись evidence,
|
|
117
|
+
приёмка — выполняются внутри одной синхронной транзакции `ExecutionStore`.
|
|
118
|
+
Внутри неё:
|
|
119
|
+
|
|
120
|
+
1. движок читает нейтральные записи (`WorkState`, `AttemptState`,
|
|
121
|
+
`ControlState`) через `ExecutionView`;
|
|
122
|
+
2. хост добавляет свои условия через `HostGuards` — они могут только запретить;
|
|
123
|
+
3. основания (digest постановки, области и политики) даёт `BasisProvider`;
|
|
124
|
+
4. изменения записываются `put*`, события — `emit`;
|
|
125
|
+
5. при приёмке до фиксации выполняется CAS `git update-ref <ref> <new> <old>`;
|
|
126
|
+
отказ CAS откатывает транзакцию.
|
|
127
|
+
|
|
128
|
+
**Standalone.** `ExecutionStore` — встроенная SQLite (`node:sqlite`,
|
|
129
|
+
`BEGIN IMMEDIATE`): документ нейтрального состояния, таблица событий и
|
|
130
|
+
локальные записи (учёт вызовов, idempotency-ключи, receipts доставки) в одной
|
|
131
|
+
базе. Других копий изменяемого состояния исполнения нет.
|
|
132
|
+
|
|
133
|
+
**Внутри хоста.** Адаптер `ExecutionStore` работает через существующую
|
|
134
|
+
транзакцию хоста и отображает его записи в нейтральные структуры. Хост не
|
|
135
|
+
заводит вторую базу с независимо изменяемыми статусами и попытками; движок не
|
|
136
|
+
переносит его исторические записи. Если хост хранит состояние в нескольких
|
|
137
|
+
базах (например, по компонентам), атомарность обеспечивает его транзакция над
|
|
138
|
+
ними всеми.
|
|
139
|
+
|
|
140
|
+
Падение процесса между `update-ref` и фиксацией разбирает recovery: попытка
|
|
141
|
+
принимается только по сохранённому integration SHA, который уже в target ref,
|
|
142
|
+
и только с полными актуальными evidence; повтор recovery не создаёт второго
|
|
143
|
+
принятия.
|
|
144
|
+
|
|
145
|
+
## Технические гарантии
|
|
146
|
+
|
|
147
|
+
- **Fencing.** Каждая операция попытки предъявляет fencing-токен; запоздалый
|
|
148
|
+
ответ прежнего владельца, истёкший lease или чужой токен ничего не пишет.
|
|
149
|
+
Токен не попадает в события, результат и логи.
|
|
150
|
+
- **Один controller.** Очередь ведёт один действующий controller с lease;
|
|
151
|
+
второй не выдаёт попыток.
|
|
152
|
+
- **Применённая политика у каждого вызова.** Начало любого учитываемого вызова
|
|
153
|
+
runtime (writer, ревью кода, плана, контракта, разбор) в той же транзакции
|
|
154
|
+
сверяет политику процесса с применённой: процесс, чью политику сменили
|
|
155
|
+
(например, понизили бюджет), новых вызовов не начинает (`APPROVAL_STALE`).
|
|
156
|
+
- **Применение политики хостом.** Запрос операции применяется только после
|
|
157
|
+
окончания работ под прежней политикой — попыток, совместных проверок,
|
|
158
|
+
заданий и работ хоста (`HostGuards.busy`, у DevContour — поставка и
|
|
159
|
+
preview). Хост, не сумевший прочитать ожидаемую политику, записывает отказ
|
|
160
|
+
с причиной (`rejectReconfigure`); повтор операции его сбрасывает. Хост с
|
|
161
|
+
`recordPolicyOnLead: false` записывает применённую политику сам
|
|
162
|
+
(`recordPolicy`) — только действующим controller.
|
|
163
|
+
- **Совместная проверка хоста.** Хост может начать проверку в своей
|
|
164
|
+
транзакции (с продуктовыми условиями) и передать её `JointRunner.run`;
|
|
165
|
+
каталог, окружение gates и подготовку задаёт хост. Digest политики и
|
|
166
|
+
основание считаются формулами хоста, если он их задаёт
|
|
167
|
+
(`BasisProvider.jointPolicyDigest/jointSpecDigest`); продуктовые условия
|
|
168
|
+
каждой записи — `HostGuards.joint`. `jointResult(workIds, id)` оценивает
|
|
169
|
+
указанную проверку.
|
|
170
|
+
- **Расход ревью плана.** Вызов о графе закрепляет за расходом группу и
|
|
171
|
+
поручения из входного графа — и до его регистрации; повтор после
|
|
172
|
+
исчерпания бюджета поручения или группы отклоняется до вызова.
|
|
173
|
+
- **Контекст ревью плана.** Reviewer плана получает закреплённый снимок
|
|
174
|
+
контекста (содержимое и digest); без нужного источника или с испорченным
|
|
175
|
+
снимком — отказ до вызова. Раунд подтверждает граф только с тем же снимком:
|
|
176
|
+
другой контекст при том же графе — новый раунд.
|
|
177
|
+
- **Удержания переживают редакции.** Новая редакция источника сохраняет
|
|
178
|
+
удержание операции; снимает его только владелец (release или передача).
|
|
179
|
+
- **Незавершённая очистка.** Если teardown окружения попытки или проверки
|
|
180
|
+
потребителя не завершился, её рабочие деревья и снимки зависимостей
|
|
181
|
+
остаются и записываются в `cleanup-pending.json`; ошибки обычного удаления
|
|
182
|
+
записываются туда же. `Harness.cleanup(runId)` повторяет teardown по
|
|
183
|
+
сохранённым `environment.json` и затем убирает деревья, повторный вызов —
|
|
184
|
+
`nothing-pending`.
|
|
185
|
+
- **Покрытие gates.** `uncoveredGates` засчитывает только evidence попыток под
|
|
186
|
+
текущим основанием политики: тот же ID gate с другой командой — другая
|
|
187
|
+
проверка.
|
|
188
|
+
- **Область записи.** Изменения вне `writeScope`, защищённых путей и
|
|
189
|
+
закреплённого контекста отклоняют попытку до интеграции.
|
|
190
|
+
- **Gates.** Тестовый gate принимается по свежему непустому отчёту без
|
|
191
|
+
failures/errors/skips на точном SHA; exit 0 и слово PASS в выводе не заменяют
|
|
192
|
+
отчёт. Gate или reviewer, изменивший дерево или HEAD, проверку не проходит.
|
|
193
|
+
- **Независимое ревью.** Reviewer — отдельная роль и свежая сессия; он
|
|
194
|
+
получает исходные критерии, согласованные контракты, закреплённый контекст,
|
|
195
|
+
diff и evidence, которые controller записал о проверяемом SHA, прежние
|
|
196
|
+
находки, но не историю рассуждений, отчёт и ID сессии writer. Права reviewer
|
|
197
|
+
только на чтение; evidence ревью пишет controller по ответу reviewer, writer
|
|
198
|
+
такого права не имеет. Невалидный ответ,
|
|
199
|
+
`approved` при блокирующей находке, таймаут — отказ, не самооценка writer.
|
|
200
|
+
- **Политика вендоров.** Reviewer задан явно для каждого вида ревью (код,
|
|
201
|
+
план, контракт). По умолчанию reviewer того же вендора, что и writer,
|
|
202
|
+
отклоняется; режим одного вендора включается явно (`same-vendor-allowed`) и
|
|
203
|
+
сохраняет все остальные условия приёмки. Неявного выбора «противоположного
|
|
204
|
+
runtime» нет ни в ревью, ни в разборе ведущего (его ведёт runtime автора).
|
|
205
|
+
- **CAS приёмки.** `git update-ref` target ref исполняется внутри транзакции
|
|
206
|
+
приёмки без hooks репозитория (`core.hooksPath=/dev/null`) и с конечным
|
|
207
|
+
пределом времени; зависший или отклонённый hook не держит блокировку и не
|
|
208
|
+
срывает приёмку.
|
|
209
|
+
- **Согласование привязано к digest.** Смена постановки, состава графа,
|
|
210
|
+
области проверок или политики требует нового согласования. Публичного метода
|
|
211
|
+
«передать PASS и принять» нет.
|
|
212
|
+
- **Внешняя предпосылка** считается выполненной только по результату движка
|
|
213
|
+
либо доверенному receipt с доступным result SHA; отметка `done` без SHA не
|
|
214
|
+
доказательство. Файловый коннектор по умолчанию не доверяет внешним receipts.
|
|
215
|
+
- **Ограниченное восстановление.** В режиме `agent` работа над графом —
|
|
216
|
+
задание технической очереди (`workflow-jobs`): стадия (согласование,
|
|
217
|
+
исполнение, завершено) сохраняется и переживает рестарт; владелец задания
|
|
218
|
+
fenced. Упавшее поручение повторяется только по записанному классу отказа:
|
|
219
|
+
в пределах повторов одинакового отпечатка для класса, попыток поручения
|
|
220
|
+
(`maxAttempts`) и бюджета восстановлений задания (`repairBudget`). Решение и
|
|
221
|
+
списание бюджета — одна транзакция с повтором. Отказ провайдера, отмена,
|
|
222
|
+
неизвестный класс и устаревшая база — остановка с причиной. Восстановление
|
|
223
|
+
снимает только свою причину паузы; паузу человека не снимает. Режим
|
|
224
|
+
`operator` автоматических повторов не делает.
|
|
225
|
+
- **Переиспользование кандидата.** После отказа окружения или по времени,
|
|
226
|
+
когда кандидат уже был, повтор берёт его вместо новой реализации, только
|
|
227
|
+
если совпадают все основания: постановка, контракты, политика, runtime и
|
|
228
|
+
модель, база, контекст, зависимости, версия движка и версия корпуса. Gates и
|
|
229
|
+
оба ревью исполняются заново; взятый кандидат проходит ту же проверку
|
|
230
|
+
области. Попытка, оборванная до кандидата, оставляет черновик в области
|
|
231
|
+
записи; отклонённый кандидат — отправная точка следующей попытки; ни то, ни
|
|
232
|
+
другое не заменяет проверок.
|
|
233
|
+
- **Бюджеты.** Каждый вызов модели (writer, ревью кода, плана и контракта)
|
|
234
|
+
идёт через учёт: в одной транзакции с регистрацией идущего вызова
|
|
235
|
+
проверяются бюджеты поручения, его групп и общий; превышенный или
|
|
236
|
+
неопределённый — отказ класса `budget` до вызова, без записи. Расход
|
|
237
|
+
считается по сохранённым записям вызовов, а не по счётчикам попыток: сброс
|
|
238
|
+
попыток, повтор и перезапуск его не уменьшают; ошибочные, идущие и
|
|
239
|
+
прерванные вызовы входят в расход. Неизвестная стоимость не становится нулём:
|
|
240
|
+
денежный бюджет тогда не определён, и `onUnknown` решает, останавливаться
|
|
241
|
+
ли. Атрибуция (поручение, группа, поручения группы) закрепляется при вызове:
|
|
242
|
+
перенос поручения в другую группу хоста расход не переносит. Тариф
|
|
243
|
+
закрепляется на старте вызова и выбирается по модели, о которой сообщил
|
|
244
|
+
runtime. Вызов умершего процесса закрывается как прерванный; владелец,
|
|
245
|
+
которого нельзя ни подтвердить, ни опровергнуть, живым не считается, а его
|
|
246
|
+
вызов не закрывается. Время — по монотонным часам; откат системных часов
|
|
247
|
+
его не уменьшает, а несравнимые метки дают неизвестное время, а не ноль.
|
|
248
|
+
Готовое поручение под исчерпанным бюджетом не выдаётся и несёт причину.
|
|
249
|
+
- **Область доказательства.** Группы gates (`@имя`) раскрываются в явный
|
|
250
|
+
список один раз, без циклов и членов вне профиля; список закрепляется за
|
|
251
|
+
попыткой. Без области — весь профиль репозитория. Область замкнута по
|
|
252
|
+
`dependsOn` gates и содержит test gate.
|
|
253
|
+
- **Потребители.** Поручение явно называет потребителей — репозитории,
|
|
254
|
+
зависящие от его репозитория, — и их gates. Потребитель проверяется на
|
|
255
|
+
integration в своём рабочем дереве на голове своей целевой ветки: компонент
|
|
256
|
+
поручения подставлен интегрированным результатом, прочие зависимости
|
|
257
|
+
потребителя собраны против него; действуют lifecycle, prepare и cleanup
|
|
258
|
+
потребителя, ресурсы его gates резервируются на всю попытку. Evidence
|
|
259
|
+
потребителя несёт его репозиторий и не закрывает ни собственные gates, ни
|
|
260
|
+
требования поручения. Приёмка требует PASS каждого gate потребителя на
|
|
261
|
+
integration SHA и записи, что проверено (голова потребителя, снимки его
|
|
262
|
+
зависимостей с интегрированным результатом, их свежесть).
|
|
263
|
+
- **Договор проверки и генеративные gates.** Контракт может нести договор
|
|
264
|
+
проверки (`checks`): обязательства по property ID с областью входов,
|
|
265
|
+
правилами ответа, независимым способом проверки и минимальным покрытием, и
|
|
266
|
+
закреплённые файлы checker/oracle (`artifacts`, Git blob). Неполный договор
|
|
267
|
+
и файлы, не совпадающие с целевой веткой, отклоняются до вызова reviewer.
|
|
268
|
+
Поручение включает механизм полем `properties`; свойства, которых нет в его
|
|
269
|
+
договорах или которые исполняет не генеративный gate, не согласуются.
|
|
270
|
+
Генеративный gate получает seed controller (`DEVCONTOUR_SEED`, свой у
|
|
271
|
+
попытки, фазы и gate), селектор свойств и закреплённый корпус; отчёт
|
|
272
|
+
свойств читается при любом исходе из каталога вне worktree. Gate проходит,
|
|
273
|
+
только если отчёт подтверждает манифест поручения: каждое свойство, его
|
|
274
|
+
минимальную выборку по семействам и все случаи корпуса (свидетельство
|
|
275
|
+
исходов, а не счёт); зелёный JUnit и код 0 этого не заменяют. Закреплённые
|
|
276
|
+
файлы контракта — защищённые пути попытки. Приёмка (`finish`, а через него
|
|
277
|
+
recovery) повторно требует для каждого gate объявленных свойств решающую
|
|
278
|
+
запись обеих фаз с манифестом этого договора и исполненным корпусом
|
|
279
|
+
закреплённой версии — независимо от состава `requiredGates`; сохранённое
|
|
280
|
+
evidence без манифеста, с прежним уровнем или заниженным корпусом не
|
|
281
|
+
принимается. Те же правила проверяет получатель переносимого результата
|
|
282
|
+
(`resultProblems`): результат прежнего формата у поручения без договора
|
|
283
|
+
проверки читается на прежнем уровне, у поручения с договором — отклоняется.
|
|
284
|
+
- **Эксперимент выполнимости (spike).** Тяжёлое обязательство ссылается на
|
|
285
|
+
ограниченный эксперимент по ID и digest. Эксперимент исполняет команду на
|
|
286
|
+
закреплённом SHA в отдельном worktree под изоляцией gates, для каждого
|
|
287
|
+
размера — с пределом времени; после таймаута большие размеры не
|
|
288
|
+
запускаются. Таймаут — `inconclusive`: не доказательство невыполнимости и
|
|
289
|
+
не основание ослаблять обязательство. Неизвестный эксперимент или другой
|
|
290
|
+
digest — отказ ревью контракта до вызова модели; reviewer получает
|
|
291
|
+
фактический результат эксперимента.
|
|
292
|
+
- **Самопроверка исполнителя.** Writer поручения со свойствами получает
|
|
293
|
+
команду самопроверки: закреплённый checker, полный корпус версии попытки
|
|
294
|
+
(а не только случаи подсказки), seed и селектор свойств — на рабочем
|
|
295
|
+
дереве. Это диагностика: gates на commit SHA исполняются всегда, и без
|
|
296
|
+
самопроверки отказы те же.
|
|
297
|
+
- **Корпус подтверждённых случаев.** Пример reviewer или ведущего — гипотеза.
|
|
298
|
+
Controller запускает закреплённый checker в режиме одного случая дважды на
|
|
299
|
+
дефектном SHA и требует воспроизводимого расхождения с эталоном; ожиданием
|
|
300
|
+
становится ответ эталона. Команда из воспроизведения не исполняется.
|
|
301
|
+
Подтверждённый случай — новая неизменяемая версия корпуса; поручение
|
|
302
|
+
принимает её отдельной операцией: посередине попытки выдача удерживается и
|
|
303
|
+
принятие ждёт её конца, в режиме `operator` — ручного подтверждения.
|
|
304
|
+
Принятое поручение версию не меняет. Повтор ключа подтверждения возвращает
|
|
305
|
+
прежнее решение. Версия проверок (`effectiveChecks`: постановка, контракты,
|
|
306
|
+
политика, корпус) закрепляется при выдаче; приёмка, recovery и reuse под
|
|
307
|
+
другой версией отклоняются. Корпус принадлежит нормативному основанию договора
|
|
308
|
+
(закреплённые файлы, gate, область входов, правила ответа, способ
|
|
309
|
+
проверки), а не ID контракта: новая редакция того же ID с другим
|
|
310
|
+
основанием получает отдельный корпус, привязка поручения к прежнему
|
|
311
|
+
снимается новой редакцией графа, принятая история прежнего корпуса
|
|
312
|
+
остаётся. Изменение постороннего контракта или текста без смены основания
|
|
313
|
+
привязку сохраняет.
|
|
314
|
+
- **Эпизод по свойству.** Два последовательных содержательных отказа (gate
|
|
315
|
+
или ревью) одного поручения по одному объявленному свойству запрещают
|
|
316
|
+
третью автоматическую выдачу до разбора. Отказ окружения, провайдера и по
|
|
317
|
+
времени счёт не увеличивает и не обнуляет; необъявленное свойство эпизод не
|
|
318
|
+
открывает. Автоматический разбор ведущего — один на эпизод и учитывается
|
|
319
|
+
вместе с бюджетом восстановлений до вызова модели; разрешено добавить
|
|
320
|
+
подтверждённые случаи или один повтор с новой гипотезой, прочие действия —
|
|
321
|
+
предложение для обычного ревью или решение человека. Эпизод закрывает
|
|
322
|
+
проверенное прохождение свойства, приёмка или согласованное новое
|
|
323
|
+
основание.
|
|
324
|
+
- **Зависимости.** Снимок зависимостей репозитория (рабочие деревья целевых
|
|
325
|
+
веток, `dependencyBuild`, digests `dependencyArtifacts`) закрепляется до
|
|
326
|
+
реализации; изменение снимка writer-ом, gate или reviewer — отказ. Свежесть
|
|
327
|
+
снимка на момент окончания записывается в попытке и результате; сдвиг ветки
|
|
328
|
+
зависимости приёмку не запрещает — сочетание версий проверяет совместная
|
|
329
|
+
проверка.
|
|
330
|
+
- **Совместная проверка.** Набор принятых поручений нескольких репозиториев
|
|
331
|
+
проверяется вместе gates уровня workspace (`workspaceGates`) на текущих
|
|
332
|
+
target ref: результат каждого поручения обязан входить в них; manifest
|
|
333
|
+
фиксирует SHA и tree каждого репозитория политики. Gates исполняются в той
|
|
334
|
+
же песочнице, что и проверки поручений, и в снимках компонентов; gate,
|
|
335
|
+
изменивший manifest, уже снятый artifact или исходники любого компонента,
|
|
336
|
+
проверку не проходит. Пока идёт проверка, попытки не выдаются, а она сама
|
|
337
|
+
не начинается при идущих попытках. Результат привязан к manifest, к
|
|
338
|
+
политике совместной проверки и к основанию — постановкам, статусам и
|
|
339
|
+
результатам поручений набора; смена любого из них делает прежний результат
|
|
340
|
+
неактуальным (`jointResult`), а сдвиг target ref после проверки виден как
|
|
341
|
+
свежесть manifest. Атомарного продвижения нескольких Git-репозиториев нет;
|
|
342
|
+
продуктовое принятие комбинации решает хост. В режиме `affected` при
|
|
343
|
+
принятой хостом прежней проверке под той же политикой исполняются только
|
|
344
|
+
изменённые компоненты, их транзитивные потребители и prerequisites их
|
|
345
|
+
gates.
|
|
346
|
+
- **Применённая политика.** В хранилище записана применённая политика
|
|
347
|
+
(digest загруженной политики целиком и поколение). Процесс, чья политика с
|
|
348
|
+
ней не совпадает, не выдаёт, не согласует, не принимает и не ведёт
|
|
349
|
+
совместную проверку. Записать свою политику применённой (перезапуск с
|
|
350
|
+
другой политикой) процесс может, только если нет живого чужого controller,
|
|
351
|
+
его политика не менялась в памяти, её файл содержит те же байты по той же
|
|
352
|
+
цели и после запуска процесса никто не применил другую — поколения
|
|
353
|
+
считаются по записям, не по часам. Операция меняет политику работающего
|
|
354
|
+
контура запросом с ожидаемым digest: новые выдачи и совместные проверки
|
|
355
|
+
удержаны, пока запрос не применён; применяет его процесс ровно с ожидаемой
|
|
356
|
+
политикой, когда работ под прежней не осталось (запись с истёкшим сроком
|
|
357
|
+
их не держит); другая политика — отказ с обоими digest. Пауза человека и
|
|
358
|
+
штатной остановки переживает операцию. Попытка, выданная под прежней
|
|
359
|
+
политикой, под новой не принимается. Пределы бюджетов и тарифы в основание
|
|
360
|
+
согласования и fencing не входят (`executionDigest`): поднятый предел
|
|
361
|
+
действует без нового согласования.
|
|
362
|
+
- **Удержания операций.** Операция удерживает поручения от выдачи; удержание
|
|
363
|
+
другой операции — конфликт; снимает и передаёт его только своя операция,
|
|
364
|
+
передача — без окна выдачи. Владение операцией проверяется в той же
|
|
365
|
+
транзакции (`fence`): утративший его ничего не пишет. Перенос базы
|
|
366
|
+
сдвигает target ref CAS-ом внутри транзакции проверки владения, без hooks
|
|
367
|
+
репозитория и с конечным пределом времени Git.
|
|
368
|
+
- **Изоляция.** Режим `os` ограничивает процессы writer, reviewer и gates; если
|
|
369
|
+
обязательный sandbox недоступен — отказ, а не тихое выполнение без изоляции.
|
|
370
|
+
Режим `none` выбирается только явно.
|
|
371
|
+
- **Проверки reviewer.** Reviewer кода, которому политика и так даёт запуск
|
|
372
|
+
команд (codex с shell, claude с Bash в профиле), получает MCP-сервер
|
|
373
|
+
`devcontour_probe` с инструментом `run_check`; reviewer только для чтения и
|
|
374
|
+
writer его не получают. Команда (argv, без shell) исполняется тем же
|
|
375
|
+
исполнителем, что и gates: песочница режима `os`, исходники только для
|
|
376
|
+
чтения, остановка потомков. Срок задаёт controller: предел на команду, общий
|
|
377
|
+
бюджет проверок с атомарным резервированием (одновременные вызовы его не
|
|
378
|
+
превышают) и резерв времени на заключение (`reviewProbes`, не меньше пятой
|
|
379
|
+
части срока прогона). Таймаут и исчерпанный бюджет — типизированный
|
|
380
|
+
результат, а не зависание ревью. Аргументы и вывод маскируются; значения
|
|
381
|
+
переменных окружения передаются серверу по имени и на диск не пишутся.
|
|
382
|
+
Запуски записываются в журнал controller (`probes.jsonl`) и попадают в
|
|
383
|
+
`review.json`; воспроизведение находки «наблюдено» только по единственному
|
|
384
|
+
состоявшемуся запуску, на который сослался reviewer (`reproduction.run`),
|
|
385
|
+
и команда в записи — та, что запускалась. Команда из текста находки не
|
|
386
|
+
исполняется.
|
|
387
|
+
- **Воспроизведения находок.** Находки ревью кода с воспроизводимым входом
|
|
388
|
+
записываются в реестр поручения (`reproductions`) уже замаскированными:
|
|
389
|
+
одно свойство на одном входе — одна запись, повтор добавляет прогон;
|
|
390
|
+
подтверждение запуском не отменяется последующей гипотезой; реестр
|
|
391
|
+
ограничен 500 записями на поручение. Следующая попытка — writer и
|
|
392
|
+
reviewer — получает последние 20 входов с ожиданием, наблюдением и командой.
|
|
393
|
+
Это диагностика: gate не расширяет и корпусом не становится без
|
|
394
|
+
подтверждения эталоном; обязательный корпус от ограничения реестра не
|
|
395
|
+
зависит.
|
|
396
|
+
- **Контекст плана и согласование.** Снимок контекста хранится по digest, а
|
|
397
|
+
действующим становится только вместе с согласованием графа
|
|
398
|
+
(`approval.context`). Пока новый снимок на ревью, после его отклонения,
|
|
399
|
+
отказа runtime reviewer, в режиме operator до `approve` и после
|
|
400
|
+
перезапуска исполняется прежний согласованный снимок. Попытка, выданная на
|
|
401
|
+
снимке, отличном от согласованного к моменту приёмки, не принимается.
|
|
402
|
+
- **Предмет вызова.** Вызов модели о графе засчитывается группе и её
|
|
403
|
+
участникам, о контракте — общему бюджету: явный вид предмета
|
|
404
|
+
(`subjectKind`) важнее совпадения строки ID с поручением. Прежняя запись
|
|
405
|
+
без вида, но с закреплённой при вызове группой и без поручения — вызов о
|
|
406
|
+
группе: закрепление (`pinLegacyCalls`) дописывает ей состав, а не
|
|
407
|
+
поручение с совпавшим ID; уже закреплённый `workId` не меняется.
|
|
408
|
+
- **Эксперимент и маска.** Запись эксперимента выполнимости (команда, вопрос,
|
|
409
|
+
пределы) маскируется известными значениями окружения до digest и записи;
|
|
410
|
+
недостающий секрет — отказ до worktree. Ошибка запуска возвращается в
|
|
411
|
+
безопасной форме: маскированы сообщение, стек, причина и все поля ошибки
|
|
412
|
+
процесса (`path`, `spawnargs` и др.), класс и код сохранены.
|
|
413
|
+
|
|
414
|
+
## Профили, skills и шаблоны
|
|
415
|
+
|
|
416
|
+
Встроенные профили (`profiles/`), skills (`skills/harness/SKILL.md` — работа
|
|
417
|
+
с поручениями, `skills/harness-setup/SKILL.md` — установка, первая настройка
|
|
418
|
+
и обновление версии) и шаблоны (`templates/`: политика, граф, инструкция
|
|
419
|
+
агентам репозитория) входят в пакет. Skills и шаблоны только объясняют использование: движок, runner и проверки их
|
|
420
|
+
не читают, и удаление каталога skills не отключает ни gates, ни ревью, ни
|
|
421
|
+
область записи, ни fencing — это проверяет smoke установленного архива.
|
|
422
|
+
Профиль — вход для сборки политики, а не исполняемый объект: разрешение не
|
|
423
|
+
запускает команд проекта, и после сборки политика несёт gates сама.
|
|
424
|
+
|
|
425
|
+
## Доставка результата
|
|
426
|
+
|
|
427
|
+
`execution accepted` и `delivery pending/failed` — разные состояния. Принятый
|
|
428
|
+
код не откатывается из-за недоступного получателя. Повтор доставки идёт с тем же
|
|
429
|
+
ключом и не вызывает моделей, интеграции или второй записи. Если в источнике
|
|
430
|
+
уже более новая редакция поручения, получатель отвечает конфликтом, а старый
|
|
431
|
+
результат её не закрывает. Коннекторы не могут менять политику, выдавать lease,
|
|
432
|
+
ослаблять gates или ставить технический PASS — у портов нет таких операций.
|
|
433
|
+
|
|
434
|
+
## Fixture-режим
|
|
435
|
+
|
|
436
|
+
Runtime `fixture` возвращает управляемые ответы для тестов и демо; это не
|
|
437
|
+
живая модель, и он не выбирается при отсутствии учётных данных. Тесты
|
|
438
|
+
адаптеров Codex/Claude проходят настоящий subprocess-протокол через fixture
|
|
439
|
+
executable. Live smoke — отдельный opt-in с явно заданными моделями и
|
|
440
|
+
лимитами. Fixture-проверки доказывают механику процесса, а не качество модели.
|
|
441
|
+
|
|
442
|
+
## Границы доверия участников
|
|
443
|
+
|
|
444
|
+
```text
|
|
445
|
+
┌──────────────────── доверенная зона: controller ─────────────────────┐
|
|
446
|
+
│ движок, состояние (SQLite), токены владения, политика, CAS target ref │
|
|
447
|
+
│ решает: выдачу, приёмку, повторы, бюджеты, доставку │
|
|
448
|
+
└───────────────▲───────────────────────────────▲──────────────────────┘
|
|
449
|
+
│ только ответы по схеме │ только записи evidence,
|
|
450
|
+
│ │ которые пишет controller
|
|
451
|
+
┌───────────────┴─────────────┐ ┌─────────────┴──────────────────────┐
|
|
452
|
+
│ writer: свой worktree, │ │ gates: команды политики в песочнице │
|
|
453
|
+
│ запись только в области │ │ отчёт JUnit/свойств читает harness │
|
|
454
|
+
├─────────────────────────────┤ ├────────────────────────────────────┤
|
|
455
|
+
│ reviewer: свежая сессия, │ │ коннекторы: источник, контекст, │
|
|
456
|
+
│ только чтение, свой SHA │ │ получатель — без права на политику, │
|
|
457
|
+
└─────────────────────────────┘ │ lease или PASS │
|
|
458
|
+
└────────────────────────────────────┘
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
| Участник | Что может | Чего не может |
|
|
462
|
+
| --------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
|
|
463
|
+
| Writer | Менять файлы своей области в своём worktree | Менять защищённые и контекстные файлы, HEAD, state controller; объявить свою работу принятой |
|
|
464
|
+
| Reviewer | Читать дерево, diff, evidence; запускать проверочные команды через probe | Править дерево или HEAD; продолжать сессию writer; одобрить при блокирующей находке |
|
|
465
|
+
| Gate | Выполнить команду политики и записать отчёт | Изменить проверяемый код (изменённое дерево делает проверку недействительной) |
|
|
466
|
+
| Коннектор | Отдать граф, контекст; принять результат | Менять политику, выдавать lease, ослаблять gates, ставить технический PASS |
|
|
467
|
+
| Оператор | Согласовать граф (`operator`), пауза, отмена, повтор, сброс | Принять поручение без gates и ревью — такой операции нет |
|
|
468
|
+
|
|
469
|
+
## Что гарантируется
|
|
470
|
+
|
|
471
|
+
- **Владение.** Каждая попытка пишет только своим токеном; поздний ответ
|
|
472
|
+
прежнего владельца, истёкший lease и второй controller ничего не меняют.
|
|
473
|
+
- **Точные SHA.** PASS gate и ревью относится к конкретному candidate или
|
|
474
|
+
integration SHA; доказательство другой фазы или другого SHA не засчитывается.
|
|
475
|
+
- **Атомарная приёмка.** Продвижение target ref — compare-and-swap внутри
|
|
476
|
+
транзакции приёмки. Чужой коммит в target ref не теряется: попытка начнётся
|
|
477
|
+
от новой базы. Падение между update-ref и записью принятия восстанавливается
|
|
478
|
+
проверкой сохранённых evidence, а не выдумыванием PASS.
|
|
479
|
+
- **Входы.** Согласование привязано к digest постановки, контрактов,
|
|
480
|
+
контекста и политики; их изменение делает согласование и попытку устаревшими.
|
|
481
|
+
- **Изоляция.** Режим `os` реально ограничивает процессы writer, reviewer и
|
|
482
|
+
gates; без механизма песочницы команда не запускается — тихого перехода к
|
|
483
|
+
запуску без неё нет. Зависшие процессы останавливаются вместе с потомками.
|
|
484
|
+
- **Секреты.** Значения секретов маскируются во всём сохраняемом: логах,
|
|
485
|
+
артефактах ревью, evidence, событиях и результате.
|
|
486
|
+
- **Бюджеты.** Проверяются до вызова модели в той же транзакции, что и запись
|
|
487
|
+
вызова; неизвестная стоимость не считается нулём.
|
|
488
|
+
- **Независимость ревью.** По умолчанию reviewer другого вендора; один вендор
|
|
489
|
+
только явным правилом, и даже тогда — отдельная роль и свежая сессия.
|
|
490
|
+
|
|
491
|
+
## Чего harness не делает
|
|
492
|
+
|
|
493
|
+
- Не оценивает качество модели: fixture-тесты проверяют механику процесса.
|
|
494
|
+
- Не обеспечивает атомарность продвижения нескольких репозиториев сразу:
|
|
495
|
+
совместная проверка удостоверяет комбинацию SHA, принятие решает хост.
|
|
496
|
+
- Не хранит продуктовых задач, досок, памяти и UI — это дело хоста.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Проверенные версии
|
|
2
|
+
|
|
3
|
+
Набор версий, на котором выпуск фактически проверен. Это не список
|
|
4
|
+
обязательных требований: другие версии могут работать, но не проверялись.
|
|
5
|
+
Строки с «TODO» заполняются по итогам приёмки выпуска.
|
|
6
|
+
|
|
7
|
+
## Пакет и потребители
|
|
8
|
+
|
|
9
|
+
| Что | Версия | Где проверено |
|
|
10
|
+
| -------------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
11
|
+
| ОС / архитектура | macOS 15 (Darwin 24.6), arm64 | все проверки выпуска |
|
|
12
|
+
| Node.js | 24.3.0 (`engines: >=24.3.0`) | все проверки выпуска |
|
|
13
|
+
| npm | 11.4.2 | C01 (установка архива), A01, A02 |
|
|
14
|
+
| pnpm | 10.12.3 | C01 (`pnpm add <архив> --prod`) |
|
|
15
|
+
| TypeScript потребителя | 6.0.3 + `@types/node` 24.13.5 | A01, C01 (ставится отдельно от пакета) |
|
|
16
|
+
| Прежний потребитель | API 0.1.0-alpha.5 | A01 |
|
|
17
|
+
| Потребитель общих операций | fixtures `consumer-h1`, `consumer-h2`, `consumer-h3` (формы DevContour) | H1–H3 (установка архива) |
|
|
18
|
+
| DevContour | 0.4.0-alpha.7 (`7191b75`), vendored 0.1.0-alpha.11 → архив; обновление с DevContour `ab35a6a` + 0.1.0-alpha.6 | D3: `npm run check`, `check:install`, `check:upgrade` двух пар source+package |
|
|
19
|
+
| Git | 2.33.0 | все сценарии |
|
|
20
|
+
|
|
21
|
+
## Инструменты целевых проектов
|
|
22
|
+
|
|
23
|
+
| Что | Версия | Где проверено |
|
|
24
|
+
| -------------- | ------ | -------------- |
|
|
25
|
+
| Turbo | TODO | T01/turbo, S01 |
|
|
26
|
+
| Go / gotestsum | TODO | T01/go |
|
|
27
|
+
| Python / uv | TODO | T01/python |
|
|
28
|
+
| Docker | TODO | S01–S06 |
|
|
29
|
+
|
|
30
|
+
## Транспорты
|
|
31
|
+
|
|
32
|
+
| Что | Версия / commit | Где проверено |
|
|
33
|
+
| ------------------- | --------------- | ------------- |
|
|
34
|
+
| Relay v1 (server) | TODO | R01, W01 |
|
|
35
|
+
| Relay-2 (CLI) / Bun | TODO | R02, R03, W01 |
|
|
36
|
+
|
|
37
|
+
## Как повторить
|
|
38
|
+
|
|
39
|
+
<!-- repo-only -->
|
|
40
|
+
|
|
41
|
+
Проверки выпуска — инструменты разработки harness: они лежат в checkout
|
|
42
|
+
репозитория (`scripts/acceptance/`, `tests/fixtures/consumer-alpha5`, `tests/fixtures/consumer-h*`) и в
|
|
43
|
+
npm-архив не входят.
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
node scripts/acceptance/package-pack.mjs --out <dir>
|
|
47
|
+
node scripts/acceptance/package-check.mjs <dir>/devcontour-harness-<ver>.tgz
|
|
48
|
+
node scripts/acceptance/consumer-check.mjs <dir>/devcontour-harness-<ver>.tgz
|
|
49
|
+
node scripts/acceptance/core-minimal-env.mjs <dir>/devcontour-harness-<ver>.tgz
|
|
50
|
+
node scripts/acceptance/consumer-h1.mjs <dir>/devcontour-harness-<ver>.tgz --out <dir>/h1
|
|
51
|
+
node scripts/acceptance/consumer-h2.mjs <dir>/devcontour-harness-<ver>.tgz --out <dir>/h2
|
|
52
|
+
node scripts/acceptance/consumer-h3.mjs <dir>/devcontour-harness-<ver>.tgz --out <dir>/h3
|
|
53
|
+
node scripts/acceptance/devcontour-check.mjs <dir>/devcontour-harness-<ver>.tgz \
|
|
54
|
+
--devcontour <путь или URL DevContour> --baseline
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Отчёты скриптов (`report.json`) содержат фактические версии `node`, `npm`,
|
|
58
|
+
`pnpm` и компилятора, hash архива и argv каждой команды.
|
|
59
|
+
|
|
60
|
+
<!-- /repo-only -->
|