agentic-orchestrator 0.1.28 → 0.2.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/.claude/settings.local.json +46 -1
- package/.cortexrc +28 -0
- package/.github/agents/copilot-instructions.md +29 -0
- package/.github/copilot-instructions.md +93 -0
- package/.vscode/settings.json +13 -0
- package/.vscode/tms.code-snippets +223 -0
- package/AGENTS.md +72 -1
- package/Agentic-Orchestrator.iml +12 -11
- package/CLAUDE.md +72 -1
- package/CONSTITUTION.md +504 -0
- package/FUTURE-ENHANCEMENTS.md +85 -0
- package/NEXT-TASKS.md +25 -0
- package/PROMPTS.md +161 -0
- package/README.md +126 -29
- package/agentic/orchestrator/agents.yaml +4 -3
- package/agentic/orchestrator/defaults/policy.defaults.yaml +39 -3
- package/agentic/orchestrator/gates.yaml +15 -3
- package/agentic/orchestrator/policy.yaml +47 -3
- package/agentic/orchestrator/prompts/builder.system.md +69 -20
- package/agentic/orchestrator/prompts/planner-intake.system.md +149 -0
- package/agentic/orchestrator/prompts/planner.system.md +113 -40
- package/agentic/orchestrator/prompts/qa.system.md +73 -18
- package/agentic/orchestrator/prompts/reconciler.system.md +119 -0
- package/agentic/orchestrator/schemas/agents.schema.json +89 -1
- package/agentic/orchestrator/schemas/execution-control.schema.json +242 -0
- package/agentic/orchestrator/schemas/index.schema.json +234 -0
- package/agentic/orchestrator/schemas/intake.review.schema.json +82 -0
- package/agentic/orchestrator/schemas/organizer-ordering-artifact.schema.json +75 -0
- package/agentic/orchestrator/schemas/plan.schema.json +44 -0
- package/agentic/orchestrator/schemas/policy.schema.json +238 -9
- package/agentic/orchestrator/schemas/policy.user.schema.json +129 -1
- package/agentic/orchestrator/schemas/spec.manifest.bootstrap.schema.json +101 -0
- package/agentic/orchestrator/schemas/spec.manifest.verified.schema.json +80 -0
- package/agentic/orchestrator/schemas/state.schema.json +298 -3
- package/agentic/orchestrator/tools/catalog.json +145 -15
- package/agentic/orchestrator/tools/schemas/input/doctor.run.input.schema.json +18 -0
- package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +4 -0
- package/agentic/orchestrator/tools/schemas/input/evidence.verify_chain.input.schema.json +13 -0
- package/agentic/orchestrator/tools/schemas/input/feature.intake_submit.input.schema.json +11 -0
- package/agentic/orchestrator/tools/schemas/input/feature.question_answer.input.schema.json +15 -0
- package/agentic/orchestrator/tools/schemas/input/feature.question_create.input.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/input/feature.question_list.input.schema.json +13 -0
- package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +5 -0
- package/agentic/orchestrator/tools/schemas/input/feature.send_message.input.schema.json +1 -1
- package/agentic/orchestrator/tools/schemas/input/replay.timeline_get.input.schema.json +32 -0
- package/agentic/orchestrator/tools/schemas/input/repo.conflict_abort.input.schema.json +16 -0
- package/agentic/orchestrator/tools/schemas/input/repo.conflict_files.input.schema.json +16 -0
- package/agentic/orchestrator/tools/schemas/input/repo.reconcile_mainline.input.schema.json +37 -0
- package/agentic/orchestrator/tools/schemas/input/repo.resolve_conflict.input.schema.json +40 -0
- package/agentic/orchestrator/tools/schemas/input/runtime.execution_request_list.input.schema.json +7 -0
- package/agentic/orchestrator/tools/schemas/input/runtime.execution_request_submit.input.schema.json +25 -0
- package/agentic/orchestrator/tools/schemas/output/doctor.run.output.schema.json +34 -0
- package/agentic/orchestrator/tools/schemas/output/evidence.verify_chain.output.schema.json +23 -0
- package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +62 -2
- package/agentic/orchestrator/tools/schemas/output/feature.intake_submit.output.schema.json +24 -0
- package/agentic/orchestrator/tools/schemas/output/feature.question_answer.output.schema.json +21 -0
- package/agentic/orchestrator/tools/schemas/output/feature.question_create.output.schema.json +12 -0
- package/agentic/orchestrator/tools/schemas/output/feature.question_list.output.schema.json +14 -0
- package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +31 -0
- package/agentic/orchestrator/tools/schemas/output/feature.send_message.output.schema.json +8 -18
- package/agentic/orchestrator/tools/schemas/output/replay.timeline_get.output.schema.json +64 -0
- package/agentic/orchestrator/tools/schemas/output/repo.conflict_abort.output.schema.json +16 -0
- package/agentic/orchestrator/tools/schemas/output/repo.conflict_files.output.schema.json +22 -0
- package/agentic/orchestrator/tools/schemas/output/repo.reconcile_mainline.output.schema.json +61 -0
- package/agentic/orchestrator/tools/schemas/output/repo.resolve_conflict.output.schema.json +19 -0
- package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +26 -0
- package/agentic/orchestrator/tools/schemas/output/runtime.execution_request_list.output.schema.json +17 -0
- package/agentic/orchestrator/tools/schemas/output/runtime.execution_request_submit.output.schema.json +24 -0
- package/agentic/orchestrator/tools.md +13 -0
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +1 -1
- package/apps/control-plane/src/application/kernel-tool-wiring.ts +140 -2
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +44 -1
- package/apps/control-plane/src/application/services/bootstrap-manifest-generator-service.ts +251 -0
- package/apps/control-plane/src/application/services/checkpoint-service.ts +87 -27
- package/apps/control-plane/src/application/services/collision-override-service.ts +906 -0
- package/apps/control-plane/src/application/services/collision-queue-service.ts +129 -38
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +94 -0
- package/apps/control-plane/src/application/services/execution-control-service.ts +599 -0
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +37 -1
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +182 -4
- package/apps/control-plane/src/application/services/feature-send-message-service.ts +17 -8
- package/apps/control-plane/src/application/services/feature-state-service.ts +191 -6
- package/apps/control-plane/src/application/services/gate-service.ts +121 -2
- package/apps/control-plane/src/application/services/git-reconciliation-service.ts +1591 -0
- package/apps/control-plane/src/application/services/intake-service.ts +1468 -0
- package/apps/control-plane/src/application/services/merge-service.ts +308 -17
- package/apps/control-plane/src/application/services/notifier-service.ts +3 -1
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +75 -0
- package/apps/control-plane/src/application/services/plan-service.ts +336 -20
- package/apps/control-plane/src/application/services/question-service.ts +693 -0
- package/apps/control-plane/src/application/services/reactions-service.ts +73 -17
- package/apps/control-plane/src/application/services/replay-timeline-service.ts +295 -0
- package/apps/control-plane/src/application/services/reporting-service.ts +194 -10
- package/apps/control-plane/src/application/services/run-lease-service.ts +121 -5
- package/apps/control-plane/src/application/services/worktree-watchdog-service.ts +95 -8
- package/apps/control-plane/src/application/tools/tool-metadata.ts +7 -0
- package/apps/control-plane/src/application/usage-types.ts +138 -0
- package/apps/control-plane/src/cli/add-command-handler.ts +162 -0
- package/apps/control-plane/src/cli/answer-command-handler.ts +113 -0
- package/apps/control-plane/src/cli/attach-command-handler.ts +12 -3
- package/apps/control-plane/src/cli/cli-argument-parser.ts +133 -11
- package/apps/control-plane/src/cli/collision-command-handler.ts +113 -0
- package/apps/control-plane/src/cli/command-catalog.ts +479 -0
- package/apps/control-plane/src/cli/complete-command-handler.ts +23 -0
- package/apps/control-plane/src/cli/completion-command-handler.ts +25 -0
- package/apps/control-plane/src/cli/completion-resolver.ts +319 -0
- package/apps/control-plane/src/cli/completion-shell-renderer.ts +58 -0
- package/apps/control-plane/src/cli/dashboard-command-handler.ts +110 -1
- package/apps/control-plane/src/cli/dashboard-runtime-runner.ts +1036 -0
- package/apps/control-plane/src/cli/dashboard-runtime.ts +31 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +17 -185
- package/apps/control-plane/src/cli/init-command-handler.ts +51 -6
- package/apps/control-plane/src/cli/merge-command-handler.ts +200 -0
- package/apps/control-plane/src/cli/questions-command-handler.ts +70 -0
- package/apps/control-plane/src/cli/replay-command-handler.ts +98 -0
- package/apps/control-plane/src/cli/resume-command-handler.ts +231 -16
- package/apps/control-plane/src/cli/retry-command-handler.ts +229 -17
- package/apps/control-plane/src/cli/retry-resume-decision.ts +75 -0
- package/apps/control-plane/src/cli/rollback-command-handler.ts +4 -2
- package/apps/control-plane/src/cli/run-command-handler.ts +35 -1
- package/apps/control-plane/src/cli/spec-ingestion-service.ts +45 -55
- package/apps/control-plane/src/cli/spec-preparation.ts +114 -0
- package/apps/control-plane/src/cli/spec-utils.ts +90 -11
- package/apps/control-plane/src/cli/status-command-handler.ts +122 -0
- package/apps/control-plane/src/cli/types.ts +41 -3
- package/apps/control-plane/src/core/collisions.ts +150 -31
- package/apps/control-plane/src/core/constants.ts +18 -1
- package/apps/control-plane/src/core/error-codes.ts +39 -0
- package/apps/control-plane/src/core/execution-control.ts +56 -0
- package/apps/control-plane/src/core/feature-resume-phase.ts +118 -0
- package/apps/control-plane/src/core/gate-freshness.ts +359 -0
- package/apps/control-plane/src/core/gate-log-extractor.ts +97 -0
- package/apps/control-plane/src/core/gates.ts +90 -1
- package/apps/control-plane/src/core/intake-artifacts.ts +295 -0
- package/apps/control-plane/src/core/kernel-types.ts +11 -0
- package/apps/control-plane/src/core/kernel.ts +604 -16
- package/apps/control-plane/src/core/mainline-conflict.ts +22 -0
- package/apps/control-plane/src/core/merge-repair.ts +149 -0
- package/apps/control-plane/src/core/path-layout.ts +46 -2
- package/apps/control-plane/src/core/path-rules.ts +11 -3
- package/apps/control-plane/src/core/plan-submit-recovery.ts +130 -0
- package/apps/control-plane/src/core/questions.ts +49 -0
- package/apps/control-plane/src/core/runtime-sessions.ts +4 -0
- package/apps/control-plane/src/core/schemas.ts +40 -1
- package/apps/control-plane/src/core/tool-caller.ts +25 -1
- package/apps/control-plane/src/core/utils/index-normalizer.ts +25 -4
- package/apps/control-plane/src/core/worktree-diff.ts +66 -0
- package/apps/control-plane/src/index.ts +29 -1
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +300 -6
- package/apps/control-plane/src/mcp/kernel-tool-executor.ts +17 -0
- package/apps/control-plane/src/mcp/tool-runtime.ts +63 -4
- package/apps/control-plane/src/providers/api-worker-provider.ts +62 -15
- package/apps/control-plane/src/providers/cli-worker-provider.ts +1037 -61
- package/apps/control-plane/src/providers/output-parsers/generic-output-parser.ts +99 -1
- package/apps/control-plane/src/providers/output-parsers/types.ts +2 -0
- package/apps/control-plane/src/providers/provider-defaults.ts +116 -7
- package/apps/control-plane/src/providers/providers.ts +225 -21
- package/apps/control-plane/src/providers/worker-provider-factory.ts +26 -2
- package/apps/control-plane/src/supervisor/artifact-stager.ts +52 -0
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +477 -166
- package/apps/control-plane/src/supervisor/execution-enrollment-service.ts +408 -0
- package/apps/control-plane/src/supervisor/organizer-enrollment-scheduler.ts +117 -0
- package/apps/control-plane/src/supervisor/organizer-sidecar-service.ts +394 -0
- package/apps/control-plane/src/supervisor/plan-conformance-scorer.ts +2 -5
- package/apps/control-plane/src/supervisor/planner-phase.ts +85 -0
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +993 -64
- package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +20 -1
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +384 -177
- package/apps/control-plane/src/supervisor/run-coordinator.ts +723 -20
- package/apps/control-plane/src/supervisor/runtime.ts +485 -9
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +220 -1
- package/apps/control-plane/src/supervisor/types.ts +152 -1
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +1030 -92
- package/apps/control-plane/test/activity-monitor.spec.ts +76 -0
- package/apps/control-plane/test/add-command-handler.spec.ts +189 -0
- package/apps/control-plane/test/application/services/feature-state-service.spec.ts +208 -0
- package/apps/control-plane/test/artifact-stager.spec.ts +93 -0
- package/apps/control-plane/test/batch-operations.spec.ts +58 -0
- package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +50 -2
- package/apps/control-plane/test/bootstrap-manifest-generator-service.spec.ts +99 -0
- package/apps/control-plane/test/bootstrap.spec.ts +177 -4
- package/apps/control-plane/test/checkpoint-service.spec.ts +977 -29
- package/apps/control-plane/test/cli-argument-parser.spec.ts +119 -0
- package/apps/control-plane/test/cli-helpers.spec.ts +1202 -12
- package/apps/control-plane/test/cli.unit.spec.ts +797 -16
- package/apps/control-plane/test/collision-command-handler.spec.ts +182 -0
- package/apps/control-plane/test/collision-override-service.spec.ts +878 -0
- package/apps/control-plane/test/collision-queue.spec.ts +430 -2
- package/apps/control-plane/test/collisions.spec.ts +209 -1
- package/apps/control-plane/test/core-utils.spec.ts +61 -0
- package/apps/control-plane/test/cost-tracking.spec.ts +224 -0
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +185 -5
- package/apps/control-plane/test/dashboard-client.spec.ts +948 -0
- package/apps/control-plane/test/dashboard-command.spec.ts +138 -6
- package/apps/control-plane/test/dashboard-runtime-runner.spec.ts +1550 -0
- package/apps/control-plane/test/dashboard-runtime.spec.ts +138 -0
- package/apps/control-plane/test/dashboard-ui-utils.spec.ts +56 -12
- package/apps/control-plane/test/dependency-scheduler.spec.ts +7 -1
- package/apps/control-plane/test/env-file.spec.ts +76 -0
- package/apps/control-plane/test/execution-control-service.spec.ts +535 -0
- package/apps/control-plane/test/execution-enrollment-service.spec.ts +648 -0
- package/apps/control-plane/test/feature-lifecycle.spec.ts +126 -0
- package/apps/control-plane/test/feature-resume-phase.spec.ts +164 -0
- package/apps/control-plane/test/feature-send-message-service.spec.ts +161 -0
- package/apps/control-plane/test/feature-state-service.spec.ts +295 -0
- package/apps/control-plane/test/fs.spec.ts +80 -0
- package/apps/control-plane/test/gate-freshness.spec.ts +590 -0
- package/apps/control-plane/test/gate-log-extractor.spec.ts +170 -0
- package/apps/control-plane/test/gates.spec.ts +108 -0
- package/apps/control-plane/test/git-reconciliation-service.spec.ts +2307 -0
- package/apps/control-plane/test/helpers.ts +65 -0
- package/apps/control-plane/test/incremental-gates.spec.ts +271 -0
- package/apps/control-plane/test/index-normalizer.spec.ts +98 -0
- package/apps/control-plane/test/init-wizard.spec.ts +17 -0
- package/apps/control-plane/test/intake-artifacts.spec.ts +203 -0
- package/apps/control-plane/test/intake-service.spec.ts +3176 -0
- package/apps/control-plane/test/kernel-collision-replay.spec.ts +3 -2
- package/apps/control-plane/test/kernel-tool-executor.spec.ts +77 -0
- package/apps/control-plane/test/kernel-tool-wiring.spec.ts +279 -0
- package/apps/control-plane/test/kernel.branches.spec.ts +15 -2
- package/apps/control-plane/test/kernel.coverage.spec.ts +7 -3
- package/apps/control-plane/test/kernel.coverage2.spec.ts +731 -2
- package/apps/control-plane/test/kernel.spec.ts +464 -2
- package/apps/control-plane/test/mainline-conflict.spec.ts +66 -0
- package/apps/control-plane/test/mcp-helpers.spec.ts +79 -0
- package/apps/control-plane/test/mcp.spec.ts +177 -13
- package/apps/control-plane/test/merge-command-handler.spec.ts +531 -0
- package/apps/control-plane/test/merge-service.spec.ts +570 -4
- package/apps/control-plane/test/notifier-service.spec.ts +26 -0
- package/apps/control-plane/test/organizer-enrollment-scheduler.spec.ts +340 -0
- package/apps/control-plane/test/organizer-ordering-artifact.spec.ts +95 -0
- package/apps/control-plane/test/organizer-sidecar-service.spec.ts +468 -0
- package/apps/control-plane/test/output-loop-detector.spec.ts +6 -0
- package/apps/control-plane/test/path-layout.spec.ts +70 -0
- package/apps/control-plane/test/performance-analytics.spec.ts +124 -0
- package/apps/control-plane/test/plan-conformance-scorer.spec.ts +53 -0
- package/apps/control-plane/test/plan-service.spec.ts +686 -4
- package/apps/control-plane/test/planning-wave-executor.spec.ts +3272 -86
- package/apps/control-plane/test/policy-loader-service.spec.ts +5 -0
- package/apps/control-plane/test/prompt-overlay.spec.ts +65 -0
- package/apps/control-plane/test/provider-command-runner-epipe.spec.ts +64 -0
- package/apps/control-plane/test/providers/api-worker-provider.spec.ts +129 -0
- package/apps/control-plane/test/providers/cli-worker-provider.spec.ts +148 -0
- package/apps/control-plane/test/providers/usage-types.spec.ts +98 -0
- package/apps/control-plane/test/providers.spec.ts +293 -16
- package/apps/control-plane/test/question-command-handlers.spec.ts +156 -0
- package/apps/control-plane/test/question-service.spec.ts +1119 -0
- package/apps/control-plane/test/reactions.spec.ts +114 -0
- package/apps/control-plane/test/replay-command-handler.spec.ts +144 -0
- package/apps/control-plane/test/replay-timeline-service.spec.ts +459 -0
- package/apps/control-plane/test/response.spec.ts +31 -0
- package/apps/control-plane/test/resume-command.spec.ts +757 -9
- package/apps/control-plane/test/retry-resume-decision.spec.ts +133 -0
- package/apps/control-plane/test/rollback-command-handler.spec.ts +334 -0
- package/apps/control-plane/test/rollback-command.spec.ts +120 -0
- package/apps/control-plane/test/run-coordinator.spec.ts +3062 -404
- package/apps/control-plane/test/schemas/state.schema.spec.ts +71 -0
- package/apps/control-plane/test/service-retry-paths.spec.ts +112 -0
- package/apps/control-plane/test/services.spec.ts +472 -2
- package/apps/control-plane/test/session-management.spec.ts +346 -1
- package/apps/control-plane/test/spec-ingestion.spec.ts +102 -28
- package/apps/control-plane/test/spec-preparation.spec.ts +182 -0
- package/apps/control-plane/test/supervisor-collaborators.spec.ts +191 -3
- package/apps/control-plane/test/supervisor.calltool.spec.ts +198 -0
- package/apps/control-plane/test/supervisor.spec.ts +95 -16
- package/apps/control-plane/test/supervisor.unit.spec.ts +385 -18
- package/apps/control-plane/test/tool-runtime.spec.ts +122 -0
- package/apps/control-plane/test/worker-decision-loop.spec.ts +3479 -476
- package/apps/control-plane/test/worker-execution-policy.spec.ts +1416 -6
- package/apps/control-plane/test/worker-provider-adapters.spec.ts +1894 -37
- package/apps/control-plane/test/worker-provider-factory.spec.ts +81 -0
- package/apps/control-plane/test/worktree-watchdog-service.spec.ts +125 -0
- package/apps/control-plane/vitest.config.ts +5 -0
- package/config/agentic/orchestrator/agents.yaml +22 -1
- package/config/agentic/orchestrator/gates.yaml +24 -7
- package/config/agentic/orchestrator/policy.yaml +23 -1
- package/config/agentic/orchestrator/prompts/builder.system.md +69 -20
- package/config/agentic/orchestrator/prompts/organizer.system.md +85 -0
- package/config/agentic/orchestrator/prompts/overrides/builder.claude.md +28 -0
- package/config/agentic/orchestrator/prompts/overrides/builder.codex.md +28 -0
- package/config/agentic/orchestrator/prompts/overrides/planner.claude.md +20 -0
- package/config/agentic/orchestrator/prompts/overrides/planner.codex.md +20 -0
- package/config/agentic/orchestrator/prompts/planner-intake.system.md +149 -0
- package/config/agentic/orchestrator/prompts/planner.system.md +113 -40
- package/config/agentic/orchestrator/prompts/qa.system.md +75 -18
- package/config/agentic/orchestrator/prompts/reconciler.system.md +119 -0
- package/dist/apps/control-plane/application/kernel-tool-wiring.d.ts +26 -2
- package/dist/apps/control-plane/application/kernel-tool-wiring.js +40 -2
- package/dist/apps/control-plane/application/kernel-tool-wiring.js.map +1 -1
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +37 -1
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.d.ts +4 -0
- package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.js +188 -0
- package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/checkpoint-service.d.ts +5 -0
- package/dist/apps/control-plane/application/services/checkpoint-service.js +69 -24
- package/dist/apps/control-plane/application/services/checkpoint-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/collision-override-service.d.ts +139 -0
- package/dist/apps/control-plane/application/services/collision-override-service.js +568 -0
- package/dist/apps/control-plane/application/services/collision-override-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +15 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js +92 -33
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +11 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +75 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/execution-control-service.d.ts +75 -0
- package/dist/apps/control-plane/application/services/execution-control-service.js +421 -0
- package/dist/apps/control-plane/application/services/execution-control-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +1 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +23 -1
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +24 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +132 -3
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-send-message-service.js +16 -8
- package/dist/apps/control-plane/application/services/feature-send-message-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-state-service.d.ts +36 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js +163 -6
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-service.d.ts +2 -1
- package/dist/apps/control-plane/application/services/gate-service.js +95 -5
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/git-reconciliation-service.d.ts +92 -0
- package/dist/apps/control-plane/application/services/git-reconciliation-service.js +1097 -0
- package/dist/apps/control-plane/application/services/git-reconciliation-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/intake-service.d.ts +63 -0
- package/dist/apps/control-plane/application/services/intake-service.js +1050 -0
- package/dist/apps/control-plane/application/services/intake-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/merge-service.d.ts +5 -1
- package/dist/apps/control-plane/application/services/merge-service.js +233 -18
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.d.ts +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.js +1 -0
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +11 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +59 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/plan-service.d.ts +5 -0
- package/dist/apps/control-plane/application/services/plan-service.js +254 -15
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/question-service.d.ts +72 -0
- package/dist/apps/control-plane/application/services/question-service.js +507 -0
- package/dist/apps/control-plane/application/services/question-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/reactions-service.d.ts +2 -0
- package/dist/apps/control-plane/application/services/reactions-service.js +60 -17
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/replay-timeline-service.d.ts +39 -0
- package/dist/apps/control-plane/application/services/replay-timeline-service.js +205 -0
- package/dist/apps/control-plane/application/services/replay-timeline-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/reporting-service.d.ts +59 -0
- package/dist/apps/control-plane/application/services/reporting-service.js +121 -9
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.d.ts +20 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js +81 -4
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.d.ts +10 -0
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.js +65 -8
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-metadata.js +7 -0
- package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -1
- package/dist/apps/control-plane/application/usage-types.d.ts +65 -0
- package/dist/apps/control-plane/application/usage-types.js +75 -0
- package/dist/apps/control-plane/application/usage-types.js.map +1 -0
- package/dist/apps/control-plane/cli/add-command-handler.d.ts +18 -0
- package/dist/apps/control-plane/cli/add-command-handler.js +110 -0
- package/dist/apps/control-plane/cli/add-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/answer-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/answer-command-handler.js +96 -0
- package/dist/apps/control-plane/cli/answer-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/attach-command-handler.js +8 -3
- package/dist/apps/control-plane/cli/attach-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/cli-argument-parser.js +131 -11
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/collision-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/collision-command-handler.js +90 -0
- package/dist/apps/control-plane/cli/collision-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/command-catalog.d.ts +21 -0
- package/dist/apps/control-plane/cli/command-catalog.js +416 -0
- package/dist/apps/control-plane/cli/command-catalog.js.map +1 -0
- package/dist/apps/control-plane/cli/complete-command-handler.d.ts +15 -0
- package/dist/apps/control-plane/cli/complete-command-handler.js +26 -0
- package/dist/apps/control-plane/cli/complete-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/completion-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/completion-command-handler.js +20 -0
- package/dist/apps/control-plane/cli/completion-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/completion-resolver.d.ts +1 -0
- package/dist/apps/control-plane/cli/completion-resolver.js +250 -0
- package/dist/apps/control-plane/cli/completion-resolver.js.map +1 -0
- package/dist/apps/control-plane/cli/completion-shell-renderer.d.ts +3 -0
- package/dist/apps/control-plane/cli/completion-shell-renderer.js +53 -0
- package/dist/apps/control-plane/cli/completion-shell-renderer.js.map +1 -0
- package/dist/apps/control-plane/cli/dashboard-command-handler.d.ts +1 -0
- package/dist/apps/control-plane/cli/dashboard-command-handler.js +83 -1
- package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/dashboard-runtime-runner.d.ts +81 -0
- package/dist/apps/control-plane/cli/dashboard-runtime-runner.js +724 -0
- package/dist/apps/control-plane/cli/dashboard-runtime-runner.js.map +1 -0
- package/dist/apps/control-plane/cli/dashboard-runtime.d.ts +1 -0
- package/dist/apps/control-plane/cli/dashboard-runtime.js +26 -0
- package/dist/apps/control-plane/cli/dashboard-runtime.js.map +1 -0
- package/dist/apps/control-plane/cli/help-command-handler.js +13 -172
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.js +51 -6
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/merge-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/merge-command-handler.js +139 -0
- package/dist/apps/control-plane/cli/merge-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/questions-command-handler.d.ts +8 -0
- package/dist/apps/control-plane/cli/questions-command-handler.js +59 -0
- package/dist/apps/control-plane/cli/questions-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/replay-command-handler.d.ts +15 -0
- package/dist/apps/control-plane/cli/replay-command-handler.js +55 -0
- package/dist/apps/control-plane/cli/replay-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/resume-command-handler.d.ts +2 -0
- package/dist/apps/control-plane/cli/resume-command-handler.js +180 -17
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-command-handler.js +202 -16
- package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-resume-decision.d.ts +26 -0
- package/dist/apps/control-plane/cli/retry-resume-decision.js +61 -0
- package/dist/apps/control-plane/cli/retry-resume-decision.js.map +1 -0
- package/dist/apps/control-plane/cli/rollback-command-handler.js +3 -2
- package/dist/apps/control-plane/cli/rollback-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/run-command-handler.js +26 -2
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-ingestion-service.d.ts +2 -0
- package/dist/apps/control-plane/cli/spec-ingestion-service.js +37 -48
- package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
- package/dist/apps/control-plane/cli/spec-preparation.d.ts +14 -0
- package/dist/apps/control-plane/cli/spec-preparation.js +81 -0
- package/dist/apps/control-plane/cli/spec-preparation.js.map +1 -0
- package/dist/apps/control-plane/cli/spec-utils.d.ts +4 -0
- package/dist/apps/control-plane/cli/spec-utils.js +70 -11
- package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
- package/dist/apps/control-plane/cli/status-command-handler.js +69 -0
- package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/types.d.ts +41 -4
- package/dist/apps/control-plane/cli/types.js +9 -1
- package/dist/apps/control-plane/cli/types.js.map +1 -1
- package/dist/apps/control-plane/core/collisions.d.ts +37 -19
- package/dist/apps/control-plane/core/collisions.js +87 -12
- package/dist/apps/control-plane/core/collisions.js.map +1 -1
- package/dist/apps/control-plane/core/constants.d.ts +17 -1
- package/dist/apps/control-plane/core/constants.js +18 -1
- package/dist/apps/control-plane/core/constants.js.map +1 -1
- package/dist/apps/control-plane/core/error-codes.d.ts +39 -0
- package/dist/apps/control-plane/core/error-codes.js +39 -0
- package/dist/apps/control-plane/core/error-codes.js.map +1 -1
- package/dist/apps/control-plane/core/execution-control.d.ts +45 -0
- package/dist/apps/control-plane/core/execution-control.js +2 -0
- package/dist/apps/control-plane/core/execution-control.js.map +1 -0
- package/dist/apps/control-plane/core/feature-resume-phase.d.ts +3 -0
- package/dist/apps/control-plane/core/feature-resume-phase.js +88 -0
- package/dist/apps/control-plane/core/feature-resume-phase.js.map +1 -0
- package/dist/apps/control-plane/core/gate-freshness.d.ts +48 -0
- package/dist/apps/control-plane/core/gate-freshness.js +267 -0
- package/dist/apps/control-plane/core/gate-freshness.js.map +1 -0
- package/dist/apps/control-plane/core/gate-log-extractor.d.ts +22 -0
- package/dist/apps/control-plane/core/gate-log-extractor.js +66 -0
- package/dist/apps/control-plane/core/gate-log-extractor.js.map +1 -0
- package/dist/apps/control-plane/core/gates.d.ts +11 -2
- package/dist/apps/control-plane/core/gates.js +67 -3
- package/dist/apps/control-plane/core/gates.js.map +1 -1
- package/dist/apps/control-plane/core/intake-artifacts.d.ts +109 -0
- package/dist/apps/control-plane/core/intake-artifacts.js +143 -0
- package/dist/apps/control-plane/core/intake-artifacts.js.map +1 -0
- package/dist/apps/control-plane/core/kernel-types.d.ts +8 -0
- package/dist/apps/control-plane/core/kernel.d.ts +256 -8
- package/dist/apps/control-plane/core/kernel.js +400 -14
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/mainline-conflict.d.ts +7 -0
- package/dist/apps/control-plane/core/mainline-conflict.js +20 -0
- package/dist/apps/control-plane/core/mainline-conflict.js.map +1 -0
- package/dist/apps/control-plane/core/merge-repair.d.ts +35 -0
- package/dist/apps/control-plane/core/merge-repair.js +99 -0
- package/dist/apps/control-plane/core/merge-repair.js.map +1 -0
- package/dist/apps/control-plane/core/path-layout.d.ts +10 -0
- package/dist/apps/control-plane/core/path-layout.js +32 -2
- package/dist/apps/control-plane/core/path-layout.js.map +1 -1
- package/dist/apps/control-plane/core/path-rules.js +9 -3
- package/dist/apps/control-plane/core/path-rules.js.map +1 -1
- package/dist/apps/control-plane/core/plan-submit-recovery.d.ts +22 -0
- package/dist/apps/control-plane/core/plan-submit-recovery.js +78 -0
- package/dist/apps/control-plane/core/plan-submit-recovery.js.map +1 -0
- package/dist/apps/control-plane/core/questions.d.ts +40 -0
- package/dist/apps/control-plane/core/questions.js +2 -0
- package/dist/apps/control-plane/core/questions.js.map +1 -0
- package/dist/apps/control-plane/core/runtime-sessions.d.ts +4 -0
- package/dist/apps/control-plane/core/schemas.d.ts +2 -0
- package/dist/apps/control-plane/core/schemas.js +31 -1
- package/dist/apps/control-plane/core/schemas.js.map +1 -1
- package/dist/apps/control-plane/core/tool-caller.d.ts +18 -1
- package/dist/apps/control-plane/core/utils/index-normalizer.js +17 -4
- package/dist/apps/control-plane/core/utils/index-normalizer.js.map +1 -1
- package/dist/apps/control-plane/core/worktree-diff.d.ts +4 -0
- package/dist/apps/control-plane/core/worktree-diff.js +52 -0
- package/dist/apps/control-plane/core/worktree-diff.js.map +1 -0
- package/dist/apps/control-plane/index.d.ts +10 -2
- package/dist/apps/control-plane/index.js +9 -2
- package/dist/apps/control-plane/index.js.map +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +236 -6
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js +16 -0
- package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-runtime.d.ts +5 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js +40 -5
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
- package/dist/apps/control-plane/providers/api-worker-provider.d.ts +2 -2
- package/dist/apps/control-plane/providers/api-worker-provider.js +40 -9
- package/dist/apps/control-plane/providers/api-worker-provider.js.map +1 -1
- package/dist/apps/control-plane/providers/cli-worker-provider.d.ts +59 -3
- package/dist/apps/control-plane/providers/cli-worker-provider.js +758 -46
- package/dist/apps/control-plane/providers/cli-worker-provider.js.map +1 -1
- package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js +91 -1
- package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js.map +1 -1
- package/dist/apps/control-plane/providers/output-parsers/types.d.ts +2 -0
- package/dist/apps/control-plane/providers/provider-defaults.d.ts +12 -0
- package/dist/apps/control-plane/providers/provider-defaults.js +103 -7
- package/dist/apps/control-plane/providers/provider-defaults.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +50 -4
- package/dist/apps/control-plane/providers/providers.js +145 -14
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +2 -0
- package/dist/apps/control-plane/providers/worker-provider-factory.js +8 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
- package/dist/apps/control-plane/supervisor/artifact-stager.d.ts +5 -0
- package/dist/apps/control-plane/supervisor/artifact-stager.js +45 -0
- package/dist/apps/control-plane/supervisor/artifact-stager.js.map +1 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +24 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +362 -150
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/execution-enrollment-service.d.ts +41 -0
- package/dist/apps/control-plane/supervisor/execution-enrollment-service.js +311 -0
- package/dist/apps/control-plane/supervisor/execution-enrollment-service.js.map +1 -0
- package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.d.ts +15 -0
- package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.js +93 -0
- package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.js.map +1 -0
- package/dist/apps/control-plane/supervisor/organizer-sidecar-service.d.ts +44 -0
- package/dist/apps/control-plane/supervisor/organizer-sidecar-service.js +311 -0
- package/dist/apps/control-plane/supervisor/organizer-sidecar-service.js.map +1 -0
- package/dist/apps/control-plane/supervisor/plan-conformance-scorer.js +2 -5
- package/dist/apps/control-plane/supervisor/plan-conformance-scorer.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planner-phase.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/planner-phase.js +70 -0
- package/dist/apps/control-plane/supervisor/planner-phase.js.map +1 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +42 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +753 -55
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +19 -1
- package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js.map +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +21 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +287 -156
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +30 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.js +561 -17
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.d.ts +84 -0
- package/dist/apps/control-plane/supervisor/runtime.js +393 -3
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +54 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +176 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/types.d.ts +142 -1
- package/dist/apps/control-plane/supervisor/types.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +68 -2
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +723 -89
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/docs/core/ARCHITECTURE.md +227 -0
- package/docs/core/DECISIONS.md +94 -0
- package/docs/core/DOMAIN-LOGIC.md +60 -0
- package/docs/core/PATTERNS.md +201 -0
- package/docs/core/TROUBLESHOOTING.md +347 -0
- package/docs/core/intentgraph-dependencies.json +39860 -0
- package/docs/core/intentgraph.index.json +46580 -0
- package/docs/plans/2026-03-10-gate-failure-targeted-repair-design.md +224 -0
- package/docs/plans/2026-03-10-gate-failure-targeted-repair.md +1032 -0
- package/docs/superpowers/plans/2026-03-16-provider-cli-config.md +743 -0
- package/docs/superpowers/plans/2026-03-23-reconcile-divergence-fix.md +777 -0
- package/docs/superpowers/plans/2026-03-28-ordering-agent-implementation.md +1754 -0
- package/docs/superpowers/plans/2026-03-29-drop-zone-and-provider-optimization.md +1108 -0
- package/docs/superpowers/plans/2026-03-29-merge-target-feature-branch.md +685 -0
- package/docs/superpowers/plans/2026-03-29-organizer-sidecar-runtime-loop.md +1289 -0
- package/docs/superpowers/specs/2026-03-23-reconcile-divergence-fix-design.md +118 -0
- package/docs/superpowers/specs/2026-03-28-ordering-agent-spec-audit-design.md +50 -0
- package/docs/superpowers/specs/2026-03-29-drop-zone-and-provider-optimization-design.md +254 -0
- package/docs/superpowers/specs/2026-03-29-merge-target-feature-branch-design.md +152 -0
- package/docs/superpowers/specs/2026-03-29-organizer-sidecar-runtime-loop-design.md +225 -0
- package/package.json +3 -2
- package/packages/web-dashboard/package.json +2 -1
- package/packages/web-dashboard/src/app/analytics/page.tsx +36 -2
- package/packages/web-dashboard/src/app/api/actions/route.ts +274 -63
- package/packages/web-dashboard/src/app/api/actions/status/route.ts +35 -0
- package/packages/web-dashboard/src/app/api/analytics/provider/route.ts +18 -0
- package/packages/web-dashboard/src/app/api/collisions/approve/route.ts +58 -0
- package/packages/web-dashboard/src/app/api/features/[id]/checkpoint-diff/route.ts +36 -0
- package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/route.ts +29 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/abort/route.ts +29 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/files/route.ts +30 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/resolve/route.ts +51 -0
- package/packages/web-dashboard/src/app/api/features/[id]/conflicts/route.ts +75 -0
- package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +16 -2
- package/packages/web-dashboard/src/app/api/features/[id]/files/route.ts +26 -0
- package/packages/web-dashboard/src/app/api/features/[id]/gate-history/route.ts +27 -0
- package/packages/web-dashboard/src/app/api/features/[id]/genealogy/route.ts +26 -0
- package/packages/web-dashboard/src/app/api/features/[id]/history/run/[runId]/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/history/runs/route.ts +34 -0
- package/packages/web-dashboard/src/app/api/features/[id]/intake-workspace/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/live-output/route.ts +74 -0
- package/packages/web-dashboard/src/app/api/features/[id]/plan/amend/route.ts +21 -0
- package/packages/web-dashboard/src/app/api/features/[id]/plan-progress/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/planner-artifacts/[artifact]/route.ts +78 -0
- package/packages/web-dashboard/src/app/api/features/[id]/planner-lifecycle/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/planning-workspace/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/features/[id]/questions/[questionId]/answer/route.ts +27 -0
- package/packages/web-dashboard/src/app/api/features/[id]/questions/route.ts +18 -0
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +14 -7
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +57 -2
- package/packages/web-dashboard/src/app/api/features/[id]/spec/route.ts +30 -0
- package/packages/web-dashboard/src/app/api/features/[id]/triage/route.ts +83 -0
- package/packages/web-dashboard/src/app/api/features/[id]/worker-events/route.ts +40 -0
- package/packages/web-dashboard/src/app/api/launch/preview/route.ts +86 -0
- package/packages/web-dashboard/src/app/api/launch/submit/route.ts +180 -0
- package/packages/web-dashboard/src/app/api/mainline/status/route.ts +74 -0
- package/packages/web-dashboard/src/app/api/merge-queue/route.ts +13 -0
- package/packages/web-dashboard/src/app/api/policy/budget/route.ts +14 -0
- package/packages/web-dashboard/src/app/api/projects/route.ts +11 -7
- package/packages/web-dashboard/src/app/api/reconciler/queue/route.ts +47 -0
- package/packages/web-dashboard/src/app/api/run/route.ts +26 -2
- package/packages/web-dashboard/src/app/api/runtime/events/route.ts +227 -0
- package/packages/web-dashboard/src/app/api/runtime/operations/route.ts +269 -0
- package/packages/web-dashboard/src/app/api/runtime/questions/route.ts +11 -0
- package/packages/web-dashboard/src/app/api/runtime/runs/route.ts +80 -0
- package/packages/web-dashboard/src/app/api/status/route.ts +4 -2
- package/packages/web-dashboard/src/app/feature/[id]/page.tsx +32 -42
- package/packages/web-dashboard/src/app/globals.css +34 -3
- package/packages/web-dashboard/src/app/launch/page.tsx +357 -0
- package/packages/web-dashboard/src/app/layout.tsx +23 -1
- package/packages/web-dashboard/src/app/page.tsx +263 -272
- package/packages/web-dashboard/src/components/dashboard/attention-strip.tsx +52 -0
- package/packages/web-dashboard/src/components/dashboard/collision-approval-drawer.tsx +185 -0
- package/packages/web-dashboard/src/components/dashboard/command-center-header.tsx +102 -0
- package/packages/web-dashboard/src/components/dashboard/mainline-status-banner.tsx +84 -0
- package/packages/web-dashboard/src/components/dashboard/merged-archive.tsx +36 -0
- package/packages/web-dashboard/src/components/dashboard/prioritized-queues.tsx +98 -0
- package/packages/web-dashboard/src/components/dashboard/reconciler-queue-card.tsx +115 -0
- package/packages/web-dashboard/src/components/dashboard/secondary-diagnostics-rail.tsx +48 -0
- package/packages/web-dashboard/src/components/dashboard/task-filter-bar.tsx +74 -0
- package/packages/web-dashboard/src/components/dashboard/triage-drawer.tsx +455 -0
- package/packages/web-dashboard/src/components/diff-viewer.tsx +19 -3
- package/packages/web-dashboard/src/components/evidence-viewer.tsx +65 -51
- package/packages/web-dashboard/src/components/feature-card.tsx +90 -7
- package/packages/web-dashboard/src/components/feature-cost-panel.tsx +112 -11
- package/packages/web-dashboard/src/components/feature-list-view.tsx +25 -4
- package/packages/web-dashboard/src/components/features/runtime-inspector/EventsTimelineView.tsx +260 -0
- package/packages/web-dashboard/src/components/features/runtime-inspector/OperationsListView.tsx +172 -0
- package/packages/web-dashboard/src/components/features/runtime-inspector/RuntimeInspectorPanel.tsx +896 -0
- package/packages/web-dashboard/src/components/filter-bar.tsx +7 -39
- package/packages/web-dashboard/src/components/focus/ActionableRiskList.tsx +46 -0
- package/packages/web-dashboard/src/components/focus/AgentRolePerformanceCard.tsx +200 -0
- package/packages/web-dashboard/src/components/focus/BlockedGuidanceBanner.tsx +149 -0
- package/packages/web-dashboard/src/components/focus/CheckpointInspector.tsx +123 -0
- package/packages/web-dashboard/src/components/focus/CheckpointRail.tsx +118 -0
- package/packages/web-dashboard/src/components/focus/CheckpointScrubber.tsx +249 -0
- package/packages/web-dashboard/src/components/focus/CollisionApprovalBanner.tsx +192 -0
- package/packages/web-dashboard/src/components/focus/CollisionRadar.tsx +136 -0
- package/packages/web-dashboard/src/components/focus/ConflictStatusCard.tsx +52 -0
- package/packages/web-dashboard/src/components/focus/ContextSidebar.tsx +108 -0
- package/packages/web-dashboard/src/components/focus/DiagnosisPanel.tsx +68 -0
- package/packages/web-dashboard/src/components/focus/FeatureDecisionBanner.tsx +68 -0
- package/packages/web-dashboard/src/components/focus/FeatureQuestionAnswerPanel.tsx +167 -0
- package/packages/web-dashboard/src/components/focus/FocusHeader.tsx +54 -0
- package/packages/web-dashboard/src/components/focus/FocusLayout.tsx +283 -0
- package/packages/web-dashboard/src/components/focus/GateFlakinessSummary.tsx +144 -0
- package/packages/web-dashboard/src/components/focus/GenealogyTree.tsx +34 -0
- package/packages/web-dashboard/src/components/focus/HeroBlock.tsx +67 -0
- package/packages/web-dashboard/src/components/focus/LiveAgentConsole.tsx +277 -0
- package/packages/web-dashboard/src/components/focus/MergeQueueCard.tsx +78 -0
- package/packages/web-dashboard/src/components/focus/OperationalSummaryCard.tsx +227 -0
- package/packages/web-dashboard/src/components/focus/PinnedActions.tsx +96 -0
- package/packages/web-dashboard/src/components/focus/PlanAmendmentPanel.tsx +250 -0
- package/packages/web-dashboard/src/components/focus/PlanProgressPanel.tsx +133 -0
- package/packages/web-dashboard/src/components/focus/PlannerArtifactViewer.tsx +158 -0
- package/packages/web-dashboard/src/components/focus/PlannerLifecycleHeader.tsx +141 -0
- package/packages/web-dashboard/src/components/focus/ProgressSnapshotCard.tsx +113 -0
- package/packages/web-dashboard/src/components/focus/RecentMaterialChanges.tsx +69 -0
- package/packages/web-dashboard/src/components/focus/RoleLogViewer.tsx +436 -0
- package/packages/web-dashboard/src/components/focus/RunHistoryBrowser.tsx +62 -0
- package/packages/web-dashboard/src/components/focus/SpecViewer.tsx +172 -0
- package/packages/web-dashboard/src/components/focus/TabBar.tsx +33 -0
- package/packages/web-dashboard/src/components/focus/UsageBurnChart.tsx +212 -0
- package/packages/web-dashboard/src/components/focus/VerificationSummaryCard.tsx +122 -0
- package/packages/web-dashboard/src/components/focus/tabs/ChangesTab.tsx +325 -0
- package/packages/web-dashboard/src/components/focus/tabs/ConflictsTab.tsx +395 -0
- package/packages/web-dashboard/src/components/focus/tabs/GatesQaTab.tsx +38 -0
- package/packages/web-dashboard/src/components/focus/tabs/HistoryTab.tsx +213 -0
- package/packages/web-dashboard/src/components/focus/tabs/IntakeTab.tsx +429 -0
- package/packages/web-dashboard/src/components/focus/tabs/OverviewTab.tsx +217 -0
- package/packages/web-dashboard/src/components/focus/tabs/PlanningTab.tsx +390 -0
- package/packages/web-dashboard/src/components/focus/tabs/ReviewTab.tsx +497 -0
- package/packages/web-dashboard/src/components/focus/tabs/RuntimeTab.tsx +213 -0
- package/packages/web-dashboard/src/components/focus/tabs/TranscriptTab.tsx +315 -0
- package/packages/web-dashboard/src/components/gate-results.tsx +2 -2
- package/packages/web-dashboard/src/components/human-input-panel.tsx +33 -57
- package/packages/web-dashboard/src/components/kanban-board.tsx +4 -0
- package/packages/web-dashboard/src/components/launch/launch-draft-card.tsx +131 -0
- package/packages/web-dashboard/src/components/plan-viewer.tsx +147 -69
- package/packages/web-dashboard/src/components/quick-launch-panel.tsx +20 -47
- package/packages/web-dashboard/src/components/summary-bar.tsx +30 -76
- package/packages/web-dashboard/src/lib/aop-client.ts +2484 -36
- package/packages/web-dashboard/src/lib/blocked-state-guidance.ts +475 -0
- package/packages/web-dashboard/src/lib/collision-radar.ts +136 -0
- package/packages/web-dashboard/src/lib/dashboard-action-states.ts +204 -0
- package/packages/web-dashboard/src/lib/dashboard-runtime-client.ts +439 -0
- package/packages/web-dashboard/src/lib/dashboard-utils.ts +179 -18
- package/packages/web-dashboard/src/lib/drop-zone-utils.ts +92 -0
- package/packages/web-dashboard/src/lib/focus-detail-derivations.ts +958 -0
- package/packages/web-dashboard/src/lib/focus-view.ts +300 -0
- package/packages/web-dashboard/src/lib/health-diagnosis.ts +356 -0
- package/packages/web-dashboard/src/lib/launch-contracts.ts +77 -0
- package/packages/web-dashboard/src/lib/launch-markdown.ts +107 -0
- package/packages/web-dashboard/src/lib/launch-page-preview.ts +89 -0
- package/packages/web-dashboard/src/lib/live-feed.ts +1 -1
- package/packages/web-dashboard/src/lib/multi-project-config.ts +33 -0
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +845 -59
- package/packages/web-dashboard/src/lib/planner-workspace.ts +1285 -0
- package/packages/web-dashboard/src/lib/review-contracts.ts +5 -3
- package/packages/web-dashboard/src/lib/runtime-files.ts +285 -0
- package/packages/web-dashboard/src/lib/tool-catalog.ts +51 -0
- package/packages/web-dashboard/src/lib/types.ts +731 -3
- package/packages/web-dashboard/src/lib/usage-burn.ts +175 -0
- package/packages/web-dashboard/src/lib/worktree-diff.ts +128 -0
- package/packages/web-dashboard/src/styles/dashboard.module.css +1742 -459
- package/packages/web-dashboard/test/api/actions/route.spec.ts +675 -0
- package/packages/web-dashboard/test/api/features/diff.route.spec.ts +57 -0
- package/packages/web-dashboard/test/api/features/feature.route.spec.ts +99 -0
- package/packages/web-dashboard/test/api/features/live-output.route.spec.ts +123 -0
- package/packages/web-dashboard/test/api/features/plan-amend.route.spec.ts +95 -0
- package/packages/web-dashboard/test/api/features/planner-workspaces.route.spec.ts +162 -0
- package/packages/web-dashboard/test/api/features/question-answer.route.spec.ts +99 -0
- package/packages/web-dashboard/test/api/features/triage.route.spec.ts +195 -0
- package/packages/web-dashboard/test/api/launch/preview.route.spec.ts +149 -0
- package/packages/web-dashboard/test/api/launch/submit.route.spec.ts +382 -0
- package/packages/web-dashboard/test/api/runtime/events/route.spec.ts +164 -0
- package/packages/web-dashboard/test/api/runtime/operations/route.spec.ts +156 -0
- package/packages/web-dashboard/test/api/runtime/runs/route.spec.ts +112 -0
- package/packages/web-dashboard/test/components/changes-tab.spec.tsx +76 -0
- package/packages/web-dashboard/test/components/command-center-root.spec.tsx +87 -0
- package/packages/web-dashboard/test/components/diagnosis-panel.spec.tsx +59 -0
- package/packages/web-dashboard/test/components/feature-card.spec.tsx +45 -0
- package/packages/web-dashboard/test/components/focus-layout.spec.tsx +299 -0
- package/packages/web-dashboard/test/components/gate-results.spec.tsx +39 -0
- package/packages/web-dashboard/test/components/gates-qa-tab.spec.tsx +118 -0
- package/packages/web-dashboard/test/components/human-input-panel.spec.tsx +54 -0
- package/packages/web-dashboard/test/components/intake-tab.spec.tsx +210 -0
- package/packages/web-dashboard/test/components/kanban-board.spec.tsx +35 -0
- package/packages/web-dashboard/test/components/launch-draft-card.spec.tsx +54 -0
- package/packages/web-dashboard/test/components/launch-page.spec.tsx +79 -0
- package/packages/web-dashboard/test/components/overview-tab.spec.tsx +236 -0
- package/packages/web-dashboard/test/components/planning-tab.spec.tsx +202 -0
- package/packages/web-dashboard/test/components/review-tab.spec.tsx +169 -0
- package/packages/web-dashboard/test/components/role-log-viewer.spec.ts +42 -0
- package/packages/web-dashboard/test/components/runtime-inspector.spec.tsx +22 -0
- package/packages/web-dashboard/test/components/runtime-tab.spec.tsx +133 -0
- package/packages/web-dashboard/test/components/transcript-tab.spec.tsx +46 -0
- package/packages/web-dashboard/test/components/triage-drawer.spec.tsx +159 -0
- package/packages/web-dashboard/test/lib/aop-client.spec.ts +235 -0
- package/packages/web-dashboard/test/lib/dashboard-runtime-client.spec.ts +144 -0
- package/packages/web-dashboard/test/lib/focus-detail-derivations.spec.ts +314 -0
- package/packages/web-dashboard/test/lib/focus-view.spec.ts +248 -0
- package/packages/web-dashboard/test/lib/health-diagnosis.spec.ts +277 -0
- package/packages/web-dashboard/test/lib/launch-markdown.spec.ts +36 -0
- package/packages/web-dashboard/test/lib/multi-project-config.spec.ts +54 -0
- package/packages/web-dashboard/test/lib/orchestrator-tools.spec.ts +352 -0
- package/packages/web-dashboard/test/lib/planner-workspace.spec.ts +289 -0
- package/packages/web-dashboard/test/lib/worktree-diff.spec.ts +119 -0
- package/packages/web-dashboard/vitest.config.ts +2 -0
- package/spec-files/completed/agentic_orchestrator_add_feature_to_active_execution_spec.md +557 -0
- package/spec-files/completed/agentic_orchestrator_dashboard_command_center_redesign_spec.md +1147 -0
- package/spec-files/completed/agentic_orchestrator_execution_mode_spec.md +18 -16
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_a_spec.md +672 -0
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_b_spec.md +794 -0
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_c_decision_centric_remediation_spec.md +1037 -0
- package/spec-files/completed/agentic_orchestrator_feature_focus_view_ux_redesign_spec.md +1432 -0
- package/spec-files/completed/agentic_orchestrator_focus_plan_tab_intake_planning_workspace_spec.md +921 -0
- package/spec-files/completed/agentic_orchestrator_intentional_collision_override_spec.md +584 -0
- package/spec-files/completed/agentic_orchestrator_interactive_planning_intake_and_requirements_verification_spec.md +1185 -0
- package/spec-files/completed/agentic_orchestrator_reactive_execution_enrollment_spec.md +864 -0
- package/spec-files/{outstanding → completed}/agentic_orchestrator_runtime_inspection_spec.md +92 -19
- package/spec-files/completed/agentic_orchestrator_scope_aware_run_lease_spec.md +408 -0
- package/spec-files/completed/git-reconciliation-engine.md +827 -0
- package/spec-files/outstanding/agentic_orchestrator_dashboard_quick_launch_and_control_surface_spec.md +331 -0
- package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +16 -6
- package/spec-files/outstanding/agentic_orchestrator_evidence_integrity_doctor_spec.md +60 -9
- package/spec-files/outstanding/agentic_orchestrator_focus_plan_tab_execution_contract_workspace_spec.md +616 -0
- package/spec-files/outstanding/agentic_orchestrator_headless_standby_dashboard_runtime_spec.md +310 -0
- package/spec-files/outstanding/agentic_orchestrator_human_input_interaction_protocol_spec.md +175 -72
- package/spec-files/outstanding/agentic_orchestrator_interactive_rename_cleanup_spec.md +197 -0
- package/spec-files/outstanding/agentic_orchestrator_interactive_resume_and_reconciliation_disposition_spec.md +412 -0
- package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +166 -137
- package/spec-files/outstanding/agentic_orchestrator_observability_replay_spec.md +3 -3
- package/spec-files/outstanding/agentic_orchestrator_phase_specific_agent_profiles_and_token_telemetry_spec.md +303 -0
- package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +18 -5
- package/spec-files/outstanding/agentic_orchestrator_policy_stratification_spec.md +225 -0
- package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +77 -50
- package/spec-files/outstanding/agentic_orchestrator_ready_to_merge_branch_handoff_spec.md +724 -0
- package/spec-files/outstanding/agentic_orchestrator_remove_deterministic_mode_spec.md +263 -0
- package/spec-files/outstanding/agentic_orchestrator_request_more_context_and_dashboard_human_input_spec.md +456 -0
- package/spec-files/outstanding/agentic_orchestrator_spec_coverage_and_reconciliation_enforcement_spec.md +1411 -0
- package/spec-files/outstanding/agentic_orchestrator_spec_ordering_agent_spec.md +370 -0
- package/spec-files/outstanding/shadow_workspace_implementation_spec.md +1 -1
- package/spec-files/progress.md +2026 -120
- package/specs/001-runtime-inspection/checklists/requirements.md +35 -0
- package/specs/001-runtime-inspection/design.md +338 -0
- package/specs/001-runtime-inspection/spec.md +95 -0
- package/specs/002-scope-aware-lease/checklists/requirements.md +35 -0
- package/specs/002-scope-aware-lease/contracts/lease-registry.schema.json +101 -0
- package/specs/002-scope-aware-lease/data-model.md +236 -0
- package/specs/002-scope-aware-lease/plan.md +766 -0
- package/specs/002-scope-aware-lease/quickstart.md +150 -0
- package/specs/002-scope-aware-lease/research.md +135 -0
- package/specs/002-scope-aware-lease/spec.md +128 -0
- package/specs/002-scope-aware-lease/tasks.md +767 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +28 -0
- package/ARCHITECTURE_ADHERENCE_ANALYSIS.md +0 -871
- package/packages/web-dashboard/next-env.d.ts +0 -6
- package/packages/web-dashboard/src/components/detail-panel.tsx +0 -1124
- package/packages/web-dashboard/src/components/review-workspace.tsx +0 -1162
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_artifact_database_publishing_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_cli_shell_tab_completion_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_dashboard_diff_and_agent_console_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_performance_improvements_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_persistent_worker_runtime_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_provider_auth_bootstrap_spec.md +0 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_real_worker_provider_execution_spec.md +0 -0
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
# Implementation Plan: Scope-Aware Run Lease
|
|
2
|
+
|
|
3
|
+
**Branch**: `002-scope-aware-lease` | **Date**: 2025-07-23 | **Spec**: [`specs/002-scope-aware-lease/spec.md`](./spec.md)
|
|
4
|
+
**Input**: Feature specification — replace the global exclusive run lease with a scope-aware conflict detector that only blocks executions whose declared codebase scopes overlap.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Summary
|
|
9
|
+
|
|
10
|
+
The current `RunLeaseService` allows only one active run at a time, regardless of which parts of the codebase each run touches. This feature replaces that global barrier with scope-aware conflict detection: when a new run requests a lease, the system compares its declared `LeaseScope` (file-system paths + plan section IDs) against all currently active leases in a shared **Lease Registry**. Two runs with non-overlapping scopes are both granted leases; overlapping scopes are serialized. Runs with an unknown (`null`) scope follow the conservative fallback and block against everything.
|
|
11
|
+
|
|
12
|
+
**Technical approach:**
|
|
13
|
+
|
|
14
|
+
1. Add a `LeaseScope` / `LeaseScopeDeclaration` type and `ActiveLeaseRecord` to the data model.
|
|
15
|
+
2. Introduce a new global **Lease Registry** file (`.aop/runtime/lease-registry.json`) protected by the existing index-level atomic lock.
|
|
16
|
+
3. Extract pure scope-overlap logic into a new `LeaseScopeConflictDetector` service (no I/O).
|
|
17
|
+
4. Update `RunLeaseService.acquireRunLease` to consult the registry and detect conflicts before granting; update `releaseRunLease` and `renewRunLease` to maintain registry state.
|
|
18
|
+
5. Add `expandRunLeaseScope` for mid-run scope expansion (FR-007).
|
|
19
|
+
6. Propagate scope from CLI / feature inputs through `RunCoordinator` → kernel.
|
|
20
|
+
7. New error code `LEASE_SCOPE_CONFLICT` for observable deferral logging (FR-010).
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Technical Context
|
|
25
|
+
|
|
26
|
+
**Language/Version**: TypeScript 5.9 strict, Node.js ESM
|
|
27
|
+
**Primary Dependencies**: AJV (JSON Schema validation), `node:crypto`, `node:path`, Vitest
|
|
28
|
+
**Storage**: File-system JSON (`.aop/runtime/lease-registry.json`); atomic writes via `atomicWriteJson`; locking via `withFileLock`
|
|
29
|
+
**Testing**: Vitest — ≥90% lines/branches/functions/statements
|
|
30
|
+
**Target Platform**: Local CLI (`aop` binary), Node.js 20+
|
|
31
|
+
**Project Type**: CLI application — Nx monorepo single app (`apps/control-plane/`)
|
|
32
|
+
**Performance Goals**: Scope conflict check adds <1 ms overhead per acquisition attempt (registry is single-digit entries; exhaustive pairwise comparison is acceptable per spec assumption)
|
|
33
|
+
**Constraints**: No `any` in source, no `@ts-ignore`, `import type` for type-only imports, `fail()` + `ERROR_CODES` for all domain failures, `withFileLock` for all state mutations
|
|
34
|
+
**Scale/Scope**: Registry holds single-digit concurrent run leases; no indexing strategy needed
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Constitution Check
|
|
39
|
+
|
|
40
|
+
_GATE: Must pass before Phase 0 research. Re-checked after Phase 1 design._
|
|
41
|
+
|
|
42
|
+
| Principle | Status | Notes |
|
|
43
|
+
| ---------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------ | ----- |
|
|
44
|
+
| KISS — prefer the simplest design | ✅ | Pairwise registry scan is O(n²) but n is always single-digit; no index needed |
|
|
45
|
+
| SRP — each module has one reason to change | ✅ | Pure conflict-detection logic isolated in `LeaseScopeConflictDetector` |
|
|
46
|
+
| Open/Closed — extend by adding adapters/services | ✅ | Existing `RunLeaseService` extended via new port methods; no unrelated kernel code touched |
|
|
47
|
+
| DI (Hexagonal) — depend on ports, not concrete infra | ✅ | New registry read/write go through `RunLeaseServicePort` methods |
|
|
48
|
+
| No `any` in source | ✅ | All new types are fully typed; `LeaseScopeDeclaration = LeaseScope | null` |
|
|
49
|
+
| `fail()` + `ERROR_CODES` for all failures | ✅ | New `LEASE_SCOPE_CONFLICT` error code added before use |
|
|
50
|
+
| `withFileLock` for all state mutations | ✅ | Registry writes go inside `withIndexLock` (same mechanism, same lock path) |
|
|
51
|
+
| No `console.log` in `apps/control-plane/src/` | ✅ | Deferral observability uses `console.warn` for SCOPE_CONFLICT logging |
|
|
52
|
+
| `no-floating-promises` | ✅ | All async calls awaited; no fire-and-forget patterns introduced |
|
|
53
|
+
|
|
54
|
+
**Constitution verdict: PASS — no violations**
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Project Structure
|
|
59
|
+
|
|
60
|
+
### Documentation (this feature)
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
specs/002-scope-aware-lease/
|
|
64
|
+
├── plan.md ← this file
|
|
65
|
+
├── research.md ← Phase 0 output
|
|
66
|
+
├── data-model.md ← Phase 1 output
|
|
67
|
+
├── contracts/
|
|
68
|
+
│ └── lease-registry.schema.json ← JSON Schema for lease-registry.json
|
|
69
|
+
└── quickstart.md ← Phase 1 output
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Source Code — affected paths
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
apps/control-plane/src/
|
|
76
|
+
├── core/
|
|
77
|
+
│ ├── runtime-sessions.ts ← ADD LeaseScope, LeaseScopeDeclaration, ActiveLeaseRecord, LeaseRegistry types
|
|
78
|
+
│ ├── error-codes.ts ← ADD LEASE_SCOPE_CONFLICT
|
|
79
|
+
│ └── path-layout.ts ← ADD leaseRegistryPath getter
|
|
80
|
+
├── application/
|
|
81
|
+
│ └── services/
|
|
82
|
+
│ ├── lease-scope-conflict-detector.ts ← NEW pure logic service
|
|
83
|
+
│ └── run-lease-service.ts ← MODIFY scope conflict integration
|
|
84
|
+
└── supervisor/
|
|
85
|
+
├── run-coordinator.ts ← MODIFY pass scope on acquireRunLease
|
|
86
|
+
└── types.ts ← MODIFY add scope to FeatureInput
|
|
87
|
+
|
|
88
|
+
apps/control-plane/test/
|
|
89
|
+
├── lease-scope-conflict-detector.spec.ts ← NEW — primary test surface
|
|
90
|
+
└── run-lease-service.spec.ts ← NEW — integration coverage for scope paths
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Structure Decision**: Single-app Nx monorepo. All changes are inside `apps/control-plane/`. No new packages. New `LeaseScopeConflictDetector` is a plain service class (no framework, no DI wrapper) — pure input/output with zero side effects, consistent with the existing pattern in e.g. `gate-selection-service.ts`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Complexity Tracking
|
|
98
|
+
|
|
99
|
+
No constitution violations. No complexity justifications needed.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Phase 0: Research
|
|
104
|
+
|
|
105
|
+
### R-001 — Scope overlap: path-prefix semantics
|
|
106
|
+
|
|
107
|
+
**Decision**: Use normalized path strings with a trailing-slash normalization rule. A path `a` overlaps path `b` if and only if `normalize(a)` is a prefix of `normalize(b)` or vice versa.
|
|
108
|
+
|
|
109
|
+
**Normalization rule**:
|
|
110
|
+
|
|
111
|
+
- Strip any trailing slash from the raw input, then re-append exactly one `/` before prefix comparison.
|
|
112
|
+
- This ensures `packages/auth` and `packages/authentication` do NOT overlap (the former only overlaps `packages/auth/…`).
|
|
113
|
+
- Empty string after strip → treated as root `/` → overlaps everything.
|
|
114
|
+
|
|
115
|
+
**Rationale**: Spec FR-003 requires "path-prefix containment." Trailing-slash normalization is the standard way to avoid false positives (e.g., `src/` vs `src-old/`). The spec calls out this edge case explicitly under "Partially overlapping nested paths."
|
|
116
|
+
|
|
117
|
+
**Alternatives considered**:
|
|
118
|
+
|
|
119
|
+
- Glob pattern matching — rejected; adds complexity, spec only requires prefix containment.
|
|
120
|
+
- `path.relative()` — rejected; cross-platform normalization issues on Windows are irrelevant for a Linux/macOS CLI, but the trailing-slash approach is simpler and portable.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### R-002 — Plan section ID overlap semantics
|
|
125
|
+
|
|
126
|
+
**Decision**: Two plan section IDs overlap if and only if they are **equal** (case-sensitive string equality). No hierarchical relationship between section IDs.
|
|
127
|
+
|
|
128
|
+
**Rationale**: Spec Assumptions: "Plan section identifiers used as scope entries are treated as opaque strings; two identifiers overlap only if they are equal (no hierarchical relationship between plan sections)."
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### R-003 — Empty scope vs. unknown (null) scope
|
|
133
|
+
|
|
134
|
+
**Decision**:
|
|
135
|
+
|
|
136
|
+
- `null` → unknown scope → conflicts with **all** active leases (conservative fallback, FR-004).
|
|
137
|
+
- `{ paths: [], plan_section_ids: [] }` → explicitly empty → conflicts with **no** active leases.
|
|
138
|
+
- `undefined` (field absent) → normalized to `null` at port boundary.
|
|
139
|
+
|
|
140
|
+
**Rationale**: The spec edge case "Empty scope list vs. no scope declared" explicitly calls for this distinction. An empty list means "touches nothing" (safe to proceed). Absent/null means "unknown" (must block).
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### R-004 — Lease Registry architecture
|
|
145
|
+
|
|
146
|
+
**Decision**: A single shared file `.aop/runtime/lease-registry.json` containing `{ leases: ActiveLeaseRecord[] }`, protected by the **existing index lock** (`withIndexLock` / `.aop/features/.index.lock`). Per-instance lease files (`.aop/runtime/<instanceId>/run-lease.json`) are retained for per-instance session metadata (heartbeat tracking, session IDs, etc.) and are written atomically inside the same lock callback.
|
|
147
|
+
|
|
148
|
+
**Rationale**:
|
|
149
|
+
|
|
150
|
+
- Avoids introducing a second lock level, which could cause priority inversion.
|
|
151
|
+
- The index lock is already the single serialization point for all lease operations (`acquireRunLease`, `renewRunLease`, `releaseRunLease`).
|
|
152
|
+
- Registry entries are pruned on every read (expired leases removed), preventing stale-entry accumulation.
|
|
153
|
+
- Single-digit concurrent runs → no performance concern.
|
|
154
|
+
|
|
155
|
+
**Alternatives considered**:
|
|
156
|
+
|
|
157
|
+
- Dedicated registry lock (`.aop/runtime/.lease-registry.lock`) — rejected; adds a second lock primitive, same critical section, more complexity for no benefit.
|
|
158
|
+
- Storing all active leases inside `index.json` under `active_leases[]` — rejected; `index.json` is the feature index and mixing lease registry into it violates SRP; dedicated file is cleaner.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### R-005 — Scope expansion (FR-007)
|
|
163
|
+
|
|
164
|
+
**Decision**: Add `expandRunLeaseScope(runId, ownerInstanceId, additionalScope)` to `RunLeaseService` and expose it as a direct kernel method. The supervisor calls this after the planning wave populates `plan.json` with the file manifest. Expansion is **additive** — existing paths are merged with new ones; no paths are removed. Pending lease requests that were blocked on this run are NOT automatically re-evaluated; they will be re-evaluated on their next acquisition retry (retryable flow).
|
|
165
|
+
|
|
166
|
+
**Rationale**: The spec says scope expansion is "an infrequent operation." Making it advisory (retry-driven re-evaluation) avoids a complex push-based notification mechanism. The `LeaseHeartbeatService` already renews on every iteration; blocked runs retry on their next iteration naturally.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### R-006 — Stale lease takeover and scope replacement (FR-008)
|
|
171
|
+
|
|
172
|
+
**Decision**: When a stale lease is taken over (`takeover_stale_run: true`), the expired entry in the Lease Registry is removed and the new acquisition's scope is used. This is identical to a release + re-acquire from the registry's perspective.
|
|
173
|
+
|
|
174
|
+
**Rationale**: Spec FR-008: "When a stale lease is taken over, the system MUST replace the expired scope with the new orchestrator's declared scope before evaluating conflicts." The simplest implementation is: prune expired leases from the registry on every read, then add the new entry. The takeover just sets `takeover_stale_run: true` which bypasses the stale-check on the per-instance file; from the registry perspective, the expired entry is already pruned.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### R-007 — Observable deferral record (FR-010)
|
|
179
|
+
|
|
180
|
+
**Decision**: When a lease acquisition is deferred due to scope conflict, the `LEASE_SCOPE_CONFLICT` error response includes `blocking_run_id`, `blocking_owner_instance_id`, and `conflicting_scope_entry` in its `details` object. Additionally, `console.warn` is emitted from `RunLeaseService` to satisfy the "log entry" requirement. This is `console.warn` (not `console.log`), which is permitted in `apps/control-plane/src/`.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Phase 1: Design & Contracts
|
|
185
|
+
|
|
186
|
+
### 1.1 Data Model
|
|
187
|
+
|
|
188
|
+
See [`data-model.md`](./data-model.md) for the full entity schema. Summary:
|
|
189
|
+
|
|
190
|
+
#### `LeaseScope` (new)
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// apps/control-plane/src/core/runtime-sessions.ts (additions)
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The declared set of codebase sections a run expects to touch.
|
|
197
|
+
* paths: file-system paths relative to repoRoot (prefix-matched)
|
|
198
|
+
* plan_section_ids: opaque plan section identifiers (equality-matched)
|
|
199
|
+
*/
|
|
200
|
+
export interface LeaseScope {
|
|
201
|
+
paths: string[];
|
|
202
|
+
plan_section_ids: string[];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* null → unknown/undeclared scope → conservative: conflicts with all active leases
|
|
207
|
+
* LeaseScope with empty arrays → explicitly empty → conflicts with nothing
|
|
208
|
+
* LeaseScope with entries → checked via prefix overlap / equality
|
|
209
|
+
*/
|
|
210
|
+
export type LeaseScopeDeclaration = LeaseScope | null;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### `ActiveLeaseRecord` (new)
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
/** One entry in the global Lease Registry. */
|
|
217
|
+
export interface ActiveLeaseRecord {
|
|
218
|
+
run_id: string;
|
|
219
|
+
owner_instance_id: string;
|
|
220
|
+
instance_id: string; // kernel instanceId (for registry→lease-file correlation)
|
|
221
|
+
scope: LeaseScopeDeclaration; // null if undeclared
|
|
222
|
+
lease_expires_at: string; // ISO-8601; used for stale pruning
|
|
223
|
+
acquired_at: string; // ISO-8601
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export interface LeaseRegistry {
|
|
227
|
+
leases: ActiveLeaseRecord[];
|
|
228
|
+
updated_at: string; // ISO-8601; last registry write timestamp
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### `RuntimeSessionsSnapshot` (modified)
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
// Existing interface — ADD one optional field:
|
|
236
|
+
export interface RuntimeSessionsSnapshot {
|
|
237
|
+
// ... existing fields unchanged ...
|
|
238
|
+
scope?: LeaseScopeDeclaration; // NEW: persisted scope declaration
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
#### `AcquireRunLeaseInput` (modified)
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
export interface AcquireRunLeaseInput {
|
|
246
|
+
run_id: string;
|
|
247
|
+
owner_instance_id: string;
|
|
248
|
+
provider: string;
|
|
249
|
+
model: string;
|
|
250
|
+
provider_config_ref_hash: string;
|
|
251
|
+
takeover_stale_run?: boolean;
|
|
252
|
+
scope?: LeaseScopeDeclaration; // NEW: declared scope for conflict detection
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
### 1.2 New Error Code
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// apps/control-plane/src/core/error-codes.ts (addition)
|
|
262
|
+
LEASE_SCOPE_CONFLICT: 'lease_scope_conflict',
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Error payload when thrown from `acquireRunLease`:
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
fail(
|
|
269
|
+
ERROR_CODES.LEASE_SCOPE_CONFLICT,
|
|
270
|
+
`Lease acquisition deferred: scope overlaps with active run ${blockingRunId}`,
|
|
271
|
+
{
|
|
272
|
+
incoming_scope: input.scope,
|
|
273
|
+
blocking_run_id: blockingRunId,
|
|
274
|
+
blocking_owner_instance_id: blockingOwnerInstanceId,
|
|
275
|
+
conflicting_scope_entry: firstConflictingEntry,
|
|
276
|
+
retryable: true, // caller should back off and retry
|
|
277
|
+
requires_human: false, // automatic — no human intervention needed
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
### 1.3 `LeaseScopeConflictDetector` (new service — pure logic)
|
|
285
|
+
|
|
286
|
+
**File**: `apps/control-plane/src/application/services/lease-scope-conflict-detector.ts`
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import type { LeaseScopeDeclaration, ActiveLeaseRecord } from '../../core/runtime-sessions.js';
|
|
290
|
+
|
|
291
|
+
export interface ScopeConflictResult {
|
|
292
|
+
conflict: boolean;
|
|
293
|
+
blocking_run_id?: string;
|
|
294
|
+
blocking_owner_instance_id?: string;
|
|
295
|
+
conflicting_scope_entry?: string; // the first path/id that caused the conflict
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export class LeaseScopeConflictDetector {
|
|
299
|
+
/**
|
|
300
|
+
* Checks whether `incoming` scope conflicts with any active lease.
|
|
301
|
+
* Expired leases must be pruned by the caller before this is invoked.
|
|
302
|
+
*/
|
|
303
|
+
detectConflict(
|
|
304
|
+
incoming: LeaseScopeDeclaration,
|
|
305
|
+
activeLeases: ActiveLeaseRecord[],
|
|
306
|
+
excludeRunId?: string, // exclude same-owner re-acquisition
|
|
307
|
+
): ScopeConflictResult;
|
|
308
|
+
|
|
309
|
+
/** Path overlap: true if a is a prefix of b or b is a prefix of a (after normalization). */
|
|
310
|
+
pathsOverlap(a: string[], b: string[]): boolean;
|
|
311
|
+
|
|
312
|
+
/** Plan section overlap: set intersection by equality. */
|
|
313
|
+
planSectionsOverlap(a: string[], b: string[]): boolean;
|
|
314
|
+
|
|
315
|
+
/** Normalize a path for prefix comparison: trim trailing slash, append one slash. */
|
|
316
|
+
normalizePath(p: string): string;
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Conflict matrix** (implemented in `detectConflict`):
|
|
321
|
+
|
|
322
|
+
| Incoming \ Active | `null` (unknown) | empty `{ paths:[], plan_section_ids:[] }` | non-empty |
|
|
323
|
+
| -------------------- | ---------------- | ----------------------------------------- | --------------------- |
|
|
324
|
+
| **`null` (unknown)** | CONFLICT | CONFLICT | CONFLICT |
|
|
325
|
+
| **empty** | CONFLICT | no conflict | no conflict |
|
|
326
|
+
| **non-empty** | CONFLICT | no conflict | check prefix/equality |
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
### 1.4 `RunLeaseServicePort` (modified)
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
export interface RunLeaseServicePort {
|
|
334
|
+
// ... existing methods unchanged ...
|
|
335
|
+
|
|
336
|
+
// NEW: Registry operations (protected by the same withIndexLock)
|
|
337
|
+
readLeaseRegistry(): Promise<LeaseRegistry>;
|
|
338
|
+
writeLeaseRegistry(registry: LeaseRegistry): Promise<void>;
|
|
339
|
+
emptyLeaseRegistry(at?: string): LeaseRegistry;
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
### 1.5 `RunLeaseService` method changes
|
|
346
|
+
|
|
347
|
+
#### `acquireRunLease` — modified flow
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
withIndexLock:
|
|
351
|
+
1. read per-instance lease file (existing)
|
|
352
|
+
2. check same-owner re-acquisition (existing)
|
|
353
|
+
3. check stale takeover (existing)
|
|
354
|
+
4. read lease registry
|
|
355
|
+
5. prune expired entries from registry (lease_expires_at < now)
|
|
356
|
+
6. detectConflict(input.scope, prunedLeases, excludeRunId=input.run_id)
|
|
357
|
+
7. if conflict → console.warn + throw LEASE_SCOPE_CONFLICT
|
|
358
|
+
8. grant: write per-instance lease (existing)
|
|
359
|
+
9. upsert this run's entry in registry (remove old same-run entry, add new)
|
|
360
|
+
10. write registry
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
> **Note on interaction with `RUN_ALREADY_ACTIVE`**: The existing `RUN_ALREADY_ACTIVE` check is for per-instance file freshness (same `run_id`/`owner_instance_id`). It runs **before** the registry check. `LEASE_SCOPE_CONFLICT` is a separate, new error code for multi-run scope blocking.
|
|
364
|
+
|
|
365
|
+
#### `renewRunLease` — modified
|
|
366
|
+
|
|
367
|
+
Inside `withIndexLock`, after writing the per-instance file, also update the `lease_expires_at` on this run's registry entry:
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
withIndexLock:
|
|
371
|
+
1. existing ownership check + per-instance write
|
|
372
|
+
2. read registry
|
|
373
|
+
3. prune expired
|
|
374
|
+
4. update lease_expires_at for this run_id in registry
|
|
375
|
+
5. write registry
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### `releaseRunLease` — modified
|
|
379
|
+
|
|
380
|
+
Inside `withIndexLock`, after clearing the per-instance file, also remove this run from the registry:
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
withIndexLock:
|
|
384
|
+
1. existing ownership check + per-instance clear
|
|
385
|
+
2. read registry
|
|
386
|
+
3. remove entry for this run_id/owner_instance_id
|
|
387
|
+
4. write registry
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### `expandRunLeaseScope` — new method
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
async expandRunLeaseScope(input: {
|
|
394
|
+
run_id: string;
|
|
395
|
+
owner_instance_id: string;
|
|
396
|
+
additional_paths?: string[];
|
|
397
|
+
additional_plan_section_ids?: string[];
|
|
398
|
+
}): Promise<{ data: { scope: LeaseScopeDeclaration } }>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Flow:
|
|
402
|
+
|
|
403
|
+
```
|
|
404
|
+
withIndexLock:
|
|
405
|
+
1. verify ownership (per-instance file)
|
|
406
|
+
2. read current scope from per-instance file
|
|
407
|
+
3. merge: union(current.paths, additional_paths), union(current.plan_section_ids, additional_plan_section_ids)
|
|
408
|
+
4. write updated scope to per-instance file
|
|
409
|
+
5. read registry
|
|
410
|
+
6. update registry entry's scope for this run_id
|
|
411
|
+
7. write registry
|
|
412
|
+
8. return { data: { scope: merged } }
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
### 1.6 `AopPathLayout` additions
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
// apps/control-plane/src/core/path-layout.ts
|
|
421
|
+
|
|
422
|
+
get leaseRegistryPath(): string {
|
|
423
|
+
return path.join(this.runtimeDataRoot, 'lease-registry.json');
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
> Uses the same `withIndexLock` (`.aop/features/.index.lock`) — no new lock path needed.
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
### 1.7 `AopKernel` additions (port implementation)
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// In kernel.ts — add to RunLeaseServicePort implementation:
|
|
435
|
+
|
|
436
|
+
async readLeaseRegistry(): Promise<LeaseRegistry> {
|
|
437
|
+
const existing = await readJson(this.pathLayout.leaseRegistryPath, null);
|
|
438
|
+
return existing ?? this.port.emptyLeaseRegistry();
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
async writeLeaseRegistry(registry: LeaseRegistry): Promise<void> {
|
|
442
|
+
await ensureDir(path.dirname(this.pathLayout.leaseRegistryPath));
|
|
443
|
+
await atomicWriteJson(this.pathLayout.leaseRegistryPath, registry);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
emptyLeaseRegistry(at = nowIso()): LeaseRegistry {
|
|
447
|
+
return { leases: [], updated_at: at };
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// New public kernel method:
|
|
451
|
+
async expandRunLeaseScope(input: ExpandRunLeaseScopeInput): Promise<{
|
|
452
|
+
data: { scope: LeaseScopeDeclaration };
|
|
453
|
+
}> {
|
|
454
|
+
return await this.runLeaseService.expandRunLeaseScope(input);
|
|
455
|
+
}
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
### 1.8 `RunCoordinator` and `SupervisorRuntime` changes
|
|
461
|
+
|
|
462
|
+
**`supervisor/types.ts`** — add optional `scope` to `FeatureInput`:
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
export interface FeatureInput {
|
|
466
|
+
feature_id: string;
|
|
467
|
+
spec_file?: string;
|
|
468
|
+
// NEW:
|
|
469
|
+
scope?: LeaseScopeDeclaration; // declared scope at launch time; may be null
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**`supervisor/run-coordinator.ts`** — `start()` method, lease acquisition:
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
// Derive aggregate scope across all features being processed in this run.
|
|
477
|
+
// If any feature has no declared scope, the run-level scope is null (conservative).
|
|
478
|
+
const runScope = this.deriveRunScope(features);
|
|
479
|
+
|
|
480
|
+
const leaseResult = await this.kernel.acquireRunLease({
|
|
481
|
+
run_id: this.state.runId,
|
|
482
|
+
owner_instance_id: this.state.ownerInstanceId,
|
|
483
|
+
provider: this.provider.selection.provider,
|
|
484
|
+
model: this.provider.selection.model,
|
|
485
|
+
provider_config_ref_hash: this.providerConfigRefHash(),
|
|
486
|
+
takeover_stale_run: this.takeoverStaleRun,
|
|
487
|
+
scope: runScope, // NEW
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Add `deriveRunScope(features: FeatureInput[]): LeaseScopeDeclaration`:
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
private deriveRunScope(features: FeatureInput[]): LeaseScopeDeclaration {
|
|
495
|
+
if (features.some((f) => f.scope === undefined || f.scope === null)) {
|
|
496
|
+
return null; // conservative: any unknown → aggregate is unknown
|
|
497
|
+
}
|
|
498
|
+
return {
|
|
499
|
+
paths: [...new Set(features.flatMap((f) => f.scope!.paths))].sort(),
|
|
500
|
+
plan_section_ids: [...new Set(features.flatMap((f) => f.scope!.plan_section_ids))].sort(),
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
After the planning wave (inside the iteration loop), the supervisor calls `expandRunLeaseScope` with the plan's file manifest. This is the FR-007 hook:
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
// After planningWaveExecutor.run(activeFeatureIds):
|
|
509
|
+
await this.expandScopesFromPlans(activeFeatureIds);
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
Where `expandScopesFromPlans` reads each active feature's `plan.json` → extracts `affected_files` → calls `this.kernel.expandRunLeaseScope(...)`.
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
### 1.9 Lease Registry JSON Schema
|
|
517
|
+
|
|
518
|
+
**File**: `specs/002-scope-aware-lease/contracts/lease-registry.schema.json`
|
|
519
|
+
|
|
520
|
+
```json
|
|
521
|
+
{
|
|
522
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
523
|
+
"title": "LeaseRegistry",
|
|
524
|
+
"type": "object",
|
|
525
|
+
"required": ["leases", "updated_at"],
|
|
526
|
+
"properties": {
|
|
527
|
+
"leases": {
|
|
528
|
+
"type": "array",
|
|
529
|
+
"items": {
|
|
530
|
+
"type": "object",
|
|
531
|
+
"required": [
|
|
532
|
+
"run_id",
|
|
533
|
+
"owner_instance_id",
|
|
534
|
+
"instance_id",
|
|
535
|
+
"scope",
|
|
536
|
+
"lease_expires_at",
|
|
537
|
+
"acquired_at"
|
|
538
|
+
],
|
|
539
|
+
"properties": {
|
|
540
|
+
"run_id": { "type": "string" },
|
|
541
|
+
"owner_instance_id": { "type": "string" },
|
|
542
|
+
"instance_id": { "type": "string" },
|
|
543
|
+
"lease_expires_at": { "type": "string", "format": "date-time" },
|
|
544
|
+
"acquired_at": { "type": "string", "format": "date-time" },
|
|
545
|
+
"scope": {
|
|
546
|
+
"oneOf": [
|
|
547
|
+
{ "type": "null" },
|
|
548
|
+
{
|
|
549
|
+
"type": "object",
|
|
550
|
+
"required": ["paths", "plan_section_ids"],
|
|
551
|
+
"properties": {
|
|
552
|
+
"paths": { "type": "array", "items": { "type": "string" } },
|
|
553
|
+
"plan_section_ids": { "type": "array", "items": { "type": "string" } }
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
]
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
"updated_at": { "type": "string", "format": "date-time" }
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## Test Strategy
|
|
569
|
+
|
|
570
|
+
All tests live in `apps/control-plane/test/`. Coverage targets: ≥90% lines/branches/functions/statements.
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
### Test File 1: `lease-scope-conflict-detector.spec.ts` (NEW)
|
|
575
|
+
|
|
576
|
+
**Unit tests — pure logic, no I/O. Full coverage of the conflict matrix.**
|
|
577
|
+
|
|
578
|
+
#### Block: `LeaseScopeConflictDetector.normalizePath`
|
|
579
|
+
|
|
580
|
+
| # | Input | Expected |
|
|
581
|
+
| ---- | ------------------- | ------------------------------- |
|
|
582
|
+
| T-01 | `"packages/auth"` | `"packages/auth/"` |
|
|
583
|
+
| T-02 | `"packages/auth/"` | `"packages/auth/"` (idempotent) |
|
|
584
|
+
| T-03 | `""` (empty string) | `"/"` (treated as root) |
|
|
585
|
+
| T-04 | `"src/config.ts"` | `"src/config.ts/"` |
|
|
586
|
+
|
|
587
|
+
#### Block: `LeaseScopeConflictDetector.pathsOverlap`
|
|
588
|
+
|
|
589
|
+
| # | a | b | Expected |
|
|
590
|
+
| ---- | ---------------------------------------- | -------------------------------------------- | --------------------------------------------- |
|
|
591
|
+
| T-05 | `["packages/auth/"]` | `["packages/payments/"]` | `false` (Story 1 — non-overlap) |
|
|
592
|
+
| T-06 | `["packages/auth/"]` | `["packages/auth/"]` | `true` (exact match) |
|
|
593
|
+
| T-07 | `["packages/"]` | `["packages/auth/"]` | `true` (parent contains child — Story 2 AC2) |
|
|
594
|
+
| T-08 | `["packages/auth/"]` | `["packages/"]` | `true` (symmetric) |
|
|
595
|
+
| T-09 | `["src/"]` | `["src/config.ts"]` | `true` (file within dir scope — Edge case) |
|
|
596
|
+
| T-10 | `["src/"]` | `["src-old/config.ts"]` | `false` (no false positive on similar prefix) |
|
|
597
|
+
| T-11 | `["packages/auth/", "packages/shared/"]` | `["packages/shared/", "packages/payments/"]` | `true` (partial overlap — Story 2 AC3) |
|
|
598
|
+
| T-12 | `[]` | `["packages/auth/"]` | `false` (empty set → no overlap) |
|
|
599
|
+
| T-13 | `[]` | `[]` | `false` |
|
|
600
|
+
|
|
601
|
+
#### Block: `LeaseScopeConflictDetector.planSectionsOverlap`
|
|
602
|
+
|
|
603
|
+
| # | a | b | Expected |
|
|
604
|
+
| ---- | ---------------------------- | ---------------------------- | -------- |
|
|
605
|
+
| T-14 | `["section-A"]` | `["section-B"]` | `false` |
|
|
606
|
+
| T-15 | `["section-A"]` | `["section-A"]` | `true` |
|
|
607
|
+
| T-16 | `["section-A", "section-B"]` | `["section-B", "section-C"]` | `true` |
|
|
608
|
+
| T-17 | `[]` | `["section-A"]` | `false` |
|
|
609
|
+
|
|
610
|
+
#### Block: `LeaseScopeConflictDetector.detectConflict` — conflict matrix
|
|
611
|
+
|
|
612
|
+
| # | incoming | active lease scope | Expected |
|
|
613
|
+
| ---- | --------------------------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------ |
|
|
614
|
+
| T-18 | `null` | any active lease (non-empty scope) | `{ conflict: true }` — Story 3 AC1 |
|
|
615
|
+
| T-19 | `null` | no active leases | `{ conflict: false }` — Story 3 AC3 |
|
|
616
|
+
| T-20 | non-empty scope | active with `null` scope | `{ conflict: true }` — Story 3 AC2 |
|
|
617
|
+
| T-21 | empty `{ paths:[], plan_section_ids:[] }` | any active lease | `{ conflict: false }` |
|
|
618
|
+
| T-22 | `{ paths:["packages/auth/"], plan_section_ids:[] }` | active `{ paths:["packages/payments/"], ... }` | `{ conflict: false }` — Story 1 AC2 |
|
|
619
|
+
| T-23 | `{ paths:["packages/auth/"], plan_section_ids:[] }` | active `{ paths:["packages/auth/"], ... }` | `{ conflict: true, blocking_run_id: "run-A" }` — Story 2 AC1 |
|
|
620
|
+
| T-24 | `{ paths:["packages/auth/utils/"], ... }` | active `{ paths:["packages/"], ... }` | `{ conflict: true }` — Spec edge case: nested path |
|
|
621
|
+
| T-25 | `{ paths:[], plan_section_ids:["plan-section-1"] }` | active `{ paths:[], plan_section_ids:["plan-section-1"] }` | `{ conflict: true }` |
|
|
622
|
+
| T-26 | excludeRunId matches the only conflicting lease | (same run re-acquire) | `{ conflict: false }` (excluded) |
|
|
623
|
+
|
|
624
|
+
---
|
|
625
|
+
|
|
626
|
+
### Test File 2: `run-lease-service.spec.ts` (NEW)
|
|
627
|
+
|
|
628
|
+
**Integration tests for `RunLeaseService` with a mock `RunLeaseServicePort` that stubs registry I/O.**
|
|
629
|
+
|
|
630
|
+
#### Block: Scope declaration persisted (Story 4)
|
|
631
|
+
|
|
632
|
+
| # | Scenario | Expected |
|
|
633
|
+
| ---- | ------------------------------------------------------------------------- | ------------------------------------------------------------- |
|
|
634
|
+
| T-30 | Acquire with `scope: { paths: ["packages/auth/"], plan_section_ids: [] }` | Lease record written to per-instance file contains that scope |
|
|
635
|
+
| T-31 | Acquire with `scope: null` | Lease record contains `scope: null` |
|
|
636
|
+
| T-32 | Acquire with no `scope` field provided | Normalized to `scope: null` (conservative) |
|
|
637
|
+
| T-33 | Acquire, read back registry entry | `ActiveLeaseRecord.scope` matches input |
|
|
638
|
+
|
|
639
|
+
#### Block: Parallel non-overlapping runs (Story 1)
|
|
640
|
+
|
|
641
|
+
| # | Scenario | Expected |
|
|
642
|
+
| ---- | -------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
643
|
+
| T-34 | Registry contains Run A (`packages/auth/`), acquire Run B (`packages/payments/`) | Returns lease granted; registry has 2 entries |
|
|
644
|
+
| T-35 | Both Run A and Run B active; both release independently | After each release, registry entry removed; other unaffected |
|
|
645
|
+
|
|
646
|
+
#### Block: Overlapping runs blocked (Story 2)
|
|
647
|
+
|
|
648
|
+
| # | Scenario | Expected |
|
|
649
|
+
| ---- | ------------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
650
|
+
| T-36 | Run A holds `packages/auth/`; Run B attempts `packages/auth/` | Throws `LEASE_SCOPE_CONFLICT` with `blocking_run_id = Run A's run_id` |
|
|
651
|
+
| T-37 | Run A holds `packages/` (parent); Run B attempts `packages/auth/` (child) | Throws `LEASE_SCOPE_CONFLICT` |
|
|
652
|
+
| T-38 | Run A holds `null` scope; Run B attempts any non-empty scope | Throws `LEASE_SCOPE_CONFLICT` |
|
|
653
|
+
|
|
654
|
+
#### Block: Conservative fallback (Story 3)
|
|
655
|
+
|
|
656
|
+
| # | Scenario | Expected |
|
|
657
|
+
| ---- | ---------------------------------------------------------- | ----------------------------- |
|
|
658
|
+
| T-39 | Any active lease exists; Run B requests with `scope: null` | Throws `LEASE_SCOPE_CONFLICT` |
|
|
659
|
+
| T-40 | No active leases; Run A requests with `scope: null` | Granted immediately |
|
|
660
|
+
|
|
661
|
+
#### Block: Stale lease takeover + scope replacement (FR-008)
|
|
662
|
+
|
|
663
|
+
| # | Scenario | Expected |
|
|
664
|
+
| ---- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
665
|
+
| T-41 | Registry has expired entry for Run A (scope `packages/auth/`); new run acquires `packages/auth/` with `takeover_stale_run: true` | Old entry pruned; new entry inserted with new scope; no `LEASE_SCOPE_CONFLICT` |
|
|
666
|
+
| T-42 | `takeover_stale_run: false` with stale conflicting lease | Throws `RUN_ALREADY_ACTIVE` (existing behavior preserved) |
|
|
667
|
+
|
|
668
|
+
#### Block: `expandRunLeaseScope` (FR-007)
|
|
669
|
+
|
|
670
|
+
| # | Scenario | Expected |
|
|
671
|
+
| ---- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
|
|
672
|
+
| T-43 | Run A holds `packages/auth/`; expands to add `packages/shared/` | Registry entry updated to `["packages/auth/", "packages/shared/"]` |
|
|
673
|
+
| T-44 | Run B (pending) was blocked on non-overlapping scope; Run A expands into Run B's scope | On Run B's next retry, `LEASE_SCOPE_CONFLICT` is returned |
|
|
674
|
+
| T-45 | `expandRunLeaseScope` called by non-owner | Throws `RUN_LEASE_NOT_OWNED` |
|
|
675
|
+
|
|
676
|
+
#### Block: `renewRunLease` updates registry TTL
|
|
677
|
+
|
|
678
|
+
| # | Scenario | Expected |
|
|
679
|
+
| ---- | ------------------------------------------------------------------------------ | ---------------------------------- |
|
|
680
|
+
| T-46 | Run A renews; registry entry `lease_expires_at` is updated | New `lease_expires_at` > old value |
|
|
681
|
+
| T-47 | Renew for non-owner → `RUN_LEASE_NOT_OWNED` (existing behavior, no regression) |
|
|
682
|
+
|
|
683
|
+
#### Block: `releaseRunLease` removes from registry
|
|
684
|
+
|
|
685
|
+
| # | Scenario | Expected |
|
|
686
|
+
| ---- | ------------------------------------------------------------------------------ | ------------------------------ |
|
|
687
|
+
| T-48 | Run A releases; registry entry removed | `registry.leases.length === 0` |
|
|
688
|
+
| T-49 | Release for wrong owner → `released: false` (existing behavior, no regression) |
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
|
|
692
|
+
### Existing test file updates
|
|
693
|
+
|
|
694
|
+
| File | Change |
|
|
695
|
+
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
696
|
+
| `apps/control-plane/test/run-coordinator.spec.ts` | Add test: `acquireRunLease` called with `scope: null` when no feature scopes declared; add test: `acquireRunLease` called with derived scope when all features have scope |
|
|
697
|
+
| `apps/control-plane/test/supervisor.spec.ts` | Add assertion: `kernel.acquireRunLease` receives `scope` field; `LEASE_SCOPE_CONFLICT` is propagated without masking |
|
|
698
|
+
| `apps/control-plane/test/kernel.spec.ts` | Add test: `readLeaseRegistry` returns empty registry on missing file; `writeLeaseRegistry` round-trips correctly |
|
|
699
|
+
|
|
700
|
+
---
|
|
701
|
+
|
|
702
|
+
## File-Level Change Map
|
|
703
|
+
|
|
704
|
+
| File | Type | Change Summary |
|
|
705
|
+
| ------------------------------------------------------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
706
|
+
| `apps/control-plane/src/core/runtime-sessions.ts` | MODIFY | Add `LeaseScope`, `LeaseScopeDeclaration`, `ActiveLeaseRecord`, `LeaseRegistry` types; add `scope?: LeaseScopeDeclaration` to `RuntimeSessionsSnapshot` |
|
|
707
|
+
| `apps/control-plane/src/core/error-codes.ts` | MODIFY | Add `LEASE_SCOPE_CONFLICT: 'lease_scope_conflict'` |
|
|
708
|
+
| `apps/control-plane/src/core/path-layout.ts` | MODIFY | Add `get leaseRegistryPath(): string` |
|
|
709
|
+
| `apps/control-plane/src/application/services/lease-scope-conflict-detector.ts` | CREATE | Pure `LeaseScopeConflictDetector` class: `normalizePath`, `pathsOverlap`, `planSectionsOverlap`, `detectConflict` |
|
|
710
|
+
| `apps/control-plane/src/application/services/run-lease-service.ts` | MODIFY | `AcquireRunLeaseInput` gains `scope?`; `acquireRunLease`, `renewRunLease`, `releaseRunLease` extended to maintain registry; new `expandRunLeaseScope`; `RunLeaseServicePort` gets `readLeaseRegistry`, `writeLeaseRegistry`, `emptyLeaseRegistry` |
|
|
711
|
+
| `apps/control-plane/src/core/kernel.ts` | MODIFY | Implement `readLeaseRegistry`, `writeLeaseRegistry`, `emptyLeaseRegistry` on `RunLeaseServicePort`; add `expandRunLeaseScope` public method |
|
|
712
|
+
| `apps/control-plane/src/supervisor/types.ts` | MODIFY | Add `scope?: LeaseScopeDeclaration` to `FeatureInput` |
|
|
713
|
+
| `apps/control-plane/src/supervisor/run-coordinator.ts` | MODIFY | Add `deriveRunScope()`; pass `scope` to `acquireRunLease`; add `expandScopesFromPlans()` called after planning wave |
|
|
714
|
+
| `apps/control-plane/test/lease-scope-conflict-detector.spec.ts` | CREATE | 26 unit tests for pure conflict-detection logic (T-01 → T-26) |
|
|
715
|
+
| `apps/control-plane/test/run-lease-service.spec.ts` | CREATE | 20 integration tests for `RunLeaseService` scope paths (T-30 → T-49) |
|
|
716
|
+
| `apps/control-plane/test/run-coordinator.spec.ts` | MODIFY | 2 tests for scope derivation and propagation |
|
|
717
|
+
| `apps/control-plane/test/supervisor.spec.ts` | MODIFY | 1 test: `LEASE_SCOPE_CONFLICT` propagation |
|
|
718
|
+
| `apps/control-plane/test/kernel.spec.ts` | MODIFY | 2 tests: `readLeaseRegistry` / `writeLeaseRegistry` round-trip |
|
|
719
|
+
| `specs/002-scope-aware-lease/contracts/lease-registry.schema.json` | CREATE | JSON Schema for `LeaseRegistry` runtime artifact |
|
|
720
|
+
| `specs/002-scope-aware-lease/data-model.md` | CREATE | Full entity descriptions and field invariants |
|
|
721
|
+
| `specs/002-scope-aware-lease/research.md` | CREATE | Research decisions R-001 → R-007 (formalized version) |
|
|
722
|
+
| `specs/002-scope-aware-lease/quickstart.md` | CREATE | How to use scope-aware leases from CLI and programmatically |
|
|
723
|
+
| `docs/core/DOMAIN-LOGIC.md` | MODIFY | Add Rule 19: lease scope semantics (null vs empty, prefix overlap, registry lifecycle) |
|
|
724
|
+
| `docs/core/DECISIONS.md` | MODIFY | Add ADR: Scope-Aware Lease Registry (global registry file vs. distributed lease files) |
|
|
725
|
+
| `spec-files/progress.md` | MODIFY | New entry after implementation |
|
|
726
|
+
|
|
727
|
+
---
|
|
728
|
+
|
|
729
|
+
## ADR: Scope-Aware Lease Registry
|
|
730
|
+
|
|
731
|
+
**Context**: The current global run lease prevents parallel orchestration of non-overlapping codebase regions. We need scope-aware conflict detection without introducing complex distributed coordination.
|
|
732
|
+
|
|
733
|
+
**Decision**: A single shared file (`.aop/runtime/lease-registry.json`) protected by the existing index atomic lock, containing all active lease records with their declared scopes.
|
|
734
|
+
|
|
735
|
+
**Reasoning**:
|
|
736
|
+
|
|
737
|
+
- **Pro**: Piggybacks on the existing `withIndexLock` serialization — no new lock primitives, no priority-inversion risk.
|
|
738
|
+
- **Pro**: Registry is simple JSON; inspectable, git-snapshotable, debuggable without tooling.
|
|
739
|
+
- **Pro**: Expired-entry pruning on every read prevents stale-entry accumulation without a background GC process.
|
|
740
|
+
- **Con**: All lease operations hold the index lock slightly longer (read registry + write registry added to each operation). Acceptable: lock hold time increases by a small constant; registry is tiny.
|
|
741
|
+
- **Alternative Considered**: Per-instance lease files only — rejected because there's no shared structure to enumerate all active leases for cross-instance conflict detection.
|
|
742
|
+
- **Alternative Considered**: `index.json` `active_leases[]` array — rejected; mixes feature index concerns with lease registry concerns (SRP violation).
|
|
743
|
+
|
|
744
|
+
**Consequences**:
|
|
745
|
+
|
|
746
|
+
- ✅ Two non-overlapping runs can hold leases simultaneously.
|
|
747
|
+
- ✅ Overlapping runs are serialized with a clear, observable error code.
|
|
748
|
+
- ✅ Lease registry survives process crashes (file-based) and is self-healing (prune-on-read).
|
|
749
|
+
- ⚠️ Index lock hold time slightly increased. Negligible at single-digit concurrency.
|
|
750
|
+
|
|
751
|
+
**Status**: Proposed
|
|
752
|
+
|
|
753
|
+
---
|
|
754
|
+
|
|
755
|
+
## Definition of Done
|
|
756
|
+
|
|
757
|
+
- [ ] `npm run typecheck` passes clean (no new type errors)
|
|
758
|
+
- [ ] `npm run lint` passes with zero warnings
|
|
759
|
+
- [ ] `npm run test` passes at ≥90% lines/branches/functions/statements
|
|
760
|
+
- [ ] `lease-scope-conflict-detector.spec.ts` — all T-01 → T-26 tests pass
|
|
761
|
+
- [ ] `run-lease-service.spec.ts` — all T-30 → T-49 tests pass
|
|
762
|
+
- [ ] Existing `run-coordinator.spec.ts`, `supervisor.spec.ts`, `kernel.spec.ts` updated and passing
|
|
763
|
+
- [ ] `specs/002-scope-aware-lease/contracts/lease-registry.schema.json` created
|
|
764
|
+
- [ ] `DOMAIN-LOGIC.md` updated with Rule 19
|
|
765
|
+
- [ ] `DECISIONS.md` updated with Scope-Aware Lease Registry ADR
|
|
766
|
+
- [ ] `spec-files/progress.md` updated with new numbered entry
|