agentic-orchestrator 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +24 -0
- package/.github/workflows/mcp-contract-validation.yml +38 -0
- package/Agentic-Orchestrator.iml +9 -0
- package/LICENSE +21 -0
- package/README.md +679 -0
- package/agentic/orchestrator/agents.yaml +14 -0
- package/agentic/orchestrator/gates.yaml +31 -0
- package/agentic/orchestrator/policy.yaml +145 -0
- package/agentic/orchestrator/prompts/builder.system.md +1 -0
- package/agentic/orchestrator/prompts/planner.system.md +15 -0
- package/agentic/orchestrator/prompts/qa.system.md +1 -0
- package/agentic/orchestrator/schemas/agents.schema.json +49 -0
- package/agentic/orchestrator/schemas/gates.schema.json +65 -0
- package/agentic/orchestrator/schemas/index.schema.json +108 -0
- package/agentic/orchestrator/schemas/plan.schema.json +127 -0
- package/agentic/orchestrator/schemas/policy.schema.json +227 -0
- package/agentic/orchestrator/schemas/qa_test_index.schema.json +53 -0
- package/agentic/orchestrator/schemas/state.schema.json +92 -0
- package/agentic/orchestrator/tools/catalog.json +399 -0
- package/agentic/orchestrator/tools/errors.schema.json +21 -0
- package/agentic/orchestrator/tools/protocol.json +8 -0
- package/agentic/orchestrator/tools/schemas/input/collisions.scan.input.schema.json +7 -0
- package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +42 -0
- package/agentic/orchestrator/tools/schemas/input/feature.discover_specs.input.schema.json +7 -0
- package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +26 -0
- package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +34 -0
- package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +28 -0
- package/agentic/orchestrator/tools/schemas/input/gates.list.input.schema.json +11 -0
- package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +29 -0
- package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +29 -0
- package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +26 -0
- package/agentic/orchestrator/tools/schemas/input/mutating.schema.json +14 -0
- package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +28 -0
- package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +29 -0
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +38 -0
- package/agentic/orchestrator/tools/schemas/input/read.schema.json +6 -0
- package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +25 -0
- package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +20 -0
- package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +20 -0
- package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/report.dashboard.input.schema.json +7 -0
- package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +17 -0
- package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +20 -0
- package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +224 -0
- package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +32 -0
- package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +40 -0
- package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +24 -0
- package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +24 -0
- package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +30 -0
- package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +18 -0
- package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +24 -0
- package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +42 -0
- package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +37 -0
- package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +34 -0
- package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +24 -0
- package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +26 -0
- package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +23 -0
- package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +23 -0
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +22 -0
- package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +19 -0
- package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +33 -0
- package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +19 -0
- package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +32 -0
- package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +29 -0
- package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +24 -0
- package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +26 -0
- package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +27 -0
- package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/output/report.feature_summary.output.schema.json +36 -0
- package/agentic/orchestrator/tools/schemas/output/standard_success.schema.json +6 -0
- package/agentic/orchestrator/tools.md +32 -0
- package/apps/control-plane/project.json +39 -0
- package/apps/control-plane/scripts/validate-architecture-rules.mjs +170 -0
- package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +84 -0
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +61 -0
- package/apps/control-plane/src/application/services/collision-queue-service.ts +227 -0
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +459 -0
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +177 -0
- package/apps/control-plane/src/application/services/feature-state-service.ts +125 -0
- package/apps/control-plane/src/application/services/gate-service.ts +232 -0
- package/apps/control-plane/src/application/services/lock-service.ts +298 -0
- package/apps/control-plane/src/application/services/merge-service.ts +246 -0
- package/apps/control-plane/src/application/services/patch-service.ts +259 -0
- package/apps/control-plane/src/application/services/plan-service.ts +302 -0
- package/apps/control-plane/src/application/services/qa-index-service.ts +98 -0
- package/apps/control-plane/src/application/services/reporting-service.ts +120 -0
- package/apps/control-plane/src/application/services/run-lease-service.ts +340 -0
- package/apps/control-plane/src/application/tools/tool-metadata.ts +56 -0
- package/apps/control-plane/src/application/tools/tool-router.ts +43 -0
- package/apps/control-plane/src/cli/aop.ts +31 -0
- package/apps/control-plane/src/cli/cli-argument-parser.ts +116 -0
- package/apps/control-plane/src/cli/delete-command-handler.ts +90 -0
- package/apps/control-plane/src/cli/io.ts +14 -0
- package/apps/control-plane/src/cli/resume-command-handler.ts +228 -0
- package/apps/control-plane/src/cli/run-command-handler.ts +57 -0
- package/apps/control-plane/src/cli/spec-ingestion-service.ts +88 -0
- package/apps/control-plane/src/cli/spec-input-resolver.ts +95 -0
- package/apps/control-plane/src/cli/spec-utils.ts +40 -0
- package/apps/control-plane/src/cli/status-command-handler.ts +17 -0
- package/apps/control-plane/src/cli/stop-command-handler.ts +5 -0
- package/apps/control-plane/src/cli/tooling.ts +36 -0
- package/apps/control-plane/src/cli/types.ts +34 -0
- package/apps/control-plane/src/core/collisions.ts +121 -0
- package/apps/control-plane/src/core/constants.ts +72 -0
- package/apps/control-plane/src/core/error-codes.ts +54 -0
- package/apps/control-plane/src/core/frontmatter.ts +42 -0
- package/apps/control-plane/src/core/fs.ts +173 -0
- package/apps/control-plane/src/core/gates.ts +361 -0
- package/apps/control-plane/src/core/git.ts +115 -0
- package/apps/control-plane/src/core/kernel.ts +1077 -0
- package/apps/control-plane/src/core/patch.ts +152 -0
- package/apps/control-plane/src/core/path-layout.ts +113 -0
- package/apps/control-plane/src/core/path-rules.ts +71 -0
- package/apps/control-plane/src/core/qa-index.ts +179 -0
- package/apps/control-plane/src/core/response.ts +62 -0
- package/apps/control-plane/src/core/runtime-sessions.ts +20 -0
- package/apps/control-plane/src/core/schemas.ts +125 -0
- package/apps/control-plane/src/index.ts +21 -0
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +100 -0
- package/apps/control-plane/src/mcp/kernel-tool-executor.ts +39 -0
- package/apps/control-plane/src/mcp/mcp-server-adapter.ts +74 -0
- package/apps/control-plane/src/mcp/operation-ledger.ts +108 -0
- package/apps/control-plane/src/mcp/protocol-contract.ts +9 -0
- package/apps/control-plane/src/mcp/runtime-factory.ts +105 -0
- package/apps/control-plane/src/mcp/runtime-types.ts +44 -0
- package/apps/control-plane/src/mcp/token-auth-verifier.ts +63 -0
- package/apps/control-plane/src/mcp/token-claims-validator.ts +72 -0
- package/apps/control-plane/src/mcp/token-codec.ts +62 -0
- package/apps/control-plane/src/mcp/tool-authorizer.ts +43 -0
- package/apps/control-plane/src/mcp/tool-client.ts +78 -0
- package/apps/control-plane/src/mcp/tool-contract-validator.ts +83 -0
- package/apps/control-plane/src/mcp/tool-registry-loader.ts +135 -0
- package/apps/control-plane/src/mcp/tool-runtime.ts +336 -0
- package/apps/control-plane/src/mcp/tools-markdown-generator.ts +26 -0
- package/apps/control-plane/src/mcp/transport-types.ts +16 -0
- package/apps/control-plane/src/mcp/types.ts +2 -0
- package/apps/control-plane/src/providers/providers.ts +177 -0
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +55 -0
- package/apps/control-plane/src/supervisor/lease-heartbeat-service.ts +22 -0
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +316 -0
- package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +62 -0
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +99 -0
- package/apps/control-plane/src/supervisor/run-coordinator.ts +224 -0
- package/apps/control-plane/src/supervisor/runtime.ts +347 -0
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +268 -0
- package/apps/control-plane/src/supervisor/types.ts +149 -0
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +299 -0
- package/apps/control-plane/test/aop.spec.ts +101 -0
- package/apps/control-plane/test/cli-helpers.spec.ts +102 -0
- package/apps/control-plane/test/cli.spec.ts +12 -0
- package/apps/control-plane/test/cli.unit.spec.ts +609 -0
- package/apps/control-plane/test/collision-queue.spec.ts +158 -0
- package/apps/control-plane/test/collisions.spec.ts +138 -0
- package/apps/control-plane/test/core-utils.spec.ts +102 -0
- package/apps/control-plane/test/delete-command-handler.spec.ts +202 -0
- package/apps/control-plane/test/epoch-tracking.spec.ts +121 -0
- package/apps/control-plane/test/gates.spec.ts +452 -0
- package/apps/control-plane/test/helpers.ts +68 -0
- package/apps/control-plane/test/index.spec.ts +18 -0
- package/apps/control-plane/test/kernel-collision-replay.spec.ts +222 -0
- package/apps/control-plane/test/kernel.branches.spec.ts +321 -0
- package/apps/control-plane/test/kernel.coverage.spec.ts +408 -0
- package/apps/control-plane/test/kernel.spec.ts +369 -0
- package/apps/control-plane/test/mcp-helpers.spec.ts +195 -0
- package/apps/control-plane/test/mcp.spec.ts +776 -0
- package/apps/control-plane/test/merge-service.spec.ts +357 -0
- package/apps/control-plane/test/plan-service.spec.ts +195 -0
- package/apps/control-plane/test/planning-wave-executor.spec.ts +229 -0
- package/apps/control-plane/test/providers.spec.ts +168 -0
- package/apps/control-plane/test/qa-index-service.spec.ts +187 -0
- package/apps/control-plane/test/qa-index.spec.ts +317 -0
- package/apps/control-plane/test/response.spec.ts +55 -0
- package/apps/control-plane/test/run-coordinator.spec.ts +334 -0
- package/apps/control-plane/test/schema-date-time.spec.ts +170 -0
- package/apps/control-plane/test/service-retry-paths.spec.ts +305 -0
- package/apps/control-plane/test/services.spec.ts +693 -0
- package/apps/control-plane/test/spec-input-resolver.spec.ts +76 -0
- package/apps/control-plane/test/supervisor-collaborators.spec.ts +201 -0
- package/apps/control-plane/test/supervisor.calltool.spec.ts +120 -0
- package/apps/control-plane/test/supervisor.spec.ts +415 -0
- package/apps/control-plane/test/supervisor.unit.spec.ts +522 -0
- package/apps/control-plane/test/token-auth-verifier.spec.ts +111 -0
- package/apps/control-plane/test/tool-registry-loader.spec.ts +268 -0
- package/apps/control-plane/test/tool-runtime.spec.ts +294 -0
- package/apps/control-plane/test/worker-decision-loop.spec.ts +587 -0
- package/apps/control-plane/tsconfig.build.json +17 -0
- package/apps/control-plane/tsconfig.json +11 -0
- package/apps/control-plane/vitest.config.ts +28 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +69 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js +158 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +79 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +336 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +81 -0
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +117 -0
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/feature-state-service.d.ts +34 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js +90 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/gate-service.d.ts +46 -0
- package/dist/apps/control-plane/application/services/gate-service.js +160 -0
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/lock-service.d.ts +56 -0
- package/dist/apps/control-plane/application/services/lock-service.js +242 -0
- package/dist/apps/control-plane/application/services/lock-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/merge-service.d.ts +33 -0
- package/dist/apps/control-plane/application/services/merge-service.js +194 -0
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/patch-service.d.ts +39 -0
- package/dist/apps/control-plane/application/services/patch-service.js +189 -0
- package/dist/apps/control-plane/application/services/patch-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/plan-service.d.ts +60 -0
- package/dist/apps/control-plane/application/services/plan-service.js +234 -0
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/qa-index-service.d.ts +26 -0
- package/dist/apps/control-plane/application/services/qa-index-service.js +66 -0
- package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/reporting-service.d.ts +47 -0
- package/dist/apps/control-plane/application/services/reporting-service.js +90 -0
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/run-lease-service.d.ts +74 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js +263 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -0
- package/dist/apps/control-plane/application/tools/tool-metadata.d.ts +8 -0
- package/dist/apps/control-plane/application/tools/tool-metadata.js +37 -0
- package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -0
- package/dist/apps/control-plane/application/tools/tool-router.d.ts +16 -0
- package/dist/apps/control-plane/application/tools/tool-router.js +25 -0
- package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -0
- package/dist/apps/control-plane/cli/aop.d.ts +5 -0
- package/dist/apps/control-plane/cli/aop.js +19 -0
- package/dist/apps/control-plane/cli/aop.js.map +1 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.d.ts +5 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js +109 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -0
- package/dist/apps/control-plane/cli/delete-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/delete-command-handler.js +77 -0
- package/dist/apps/control-plane/cli/delete-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/io.d.ts +2 -0
- package/dist/apps/control-plane/cli/io.js +14 -0
- package/dist/apps/control-plane/cli/io.js.map +1 -0
- package/dist/apps/control-plane/cli/resume-command-handler.d.ts +17 -0
- package/dist/apps/control-plane/cli/resume-command-handler.js +178 -0
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/run-command-handler.d.ts +15 -0
- package/dist/apps/control-plane/cli/run-command-handler.js +39 -0
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/spec-ingestion-service.d.ts +8 -0
- package/dist/apps/control-plane/cli/spec-ingestion-service.js +77 -0
- package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -0
- package/dist/apps/control-plane/cli/spec-input-resolver.d.ts +9 -0
- package/dist/apps/control-plane/cli/spec-input-resolver.js +81 -0
- package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -0
- package/dist/apps/control-plane/cli/spec-utils.d.ts +3 -0
- package/dist/apps/control-plane/cli/spec-utils.js +36 -0
- package/dist/apps/control-plane/cli/spec-utils.js.map +1 -0
- package/dist/apps/control-plane/cli/status-command-handler.d.ts +7 -0
- package/dist/apps/control-plane/cli/status-command-handler.js +14 -0
- package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/stop-command-handler.d.ts +3 -0
- package/dist/apps/control-plane/cli/stop-command-handler.js +6 -0
- package/dist/apps/control-plane/cli/stop-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/tooling.d.ts +4 -0
- package/dist/apps/control-plane/cli/tooling.js +24 -0
- package/dist/apps/control-plane/cli/tooling.js.map +1 -0
- package/dist/apps/control-plane/cli/types.d.ts +31 -0
- package/dist/apps/control-plane/cli/types.js +2 -0
- package/dist/apps/control-plane/cli/types.js.map +1 -0
- package/dist/apps/control-plane/core/collisions.d.ts +39 -0
- package/dist/apps/control-plane/core/collisions.js +78 -0
- package/dist/apps/control-plane/core/collisions.js.map +1 -0
- package/dist/apps/control-plane/core/constants.d.ts +64 -0
- package/dist/apps/control-plane/core/constants.js +64 -0
- package/dist/apps/control-plane/core/constants.js.map +1 -0
- package/dist/apps/control-plane/core/error-codes.d.ts +50 -0
- package/dist/apps/control-plane/core/error-codes.js +52 -0
- package/dist/apps/control-plane/core/error-codes.js.map +1 -0
- package/dist/apps/control-plane/core/frontmatter.d.ts +11 -0
- package/dist/apps/control-plane/core/frontmatter.js +30 -0
- package/dist/apps/control-plane/core/frontmatter.js.map +1 -0
- package/dist/apps/control-plane/core/fs.d.ts +33 -0
- package/dist/apps/control-plane/core/fs.js +134 -0
- package/dist/apps/control-plane/core/fs.js.map +1 -0
- package/dist/apps/control-plane/core/gates.d.ts +88 -0
- package/dist/apps/control-plane/core/gates.js +229 -0
- package/dist/apps/control-plane/core/gates.js.map +1 -0
- package/dist/apps/control-plane/core/git.d.ts +31 -0
- package/dist/apps/control-plane/core/git.js +79 -0
- package/dist/apps/control-plane/core/git.js.map +1 -0
- package/dist/apps/control-plane/core/kernel.d.ts +445 -0
- package/dist/apps/control-plane/core/kernel.js +805 -0
- package/dist/apps/control-plane/core/kernel.js.map +1 -0
- package/dist/apps/control-plane/core/patch.d.ts +23 -0
- package/dist/apps/control-plane/core/patch.js +118 -0
- package/dist/apps/control-plane/core/patch.js.map +1 -0
- package/dist/apps/control-plane/core/path-layout.d.ts +23 -0
- package/dist/apps/control-plane/core/path-layout.js +90 -0
- package/dist/apps/control-plane/core/path-layout.js.map +1 -0
- package/dist/apps/control-plane/core/path-rules.d.ts +13 -0
- package/dist/apps/control-plane/core/path-rules.js +52 -0
- package/dist/apps/control-plane/core/path-rules.js.map +1 -0
- package/dist/apps/control-plane/core/qa-index.d.ts +53 -0
- package/dist/apps/control-plane/core/qa-index.js +112 -0
- package/dist/apps/control-plane/core/qa-index.js.map +1 -0
- package/dist/apps/control-plane/core/response.d.ts +19 -0
- package/dist/apps/control-plane/core/response.js +34 -0
- package/dist/apps/control-plane/core/response.js.map +1 -0
- package/dist/apps/control-plane/core/runtime-sessions.d.ts +19 -0
- package/dist/apps/control-plane/core/runtime-sessions.js +2 -0
- package/dist/apps/control-plane/core/runtime-sessions.js.map +1 -0
- package/dist/apps/control-plane/core/schemas.d.ts +23 -0
- package/dist/apps/control-plane/core/schemas.js +80 -0
- package/dist/apps/control-plane/core/schemas.js.map +1 -0
- package/dist/apps/control-plane/index.d.ts +11 -0
- package/dist/apps/control-plane/index.js +9 -0
- package/dist/apps/control-plane/index.js.map +1 -0
- package/dist/apps/control-plane/interfaces/cli/bootstrap.d.ts +2 -0
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +86 -0
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -0
- package/dist/apps/control-plane/mcp/kernel-tool-executor.d.ts +14 -0
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js +26 -0
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -0
- package/dist/apps/control-plane/mcp/mcp-server-adapter.d.ts +19 -0
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js +55 -0
- package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -0
- package/dist/apps/control-plane/mcp/operation-ledger.d.ts +21 -0
- package/dist/apps/control-plane/mcp/operation-ledger.js +75 -0
- package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -0
- package/dist/apps/control-plane/mcp/protocol-contract.d.ts +8 -0
- package/dist/apps/control-plane/mcp/protocol-contract.js +9 -0
- package/dist/apps/control-plane/mcp/protocol-contract.js.map +1 -0
- package/dist/apps/control-plane/mcp/runtime-factory.d.ts +38 -0
- package/dist/apps/control-plane/mcp/runtime-factory.js +71 -0
- package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -0
- package/dist/apps/control-plane/mcp/runtime-types.d.ts +40 -0
- package/dist/apps/control-plane/mcp/runtime-types.js +2 -0
- package/dist/apps/control-plane/mcp/runtime-types.js.map +1 -0
- package/dist/apps/control-plane/mcp/token-auth-verifier.d.ts +24 -0
- package/dist/apps/control-plane/mcp/token-auth-verifier.js +45 -0
- package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -0
- package/dist/apps/control-plane/mcp/token-claims-validator.d.ts +9 -0
- package/dist/apps/control-plane/mcp/token-claims-validator.js +62 -0
- package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -0
- package/dist/apps/control-plane/mcp/token-codec.d.ts +11 -0
- package/dist/apps/control-plane/mcp/token-codec.js +46 -0
- package/dist/apps/control-plane/mcp/token-codec.js.map +1 -0
- package/dist/apps/control-plane/mcp/tool-authorizer.d.ts +8 -0
- package/dist/apps/control-plane/mcp/tool-authorizer.js +36 -0
- package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -0
- package/dist/apps/control-plane/mcp/tool-client.d.ts +30 -0
- package/dist/apps/control-plane/mcp/tool-client.js +50 -0
- package/dist/apps/control-plane/mcp/tool-client.js.map +1 -0
- package/dist/apps/control-plane/mcp/tool-contract-validator.d.ts +29 -0
- package/dist/apps/control-plane/mcp/tool-contract-validator.js +61 -0
- package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -0
- package/dist/apps/control-plane/mcp/tool-registry-loader.d.ts +15 -0
- package/dist/apps/control-plane/mcp/tool-registry-loader.js +109 -0
- package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -0
- package/dist/apps/control-plane/mcp/tool-runtime.d.ts +34 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js +252 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -0
- package/dist/apps/control-plane/mcp/tools-markdown-generator.d.ts +7 -0
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js +22 -0
- package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -0
- package/dist/apps/control-plane/mcp/transport-types.d.ts +14 -0
- package/dist/apps/control-plane/mcp/transport-types.js +2 -0
- package/dist/apps/control-plane/mcp/transport-types.js.map +1 -0
- package/dist/apps/control-plane/mcp/types.d.ts +2 -0
- package/dist/apps/control-plane/mcp/types.js +3 -0
- package/dist/apps/control-plane/mcp/types.js.map +1 -0
- package/dist/apps/control-plane/providers/providers.d.ts +72 -0
- package/dist/apps/control-plane/providers/providers.js +94 -0
- package/dist/apps/control-plane/providers/providers.js.map +1 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +13 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +40 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -0
- package/dist/apps/control-plane/supervisor/lease-heartbeat-service.d.ts +12 -0
- package/dist/apps/control-plane/supervisor/lease-heartbeat-service.js +14 -0
- package/dist/apps/control-plane/supervisor/lease-heartbeat-service.js.map +1 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +19 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +249 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -0
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.d.ts +9 -0
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +53 -0
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js.map +1 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +24 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +70 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +49 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.js +162 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -0
- package/dist/apps/control-plane/supervisor/runtime.d.ts +58 -0
- package/dist/apps/control-plane/supervisor/runtime.js +270 -0
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +29 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +211 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -0
- package/dist/apps/control-plane/supervisor/types.d.ts +148 -0
- package/dist/apps/control-plane/supervisor/types.js +2 -0
- package/dist/apps/control-plane/supervisor/types.js.map +1 -0
- package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +37 -0
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +236 -0
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -0
- package/docker/mcp.Dockerfile +14 -0
- package/docker/mcp.compose.yaml +15 -0
- package/docker/mcp.entrypoint.sh +17 -0
- package/eslint.config.mjs +93 -0
- package/example-configurations/README.md +26 -0
- package/example-configurations/java/agents.yaml +14 -0
- package/example-configurations/java/gates.yaml +29 -0
- package/example-configurations/java/policy.yaml +148 -0
- package/example-configurations/node/agents.yaml +14 -0
- package/example-configurations/node/gates.yaml +32 -0
- package/example-configurations/node/policy.yaml +143 -0
- package/nx.json +16 -0
- package/package.json +39 -0
- package/prompts/vitest-testing-standards.instructions.md +204 -0
- package/scripts/dev-shell-env.sh +7 -0
- package/scripts/nx-safe.mjs +33 -0
- package/spec-files/agentic_orchestrator_cli_delete_command_spec.md +310 -0
- package/spec-files/agentic_orchestrator_dot_aop_generated_artifacts_spec.md +211 -0
- package/spec-files/agentic_orchestrator_mcp_formalization_spec.md +379 -0
- package/spec-files/agentic_orchestrator_oop_refactor_spec.md +415 -0
- package/spec-files/agentic_orchestrator_single_global_orchestrator_spec.md +265 -0
- package/spec-files/agentic_orchestrator_spec.md +1334 -0
- package/spec-files/progress.md +452 -0
- package/tsconfig.base.json +15 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,1334 @@
|
|
|
1
|
+
# Feature Spec: MCP‑First, Platform‑Agnostic Multi‑Agent Orchestrator for Parallel Feature Development (AOP)
|
|
2
|
+
|
|
3
|
+
> **Purpose of this document**: A single, implementable specification an AI agent can use to build the complete feature set described across the conversation: an **MCP-first “kernel”** plus a **Supervisor Runtime** that runs an **Orchestrator/Agent‑Cluster architecture** to develop **multiple features in parallel** with deterministic gates, collision detection, locks, worktrees, evidence, and auditable state.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Objectives
|
|
8
|
+
|
|
9
|
+
### 1.1 Must‑Have Capabilities
|
|
10
|
+
|
|
11
|
+
- **MCP-first kernel** (deterministic): Git worktrees, patch application, gate execution, locking, collision detection, evidence/log capture, and canonical state writing.
|
|
12
|
+
- **Platform-agnostic**: Gate commands are defined by repo-local config (`agentic/orchestrator/gates.yaml`) and executed by MCP; no toolchain-specific logic in MCP beyond generic process execution and optional artifact parsing.
|
|
13
|
+
- **Implementation substrate**: The orchestrator implementation itself MUST be delivered as an **Nx monorepo**.
|
|
14
|
+
- **Testing standard**: The orchestrator implementation test framework MUST be **Vitest**.
|
|
15
|
+
- **Scope of Nx+Vitest requirement**: This applies only to the orchestrator control-plane codebase (CLI/Supervisor/MCP). It does not constrain managed target repository toolchains.
|
|
16
|
+
- **Orchestrator/Agent Cluster model**:
|
|
17
|
+
- User only interacts with **Orchestrator Agent**.
|
|
18
|
+
- Orchestrator consumes `spec.md` per feature and supervises an **Agent Cluster (Planner, Builder, QA)** per feature.
|
|
19
|
+
- **Supervisor Runtime** spawns worker sessions and enforces role permissions.
|
|
20
|
+
- **Parallelism**: Support at least **5 features** in parallel with isolation using **git worktrees** and conflict prevention using **locks + collision detection** at plan time.
|
|
21
|
+
- **Host review**: All changes must be visible on host filesystem prior to merge. User review occurs while feature diffs are still unmerged.
|
|
22
|
+
- **Explicit merge control**: MCP/Supervisor MUST NOT auto-merge as part of gate success alone. Commit + merge is only allowed through an explicit `feature.ready_to_merge` tool call after user approval.
|
|
23
|
+
|
|
24
|
+
### 1.2 Non‑Goals
|
|
25
|
+
|
|
26
|
+
- Not building a proprietary agent model framework.
|
|
27
|
+
- Not requiring cloud infrastructure.
|
|
28
|
+
- Not forcing auto-merge; explicit user review and approval remain default.
|
|
29
|
+
- Not implementing a full PR hosting integration (optional later).
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 2. Concepts and Terminology
|
|
34
|
+
|
|
35
|
+
- **Control Plane (deterministic)**: MCP server + tool handlers.
|
|
36
|
+
- **Cognitive Plane (non-deterministic)**: Orchestrator agent and worker agents generating plans/patches and reacting to logs.
|
|
37
|
+
- **Agent Cluster (AC)**: Planner + Builder + QA agents for a single feature.
|
|
38
|
+
- **Ralph Loop**: propose → validate (via MCP gates) → repair → repeat.
|
|
39
|
+
- **Worktree**: Separate checkout per feature branch via `git worktree`.
|
|
40
|
+
- **Gate**: A deterministic command sequence that must pass (exit code 0 and policy constraints) to advance.
|
|
41
|
+
- **Lock**: Exclusive resource ownership (openapi, db migrations, protected libs, etc.).
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 3. System Architecture
|
|
46
|
+
|
|
47
|
+
### 3.1 Processes
|
|
48
|
+
|
|
49
|
+
**A) MCP Server (inside Docker, bind-mounted repo)**
|
|
50
|
+
- Exposes tools via MCP.
|
|
51
|
+
- Runs git and gate commands inside bind mount.
|
|
52
|
+
- Enforces schemas, policies, locks, collisions, and patch constraints.
|
|
53
|
+
- Writes canonical state and evidence.
|
|
54
|
+
|
|
55
|
+
**B) Supervisor Runtime (outside MCP, vendor-agnostic)**
|
|
56
|
+
- Responsible for “spinning up agents” (Orchestrator + workers).
|
|
57
|
+
- Applies role-scoped tool permissions.
|
|
58
|
+
- Runs orchestration algorithm across features and clusters.
|
|
59
|
+
|
|
60
|
+
**C) Agent Runtime(s) (Claude Code, Codex CLI, etc.)**
|
|
61
|
+
- Connect to MCP tools.
|
|
62
|
+
- Generate structured artifacts and diffs under Supervisor control.
|
|
63
|
+
|
|
64
|
+
> **Key design decision**: MCP server is vendor-agnostic and should **not** call Claude/Codex directly. The Supervisor Runtime owns provider-specific session management.
|
|
65
|
+
|
|
66
|
+
### 3.2 Docker + Host Visibility
|
|
67
|
+
|
|
68
|
+
- Target repo **MUST be bind-mounted** into container at `/repo`.
|
|
69
|
+
- Worktrees MUST be created under `/repo/.worktrees/<featureId>` (or configurable but within bind mount).
|
|
70
|
+
- Therefore host sees changes immediately at `<repo>/.worktrees/<featureId>`.
|
|
71
|
+
|
|
72
|
+
### 3.3 Isolation and Parallelism
|
|
73
|
+
|
|
74
|
+
- For N features in parallel (target 5): one worktree per feature branch.
|
|
75
|
+
- MCP never switches the main working tree branch; it operates only in the worktree per feature.
|
|
76
|
+
- Concurrency controls:
|
|
77
|
+
- gate execution concurrency limit (CPU)
|
|
78
|
+
- lock ownership checks
|
|
79
|
+
- collision rejection/blocking at plan submit
|
|
80
|
+
|
|
81
|
+
### 3.4 State Consistency (Atomicity + Concurrency)
|
|
82
|
+
|
|
83
|
+
- All writes to `agentic/features/index.json` and `agentic/features/*/state.md` MUST be atomic using write-temp + fsync + rename semantics.
|
|
84
|
+
- MCP MUST serialize mutations with file locks:
|
|
85
|
+
- global index lock for `index.json` updates
|
|
86
|
+
- per-feature lock for `state.md` + `plan.json` updates
|
|
87
|
+
- State-bearing files MUST include `version` (monotonic integer).
|
|
88
|
+
- Mutating tools MUST use optimistic concurrency (`expected_version`) and fail with `error=version_conflict` when stale.
|
|
89
|
+
- Deterministic ordering rule for concurrent lock acquisitions: lexicographic lock ordering by resource id.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 4. Repo File Layout (Canonical)
|
|
94
|
+
|
|
95
|
+
At repo root:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
agentic/
|
|
99
|
+
orchestrator/
|
|
100
|
+
gates.yaml
|
|
101
|
+
policy.yaml
|
|
102
|
+
agents.yaml
|
|
103
|
+
prompts/
|
|
104
|
+
planner.system.md
|
|
105
|
+
builder.system.md
|
|
106
|
+
qa.system.md
|
|
107
|
+
schemas/
|
|
108
|
+
plan.schema.json
|
|
109
|
+
state.schema.json
|
|
110
|
+
index.schema.json
|
|
111
|
+
gates.schema.json
|
|
112
|
+
policy.schema.json
|
|
113
|
+
agents.schema.json
|
|
114
|
+
qa_test_index.schema.json
|
|
115
|
+
tools/
|
|
116
|
+
catalog.json
|
|
117
|
+
protocol.json
|
|
118
|
+
errors.schema.json
|
|
119
|
+
schemas/
|
|
120
|
+
input/*.schema.json
|
|
121
|
+
output/*.schema.json
|
|
122
|
+
tools.md
|
|
123
|
+
features/
|
|
124
|
+
index.json
|
|
125
|
+
my_feature/
|
|
126
|
+
spec.md
|
|
127
|
+
state.md
|
|
128
|
+
plan.json
|
|
129
|
+
qa_test_index.json
|
|
130
|
+
decisions.md
|
|
131
|
+
logs/
|
|
132
|
+
evidence/
|
|
133
|
+
another_feature/...
|
|
134
|
+
.git/
|
|
135
|
+
.worktrees/
|
|
136
|
+
my_feature/
|
|
137
|
+
another_feature/
|
|
138
|
+
...
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 5. Deterministic vs Agent Responsibilities
|
|
144
|
+
|
|
145
|
+
### 5.1 MCP (deterministic) MUST do
|
|
146
|
+
|
|
147
|
+
- Validate `plan.json` against schema and policy.
|
|
148
|
+
- Validate `state.md` front matter against schema when writing.
|
|
149
|
+
- Detect collisions at plan time using accepted plans.
|
|
150
|
+
- Enforce locks for contract resources and protected areas.
|
|
151
|
+
- Apply patches with policy enforcement (allowed areas, planned files, lock constraints).
|
|
152
|
+
- Run gates from config; capture logs; parse artifacts; enforce thresholds.
|
|
153
|
+
- Persist evidence and update state files.
|
|
154
|
+
- Produce review bundles (diff summaries, evidence summaries).
|
|
155
|
+
- Enforce legal status transitions and optimistic concurrency on state changes.
|
|
156
|
+
- Enforce configuration precedence across policy/gates/plan overrides.
|
|
157
|
+
- Maintain per-feature `qa_test_index.json` from current worktree diff (file + line hunk granularity).
|
|
158
|
+
- Provide resumable context bundles for agent respawn (state, plan, diff/evidence summary, QA index).
|
|
159
|
+
|
|
160
|
+
### 5.2 Agents MUST do
|
|
161
|
+
|
|
162
|
+
- Interpret `spec.md` and existing code patterns.
|
|
163
|
+
- Produce `plan.json` and diffs (unified patches).
|
|
164
|
+
- Use Ralph Loop by reacting to MCP gate outputs.
|
|
165
|
+
- Orchestrator chooses collision resolution strategy and merge order.
|
|
166
|
+
|
|
167
|
+
### 5.3 Supervisor Runtime MUST do (enforcement that is *not* MCP)
|
|
168
|
+
|
|
169
|
+
- Spawn/maintain sessions for orchestrator + workers.
|
|
170
|
+
- Enforce role tool permissions (tool-call firewall).
|
|
171
|
+
- Route tool results and failure logs to the correct worker.
|
|
172
|
+
- Decide when to advance phase: planning → building → qa → ready.
|
|
173
|
+
- Support ephemeral QA workers: close QA session after a test batch and respawn later with MCP-sourced context.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 6. Schemas (Formal Definitions)
|
|
178
|
+
|
|
179
|
+
> **Requirement**: MCP server MUST load these schemas from `agentic/orchestrator/schemas/` and validate on relevant tool calls. Rejection MUST be structured and actionable.
|
|
180
|
+
|
|
181
|
+
### 6.0 MCP Tool Contract Schemas
|
|
182
|
+
|
|
183
|
+
In addition to runtime state schemas, the MCP boundary MUST be formalized with:
|
|
184
|
+
- `agentic/orchestrator/tools/catalog.json` as the single source of truth for tool metadata and schema references.
|
|
185
|
+
- `agentic/orchestrator/tools/protocol.json` for pinned MCP protocol/SDK/transports.
|
|
186
|
+
- `agentic/orchestrator/tools/errors.schema.json` for normalized error envelopes.
|
|
187
|
+
- `agentic/orchestrator/tools/schemas/input/*.schema.json` and `agentic/orchestrator/tools/schemas/output/*.schema.json` for per-tool contracts.
|
|
188
|
+
|
|
189
|
+
Contract validation MUST fail CI when protocol pins drift or when `catalog.json`, `tools.md`, and schema files are out of sync.
|
|
190
|
+
|
|
191
|
+
### 6.1 `plan.json` JSON Schema (`plan.schema.json`)
|
|
192
|
+
|
|
193
|
+
**Required fields**:
|
|
194
|
+
- `feature_id` (string, derived from spec filename; pattern `^[a-z0-9_][a-z0-9_-]*$` recommended)
|
|
195
|
+
- `plan_version` (integer, starts at `1`, increments by `+1` on each accepted update)
|
|
196
|
+
- `summary` (string, min 5 chars)
|
|
197
|
+
- `allowed_areas` (array of non-empty strings)
|
|
198
|
+
- `forbidden_areas` (array; can be empty)
|
|
199
|
+
- `base_ref` (string, commit SHA or ref used for planning snapshot)
|
|
200
|
+
- `files` object:
|
|
201
|
+
- `create` array
|
|
202
|
+
- `modify` array
|
|
203
|
+
- `delete` array
|
|
204
|
+
- `contracts` object with enums:
|
|
205
|
+
- `openapi`: `"none" | "modify"`
|
|
206
|
+
- `events`: `"none" | "modify"`
|
|
207
|
+
- `db`: `"none" | "migration"`
|
|
208
|
+
- `acceptance_criteria` (array of non-empty strings, minItems=1)
|
|
209
|
+
- `gate_profile` (string, default `"default"`)
|
|
210
|
+
- Optional: `gate_targets` (array of strings)
|
|
211
|
+
- Optional: `verification_overrides` (object) – see below
|
|
212
|
+
- Optional: `risk` (array of strings)
|
|
213
|
+
- Optional: `revision_of` (integer plan version being replaced)
|
|
214
|
+
- Optional: `revision_reason` (string)
|
|
215
|
+
|
|
216
|
+
**Verification overrides** (optional):
|
|
217
|
+
- `modes.fast.steps` array of gate step overrides (rare; discourage)
|
|
218
|
+
- `modes.full.steps` overrides
|
|
219
|
+
Default behavior is use `gates.yaml`.
|
|
220
|
+
|
|
221
|
+
**Plan revision rules**:
|
|
222
|
+
- First accepted plan MUST have `plan_version=1` and no `revision_of`.
|
|
223
|
+
- `plan.update` MUST require `expected_plan_version` and reject stale updates.
|
|
224
|
+
- MCP MUST re-run schema, policy, lock, and collision checks for every revision.
|
|
225
|
+
|
|
226
|
+
**Plan Schema (canonical draft)**: see Appendix A for full JSON Schema.
|
|
227
|
+
|
|
228
|
+
### 6.2 `state.md` JSON Schema (`state.schema.json`)
|
|
229
|
+
|
|
230
|
+
State file is Markdown with YAML front matter. MCP validates the front matter object.
|
|
231
|
+
|
|
232
|
+
Required fields:
|
|
233
|
+
- `feature_id` (string)
|
|
234
|
+
- `version` (integer, monotonic)
|
|
235
|
+
- `branch` (string)
|
|
236
|
+
- `worktree_path` (string)
|
|
237
|
+
- `status` enum: `planning|building|qa|blocked|ready_to_merge|merged|failed`
|
|
238
|
+
- `gate_profile` (string)
|
|
239
|
+
- `gates` object with gate result enums `pass|fail|na`
|
|
240
|
+
- `locks.held` array
|
|
241
|
+
- `collisions` structure
|
|
242
|
+
- `cluster` session ids (strings; may be `"unknown"` if runtime doesn’t provide)
|
|
243
|
+
- `role_status` for planner/builder/qa
|
|
244
|
+
- `last_updated` ISO string
|
|
245
|
+
- Optional: `evidence` object (last gate id, artifacts)
|
|
246
|
+
- Optional: `status_reason` (string)
|
|
247
|
+
|
|
248
|
+
### 6.3 `index.json` JSON Schema (`index.schema.json`)
|
|
249
|
+
|
|
250
|
+
Tracks global orchestration status.
|
|
251
|
+
|
|
252
|
+
Required fields:
|
|
253
|
+
- `version` integer (monotonic)
|
|
254
|
+
- `active` array of feature ids
|
|
255
|
+
- `blocked` array
|
|
256
|
+
- `merged` array
|
|
257
|
+
- `locks` object mapping resource name → feature id or null
|
|
258
|
+
- `lock_leases` object mapping resource name → lease metadata (holder, lease_id, expires_at)
|
|
259
|
+
- `blocked_queue` array (for `collision_policy=block`)
|
|
260
|
+
- Optional: `updated_at`
|
|
261
|
+
|
|
262
|
+
### 6.4 `gates.yaml` Schema (`gates.schema.json`)
|
|
263
|
+
|
|
264
|
+
YAML is validated by loading and validating against JSON schema equivalent.
|
|
265
|
+
|
|
266
|
+
Required fields:
|
|
267
|
+
- `version` number
|
|
268
|
+
- `profiles` object:
|
|
269
|
+
- profile name → profile object
|
|
270
|
+
- Profile object required:
|
|
271
|
+
- `modes` object:
|
|
272
|
+
- mode name (`fast`, `full`, optional `merge`) → array of steps
|
|
273
|
+
- Step object required:
|
|
274
|
+
- `name` string
|
|
275
|
+
- `cmd` array of strings (exec args)
|
|
276
|
+
- Optional: `cwd` string (relative to worktree root)
|
|
277
|
+
- Optional: `env` object
|
|
278
|
+
- Optional: `timeout_seconds` number
|
|
279
|
+
|
|
280
|
+
Optional:
|
|
281
|
+
- `parsers.coverage` with:
|
|
282
|
+
- `type`: `none|lcov|junit_xml|jacoco_xml|cobertura_xml|custom`
|
|
283
|
+
- `path` string
|
|
284
|
+
- `thresholds.coverage_line_min` number 0..1
|
|
285
|
+
- `thresholds.coverage_branch_min` number 0..1
|
|
286
|
+
- `thresholds.coverage_line_target` number 0..1
|
|
287
|
+
- `thresholds.coverage_branch_target` number 0..1
|
|
288
|
+
- `capabilities` list (declares supported parsers)
|
|
289
|
+
|
|
290
|
+
### 6.5 `policy.yaml` Schema (`policy.schema.json`)
|
|
291
|
+
|
|
292
|
+
Required fields:
|
|
293
|
+
- `version`
|
|
294
|
+
- `commit_policy.allow_commit` boolean
|
|
295
|
+
- `commit_policy.allow_merge` boolean
|
|
296
|
+
- `patch_policy.enforce_plan` boolean
|
|
297
|
+
- `patch_policy.enforce_allowed_areas` boolean
|
|
298
|
+
- `locks.resources` array
|
|
299
|
+
- `locks.contract_to_resource` object (`openapi|events|db` to lock resource id)
|
|
300
|
+
- `locks.lease_ttl_seconds` number
|
|
301
|
+
- `protected_areas` array
|
|
302
|
+
- `exclusive_areas` array (optional but recommended for high-collision repos)
|
|
303
|
+
- `required_modes` array
|
|
304
|
+
- `required_merge_mode` string
|
|
305
|
+
- `collision_policy` enum `reject|block`
|
|
306
|
+
- `config_precedence` object defining deterministic precedence:
|
|
307
|
+
- `policy_hard_constraints`
|
|
308
|
+
- `gates_profile_defaults`
|
|
309
|
+
- `plan_verification_overrides`
|
|
310
|
+
- `locks.acquire_behavior` enum `wait|fail` (default `wait`)
|
|
311
|
+
- `locks.default_wait_timeout_seconds` number (default `300`)
|
|
312
|
+
- `locks.acquire_backoff` object with jittered exponential settings
|
|
313
|
+
- `rbac` matrix: role -> allowed tool names
|
|
314
|
+
- `path_rules` object:
|
|
315
|
+
- `matching` enum `repo_prefix|glob`
|
|
316
|
+
- `normalize_paths` boolean (must be true)
|
|
317
|
+
- `allow_symlink_traversal` boolean (must default false)
|
|
318
|
+
- `execution.default_step_timeout_seconds` number (default `600`)
|
|
319
|
+
- `execution.retry_policy` object:
|
|
320
|
+
- `transient_max_retries` number (default `1`)
|
|
321
|
+
- `transient_error_codes` array
|
|
322
|
+
- `non_retryable_error_codes` array
|
|
323
|
+
- `execution.env_allowlist` array
|
|
324
|
+
- `implementation.workspace` enum `nx` (required for this implementation)
|
|
325
|
+
- `testing.framework` enum `vitest`
|
|
326
|
+
- `testing.coverage.minimums.line` number (default `0.90`)
|
|
327
|
+
- `testing.coverage.minimums.branch` number (default `0.90`)
|
|
328
|
+
- `testing.coverage.targets.line` number (default `1.00`)
|
|
329
|
+
- `testing.coverage.targets.branch` number (default `1.00`)
|
|
330
|
+
- `merge_policy.require_user_approval` boolean
|
|
331
|
+
- `merge_policy.allowed_strategies` array (`merge_commit|squash|rebase`)
|
|
332
|
+
- `worktree.base_branch` string (for initial branch cut)
|
|
333
|
+
- Optional additional thresholds (coverage, performance, repo-specific gates) beyond the required testing minima above.
|
|
334
|
+
|
|
335
|
+
Policy interpretation notes:
|
|
336
|
+
- `commit_policy.*` controls direct low-level commit tools (`repo.commit`).
|
|
337
|
+
- `merge_policy.*` controls high-level merge promotion (`feature.ready_to_merge`), including the commit created as part of merge promotion.
|
|
338
|
+
- `implementation.workspace` and `testing.*` constrain the orchestrator codebase implementation; they do not remove platform-agnostic support for managed target repositories.
|
|
339
|
+
|
|
340
|
+
### 6.6 Path Canonicalization and Matching Rules
|
|
341
|
+
|
|
342
|
+
- MCP MUST canonicalize all candidate paths to repo-relative POSIX form before validation.
|
|
343
|
+
- Any path that escapes repo root (`..`, absolute host paths) MUST fail with `error=path_out_of_bounds`.
|
|
344
|
+
- Symlink traversal outside repo root is forbidden by default and controlled by `policy.path_rules.allow_symlink_traversal`.
|
|
345
|
+
- Area matching semantics are policy-controlled:
|
|
346
|
+
- `repo_prefix`: area `src/api` means any path with that normalized prefix.
|
|
347
|
+
- `glob`: area values interpreted as POSIX globs.
|
|
348
|
+
- `repo.apply_patch` MUST evaluate renamed, copied, deleted, and mode-changed files against plan/policy with both old and new paths.
|
|
349
|
+
|
|
350
|
+
### 6.7 `agents.yaml` Schema (`agents.schema.json`)
|
|
351
|
+
|
|
352
|
+
Repo-level worker prompt configuration.
|
|
353
|
+
|
|
354
|
+
Required fields:
|
|
355
|
+
- `version`
|
|
356
|
+
- `roles` object:
|
|
357
|
+
- `planner.system_prompt_path` (optional)
|
|
358
|
+
- `builder.system_prompt_path` (optional)
|
|
359
|
+
- `qa.system_prompt_path` (optional)
|
|
360
|
+
- `missing_prompt_behavior` enum `ignore|error` (default `ignore`)
|
|
361
|
+
- Optional `runtime` object:
|
|
362
|
+
- `default_provider` enum `codex|claude|gemini|custom`
|
|
363
|
+
- `default_model` string
|
|
364
|
+
- `provider_config_env` string (env var name containing provider auth/config)
|
|
365
|
+
- `role_provider_overrides` object (optional per-role provider/model overrides)
|
|
366
|
+
|
|
367
|
+
Prompt loading rules:
|
|
368
|
+
- If configured prompt path exists, Supervisor MUST load and inject it as the role system prompt.
|
|
369
|
+
- If path is absent or file missing and `missing_prompt_behavior=ignore`, Supervisor uses built-in defaults.
|
|
370
|
+
- Prompt paths MUST be repo-relative and validated with path rules (§6.6).
|
|
371
|
+
- Provider defaults in `runtime` are used only when CLI/env do not override.
|
|
372
|
+
|
|
373
|
+
### 6.8 `qa_test_index.json` Schema (`qa_test_index.schema.json`)
|
|
374
|
+
|
|
375
|
+
Per-feature QA execution index used to keep QA agent context small and resumable.
|
|
376
|
+
|
|
377
|
+
Required fields:
|
|
378
|
+
- `feature_id`
|
|
379
|
+
- `version` (integer, monotonic)
|
|
380
|
+
- `source_diff_ref` (string identifying diff snapshot)
|
|
381
|
+
- `items` array where each item includes:
|
|
382
|
+
- `path` (repo-relative)
|
|
383
|
+
- `hunks` array of `{start_line, end_line, change_type}`
|
|
384
|
+
- `required_tests` array of strings
|
|
385
|
+
- `status` enum `pending|running|passed|failed|waived`
|
|
386
|
+
- optional `last_run_at`
|
|
387
|
+
- optional `evidence_refs` array
|
|
388
|
+
|
|
389
|
+
Rules:
|
|
390
|
+
- MCP MUST update file/hunk entries after every successful `repo.apply_patch`.
|
|
391
|
+
- MCP MUST compute `required_tests` deterministically from configured gate steps and changed paths/hunks so QA sees exact pending test obligations at any time.
|
|
392
|
+
- QA agent MUST update statuses/evidence after each executed test batch.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## 7. MCP Tool Catalog (Deterministic Kernel)
|
|
397
|
+
|
|
398
|
+
### 7.1 Tool Contract Norms
|
|
399
|
+
|
|
400
|
+
All tools MUST:
|
|
401
|
+
- Accept `actor_type` (`orchestrator|planner|builder|qa|system`) and `actor_id` (string).
|
|
402
|
+
- Return JSON with at least:
|
|
403
|
+
- `ok` boolean
|
|
404
|
+
- `data` object if ok
|
|
405
|
+
- `error` object if not ok
|
|
406
|
+
- `evidence` object when relevant (log paths, command, exit code)
|
|
407
|
+
|
|
408
|
+
Tools MUST be idempotent when reasonable (`ensure_worktree`, `feature.init`).
|
|
409
|
+
Mutating tools MUST require `expected_version` for optimistic concurrency where a state/index file is updated.
|
|
410
|
+
Authorization MUST be deny-by-default; any disallowed role/tool attempt fails with `error=forbidden_tool_for_role`.
|
|
411
|
+
|
|
412
|
+
### 7.1.1 Normative RBAC Matrix (Default)
|
|
413
|
+
|
|
414
|
+
- `orchestrator`: may call all read/report tools, `feature.init`, `plan.get`, `plan.submit`, `plan.update`, `locks.acquire`, `locks.release`, `gates.run`, `feature.ready_to_merge`.
|
|
415
|
+
- `planner`: may call read tools, `plan.submit`, `plan.update`, `collisions.scan`.
|
|
416
|
+
- `builder`: may call read tools, `repo.apply_patch`, `repo.status`, `repo.diff`, `gates.run`.
|
|
417
|
+
- `qa`: may call read tools, `repo.apply_patch`, `repo.diff`, `gates.run`, `evidence.latest`, `qa.test_index_get`, `qa.test_index_update`.
|
|
418
|
+
- `system`: unrestricted internal automation role.
|
|
419
|
+
- `feature.state_patch` is restricted to `system|orchestrator` unless policy explicitly expands access.
|
|
420
|
+
- `locks.acquire`/`locks.release` are restricted to `orchestrator|system`; worker roles request lock actions via `REQUEST`.
|
|
421
|
+
|
|
422
|
+
### 7.2 Required Tools (V1)
|
|
423
|
+
|
|
424
|
+
#### Feature lifecycle
|
|
425
|
+
1) `feature.discover_specs()`
|
|
426
|
+
- Returns list of `{feature_id, spec_path}` under `agentic/features/*/spec.md`.
|
|
427
|
+
|
|
428
|
+
2) `feature.init(feature_id)`
|
|
429
|
+
- Creates feature folder structure if missing.
|
|
430
|
+
- Creates/ensures branch + worktree (see `repo.ensure_worktree`).
|
|
431
|
+
- Writes `state.md` default with `status=planning`.
|
|
432
|
+
|
|
433
|
+
3) `feature.get_context(feature_id)`
|
|
434
|
+
- Returns: spec.md text, parsed state front matter, plan.json (if exists), latest evidence summary, and current `qa_test_index.json`.
|
|
435
|
+
|
|
436
|
+
4) `feature.state_get(feature_id)`
|
|
437
|
+
- Returns parsed state front matter + raw markdown body.
|
|
438
|
+
|
|
439
|
+
5) `feature.state_patch(feature_id, expected_version, patch)`
|
|
440
|
+
- Restricted: allowed only for `actor_type=system|orchestrator` by policy; typically MCP internal.
|
|
441
|
+
- Validates against schema before writing.
|
|
442
|
+
|
|
443
|
+
6) `feature.log_append(feature_id, note)`
|
|
444
|
+
- Appends to `decisions.md` or `state.md` body section; includes `actor` stamp.
|
|
445
|
+
|
|
446
|
+
#### Plan
|
|
447
|
+
7) `plan.submit(feature_id, plan_json, expected_version?)`
|
|
448
|
+
- Validates plan schema.
|
|
449
|
+
- Enforces `policy.yaml` constraints:
|
|
450
|
+
- required fields
|
|
451
|
+
- disallowed contract changes without locks
|
|
452
|
+
- forbidden/protected areas
|
|
453
|
+
- Collision scan against other accepted plans (see §8).
|
|
454
|
+
- Persists `plan.json`.
|
|
455
|
+
- Updates `state.md` gates: `plan=pass` and status to `building` if allowed.
|
|
456
|
+
|
|
457
|
+
8) `plan.get(feature_id)`
|
|
458
|
+
|
|
459
|
+
9) `plan.update(feature_id, expected_plan_version, plan_json)`
|
|
460
|
+
- Requires `plan_json.plan_version = expected_plan_version + 1`.
|
|
461
|
+
- Requires `plan_json.revision_of = expected_plan_version`.
|
|
462
|
+
- Re-runs full validation, lock checks, and collision scan.
|
|
463
|
+
- Overwrites `plan.json` atomically only if checks pass.
|
|
464
|
+
- Existing worktree diffs are retained, but all subsequent `repo.apply_patch` operations MUST validate against the latest accepted plan.
|
|
465
|
+
|
|
466
|
+
#### Repo/worktree
|
|
467
|
+
10) `repo.ensure_worktree(feature_id)`
|
|
468
|
+
- Ensures `.worktrees/<feature_id>` exists and is checked out to `<feature_id>` branch.
|
|
469
|
+
- If branch is newly created, cut it from `policy.worktree.base_branch` at the current head SHA.
|
|
470
|
+
- Must store branch name in state.
|
|
471
|
+
|
|
472
|
+
11) `repo.apply_patch(feature_id, unified_diff)`
|
|
473
|
+
- Validates: plan exists (unless policy allows).
|
|
474
|
+
- Parses patch to determine touched paths.
|
|
475
|
+
- Enforces:
|
|
476
|
+
- touched paths ⊆ allowed_areas
|
|
477
|
+
- no forbidden/protected area edits without permission/lock
|
|
478
|
+
- touched files are in plan’s create/modify/delete lists (strict by default)
|
|
479
|
+
- contract resources require locks
|
|
480
|
+
- path normalization and path-out-of-bounds checks (§6.6)
|
|
481
|
+
- Applies patch in the worktree.
|
|
482
|
+
- Returns updated `git status --porcelain` plus list of changed files.
|
|
483
|
+
- Rebuilds or incrementally updates `qa_test_index.json` for changed files/hunks.
|
|
484
|
+
|
|
485
|
+
12) `repo.status(feature_id)`
|
|
486
|
+
13) `repo.diff(feature_id, options?)`
|
|
487
|
+
- Options: `--stat`, `--name-only`, etc.
|
|
488
|
+
|
|
489
|
+
14) `repo.read_file(feature_id, path)`
|
|
490
|
+
15) `repo.search(feature_id, query)`
|
|
491
|
+
- Wrapper around `rg` with safe defaults; returns file/line matches.
|
|
492
|
+
|
|
493
|
+
16) `repo.diff_bundle(feature_id)`
|
|
494
|
+
- Returns a “review bundle”:
|
|
495
|
+
- diff stat
|
|
496
|
+
- full diff (or path to stored diff)
|
|
497
|
+
- touched file list
|
|
498
|
+
- last gate summary
|
|
499
|
+
|
|
500
|
+
17) `feature.ready_to_merge(feature_id, commit_message, merge_strategy, user_approval_token)`
|
|
501
|
+
- Preconditions:
|
|
502
|
+
- feature status is `ready_to_merge`
|
|
503
|
+
- required `full` + `merge` modes pass (policy-controlled)
|
|
504
|
+
- `merge_policy.require_user_approval=true` implies valid `user_approval_token`
|
|
505
|
+
- Performs deterministic commit in feature branch and merge into base branch.
|
|
506
|
+
- On success:
|
|
507
|
+
- updates state status to `merged`
|
|
508
|
+
- appends merge evidence (commit SHA, merge SHA, strategy, gate snapshot)
|
|
509
|
+
- releases held locks.
|
|
510
|
+
|
|
511
|
+
> Low-level git tools MAY exist for debugging but SHOULD be blocked by RBAC for non-system roles:
|
|
512
|
+
18) `repo.commit(feature_id, message)` (internal/optional)
|
|
513
|
+
19) `repo.rebase_onto_main(feature_id)` (internal/optional)
|
|
514
|
+
20) `repo.merge(feature_id)` (internal/optional)
|
|
515
|
+
|
|
516
|
+
#### Gates/evidence
|
|
517
|
+
21) `gates.list(profile?)`
|
|
518
|
+
22) `gates.run(feature_id, profile, mode)`
|
|
519
|
+
- Loads `gates.yaml`, selects profile and mode.
|
|
520
|
+
- Runs steps sequentially (or optionally parallel if configured, but default sequential for determinism).
|
|
521
|
+
- Captures stdout/stderr per step to `logs/`.
|
|
522
|
+
- On non-zero exit code: stop and report failure.
|
|
523
|
+
- If configured, parse coverage artifact and enforce thresholds.
|
|
524
|
+
- Writes state updates:
|
|
525
|
+
- per-step results
|
|
526
|
+
- overall mode result
|
|
527
|
+
- evidence pointers
|
|
528
|
+
|
|
529
|
+
23) `evidence.latest(feature_id)`
|
|
530
|
+
- Returns last gate run summary with key log excerpt tail.
|
|
531
|
+
|
|
532
|
+
#### QA context / test index
|
|
533
|
+
24) `qa.test_index_get(feature_id)`
|
|
534
|
+
- Returns parsed `qa_test_index.json`, summary counts by status, and exact pending `required_tests` grouped by file/hunk.
|
|
535
|
+
|
|
536
|
+
25) `qa.test_index_update(feature_id, expected_version, updates, evidence_refs?)`
|
|
537
|
+
- Allowed for `qa|system|orchestrator`.
|
|
538
|
+
- Applies status updates to index entries and increments index version.
|
|
539
|
+
- Requires line-hunk references when marking entries `passed|failed|waived`.
|
|
540
|
+
- MUST be called by QA agent after each test batch.
|
|
541
|
+
|
|
542
|
+
#### Locks/collisions
|
|
543
|
+
26) `locks.acquire(resource, feature_id, wait_timeout_seconds?)`
|
|
544
|
+
- Resource names from policy.
|
|
545
|
+
- Stores in `index.json` and feature state.
|
|
546
|
+
- Enforces ownership.
|
|
547
|
+
- MUST create lease metadata (`lease_id`, `expires_at`) and renew while holder is healthy.
|
|
548
|
+
|
|
549
|
+
27) `locks.release(resource, feature_id)`
|
|
550
|
+
|
|
551
|
+
28) `collisions.scan()`
|
|
552
|
+
- Returns global collision matrix based on accepted plans.
|
|
553
|
+
|
|
554
|
+
#### Reporting (for orchestrator UX)
|
|
555
|
+
29) `report.dashboard()`
|
|
556
|
+
- Returns summary of all features: status, blocks, locks, last gates.
|
|
557
|
+
|
|
558
|
+
30) `report.feature_summary(feature_id)`
|
|
559
|
+
- Returns state summary + diff summary + latest evidence links.
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## 8. Collision Detection and Resolution
|
|
564
|
+
|
|
565
|
+
### 8.1 Collision Types (detected by MCP at `plan.submit`)
|
|
566
|
+
|
|
567
|
+
- **File collision:** two accepted plans modify the same file path.
|
|
568
|
+
- **Area collision:** overlap within protected_areas or explicitly configured “exclusive areas”.
|
|
569
|
+
- **Contract collision:** multiple plans request `openapi/events/db` modification.
|
|
570
|
+
- **Migration collision:** multiple plans set `db=migration` simultaneously (serializable via lock).
|
|
571
|
+
|
|
572
|
+
### 8.2 Collision Policy
|
|
573
|
+
|
|
574
|
+
Defined in `policy.yaml`:
|
|
575
|
+
- `collision_policy: reject|block`
|
|
576
|
+
Default: `reject` with structured report so orchestrator can revise.
|
|
577
|
+
|
|
578
|
+
If `collision_policy=block`:
|
|
579
|
+
- MCP MUST persist blocked plan requests in `index.json.blocked_queue`.
|
|
580
|
+
- Queue entries MUST include `{feature_id, plan_version, detected_at, collision_fingerprint, required_resources}`.
|
|
581
|
+
- MCP MUST re-evaluate queued entries when relevant locks are released or plans change.
|
|
582
|
+
- Queue order MUST be deterministic: oldest `detected_at`, then `feature_id`.
|
|
583
|
+
|
|
584
|
+
### 8.3 Collision Report Format
|
|
585
|
+
|
|
586
|
+
On collision, MCP returns:
|
|
587
|
+
- collision items
|
|
588
|
+
- owning feature ids
|
|
589
|
+
- normalized path/resource identifiers
|
|
590
|
+
- collision fingerprint (stable hash for dedupe)
|
|
591
|
+
- recommended actions:
|
|
592
|
+
- acquire lock
|
|
593
|
+
- revise plan to avoid overlap
|
|
594
|
+
- create “shared prerequisite” feature
|
|
595
|
+
|
|
596
|
+
Orchestrator agent decides strategy; Supervisor updates states accordingly.
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## 9. Locks
|
|
601
|
+
|
|
602
|
+
### 9.1 Lock Resources
|
|
603
|
+
|
|
604
|
+
Configured by `policy.yaml`, recommended defaults:
|
|
605
|
+
- `openapi`
|
|
606
|
+
- `events`
|
|
607
|
+
- `db_migrations`
|
|
608
|
+
- optionally: `protected:libs/core`
|
|
609
|
+
|
|
610
|
+
Contract-to-lock mapping MUST be explicit:
|
|
611
|
+
- `contracts.openapi=modify` requires lock `policy.locks.contract_to_resource.openapi` (default `openapi`).
|
|
612
|
+
- `contracts.events=modify` requires lock `policy.locks.contract_to_resource.events` (default `events`).
|
|
613
|
+
- `contracts.db=migration` requires lock `policy.locks.contract_to_resource.db` (default `db_migrations`).
|
|
614
|
+
|
|
615
|
+
Lease rules:
|
|
616
|
+
- Locks are leased, not perpetual.
|
|
617
|
+
- Lease TTL is `policy.locks.lease_ttl_seconds`.
|
|
618
|
+
- Supervisor/MCP heartbeat renews leases.
|
|
619
|
+
- Expired leases may be reclaimed by MCP with `error=stale_lock_reclaimed` evidence.
|
|
620
|
+
- Default acquisition behavior is queued/blocking (`locks.acquire_behavior=wait`) with timeout/backoff from policy.
|
|
621
|
+
|
|
622
|
+
### 9.2 Lock Enforcement
|
|
623
|
+
|
|
624
|
+
- `plan.submit` fails if plan indicates contract changes but lock not acquired.
|
|
625
|
+
- `repo.apply_patch` fails if patch touches contract paths without lock.
|
|
626
|
+
- `feature.ready_to_merge` MUST fail if any required lock is lost before merge.
|
|
627
|
+
- Lock operations are performed by `orchestrator|system`; workers issue `REQUEST` outputs for arbitration.
|
|
628
|
+
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
## 10. Supervisor Runtime (Cluster Runner) — Required Behavior
|
|
632
|
+
|
|
633
|
+
### 10.1 Responsibilities
|
|
634
|
+
|
|
635
|
+
- Maintain **one Orchestrator Agent** session (user-facing).
|
|
636
|
+
- Spawn **three worker sessions per feature**:
|
|
637
|
+
- Planner
|
|
638
|
+
- Builder
|
|
639
|
+
- QA
|
|
640
|
+
- Enforce **role-scoped tool access**:
|
|
641
|
+
- Implement a “tool-call firewall” that blocks calls not allowed for the role.
|
|
642
|
+
- Load role system prompts from `agentic/orchestrator/agents.yaml` when configured and inject at worker creation.
|
|
643
|
+
- Resolve agent runtime provider/model selection from CLI/env/config and initialize the corresponding provider adapter.
|
|
644
|
+
- Maintain lock lease heartbeats for active features.
|
|
645
|
+
- Support restart recovery:
|
|
646
|
+
- reattach to existing sessions when possible
|
|
647
|
+
- reconstruct state from `index.json` + feature states when sessions are unavailable
|
|
648
|
+
- re-drive blocked/retryable operations deterministically
|
|
649
|
+
- Run orchestration loop across features:
|
|
650
|
+
1) init
|
|
651
|
+
2) planning wave
|
|
652
|
+
3) collision arbitration
|
|
653
|
+
4) build wave
|
|
654
|
+
5) qa wave
|
|
655
|
+
6) readiness report (full gates)
|
|
656
|
+
|
|
657
|
+
### 10.2 Vendor-Agnostic Worker Interface
|
|
658
|
+
|
|
659
|
+
Supervisor must treat workers abstractly:
|
|
660
|
+
|
|
661
|
+
- Worker input: `{role, feature_id, context_bundle, instructions, last_tool_results}`
|
|
662
|
+
- Worker input MUST include runtime selection metadata: `{provider, model, provider_config_ref}`.
|
|
663
|
+
- Worker output types:
|
|
664
|
+
- `PLAN_SUBMISSION` (planner emits plan json)
|
|
665
|
+
- `PATCH` (builder/qa emits unified diff)
|
|
666
|
+
- `NOTE` (decisions/summary)
|
|
667
|
+
- `REQUEST` (ask for lock, ask to amend plan, ask for more context)
|
|
668
|
+
|
|
669
|
+
Supervisor routes outputs to MCP tools and returns results to worker.
|
|
670
|
+
|
|
671
|
+
Context bundle MUST include:
|
|
672
|
+
- current feature state + accepted plan
|
|
673
|
+
- latest evidence summary
|
|
674
|
+
- current diff summary
|
|
675
|
+
- `qa_test_index.json` for QA workers
|
|
676
|
+
|
|
677
|
+
### 10.3 Concurrency
|
|
678
|
+
|
|
679
|
+
Configurable:
|
|
680
|
+
- `max_active_features` default 5
|
|
681
|
+
- `max_parallel_gate_runs` default 2–3 (CPU dependent)
|
|
682
|
+
- `max_iterations_per_phase` default 5–10
|
|
683
|
+
- `lock_acquire_backoff_seconds` default jittered exponential backoff
|
|
684
|
+
- `lock_wait_timeout_seconds` default 300
|
|
685
|
+
|
|
686
|
+
### 10.4 Phase Advancement Rules
|
|
687
|
+
|
|
688
|
+
- Feature can move to `building` only after `plan.submit` accepted.
|
|
689
|
+
- Feature can move to `qa` only after `fast` gates pass (policy-configurable).
|
|
690
|
+
- Feature can move to `ready_to_merge` only after `full` gates pass; this state is still unmerged and reviewable.
|
|
691
|
+
- User review MUST happen while in `ready_to_merge` before merge execution.
|
|
692
|
+
- `feature.ready_to_merge` (explicit call) performs commit + merge and transitions to `merged` on success.
|
|
693
|
+
- Feature becomes `blocked` on lock denial or collision policy outcome.
|
|
694
|
+
|
|
695
|
+
Supervisor updates status through MCP state patch tool (or via MCP internal updates triggered by other tools).
|
|
696
|
+
Supervisor proposes transitions; MCP is source of truth and MUST validate transition legality.
|
|
697
|
+
|
|
698
|
+
### 10.5 Legal Status Transition Matrix (Normative)
|
|
699
|
+
|
|
700
|
+
- `planning -> building`: only via accepted `plan.submit` or `plan.update`.
|
|
701
|
+
- `building -> qa`: only via passing required `fast` gates.
|
|
702
|
+
- `qa -> ready_to_merge`: only via passing required `full` gates.
|
|
703
|
+
- `ready_to_merge -> merged`: only via successful `feature.ready_to_merge` call.
|
|
704
|
+
- `* -> blocked`: on lock/collision denial, unrecoverable gate failure, or policy violation.
|
|
705
|
+
- `blocked -> planning|building|qa`: only after explicit unblock event with `status_reason` update.
|
|
706
|
+
- Any undefined transition MUST fail with `error=invalid_status_transition`.
|
|
707
|
+
|
|
708
|
+
### 10.6 Crash Recovery and Resume Algorithm
|
|
709
|
+
|
|
710
|
+
On Supervisor or MCP restart:
|
|
711
|
+
1) Load and validate `index.json` and all active feature `state.md` files.
|
|
712
|
+
2) Reconcile lock leases:
|
|
713
|
+
- if holder heartbeat is fresh, preserve lease
|
|
714
|
+
- if stale, reclaim and mark affected features `blocked` with reason
|
|
715
|
+
3) Reconstruct pending work from:
|
|
716
|
+
- features not terminal (`merged|failed`)
|
|
717
|
+
- queued collisions (`blocked_queue`)
|
|
718
|
+
- gate runs with no terminal evidence record
|
|
719
|
+
- current `qa_test_index.json` entries not in terminal status (`passed|waived`)
|
|
720
|
+
4) Resume orchestration from the earliest incomplete phase per feature.
|
|
721
|
+
5) All tool retries MUST be idempotent and keyed by operation id; duplicate execution must not double-apply patches or merges.
|
|
722
|
+
|
|
723
|
+
### 10.7 Ephemeral QA Session Lifecycle (Context Control)
|
|
724
|
+
|
|
725
|
+
- QA workers are intentionally short-lived to prevent unbounded context growth.
|
|
726
|
+
- After each QA test batch:
|
|
727
|
+
- QA worker MUST call `qa.test_index_update`.
|
|
728
|
+
- Supervisor MUST close the QA worker session.
|
|
729
|
+
- On next QA iteration, Supervisor MUST be able to spawn a fresh QA worker that consumes:
|
|
730
|
+
- `feature.get_context`
|
|
731
|
+
- `qa.test_index_get`
|
|
732
|
+
- latest gate/evidence summaries
|
|
733
|
+
- This resume flow MUST preserve progress without requiring prior conversational context.
|
|
734
|
+
|
|
735
|
+
---
|
|
736
|
+
|
|
737
|
+
## 11. Orchestrator Agent Contract (User-Facing Behavior)
|
|
738
|
+
|
|
739
|
+
Orchestrator Agent must:
|
|
740
|
+
- Discover provided specs from CLI-resolved inputs (`-fi`/`-fl`) or canonical repo discovery and ask user which to run if more than N are present (optional; default pick first N).
|
|
741
|
+
- Report dashboard status periodically (using `report.dashboard`).
|
|
742
|
+
- Decide collision resolution (revise plan, wait, shared prerequisite).
|
|
743
|
+
- Provide user review pack before merge execution:
|
|
744
|
+
- `repo.diff_bundle`
|
|
745
|
+
- `report.feature_summary`
|
|
746
|
+
- evidence links
|
|
747
|
+
- Request explicit user approval token before invoking `feature.ready_to_merge`.
|
|
748
|
+
|
|
749
|
+
Orchestrator must never claim gates passed without MCP results.
|
|
750
|
+
|
|
751
|
+
---
|
|
752
|
+
|
|
753
|
+
## 12. Gate Execution (Platform-Agnostic)
|
|
754
|
+
|
|
755
|
+
### 12.1 Command Execution
|
|
756
|
+
|
|
757
|
+
MCP executes `cmd` arrays from `gates.yaml` with:
|
|
758
|
+
- `cwd` set to the feature worktree root
|
|
759
|
+
- safe environment with secret scrubbing enabled by default
|
|
760
|
+
- environment variable pass-through restricted to `policy.execution.env_allowlist`
|
|
761
|
+
|
|
762
|
+
### 12.2 Parsers / Metrics
|
|
763
|
+
|
|
764
|
+
Supported parsers (V1):
|
|
765
|
+
- `none`
|
|
766
|
+
- `lcov` (line coverage)
|
|
767
|
+
- `junit_xml` (pass/fail + counts)
|
|
768
|
+
- `jacoco_xml` (line coverage)
|
|
769
|
+
- `cobertura_xml` (line coverage)
|
|
770
|
+
|
|
771
|
+
If parser type is unrecognized: gate fails with `error=unsupported_parser` unless policy allows skip.
|
|
772
|
+
|
|
773
|
+
### 12.3 Threshold Enforcement
|
|
774
|
+
|
|
775
|
+
If coverage threshold configured in policy or gates:
|
|
776
|
+
- MCP must parse coverage and compare.
|
|
777
|
+
- Failure sets `gates.coverage_* = fail`.
|
|
778
|
+
|
|
779
|
+
For this implementation:
|
|
780
|
+
- Minimum blocking thresholds are `line >= 0.90` and `branch >= 0.90`.
|
|
781
|
+
- Target thresholds are `line = 1.00` and `branch = 1.00` (reported as target attainment metrics).
|
|
782
|
+
|
|
783
|
+
### 12.4 Timeouts and Retry Defaults (Normative)
|
|
784
|
+
|
|
785
|
+
- If a gate step omits `timeout_seconds`, MCP MUST apply `policy.execution.default_step_timeout_seconds` (default `600`).
|
|
786
|
+
- Retries are allowed only for transient execution failures per `policy.execution.retry_policy.transient_error_codes`.
|
|
787
|
+
- Default transient retry count is `1`.
|
|
788
|
+
- Schema/policy/authorization/path violations are non-retryable by default.
|
|
789
|
+
|
|
790
|
+
### 12.5 Configuration Precedence (Normative)
|
|
791
|
+
|
|
792
|
+
For any gate execution parameter, precedence is:
|
|
793
|
+
1) `policy.yaml` hard constraints (cannot be relaxed)
|
|
794
|
+
2) `gates.yaml` selected profile/mode defaults
|
|
795
|
+
3) `plan.json.verification_overrides` (may only narrow scope or tighten thresholds)
|
|
796
|
+
|
|
797
|
+
If a lower-priority source attempts to relax a higher-priority constraint, MCP MUST fail with `error=invalid_override_precedence`.
|
|
798
|
+
|
|
799
|
+
### 12.6 Nx + Vitest Testing Contract (Implementation)
|
|
800
|
+
|
|
801
|
+
- The orchestrator codebase MUST be implemented as an Nx monorepo.
|
|
802
|
+
- The unit/integration test runner for the orchestrator codebase MUST be Vitest.
|
|
803
|
+
- Default test gate commands for orchestrator projects SHOULD use Nx task execution (for example `nx test <project> --coverage`).
|
|
804
|
+
- Coverage artifacts MUST be emitted in a parser-compatible format (`lcov` preferred) so MCP can enforce thresholds.
|
|
805
|
+
|
|
806
|
+
---
|
|
807
|
+
|
|
808
|
+
## 13. Docker Deployment Requirements
|
|
809
|
+
|
|
810
|
+
### 13.1 Required Mounts
|
|
811
|
+
|
|
812
|
+
- Repo mounted to `/repo`
|
|
813
|
+
- Optional caches:
|
|
814
|
+
- `/cache/pnpm`
|
|
815
|
+
- `/cache/m2`
|
|
816
|
+
- `/cache/cargo`
|
|
817
|
+
|
|
818
|
+
### 13.2 Toolchains
|
|
819
|
+
|
|
820
|
+
Repo toolchains must exist in the container image used to run MCP (either per-repo image or universal). MCP itself stays toolchain-agnostic.
|
|
821
|
+
For this implementation, container/runtime environment MUST include Node.js and Nx-compatible tooling required to run Vitest via Nx tasks.
|
|
822
|
+
|
|
823
|
+
---
|
|
824
|
+
|
|
825
|
+
## 14. Acceptance Criteria (Complete)
|
|
826
|
+
|
|
827
|
+
A) **Kernel correctness**
|
|
828
|
+
- Plan schema validation rejects invalid plans with actionable errors.
|
|
829
|
+
- Plan revisions are versioned and protected by optimistic concurrency.
|
|
830
|
+
- Patch enforcement prevents edits outside plan/allowed areas.
|
|
831
|
+
- Gate runner executes config commands and stores logs/evidence.
|
|
832
|
+
- Locks and collisions prevent conflicting edits deterministically.
|
|
833
|
+
- State files are updated only by MCP and validated by schema.
|
|
834
|
+
- State/index writes are atomic and race-safe under parallel runs.
|
|
835
|
+
|
|
836
|
+
B) **Parallelism and visibility**
|
|
837
|
+
- 5 features can run concurrently with 5 worktrees.
|
|
838
|
+
- User can open `.worktrees/<feature_id>` (for example `.worktrees/my_feature`) locally to review unmerged changes.
|
|
839
|
+
|
|
840
|
+
C) **Platform-agnostic gates**
|
|
841
|
+
- Same MCP works on managed target repositories:
|
|
842
|
+
- Nx repo (nx commands in gates.yaml)
|
|
843
|
+
- Java repo (mvn/gradle commands in gates.yaml)
|
|
844
|
+
- Rust repo (cargo commands in gates.yaml)
|
|
845
|
+
No MCP code changes required.
|
|
846
|
+
|
|
847
|
+
D) **Orchestrator/cluster architecture**
|
|
848
|
+
- User interacts only with Orchestrator Agent.
|
|
849
|
+
- Supervisor spawns worker sessions per feature.
|
|
850
|
+
- Tool-call firewall enforces role tool permissions.
|
|
851
|
+
- System produces dashboard and per-feature review bundle.
|
|
852
|
+
- Merge only occurs via explicit `feature.ready_to_merge` call after user approval.
|
|
853
|
+
- If role prompts exist in repo config, spawned workers receive them as system prompts.
|
|
854
|
+
- QA worker runs can be closed/restarted while preserving progress via MCP-backed `qa_test_index.json`.
|
|
855
|
+
|
|
856
|
+
E) **CLI entrypoint contract**
|
|
857
|
+
- `aop run -fi <file>` launches exactly one Agent Cluster for that file.
|
|
858
|
+
- `aop run -fl <folder>` launches one Agent Cluster per resolved spec file in the folder.
|
|
859
|
+
- `-fi` and `-fl` mutual exclusion is enforced with deterministic structured errors.
|
|
860
|
+
- Folder inputs are resolved deterministically and queued beyond `max_active_features`.
|
|
861
|
+
- Agent runtime provider/model can be selected via CLI flags with env/config fallback and deterministic precedence.
|
|
862
|
+
- Feature branch/worktree folder names are derived from spec filenames using the `.spec` / `-spec` trimming rules.
|
|
863
|
+
|
|
864
|
+
F) **Implementation testing standards**
|
|
865
|
+
- Orchestrator control-plane implementation (CLI/Supervisor/MCP) is structured as an Nx monorepo.
|
|
866
|
+
- Automated tests for that control-plane implementation are executed with Vitest.
|
|
867
|
+
- Blocking coverage minimum is 90% for both line and branch.
|
|
868
|
+
- Coverage target is 100% for both line and branch, reported in evidence summaries.
|
|
869
|
+
- Managed target repositories remain toolchain-agnostic and are validated only by their configured gates.
|
|
870
|
+
|
|
871
|
+
---
|
|
872
|
+
|
|
873
|
+
## 15. Implementation Milestones
|
|
874
|
+
|
|
875
|
+
### 15.1 Implementation Progress Artifact (Non-Runtime Requirement)
|
|
876
|
+
|
|
877
|
+
While implementing this spec, the implementing agent MUST maintain `spec-files/progress.md` used only for implementation continuity.
|
|
878
|
+
|
|
879
|
+
Required `spec-files/progress.md` contents:
|
|
880
|
+
- current milestone (`M0..M9`) and current task
|
|
881
|
+
- completed tasks since last update
|
|
882
|
+
- next tasks planned
|
|
883
|
+
- open blockers/risks
|
|
884
|
+
- handoff summary for the next agent session
|
|
885
|
+
- last updated timestamp
|
|
886
|
+
|
|
887
|
+
Update policy:
|
|
888
|
+
- update `spec-files/progress.md` after each meaningful implementation step
|
|
889
|
+
- update `spec-files/progress.md` before ending/closing an agent session for context reset
|
|
890
|
+
- the next agent session MUST start by reading `spec-files/progress.md` before making changes
|
|
891
|
+
|
|
892
|
+
Scope note:
|
|
893
|
+
- `spec-files/progress.md` in this section is an implementation-process artifact only.
|
|
894
|
+
- It MUST NOT be required by, read by, or enforced by the orchestrator runtime (MCP/Supervisor/worker logic).
|
|
895
|
+
|
|
896
|
+
**M0: Implementation Handoff Tracking (non-runtime)**
|
|
897
|
+
- create and maintain `spec-files/progress.md` throughout implementation.
|
|
898
|
+
- keep milestone position and handoff notes current for session-to-session continuity.
|
|
899
|
+
|
|
900
|
+
**M1: MCP Kernel V1 (single feature)**
|
|
901
|
+
- feature.init, plan.submit validation, ensure_worktree, apply_patch enforcement, gates.run, evidence.latest, state updates.
|
|
902
|
+
|
|
903
|
+
**M2: Worktrees + Parallelism**
|
|
904
|
+
- worktree-per-feature, index.json, locks, collisions.
|
|
905
|
+
|
|
906
|
+
**M3: Supervisor Runtime**
|
|
907
|
+
- orchestrator + worker abstractions, role enforcement, orchestration loop, reporting tools.
|
|
908
|
+
|
|
909
|
+
**M4: Platform-Agnostic Profiles**
|
|
910
|
+
- gates.yaml profiles, multi-target gate runs, line/branch coverage parsing.
|
|
911
|
+
|
|
912
|
+
**M5: Review + Merge Control**
|
|
913
|
+
- diff bundles, dashboard summary, explicit user approval flow, `feature.ready_to_merge` commit+merge path.
|
|
914
|
+
|
|
915
|
+
**M6: Resilience and Recovery**
|
|
916
|
+
- lock leases + heartbeat, restart recovery, queued collision unblock processing.
|
|
917
|
+
|
|
918
|
+
**M7: Prompt + QA Context Management**
|
|
919
|
+
- repo-level worker prompt loading via `agents.yaml`.
|
|
920
|
+
- per-feature QA change/test index maintenance and short-lived QA worker resume flow.
|
|
921
|
+
|
|
922
|
+
**M8: Supervisor CLI Entrypoint**
|
|
923
|
+
- implement `aop run` contract with `-fi` and `-fl`.
|
|
924
|
+
- deterministic folder scan + spec ingestion to canonical feature layout.
|
|
925
|
+
- derive `feature_id`/branch/worktree folder names from spec filename stems with `.spec` / `-spec` suffix trimming.
|
|
926
|
+
- startup validation, provider selection resolution, structured errors, and dashboard streaming bootstrap.
|
|
927
|
+
|
|
928
|
+
**M9: Nx + Vitest Quality Gates**
|
|
929
|
+
- scaffold/organize orchestrator implementation as Nx monorepo projects.
|
|
930
|
+
- implement Vitest-based test tasks and coverage artifact generation.
|
|
931
|
+
- enforce 90% line/branch minimums with 100% line/branch target reporting.
|
|
932
|
+
|
|
933
|
+
---
|
|
934
|
+
|
|
935
|
+
## 16. Resolved Operational Defaults
|
|
936
|
+
|
|
937
|
+
The following defaults are accepted and normative:
|
|
938
|
+
|
|
939
|
+
1) Lock operations are owned by `orchestrator|system`; worker roles submit `REQUEST`.
|
|
940
|
+
2) Lock acquisition defaults to blocking/queued with timeout + jittered backoff.
|
|
941
|
+
3) Plan revisions keep existing diffs in worktree; future patch applies are validated against latest accepted plan.
|
|
942
|
+
4) Supervisor proposes state transitions, MCP validates legality and persists canonical state.
|
|
943
|
+
5) `collision_policy=block` uses persistent `blocked_queue` with deterministic ordering.
|
|
944
|
+
6) Precedence is `policy hard constraints > gates profile defaults > plan overrides (tighten-only)`.
|
|
945
|
+
7) Gate timeout default is 600s when unspecified; transient retry default is 1; policy/schema violations are non-retryable.
|
|
946
|
+
8) Review artifacts are unmerged worktree diffs; commit+merge happen only through explicit `feature.ready_to_merge`.
|
|
947
|
+
9) Restart recovery uses lease heartbeats and stale-lease reclamation with deterministic unblock flow.
|
|
948
|
+
10) Secret handling is default-on scrub/redaction with explicit env allowlist.
|
|
949
|
+
11) Orchestrator implementation uses Nx + Vitest with 90% line/branch minimum coverage and 100% line/branch target.
|
|
950
|
+
12) Agent provider/model selection precedence is CLI flags > env vars > `agents.yaml` runtime defaults.
|
|
951
|
+
|
|
952
|
+
---
|
|
953
|
+
|
|
954
|
+
## 17. CLI Entrypoint Contract
|
|
955
|
+
|
|
956
|
+
The Supervisor Runtime MUST provide a CLI entrypoint named `aop`.
|
|
957
|
+
|
|
958
|
+
### 17.1 Primary Command
|
|
959
|
+
|
|
960
|
+
```bash
|
|
961
|
+
aop run [options]
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
Required behavior:
|
|
965
|
+
- Starts/attaches MCP connectivity.
|
|
966
|
+
- Creates one user-facing Orchestrator session.
|
|
967
|
+
- Resolves input specs (from `-fi`, `-fl`, or default discovery).
|
|
968
|
+
- Spins up one Agent Cluster per resolved feature spec (subject to `max_active_features`; overflow queues deterministically).
|
|
969
|
+
|
|
970
|
+
### 17.2 Input Selection Options
|
|
971
|
+
|
|
972
|
+
Supported options:
|
|
973
|
+
- `-fi <path>`: file input. Treat the referenced file as one feature spec and spin up exactly one Agent Cluster.
|
|
974
|
+
- `-fl <path>`: folder input. Treat all spec files in the folder as feature inputs and spin up one Agent Cluster per resolved file.
|
|
975
|
+
- `--agent-provider <codex|claude|gemini|custom>`: selects agent runtime provider for orchestrator and worker sessions.
|
|
976
|
+
- `--agent-model <model-id>`: selects provider model identifier.
|
|
977
|
+
- `--provider-config-env <ENV_VAR>`: env var name carrying provider credentials/config reference.
|
|
978
|
+
|
|
979
|
+
Mutual exclusion and defaults:
|
|
980
|
+
- `-fi` and `-fl` are mutually exclusive.
|
|
981
|
+
- If both are provided, CLI MUST fail with `error=invalid_cli_args`.
|
|
982
|
+
- If neither is provided, use canonical discovery (`feature.discover_specs`).
|
|
983
|
+
|
|
984
|
+
Example:
|
|
985
|
+
|
|
986
|
+
```bash
|
|
987
|
+
aop run -fl ./specfiles
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
### 17.3 Folder Resolution Rules (`-fl`)
|
|
991
|
+
|
|
992
|
+
- Folder traversal MUST be deterministic (lexicographic path order).
|
|
993
|
+
- Default scan pattern is recursive `**/*.md`.
|
|
994
|
+
- Each resolved file is treated as an independent feature spec input.
|
|
995
|
+
- If no spec files are found, CLI MUST fail with `error=no_specs_found`.
|
|
996
|
+
|
|
997
|
+
### 17.4 Spec Ingestion to Canonical Repo Layout
|
|
998
|
+
|
|
999
|
+
For inputs outside `agentic/features/*/spec.md`, Supervisor MUST ingest them into canonical layout:
|
|
1000
|
+
- Derive `feature_id` deterministically from spec filename using this algorithm:
|
|
1001
|
+
1. Start from filename stem (basename without final extension).
|
|
1002
|
+
2. If the stem ends with `.spec`, remove that suffix.
|
|
1003
|
+
3. Else if the stem ends with `-spec`, remove that suffix.
|
|
1004
|
+
4. Resulting value is `feature_id` and MUST be used as both branch name and worktree folder name.
|
|
1005
|
+
5. Resulting `feature_id` MUST match `^[a-z0-9_][a-z0-9_-]*$`.
|
|
1006
|
+
- Copy source content to `agentic/features/<feature_id>/spec.md`.
|
|
1007
|
+
- Record source path and source hash in feature state metadata.
|
|
1008
|
+
- If derived `feature_id` is empty or does not meet naming rules, fail with `error=invalid_feature_slug`.
|
|
1009
|
+
- If multiple inputs resolve to the same `feature_id`, fail with `error=feature_slug_collision`.
|
|
1010
|
+
|
|
1011
|
+
If input path is already canonical (`agentic/features/<feature_id>/spec.md`):
|
|
1012
|
+
- Use existing `feature_id` from path and do not duplicate content.
|
|
1013
|
+
|
|
1014
|
+
Examples:
|
|
1015
|
+
- `my_feature.spec.md` -> `feature_id=my_feature`, branch `my_feature`, worktree `.worktrees/my_feature`
|
|
1016
|
+
- `my_feature-spec.md` -> `feature_id=my_feature`, branch `my_feature`, worktree `.worktrees/my_feature`
|
|
1017
|
+
- `my_feature.md` -> `feature_id=my_feature`, branch `my_feature`, worktree `.worktrees/my_feature`
|
|
1018
|
+
|
|
1019
|
+
### 17.5 Operational Semantics
|
|
1020
|
+
|
|
1021
|
+
- `aop run -fi ...` starts one feature flow.
|
|
1022
|
+
- `aop run -fl ...` starts N feature flows (N = resolved spec files).
|
|
1023
|
+
- Features beyond `max_active_features` MUST be queued and activated as slots free up.
|
|
1024
|
+
- CLI SHOULD stream dashboard updates derived from `report.dashboard`.
|
|
1025
|
+
|
|
1026
|
+
### 17.6 Exit and Status Contract
|
|
1027
|
+
|
|
1028
|
+
- Exit `0` when run initializes successfully and runtime enters active orchestration mode.
|
|
1029
|
+
- Non-zero exit on startup/argument/input validation failures.
|
|
1030
|
+
- MUST return structured error payloads aligned with Appendix D error format for machine callers.
|
|
1031
|
+
|
|
1032
|
+
### 17.7 Agent Provider Selection Contract
|
|
1033
|
+
|
|
1034
|
+
Provider selection precedence (highest to lowest):
|
|
1035
|
+
1) CLI flags: `--agent-provider`, `--agent-model`, `--provider-config-env`
|
|
1036
|
+
2) Environment variables:
|
|
1037
|
+
- `AOP_AGENT_PROVIDER`
|
|
1038
|
+
- `AOP_AGENT_MODEL`
|
|
1039
|
+
- `AOP_PROVIDER_CONFIG_ENV`
|
|
1040
|
+
3) `agentic/orchestrator/agents.yaml` `runtime.*` defaults
|
|
1041
|
+
|
|
1042
|
+
Rules:
|
|
1043
|
+
- If no provider can be resolved, CLI MUST fail with `error=agent_provider_not_configured`.
|
|
1044
|
+
- If provider value is unsupported, CLI MUST fail with `error=unsupported_agent_provider`.
|
|
1045
|
+
- If provider requires credentials/config and none is available, CLI MUST fail with `error=provider_auth_missing`.
|
|
1046
|
+
- Supervisor MUST record resolved provider/model in run metadata for auditability.
|
|
1047
|
+
|
|
1048
|
+
Recommended additional commands (V1.1):
|
|
1049
|
+
- `aop status` (reads dashboard/status)
|
|
1050
|
+
- `aop resume` (resume prior run state)
|
|
1051
|
+
- `aop stop` (graceful shutdown)
|
|
1052
|
+
|
|
1053
|
+
---
|
|
1054
|
+
|
|
1055
|
+
## Appendix A — Full JSON Schema: plan.schema.json (Draft)
|
|
1056
|
+
|
|
1057
|
+
```json
|
|
1058
|
+
{
|
|
1059
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1060
|
+
"$id": "https://example.local/agentic/plan.schema.json",
|
|
1061
|
+
"type": "object",
|
|
1062
|
+
"additionalProperties": false,
|
|
1063
|
+
"required": [
|
|
1064
|
+
"feature_id",
|
|
1065
|
+
"plan_version",
|
|
1066
|
+
"summary",
|
|
1067
|
+
"allowed_areas",
|
|
1068
|
+
"forbidden_areas",
|
|
1069
|
+
"base_ref",
|
|
1070
|
+
"files",
|
|
1071
|
+
"contracts",
|
|
1072
|
+
"acceptance_criteria",
|
|
1073
|
+
"gate_profile"
|
|
1074
|
+
],
|
|
1075
|
+
"properties": {
|
|
1076
|
+
"feature_id": {
|
|
1077
|
+
"type": "string",
|
|
1078
|
+
"pattern": "^[a-z0-9_][a-z0-9_-]*$"
|
|
1079
|
+
},
|
|
1080
|
+
"plan_version": {
|
|
1081
|
+
"type": "integer",
|
|
1082
|
+
"minimum": 1
|
|
1083
|
+
},
|
|
1084
|
+
"summary": {
|
|
1085
|
+
"type": "string",
|
|
1086
|
+
"minLength": 5
|
|
1087
|
+
},
|
|
1088
|
+
"allowed_areas": {
|
|
1089
|
+
"type": "array",
|
|
1090
|
+
"items": { "type": "string", "minLength": 1 },
|
|
1091
|
+
"minItems": 1
|
|
1092
|
+
},
|
|
1093
|
+
"forbidden_areas": {
|
|
1094
|
+
"type": "array",
|
|
1095
|
+
"items": { "type": "string", "minLength": 1 }
|
|
1096
|
+
},
|
|
1097
|
+
"base_ref": {
|
|
1098
|
+
"type": "string",
|
|
1099
|
+
"minLength": 1
|
|
1100
|
+
},
|
|
1101
|
+
"files": {
|
|
1102
|
+
"type": "object",
|
|
1103
|
+
"additionalProperties": false,
|
|
1104
|
+
"required": ["create", "modify", "delete"],
|
|
1105
|
+
"properties": {
|
|
1106
|
+
"create": { "type": "array", "items": { "type": "string", "minLength": 1 } },
|
|
1107
|
+
"modify": { "type": "array", "items": { "type": "string", "minLength": 1 } },
|
|
1108
|
+
"delete": { "type": "array", "items": { "type": "string", "minLength": 1 } }
|
|
1109
|
+
}
|
|
1110
|
+
},
|
|
1111
|
+
"contracts": {
|
|
1112
|
+
"type": "object",
|
|
1113
|
+
"additionalProperties": false,
|
|
1114
|
+
"required": ["openapi", "events", "db"],
|
|
1115
|
+
"properties": {
|
|
1116
|
+
"openapi": { "type": "string", "enum": ["none", "modify"] },
|
|
1117
|
+
"events": { "type": "string", "enum": ["none", "modify"] },
|
|
1118
|
+
"db": { "type": "string", "enum": ["none", "migration"] }
|
|
1119
|
+
}
|
|
1120
|
+
},
|
|
1121
|
+
"acceptance_criteria": {
|
|
1122
|
+
"type": "array",
|
|
1123
|
+
"items": { "type": "string", "minLength": 1 },
|
|
1124
|
+
"minItems": 1
|
|
1125
|
+
},
|
|
1126
|
+
"gate_profile": { "type": "string", "minLength": 1 },
|
|
1127
|
+
"gate_targets": {
|
|
1128
|
+
"type": "array",
|
|
1129
|
+
"items": { "type": "string", "minLength": 1 },
|
|
1130
|
+
"minItems": 1
|
|
1131
|
+
},
|
|
1132
|
+
"risk": {
|
|
1133
|
+
"type": "array",
|
|
1134
|
+
"items": { "type": "string", "minLength": 1 }
|
|
1135
|
+
},
|
|
1136
|
+
"revision_of": {
|
|
1137
|
+
"type": "integer",
|
|
1138
|
+
"minimum": 1
|
|
1139
|
+
},
|
|
1140
|
+
"revision_reason": {
|
|
1141
|
+
"type": "string",
|
|
1142
|
+
"minLength": 1
|
|
1143
|
+
},
|
|
1144
|
+
"verification_overrides": {
|
|
1145
|
+
"type": "object",
|
|
1146
|
+
"additionalProperties": false,
|
|
1147
|
+
"properties": {
|
|
1148
|
+
"modes": {
|
|
1149
|
+
"type": "object",
|
|
1150
|
+
"additionalProperties": false,
|
|
1151
|
+
"properties": {
|
|
1152
|
+
"fast": { "$ref": "#/$defs/modeOverride" },
|
|
1153
|
+
"full": { "$ref": "#/$defs/modeOverride" }
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
},
|
|
1159
|
+
"$defs": {
|
|
1160
|
+
"modeOverride": {
|
|
1161
|
+
"type": "object",
|
|
1162
|
+
"additionalProperties": false,
|
|
1163
|
+
"properties": {
|
|
1164
|
+
"steps": {
|
|
1165
|
+
"type": "array",
|
|
1166
|
+
"items": {
|
|
1167
|
+
"type": "object",
|
|
1168
|
+
"additionalProperties": false,
|
|
1169
|
+
"required": ["name", "cmd"],
|
|
1170
|
+
"properties": {
|
|
1171
|
+
"name": { "type": "string", "minLength": 1 },
|
|
1172
|
+
"cmd": {
|
|
1173
|
+
"type": "array",
|
|
1174
|
+
"items": { "type": "string", "minLength": 1 },
|
|
1175
|
+
"minItems": 1
|
|
1176
|
+
},
|
|
1177
|
+
"timeout_seconds": { "type": "number", "minimum": 1 }
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
---
|
|
1188
|
+
|
|
1189
|
+
## Appendix B — state.schema.json (Front matter object) Outline
|
|
1190
|
+
|
|
1191
|
+
```json
|
|
1192
|
+
{
|
|
1193
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1194
|
+
"type": "object",
|
|
1195
|
+
"additionalProperties": true,
|
|
1196
|
+
"required": [
|
|
1197
|
+
"feature_id",
|
|
1198
|
+
"version",
|
|
1199
|
+
"branch",
|
|
1200
|
+
"worktree_path",
|
|
1201
|
+
"status",
|
|
1202
|
+
"gate_profile",
|
|
1203
|
+
"gates",
|
|
1204
|
+
"locks",
|
|
1205
|
+
"collisions",
|
|
1206
|
+
"cluster",
|
|
1207
|
+
"role_status",
|
|
1208
|
+
"last_updated"
|
|
1209
|
+
],
|
|
1210
|
+
"properties": {
|
|
1211
|
+
"feature_id": { "type": "string" },
|
|
1212
|
+
"version": { "type": "integer", "minimum": 1 },
|
|
1213
|
+
"branch": { "type": "string" },
|
|
1214
|
+
"worktree_path": { "type": "string" },
|
|
1215
|
+
"status": {
|
|
1216
|
+
"type": "string",
|
|
1217
|
+
"enum": ["planning","building","qa","blocked","ready_to_merge","merged","failed"]
|
|
1218
|
+
},
|
|
1219
|
+
"gate_profile": { "type": "string" },
|
|
1220
|
+
"gates": {
|
|
1221
|
+
"type": "object",
|
|
1222
|
+
"additionalProperties": { "type": "string", "enum": ["pass","fail","na"] }
|
|
1223
|
+
},
|
|
1224
|
+
"locks": {
|
|
1225
|
+
"type": "object",
|
|
1226
|
+
"required": ["held"],
|
|
1227
|
+
"properties": {
|
|
1228
|
+
"held": { "type": "array", "items": { "type": "string" } }
|
|
1229
|
+
}
|
|
1230
|
+
},
|
|
1231
|
+
"collisions": {
|
|
1232
|
+
"type": "object",
|
|
1233
|
+
"required": ["files","areas","contracts"],
|
|
1234
|
+
"properties": {
|
|
1235
|
+
"files": { "type": "array", "items": { "type": "object" } },
|
|
1236
|
+
"areas": { "type": "array", "items": { "type": "object" } },
|
|
1237
|
+
"contracts": { "type": "array", "items": { "type": "object" } }
|
|
1238
|
+
}
|
|
1239
|
+
},
|
|
1240
|
+
"cluster": {
|
|
1241
|
+
"type": "object",
|
|
1242
|
+
"required": ["orchestrator_session_id","planner_session_id","builder_session_id","qa_session_id"],
|
|
1243
|
+
"properties": {
|
|
1244
|
+
"orchestrator_session_id": { "type": "string" },
|
|
1245
|
+
"planner_session_id": { "type": "string" },
|
|
1246
|
+
"builder_session_id": { "type": "string" },
|
|
1247
|
+
"qa_session_id": { "type": "string" }
|
|
1248
|
+
}
|
|
1249
|
+
},
|
|
1250
|
+
"role_status": {
|
|
1251
|
+
"type": "object",
|
|
1252
|
+
"required": ["planner","builder","qa"],
|
|
1253
|
+
"properties": {
|
|
1254
|
+
"planner": { "type": "string", "enum": ["ready","running","blocked","done"] },
|
|
1255
|
+
"builder": { "type": "string", "enum": ["ready","running","blocked","done"] },
|
|
1256
|
+
"qa": { "type": "string", "enum": ["ready","running","blocked","done"] }
|
|
1257
|
+
}
|
|
1258
|
+
},
|
|
1259
|
+
"last_updated": { "type": "string" },
|
|
1260
|
+
"status_reason": { "type": "string" }
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
```
|
|
1264
|
+
|
|
1265
|
+
---
|
|
1266
|
+
|
|
1267
|
+
## Appendix C — gates.yaml + policy.yaml + agents.yaml Schema Notes
|
|
1268
|
+
|
|
1269
|
+
- MCP MUST validate loaded YAML against `gates.schema.json` and `policy.schema.json` and fail fast if invalid.
|
|
1270
|
+
- Supervisor/MCP MUST validate `agents.yaml` against `agents.schema.json` if file is present.
|
|
1271
|
+
- Unknown gate profile/mode must yield `error=unknown_gate_profile_or_mode`.
|
|
1272
|
+
- If `policy.commit_policy.allow_commit=false`, `repo.commit` must return `error=commit_disabled`.
|
|
1273
|
+
- Precedence MUST follow §12.5; invalid relaxations must return `error=invalid_override_precedence`.
|
|
1274
|
+
- If `policy.merge_policy.require_user_approval=true`, `feature.ready_to_merge` without valid approval token MUST return `error=user_approval_required`.
|
|
1275
|
+
- If `agents.yaml.missing_prompt_behavior=error`, missing configured prompt file MUST return `error=missing_role_prompt`.
|
|
1276
|
+
- For this implementation, `policy.implementation.workspace` MUST be `nx` and `policy.testing.framework` MUST be `vitest`.
|
|
1277
|
+
- Coverage policy minimums MUST enforce `line>=0.90` and `branch>=0.90`; targets MUST be configured at `1.00`.
|
|
1278
|
+
- CLI/env/provider resolution MUST follow §17.7 and fail closed on unresolved/unsupported providers.
|
|
1279
|
+
|
|
1280
|
+
---
|
|
1281
|
+
|
|
1282
|
+
## Appendix D — Required Structured Error Format
|
|
1283
|
+
|
|
1284
|
+
All MCP tool failures must return:
|
|
1285
|
+
|
|
1286
|
+
```json
|
|
1287
|
+
{
|
|
1288
|
+
"ok": false,
|
|
1289
|
+
"error": {
|
|
1290
|
+
"code": "string_enum",
|
|
1291
|
+
"message": "human readable",
|
|
1292
|
+
"details": { "any": "json" }
|
|
1293
|
+
},
|
|
1294
|
+
"evidence": { "log_path": "optional" }
|
|
1295
|
+
}
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
Required error codes (minimum set):
|
|
1299
|
+
- `forbidden_tool_for_role`
|
|
1300
|
+
- `version_conflict`
|
|
1301
|
+
- `invalid_status_transition`
|
|
1302
|
+
- `unknown_gate_profile_or_mode`
|
|
1303
|
+
- `unsupported_parser`
|
|
1304
|
+
- `gate_timeout`
|
|
1305
|
+
- `transient_exec_failure`
|
|
1306
|
+
- `coverage_below_minimum`
|
|
1307
|
+
- `invalid_override_precedence`
|
|
1308
|
+
- `path_out_of_bounds`
|
|
1309
|
+
- `lock_not_held`
|
|
1310
|
+
- `lock_conflict`
|
|
1311
|
+
- `stale_lock_reclaimed`
|
|
1312
|
+
- `collision_detected`
|
|
1313
|
+
- `blocked_by_collision_policy`
|
|
1314
|
+
- `commit_disabled`
|
|
1315
|
+
- `merge_disabled`
|
|
1316
|
+
- `user_approval_required`
|
|
1317
|
+
- `missing_role_prompt`
|
|
1318
|
+
- `qa_index_version_conflict`
|
|
1319
|
+
- `invalid_cli_args`
|
|
1320
|
+
- `input_path_not_found`
|
|
1321
|
+
- `no_specs_found`
|
|
1322
|
+
- `spec_ingest_failed`
|
|
1323
|
+
- `invalid_feature_slug`
|
|
1324
|
+
- `feature_slug_collision`
|
|
1325
|
+
- `invalid_workspace_implementation`
|
|
1326
|
+
- `agent_provider_not_configured`
|
|
1327
|
+
- `unsupported_agent_provider`
|
|
1328
|
+
- `provider_auth_missing`
|
|
1329
|
+
|
|
1330
|
+
Error details SHOULD include:
|
|
1331
|
+
- `retryable` boolean
|
|
1332
|
+
- `requires_human` boolean
|
|
1333
|
+
- `conflicting_feature_ids` (when relevant)
|
|
1334
|
+
- `suggested_next_actions` array
|