agentic-orchestrator 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +139 -0
- package/CLAUDE.md +12 -0
- package/agentic/orchestrator/agents.yaml +3 -0
- package/agentic/orchestrator/defaults/policy.defaults.yaml +3 -0
- package/agentic/orchestrator/policy.yaml +3 -0
- package/agentic/orchestrator/schemas/agents.schema.json +15 -0
- package/agentic/orchestrator/schemas/policy.schema.json +14 -0
- package/apps/control-plane/src/cli/cli-argument-parser.ts +7 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +8 -0
- package/apps/control-plane/src/cli/init-command-handler.ts +6 -0
- package/apps/control-plane/src/cli/resume-command-handler.ts +31 -2
- package/apps/control-plane/src/cli/run-command-handler.ts +31 -3
- package/apps/control-plane/src/cli/types.ts +1 -0
- package/apps/control-plane/src/core/error-codes.ts +4 -0
- package/apps/control-plane/src/core/kernel.ts +3 -0
- package/apps/control-plane/src/index.ts +14 -0
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +25 -3
- package/apps/control-plane/src/providers/api-worker-provider.ts +115 -0
- package/apps/control-plane/src/providers/cli-worker-provider.ts +385 -0
- package/apps/control-plane/src/providers/output-parsers/generic-output-parser.ts +100 -0
- package/apps/control-plane/src/providers/output-parsers/index.ts +11 -0
- package/apps/control-plane/src/providers/output-parsers/types.ts +23 -0
- package/apps/control-plane/src/providers/providers.ts +19 -0
- package/apps/control-plane/src/providers/worker-provider-factory.ts +198 -0
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +140 -3
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +125 -5
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +144 -2
- package/apps/control-plane/src/supervisor/runtime.ts +24 -0
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +134 -12
- package/apps/control-plane/test/cli.unit.spec.ts +36 -0
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +2 -2
- package/apps/control-plane/test/resume-command.spec.ts +31 -1
- package/apps/control-plane/test/worker-decision-loop.spec.ts +3 -0
- package/apps/control-plane/test/worker-execution-policy.spec.ts +284 -0
- package/apps/control-plane/test/worker-provider-adapters.spec.ts +440 -0
- package/apps/control-plane/test/worker-provider-factory.spec.ts +151 -0
- package/config/agentic/orchestrator/agents.yaml +3 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js +7 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/help-command-handler.js +8 -0
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.js +6 -0
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/resume-command-handler.d.ts +3 -0
- package/dist/apps/control-plane/cli/resume-command-handler.js +18 -2
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/run-command-handler.d.ts +3 -1
- package/dist/apps/control-plane/cli/run-command-handler.js +17 -3
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/types.d.ts +1 -0
- package/dist/apps/control-plane/core/error-codes.d.ts +4 -0
- package/dist/apps/control-plane/core/error-codes.js +4 -0
- package/dist/apps/control-plane/core/error-codes.js.map +1 -1
- package/dist/apps/control-plane/core/kernel.d.ts +3 -0
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/index.d.ts +2 -0
- package/dist/apps/control-plane/index.js +1 -0
- package/dist/apps/control-plane/index.js.map +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +14 -2
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/providers/api-worker-provider.d.ts +31 -0
- package/dist/apps/control-plane/providers/api-worker-provider.js +73 -0
- package/dist/apps/control-plane/providers/api-worker-provider.js.map +1 -0
- package/dist/apps/control-plane/providers/cli-worker-provider.d.ts +46 -0
- package/dist/apps/control-plane/providers/cli-worker-provider.js +274 -0
- package/dist/apps/control-plane/providers/cli-worker-provider.js.map +1 -0
- package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.d.ts +10 -0
- package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js +79 -0
- package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js.map +1 -0
- package/dist/apps/control-plane/providers/output-parsers/index.d.ts +2 -0
- package/dist/apps/control-plane/providers/output-parsers/index.js +2 -0
- package/dist/apps/control-plane/providers/output-parsers/index.js.map +1 -0
- package/dist/apps/control-plane/providers/output-parsers/types.d.ts +21 -0
- package/dist/apps/control-plane/providers/output-parsers/types.js +2 -0
- package/dist/apps/control-plane/providers/output-parsers/types.js.map +1 -0
- package/dist/apps/control-plane/providers/providers.d.ts +4 -0
- package/dist/apps/control-plane/providers/providers.js +15 -0
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +41 -0
- package/dist/apps/control-plane/providers/worker-provider-factory.js +104 -0
- package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +13 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +92 -3
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +12 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +83 -5
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +13 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +91 -2
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.js +19 -0
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +10 -0
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +113 -12
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/package.json +2 -2
- package/packages/web-dashboard/next-env.d.ts +2 -1
- package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +4 -3
- package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +6 -2
- package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +6 -5
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +5 -4
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +7 -3
- package/packages/web-dashboard/src/lib/aop-client.ts +2 -2
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +1 -1
- package/packages/web-dashboard/tsconfig.json +1 -0
- package/spec-files/outstanding/agentic_orchestrator_human_input_interaction_protocol_spec.md +590 -0
- package/spec-files/outstanding/agentic_orchestrator_real_worker_provider_execution_spec.md +616 -0
- package/spec-files/progress.md +91 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
# Feature Spec: Real Worker Provider Execution Path and Cluster Role Semantics (AOP)
|
|
2
|
+
|
|
3
|
+
> **Purpose of this document**: Define implementation-ready changes to replace stubbed worker execution (`NullWorkerProvider`) in `aop run`/`aop resume` with real provider-backed execution, while preserving deterministic orchestration and making planner/builder/qa behavior explicit and auditable.
|
|
4
|
+
|
|
5
|
+
**Version:** 1.1
|
|
6
|
+
**Date:** 2026-03-04
|
|
7
|
+
**Status:** Draft
|
|
8
|
+
**Roadmap Mapping:** M42
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 0. Standards and Dependencies
|
|
13
|
+
|
|
14
|
+
### 0.1 Required Standards
|
|
15
|
+
|
|
16
|
+
All implementation MUST preserve:
|
|
17
|
+
|
|
18
|
+
- deterministic tool envelopes and error normalization
|
|
19
|
+
- MCP/in-process transport parity at the tool boundary
|
|
20
|
+
- strict schema validation (`validate:mcp-contracts`, `validate:architecture`)
|
|
21
|
+
- canonical state under `.aop/**` as source of truth
|
|
22
|
+
- run lease + session ownership invariants from global orchestrator topology spec
|
|
23
|
+
|
|
24
|
+
### 0.2 Required Upstream Inputs
|
|
25
|
+
|
|
26
|
+
Implementing agents MUST read:
|
|
27
|
+
|
|
28
|
+
- `spec-files/completed/agentic_orchestrator_single_global_orchestrator_spec.md`
|
|
29
|
+
- `spec-files/outstanding/agentic_orchestrator_provider_auth_bootstrap_spec.md`
|
|
30
|
+
- `apps/control-plane/src/cli/run-command-handler.ts`
|
|
31
|
+
- `apps/control-plane/src/cli/resume-command-handler.ts`
|
|
32
|
+
- `apps/control-plane/src/providers/providers.ts`
|
|
33
|
+
- `apps/control-plane/src/supervisor/runtime.ts`
|
|
34
|
+
- `apps/control-plane/src/supervisor/session-orchestrator.ts`
|
|
35
|
+
- `apps/control-plane/src/supervisor/planning-wave-executor.ts`
|
|
36
|
+
- `apps/control-plane/src/supervisor/build-wave-executor.ts`
|
|
37
|
+
- `apps/control-plane/src/supervisor/qa-wave-executor.ts`
|
|
38
|
+
- `apps/control-plane/src/supervisor/worker-decision-loop.ts`
|
|
39
|
+
- `apps/control-plane/src/core/error-codes.ts`
|
|
40
|
+
- `agentic/orchestrator/agents.yaml`
|
|
41
|
+
- `agentic/orchestrator/schemas/agents.schema.json`
|
|
42
|
+
- `agentic/orchestrator/policy.yaml`
|
|
43
|
+
- `agentic/orchestrator/schemas/policy.schema.json`
|
|
44
|
+
|
|
45
|
+
### 0.3 Scope
|
|
46
|
+
|
|
47
|
+
This spec implements:
|
|
48
|
+
|
|
49
|
+
- real provider-backed worker execution for `run` and `resume`
|
|
50
|
+
- provider factory/wiring so selected provider determines runtime behavior
|
|
51
|
+
- strict planner/builder/qa role contracts for outputs and progress
|
|
52
|
+
- deterministic handling of no-output/no-progress/malformed-output failure modes
|
|
53
|
+
- regression coverage so `npm run verify` catches the current “plan -> ready_to_merge without edits” defect class
|
|
54
|
+
|
|
55
|
+
Out of scope:
|
|
56
|
+
|
|
57
|
+
- new model vendors beyond currently registered provider names
|
|
58
|
+
- replacing gate engine semantics
|
|
59
|
+
- changing merge approval governance rules
|
|
60
|
+
|
|
61
|
+
### 0.4 OOP and Architecture Guardrails (Mandatory)
|
|
62
|
+
|
|
63
|
+
Implementation for this spec MUST follow explicit object-oriented and architectural best practices:
|
|
64
|
+
|
|
65
|
+
- **KISS**: prefer the simplest design that satisfies deterministic behavior and contract requirements; avoid speculative abstractions.
|
|
66
|
+
- **SRP (Single Responsibility Principle)**: each class/module should have one clear reason to change (factory selection, provider execution, parsing, orchestration policy, etc.).
|
|
67
|
+
- **SOLID-oriented design** (applied pragmatically):
|
|
68
|
+
- open/closed for new provider adapters without modifying orchestration flow logic
|
|
69
|
+
- interface segregation for provider capabilities (`WorkerProvider`, parser contracts, factory contracts)
|
|
70
|
+
- dependency inversion via ports/interfaces rather than direct runtime coupling
|
|
71
|
+
- **Hexagonal architecture alignment**: keep provider SDK/CLI process details in adapter layer; supervisor/core should depend on ports/contracts only.
|
|
72
|
+
- **Composition over inheritance**: adapters compose parser/runner dependencies; avoid deep class hierarchies.
|
|
73
|
+
- **High cohesion / low coupling**: no mixing of CLI parsing, provider transport logic, and supervisor decision routing in the same class.
|
|
74
|
+
|
|
75
|
+
Code organization requirements for this spec:
|
|
76
|
+
|
|
77
|
+
- factory logic remains in dedicated factory module(s)
|
|
78
|
+
- provider transport concerns remain in adapter modules
|
|
79
|
+
- provider payload normalization remains in parser modules
|
|
80
|
+
- supervisor wave executors and decision loop consume normalized contracts only
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 1. Architectural Critique of Current Behavior
|
|
85
|
+
|
|
86
|
+
1. **`run` and `resume` always instantiate `NullWorkerProvider`**
|
|
87
|
+
|
|
88
|
+
- `resolveProviderSelection()` resolves provider/model, but the selected provider is not used to choose a runtime implementation.
|
|
89
|
+
- Result: all providers execute a stub path.
|
|
90
|
+
|
|
91
|
+
2. **`NullWorkerProvider.runWorker()` emits NOTE-only behavior**
|
|
92
|
+
|
|
93
|
+
- Planner/builder/qa paths return `NOTE` instead of substantive worker actions (`PLAN_SUBMISSION`, `PATCH`, actionable `REQUEST` flows).
|
|
94
|
+
- Result: no code modification signal can exist unless externally injected.
|
|
95
|
+
|
|
96
|
+
3. **Planner fallback auto-submits a generated plan**
|
|
97
|
+
|
|
98
|
+
- `PlanningWaveExecutor` submits deterministic initial plan when no plan is returned by worker.
|
|
99
|
+
- Result: planning phase appears to complete even when provider produced no meaningful work.
|
|
100
|
+
|
|
101
|
+
4. **Promotion is status/gate-driven, not delivery-driven**
|
|
102
|
+
|
|
103
|
+
- Build/QA phases can pass gates and transition state even when no patches occurred.
|
|
104
|
+
- Result: feature can reach `ready_to_merge` with empty worktree diff.
|
|
105
|
+
|
|
106
|
+
5. **Cluster sessions give false confidence**
|
|
107
|
+
|
|
108
|
+
- Session IDs are created/rotated and persisted, so runtime looks healthy in dashboard/index.
|
|
109
|
+
- Result: “session active” logs hide execution no-op.
|
|
110
|
+
|
|
111
|
+
6. **Current tests do not hard-fail on stub execution in run/resume**
|
|
112
|
+
|
|
113
|
+
- Existing coverage validates many orchestration mechanics but not “live provider required for delivery” invariants.
|
|
114
|
+
- Result: regression can pass `verify` while actual feature delivery is broken.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 2. Revised Architecture Fit
|
|
119
|
+
|
|
120
|
+
### 2.1 Provider Runtime Selection Must Be Explicit
|
|
121
|
+
|
|
122
|
+
Introduce a provider runtime factory used by `run`, `resume`, and attach/send paths:
|
|
123
|
+
|
|
124
|
+
- `createWorkerProvider(selection, context)` returns concrete provider implementation
|
|
125
|
+
- `run`/`resume` MUST require `mode=live` by default
|
|
126
|
+
- stub mode remains allowed only for tests/explicit local override
|
|
127
|
+
|
|
128
|
+
### 2.2 Worker Execution Is a Contracted Output Channel
|
|
129
|
+
|
|
130
|
+
`WorkerProvider.runWorker(...)` MUST return normalized output envelopes consumed by `WorkerDecisionLoop`:
|
|
131
|
+
|
|
132
|
+
- supported output types: `PLAN_SUBMISSION`, `PATCH`, `REQUEST`, `NOTE`
|
|
133
|
+
- malformed output is deterministic error, not silent ignore
|
|
134
|
+
- multi-output responses MUST preserve deterministic order
|
|
135
|
+
|
|
136
|
+
### 2.3 Role Semantics Across Cluster
|
|
137
|
+
|
|
138
|
+
Planner, builder, and QA roles keep their current tool firewall, but output expectations become explicit:
|
|
139
|
+
|
|
140
|
+
- planner: must drive plan evolution (`PLAN_SUBMISSION` / `amend_plan` request path)
|
|
141
|
+
- builder: must propose patch actions before/around fast gate retries
|
|
142
|
+
- qa: must propose remediation patches before/around full gate retries
|
|
143
|
+
- note-only execution is allowed transiently, not indefinitely
|
|
144
|
+
|
|
145
|
+
### 2.4 Session Topology Compatibility
|
|
146
|
+
|
|
147
|
+
No change to `1 + 3N` topology:
|
|
148
|
+
|
|
149
|
+
- one orchestrator session per run
|
|
150
|
+
- planner/builder/qa per active feature
|
|
151
|
+
- queued features remain `unassigned`
|
|
152
|
+
- QA session rotation remains supported and must work with real provider sessions
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 3. Contract and Schema Deltas
|
|
157
|
+
|
|
158
|
+
### 3.1 Agents Runtime Contract (`agents.schema.json`)
|
|
159
|
+
|
|
160
|
+
Add runtime execution controls:
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
runtime:
|
|
164
|
+
worker_provider_mode: live # live | stub
|
|
165
|
+
worker_response_timeout_ms: 120000
|
|
166
|
+
max_consecutive_no_progress_iterations: 2
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Rules:
|
|
170
|
+
|
|
171
|
+
- `worker_provider_mode=live` is default for `aop run` and `aop resume`
|
|
172
|
+
- `stub` is permitted only in tests or explicit debug mode
|
|
173
|
+
- timeout and no-progress thresholds must be bounded positive integers
|
|
174
|
+
|
|
175
|
+
### 3.2 Policy Contract (`policy.schema.json`)
|
|
176
|
+
|
|
177
|
+
Add deterministic enforcement toggles:
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
execution:
|
|
181
|
+
require_live_provider_for_run: true
|
|
182
|
+
malformed_worker_output_action: block_feature # block_feature | fail_run
|
|
183
|
+
no_progress_action: block_feature # block_feature | fail_run
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Rules:
|
|
187
|
+
|
|
188
|
+
- when `require_live_provider_for_run=true`, constructing a stub provider in run/resume is a hard error
|
|
189
|
+
- action routing is deterministic and auditable in decisions log
|
|
190
|
+
|
|
191
|
+
### 3.3 Worker Output Envelope Contract
|
|
192
|
+
|
|
193
|
+
Normalize provider output:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"session_id": "builder-feature_x-...",
|
|
198
|
+
"role": "builder",
|
|
199
|
+
"feature_id": "feature_x",
|
|
200
|
+
"outputs": [
|
|
201
|
+
{ "type": "PATCH", "unified_diff": "..." },
|
|
202
|
+
{ "type": "NOTE", "content": "Applied auth fix for retry #1" }
|
|
203
|
+
],
|
|
204
|
+
"provider_meta": {
|
|
205
|
+
"provider": "claude",
|
|
206
|
+
"model": "local-default"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Rules:
|
|
212
|
+
|
|
213
|
+
- `outputs` is required; empty outputs count as no-progress
|
|
214
|
+
- unknown output `type` is invalid output
|
|
215
|
+
- provider adapter is responsible for parsing provider-native payload into this envelope
|
|
216
|
+
|
|
217
|
+
### 3.4 Runtime Diagnostic Artifact Contract
|
|
218
|
+
|
|
219
|
+
Add worker execution journal:
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
.aop/runtime/worker-events/<run_id>.jsonl
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Each entry:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"ts": "2026-03-04T00:00:00.000Z",
|
|
230
|
+
"run_id": "run:...",
|
|
231
|
+
"feature_id": "feature_x",
|
|
232
|
+
"role": "builder",
|
|
233
|
+
"session_id": "builder-feature_x-...",
|
|
234
|
+
"output_types": ["PATCH", "NOTE"],
|
|
235
|
+
"patch_count": 1,
|
|
236
|
+
"plan_submission_count": 0,
|
|
237
|
+
"request_count": 0,
|
|
238
|
+
"note_count": 1,
|
|
239
|
+
"valid": true,
|
|
240
|
+
"error_code": null
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Rules:
|
|
245
|
+
|
|
246
|
+
- append-only JSONL
|
|
247
|
+
- used for operator diagnostics and regression assertions
|
|
248
|
+
|
|
249
|
+
### 3.5 Error Taxonomy Extensions
|
|
250
|
+
|
|
251
|
+
Add deterministic error codes:
|
|
252
|
+
|
|
253
|
+
- `provider_stub_disallowed`
|
|
254
|
+
- `provider_runtime_unavailable`
|
|
255
|
+
- `provider_output_invalid`
|
|
256
|
+
- `provider_no_progress`
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 4. Provider Runtime Design
|
|
261
|
+
|
|
262
|
+
### 4.1 ProviderFactory Interface (Normative)
|
|
263
|
+
|
|
264
|
+
The provider module MUST expose a concrete factory contract, not just helper functions:
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
export type WorkerProviderMode = 'live' | 'stub';
|
|
268
|
+
export type ProviderCommandContext = 'run' | 'resume' | 'send' | 'attach';
|
|
269
|
+
|
|
270
|
+
export interface CreateWorkerProviderInput {
|
|
271
|
+
selection: ProviderSelection;
|
|
272
|
+
mode: WorkerProviderMode;
|
|
273
|
+
context: ProviderCommandContext;
|
|
274
|
+
policy: {
|
|
275
|
+
require_live_provider_for_run: boolean;
|
|
276
|
+
};
|
|
277
|
+
runtime: {
|
|
278
|
+
worker_response_timeout_ms: number;
|
|
279
|
+
max_consecutive_no_progress_iterations: number;
|
|
280
|
+
};
|
|
281
|
+
commandRunner?: ProviderCommandRunner;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export interface WorkerProviderFactory {
|
|
285
|
+
create(input: CreateWorkerProviderInput): WorkerProvider;
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Requirements:
|
|
290
|
+
|
|
291
|
+
- `run` and `resume` MUST call `factory.create(...)` exactly once per CLI invocation.
|
|
292
|
+
- the returned `WorkerProvider` instance is shared by planner/builder/qa/orchestrator session management for that runtime.
|
|
293
|
+
- `create(...)` is the single enforcement point for `provider_stub_disallowed`.
|
|
294
|
+
|
|
295
|
+
### 4.2 Concrete Objects the Factory Must Create
|
|
296
|
+
|
|
297
|
+
The spec requires an explicit object set so planner/builder/qa behavior is not ambiguous:
|
|
298
|
+
|
|
299
|
+
1. `DefaultWorkerProviderFactory` (new)
|
|
300
|
+
|
|
301
|
+
- owns provider-to-adapter mapping and mode/policy enforcement
|
|
302
|
+
- created in CLI composition (`bootstrap.ts`) and injected into run/resume handlers
|
|
303
|
+
|
|
304
|
+
2. `NullWorkerProvider` (existing)
|
|
305
|
+
|
|
306
|
+
- only returned when `mode='stub'` and policy/context allows it
|
|
307
|
+
|
|
308
|
+
3. `CliWorkerProvider` (new live adapter)
|
|
309
|
+
|
|
310
|
+
- handles CLI-backed providers: `codex`, `claude`, `kiro-cli`, `copilot`, `custom`
|
|
311
|
+
- responsible for command invocation + payload parsing + normalized envelope output
|
|
312
|
+
|
|
313
|
+
4. `ApiWorkerProvider` (new live adapter)
|
|
314
|
+
|
|
315
|
+
- handles API-backed providers (initially `gemini`)
|
|
316
|
+
- responsible for SDK/API request/response + normalized envelope output
|
|
317
|
+
|
|
318
|
+
5. `ProviderOutputParser` implementations (new)
|
|
319
|
+
|
|
320
|
+
- `CodexOutputParser`
|
|
321
|
+
- `ClaudeOutputParser`
|
|
322
|
+
- `GenericCliOutputParser` (`kiro-cli`/`copilot`/`custom` initial path)
|
|
323
|
+
- `GeminiOutputParser`
|
|
324
|
+
|
|
325
|
+
The live provider adapters MUST compose a parser object; parsing logic MUST NOT live in wave executors.
|
|
326
|
+
|
|
327
|
+
### 4.3 Provider Mapping Table (Normative)
|
|
328
|
+
|
|
329
|
+
`DefaultWorkerProviderFactory` MUST use deterministic mapping:
|
|
330
|
+
|
|
331
|
+
| `selection.provider` | `mode` | Adapter object |
|
|
332
|
+
| ---------------------- | ------ | ------------------------------------------------ |
|
|
333
|
+
| `codex` | `live` | `CliWorkerProvider` + `CodexOutputParser` |
|
|
334
|
+
| `claude` | `live` | `CliWorkerProvider` + `ClaudeOutputParser` |
|
|
335
|
+
| `kiro-cli` | `live` | `CliWorkerProvider` + `GenericCliOutputParser` |
|
|
336
|
+
| `copilot` | `live` | `CliWorkerProvider` + `GenericCliOutputParser` |
|
|
337
|
+
| `custom` | `live` | `CliWorkerProvider` + `GenericCliOutputParser` |
|
|
338
|
+
| `gemini` | `live` | `ApiWorkerProvider` + `GeminiOutputParser` |
|
|
339
|
+
| any supported provider | `stub` | `NullWorkerProvider` (subject to policy/context) |
|
|
340
|
+
|
|
341
|
+
Unknown provider names are already rejected by `resolveProviderSelection()` and MUST NOT reach factory mapping.
|
|
342
|
+
|
|
343
|
+
### 4.4 Factory Decision Algorithm (Normative)
|
|
344
|
+
|
|
345
|
+
`DefaultWorkerProviderFactory.create(input)` must behave as follows:
|
|
346
|
+
|
|
347
|
+
1. Validate provider is supported.
|
|
348
|
+
2. If `input.mode === 'stub'`:
|
|
349
|
+
|
|
350
|
+
- if `context in {'run','resume'}` and `policy.require_live_provider_for_run === true`, throw `provider_stub_disallowed`.
|
|
351
|
+
- else return `new NullWorkerProvider(selection, ...)`.
|
|
352
|
+
|
|
353
|
+
3. If `input.mode === 'live'`:
|
|
354
|
+
|
|
355
|
+
- resolve adapter class by mapping table.
|
|
356
|
+
- instantiate adapter with deterministic dependencies (`selection`, timeout, command runner/api client, parser).
|
|
357
|
+
- if required runtime dependency is unavailable, throw `provider_runtime_unavailable`.
|
|
358
|
+
|
|
359
|
+
4. Return `WorkerProvider`.
|
|
360
|
+
|
|
361
|
+
### 4.5 Planner/Builder/QA Provider Usage and Object Lifecycle
|
|
362
|
+
|
|
363
|
+
This section defines how cluster roles actually consume the factory output:
|
|
364
|
+
|
|
365
|
+
1. CLI bootstrap resolves selection and creates a single `WorkerProvider` instance via factory.
|
|
366
|
+
2. `SupervisorRuntime` receives that single provider instance.
|
|
367
|
+
3. `SessionOrchestrator` creates role sessions through this provider:
|
|
368
|
+
|
|
369
|
+
- orchestrator: `createSession('orchestrator','global',null)`
|
|
370
|
+
- planner: `createSession('planner', featureId, prompts.planner)`
|
|
371
|
+
- builder: `createSession('builder', featureId, prompts.builder)`
|
|
372
|
+
- qa: `createSession('qa', featureId, prompts.qa)`
|
|
373
|
+
|
|
374
|
+
4. `WorkerDecisionLoop` invokes `provider.runWorker(...)` for planner/builder/qa turns.
|
|
375
|
+
5. QA rotation closes prior QA session and re-creates QA session through the same provider instance.
|
|
376
|
+
|
|
377
|
+
Important clarification: planner/builder/qa do not each instantiate providers directly; they consume sessions from the runtime-scoped provider instance created by `ProviderFactory`.
|
|
378
|
+
|
|
379
|
+
### 4.6 Live Adapter Responsibilities
|
|
380
|
+
|
|
381
|
+
Each live adapter MUST:
|
|
382
|
+
|
|
383
|
+
- create/reattach/close sessions deterministically
|
|
384
|
+
- submit role instructions + context bundle to provider runtime
|
|
385
|
+
- parse provider response into normalized `outputs`
|
|
386
|
+
- surface transport/process failures via normalized error codes
|
|
387
|
+
- emit provider metadata needed for worker-events journaling
|
|
388
|
+
|
|
389
|
+
### 4.7 Stub Adapter Responsibilities
|
|
390
|
+
|
|
391
|
+
`NullWorkerProvider` stays in codebase for:
|
|
392
|
+
|
|
393
|
+
- unit tests
|
|
394
|
+
- explicit debug mode
|
|
395
|
+
|
|
396
|
+
It MUST NOT be default for production `run`/`resume`.
|
|
397
|
+
|
|
398
|
+
### 4.8 File Decomposition Requirement for ProviderFactory
|
|
399
|
+
|
|
400
|
+
Implementation must split provider concerns into explicit files (exact names may vary but boundaries are mandatory):
|
|
401
|
+
|
|
402
|
+
- factory: `providers/worker-provider-factory.ts`
|
|
403
|
+
- adapter(s): `providers/cli-worker-provider.ts`, `providers/api-worker-provider.ts`
|
|
404
|
+
- parser(s): `providers/output-parsers/*.ts`
|
|
405
|
+
- compatibility export barrel: `providers/providers.ts`
|
|
406
|
+
|
|
407
|
+
`providers/providers.ts` may re-export these modules for compatibility, but factory logic MUST NOT remain implicit inside CLI handlers.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## 5. Cluster Agent Behavior Changes
|
|
412
|
+
|
|
413
|
+
### 5.1 Planner Agent
|
|
414
|
+
|
|
415
|
+
Current behavior to change:
|
|
416
|
+
|
|
417
|
+
- planner can silently rely on generated fallback plan.
|
|
418
|
+
|
|
419
|
+
Required behavior:
|
|
420
|
+
|
|
421
|
+
- in live mode, if planner returns no valid plan actions for `N` iterations, feature is blocked with `provider_no_progress`
|
|
422
|
+
- fallback initial plan generation remains allowed only when provider mode is `stub` (or explicit policy override)
|
|
423
|
+
|
|
424
|
+
### 5.2 Builder Agent
|
|
425
|
+
|
|
426
|
+
Current behavior to change:
|
|
427
|
+
|
|
428
|
+
- builder can run fast gates after NOTE-only outputs.
|
|
429
|
+
|
|
430
|
+
Required behavior:
|
|
431
|
+
|
|
432
|
+
- builder may emit NOTE/REQUEST, but repeated no-progress cycles in live mode block feature
|
|
433
|
+
- gate-repair retries still supported, but retries must include a valid worker output envelope each cycle
|
|
434
|
+
|
|
435
|
+
### 5.3 QA Agent
|
|
436
|
+
|
|
437
|
+
Current behavior to keep + harden:
|
|
438
|
+
|
|
439
|
+
- QA session rotation after each cycle stays in place.
|
|
440
|
+
|
|
441
|
+
Required behavior:
|
|
442
|
+
|
|
443
|
+
- rotation must preserve continuity despite provider-backed sessions
|
|
444
|
+
- malformed/no-progress QA outputs in live mode trigger deterministic block/fail action
|
|
445
|
+
- full-gate retry loop remains, but must be backed by valid worker execution envelopes
|
|
446
|
+
|
|
447
|
+
### 5.4 Orchestrator Agent
|
|
448
|
+
|
|
449
|
+
No role contract expansion, but orchestrator must:
|
|
450
|
+
|
|
451
|
+
- journal provider execution diagnostics
|
|
452
|
+
- apply policy actions for malformed/no-progress outputs
|
|
453
|
+
- preserve queue/session invariants for active vs queued features
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## 6. Edge-Case Matrix (Normative)
|
|
458
|
+
|
|
459
|
+
1. Provider binary/SDK unavailable at startup:
|
|
460
|
+
|
|
461
|
+
- `run`/`resume` fails fast with `provider_runtime_unavailable`.
|
|
462
|
+
|
|
463
|
+
2. Provider session creation succeeds but runWorker times out:
|
|
464
|
+
|
|
465
|
+
- deterministic timeout error; action governed by policy (`block_feature` vs `fail_run`).
|
|
466
|
+
|
|
467
|
+
3. Provider returns unparsable payload:
|
|
468
|
+
|
|
469
|
+
- record invalid output event; apply malformed-output action.
|
|
470
|
+
|
|
471
|
+
4. Provider returns unknown output types:
|
|
472
|
+
|
|
473
|
+
- treat as invalid output (not ignored silently).
|
|
474
|
+
|
|
475
|
+
5. Provider returns NOTE-only for repeated iterations:
|
|
476
|
+
|
|
477
|
+
- treated as no-progress once threshold exceeded.
|
|
478
|
+
|
|
479
|
+
6. Resume path with stale runtime sessions:
|
|
480
|
+
|
|
481
|
+
- reattach when possible; otherwise create new sessions without violating `1 + 3N`.
|
|
482
|
+
|
|
483
|
+
7. Takeover of stale run with epoch increment:
|
|
484
|
+
|
|
485
|
+
- orphan sessions closed/marked; new live provider sessions established.
|
|
486
|
+
|
|
487
|
+
8. Queued features:
|
|
488
|
+
|
|
489
|
+
- remain `unassigned`; no worker provider calls until promoted active.
|
|
490
|
+
|
|
491
|
+
9. QA session rotation failures:
|
|
492
|
+
|
|
493
|
+
- close/create failures are deterministic provider runtime errors; no silent skip.
|
|
494
|
+
|
|
495
|
+
10. Concurrent features with max parallel gates:
|
|
496
|
+
|
|
497
|
+
- provider errors isolated per feature; other active features continue unless policy says `fail_run`.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## 7. Implementation Plan
|
|
502
|
+
|
|
503
|
+
### M42.1 Provider Factory + Wiring
|
|
504
|
+
|
|
505
|
+
- replace direct `new NullWorkerProvider(...)` in:
|
|
506
|
+
- `run-command-handler.ts`
|
|
507
|
+
- `resume-command-handler.ts`
|
|
508
|
+
- add provider factory wiring in CLI bootstrap composition path
|
|
509
|
+
- preserve attach/send behavior via factory output
|
|
510
|
+
|
|
511
|
+
### M42.2 Live Provider Adapter Layer
|
|
512
|
+
|
|
513
|
+
- split provider module into:
|
|
514
|
+
- selection + credentials
|
|
515
|
+
- provider factory
|
|
516
|
+
- live adapter(s)
|
|
517
|
+
- stub adapter
|
|
518
|
+
- keep public exports backward-compatible where feasible
|
|
519
|
+
|
|
520
|
+
### M42.3 Worker Decision Hardening
|
|
521
|
+
|
|
522
|
+
- validate output envelope before routing decisions
|
|
523
|
+
- record worker-events journal entries
|
|
524
|
+
- enforce no-progress counters and policy action
|
|
525
|
+
|
|
526
|
+
### M42.4 Planner/Builder/QA Execution Semantics
|
|
527
|
+
|
|
528
|
+
- planner fallback constrained by provider mode/policy
|
|
529
|
+
- builder/qa no-progress behavior enforced in live mode
|
|
530
|
+
- QA rotation compatibility tested with live adapter stubs/fakes
|
|
531
|
+
|
|
532
|
+
### M42.5 Regression and Verify Hardening
|
|
533
|
+
|
|
534
|
+
- add targeted tests to ensure `npm run verify` fails when run/resume silently use stub mode
|
|
535
|
+
- add integration test proving real provider outputs lead to plan + patch + gates progression
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## 8. File-Level Change Targets
|
|
540
|
+
|
|
541
|
+
- `apps/control-plane/src/providers/providers.ts`
|
|
542
|
+
- `apps/control-plane/src/providers/worker-provider-factory.ts` (new)
|
|
543
|
+
- `apps/control-plane/src/providers/cli-worker-provider.ts` (new)
|
|
544
|
+
- `apps/control-plane/src/providers/api-worker-provider.ts` (new)
|
|
545
|
+
- `apps/control-plane/src/providers/output-parsers/` (new folder)
|
|
546
|
+
- `apps/control-plane/src/cli/run-command-handler.ts`
|
|
547
|
+
- `apps/control-plane/src/cli/resume-command-handler.ts`
|
|
548
|
+
- `apps/control-plane/src/interfaces/cli/bootstrap.ts`
|
|
549
|
+
- `apps/control-plane/src/supervisor/worker-decision-loop.ts`
|
|
550
|
+
- `apps/control-plane/src/supervisor/planning-wave-executor.ts`
|
|
551
|
+
- `apps/control-plane/src/supervisor/build-wave-executor.ts`
|
|
552
|
+
- `apps/control-plane/src/supervisor/qa-wave-executor.ts`
|
|
553
|
+
- `apps/control-plane/src/core/error-codes.ts`
|
|
554
|
+
- `agentic/orchestrator/schemas/agents.schema.json`
|
|
555
|
+
- `agentic/orchestrator/schemas/policy.schema.json`
|
|
556
|
+
- `agentic/orchestrator/agents.yaml`
|
|
557
|
+
- `agentic/orchestrator/policy.yaml`
|
|
558
|
+
- `apps/control-plane/test/providers.spec.ts`
|
|
559
|
+
- `apps/control-plane/test/cli.unit.spec.ts`
|
|
560
|
+
- `apps/control-plane/test/resume-command.spec.ts`
|
|
561
|
+
- `apps/control-plane/test/worker-decision-loop.spec.ts`
|
|
562
|
+
- `apps/control-plane/test/supervisor.spec.ts`
|
|
563
|
+
- `apps/control-plane/test/supervisor.unit.spec.ts`
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
567
|
+
## 9. Test Plan (Must Be in `npm run verify` Path)
|
|
568
|
+
|
|
569
|
+
### 9.1 Unit
|
|
570
|
+
|
|
571
|
+
- provider factory returns live adapter for run/resume defaults
|
|
572
|
+
- stub mode requires explicit opt-in
|
|
573
|
+
- malformed envelope parsing returns `provider_output_invalid`
|
|
574
|
+
|
|
575
|
+
### 9.2 Supervisor Integration
|
|
576
|
+
|
|
577
|
+
- GIVEN live provider emits plan+patch outputs WHEN run executes THEN feature transitions through planning/building/qa with non-empty diff evidence
|
|
578
|
+
- GIVEN live provider emits repeated NOTE-only outputs WHEN threshold exceeded THEN feature blocks with `provider_no_progress`
|
|
579
|
+
- GIVEN queued features WHEN runtime starts THEN no worker calls occur for queued features
|
|
580
|
+
|
|
581
|
+
### 9.3 Resume/Recovery
|
|
582
|
+
|
|
583
|
+
- GIVEN resumable feature WHEN resume executes THEN factory uses live adapter and respects existing session assignments
|
|
584
|
+
- GIVEN stale sessions/timeouts WHEN resume executes THEN recovery and epoch/session invariants hold
|
|
585
|
+
|
|
586
|
+
### 9.4 Regression for Current Defect
|
|
587
|
+
|
|
588
|
+
- GIVEN run path configured for live mode WHEN provider resolves to stub THEN command fails (not silently proceeds)
|
|
589
|
+
- GIVEN no patch and no valid worker progress in live mode WHEN gates pass spuriously THEN feature does not auto-promote to `ready_to_merge`
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## 10. Acceptance Criteria
|
|
594
|
+
|
|
595
|
+
1. `aop run` and `aop resume` do not use `NullWorkerProvider` unless explicit stub mode is enabled.
|
|
596
|
+
2. Provider selection materially changes runtime behavior through factory-selected live adapters.
|
|
597
|
+
3. Planner/builder/qa output processing is deterministic and validated.
|
|
598
|
+
4. Malformed/no-progress worker behaviors are auditable and policy-controlled.
|
|
599
|
+
5. Global topology invariants (`1 + 3N`, queued `unassigned`) remain intact.
|
|
600
|
+
6. `npm run verify` contains regression tests that fail for the “planning -> ready_to_merge with no build output/diff” defect class.
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
## 11. Risks and Mitigations
|
|
605
|
+
|
|
606
|
+
- Risk: provider-specific payload variability breaks parser.
|
|
607
|
+
- Mitigation: strict adapter normalization layer + invalid-output policy action.
|
|
608
|
+
|
|
609
|
+
- Risk: session churn (especially QA rotation) increases provider flakiness.
|
|
610
|
+
- Mitigation: explicit timeout handling + deterministic recovery + targeted QA rotation tests.
|
|
611
|
+
|
|
612
|
+
- Risk: introducing live enforcement breaks existing tests that rely on stub behavior.
|
|
613
|
+
- Mitigation: explicit stub mode for tests and incremental migration of unit fixtures.
|
|
614
|
+
|
|
615
|
+
- Risk: false positives in no-progress detection for legitimately small/no-op work.
|
|
616
|
+
- Mitigation: policy threshold and explicit override path with audited rationale.
|