|
|
|
@@ -0,0 +1,162 @@
|
|
|
|
|
# Track Specification: Native Orchestrator (native_orchestrator_20260306)
|
|
|
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
Absorb `mma_exec.py` functionality into core application. Manual Slop natively reads/writes plan.md, manages metadata.json, and orchestrates MMA tiers in pure Python without external CLI subprocess calls.
|
|
|
|
|
|
|
|
|
|
## Current State Audit
|
|
|
|
|
|
|
|
|
|
### Already Implemented (DO NOT re-implement)
|
|
|
|
|
|
|
|
|
|
#### mma_exec.py (scripts/mma_exec.py)
|
|
|
|
|
- **CLI wrapper**: Parses `--role` argument, builds prompt, calls AI
|
|
|
|
|
- **Model selection**: Maps role to model (tier3-worker → gemini-2.5-flash-lite)
|
|
|
|
|
- **Subprocess execution**: Spawns new Python process for each delegation
|
|
|
|
|
- **Logging**: Writes to `logs/agents/` directory
|
|
|
|
|
|
|
|
|
|
#### ConductorEngine (src/multi_agent_conductor.py)
|
|
|
|
|
- **`run()` method**: Executes tickets via `run_worker_lifecycle()`
|
|
|
|
|
- **`run_worker_lifecycle()`**: Calls `ai_client.send()` directly
|
|
|
|
|
- **In-process execution**: Workers run in same process (thread pool)
|
|
|
|
|
|
|
|
|
|
#### orchestrator_pm.py (src/orchestrator_pm.py)
|
|
|
|
|
- **`scan_work_summary()`**: Reads conductor/archive/ and conductor/tracks/
|
|
|
|
|
- **Uses hardcoded `CONDUCTOR_PATH`**: Addressed in conductor_path_configurable track
|
|
|
|
|
|
|
|
|
|
#### project_manager.py (src/project_manager.py)
|
|
|
|
|
- **`save_track_state()`**: Writes state.toml
|
|
|
|
|
- **`load_track_state()`**: Reads state.toml
|
|
|
|
|
- **`get_all_tracks()`**: Scans tracks directory
|
|
|
|
|
|
|
|
|
|
### Gaps to Fill (This Track's Scope)
|
|
|
|
|
- No native plan.md parsing/writing
|
|
|
|
|
- No native metadata.json management in ConductorEngine
|
|
|
|
|
- External mma_exec.py still used for some operations
|
|
|
|
|
- No unified orchestration interface
|
|
|
|
|
|
|
|
|
|
## Architectural Constraints
|
|
|
|
|
|
|
|
|
|
### Backward Compatibility
|
|
|
|
|
- Existing track files MUST remain loadable
|
|
|
|
|
- mma_exec.py CLI MUST still work (as wrapper)
|
|
|
|
|
- No breaking changes to file formats
|
|
|
|
|
|
|
|
|
|
### Single Process
|
|
|
|
|
- All tier execution in same process
|
|
|
|
|
- Use threading, not multiprocessing
|
|
|
|
|
- Shared ai_client state (with locks)
|
|
|
|
|
|
|
|
|
|
### Error Propagation
|
|
|
|
|
- Tier errors MUST propagate to caller
|
|
|
|
|
- No silent failures
|
|
|
|
|
- Structured error reporting
|
|
|
|
|
|
|
|
|
|
## Architecture Reference
|
|
|
|
|
|
|
|
|
|
### Key Integration Points
|
|
|
|
|
|
|
|
|
|
| File | Lines | Purpose |
|
|
|
|
|
|------|-------|---------|
|
|
|
|
|
| `src/orchestrator_pm.py` | 10-50 | `scan_work_summary()` |
|
|
|
|
|
| `src/multi_agent_conductor.py` | 100-250 | `ConductorEngine`, `run_worker_lifecycle()` |
|
|
|
|
|
| `src/conductor_tech_lead.py` | 10-50 | `generate_tickets()` |
|
|
|
|
|
| `src/project_manager.py` | 238-310 | Track state CRUD |
|
|
|
|
|
| `scripts/mma_exec.py` | 1-200 | Current CLI wrapper |
|
|
|
|
|
|
|
|
|
|
### Proposed Native Orchestration Module
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
# src/native_orchestrator.py (new file)
|
|
|
|
|
from src import ai_client
|
|
|
|
|
from src import conductor_tech_lead
|
|
|
|
|
from src import multi_agent_conductor
|
|
|
|
|
from src.models import Ticket, Track
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
class NativeOrchestrator:
|
|
|
|
|
def __init__(self, base_dir: str = "."):
|
|
|
|
|
self.base_dir = Path(base_dir)
|
|
|
|
|
self._conductor: multi_agent_conductor.ConductorEngine | None = None
|
|
|
|
|
|
|
|
|
|
def load_track(self, track_id: str) -> Track:
|
|
|
|
|
"""Load track from state.toml or metadata.json"""
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
def save_track(self, track: Track) -> None:
|
|
|
|
|
"""Persist track state"""
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
def execute_track(self, track: Track) -> None:
|
|
|
|
|
"""Execute all tickets in track"""
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
def generate_tickets_for_track(self, brief: str) -> list[Ticket]:
|
|
|
|
|
"""Tier 2: Generate tickets from brief"""
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
def execute_ticket(self, ticket: Ticket) -> str:
|
|
|
|
|
"""Tier 3: Execute single ticket"""
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
def analyze_error(self, error: str) -> str:
|
|
|
|
|
"""Tier 4: Analyze error"""
|
|
|
|
|
...
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Functional Requirements
|
|
|
|
|
|
|
|
|
|
### FR1: Plan.md CRUD
|
|
|
|
|
- `read_plan(track_id) -> str`: Read plan.md content
|
|
|
|
|
- `write_plan(track_id, content)`: Write plan.md content
|
|
|
|
|
- `parse_plan_tasks(content) -> list[dict]`: Extract task checkboxes
|
|
|
|
|
|
|
|
|
|
### FR2: Metadata Management
|
|
|
|
|
- `read_metadata(track_id) -> Metadata`: Load metadata.json
|
|
|
|
|
- `write_metadata(track_id, metadata)`: Save metadata.json
|
|
|
|
|
- `create_metadata(track_id, name) -> Metadata`: Create new metadata
|
|
|
|
|
|
|
|
|
|
### FR3: Tier Delegation (In-Process)
|
|
|
|
|
- **Tier 1**: Call `orchestrator_pm` functions directly
|
|
|
|
|
- **Tier 2**: Call `conductor_tech_lead.generate_tickets()` directly
|
|
|
|
|
- **Tier 3**: Call `ai_client.send()` directly in thread
|
|
|
|
|
- **Tier 4**: Call `ai_client.run_tier4_analysis()` directly
|
|
|
|
|
|
|
|
|
|
### FR4: CLI Fallback
|
|
|
|
|
- `mma_exec.py` becomes thin wrapper around `NativeOrchestrator`
|
|
|
|
|
- Maintains backward compatibility for external tools
|
|
|
|
|
|
|
|
|
|
## Non-Functional Requirements
|
|
|
|
|
|
|
|
|
|
| Requirement | Constraint |
|
|
|
|
|
|-------------|------------|
|
|
|
|
|
| Latency | <10ms overhead vs subprocess |
|
|
|
|
|
| Memory | No additional per-tier overhead |
|
|
|
|
|
| Compatibility | 100% file format compatible |
|
|
|
|
|
|
|
|
|
|
## Testing Requirements
|
|
|
|
|
|
|
|
|
|
### Unit Tests
|
|
|
|
|
- Test plan.md parsing
|
|
|
|
|
- Test metadata.json read/write
|
|
|
|
|
- Test tier delegation calls correct functions
|
|
|
|
|
|
|
|
|
|
### Integration Tests
|
|
|
|
|
- Load existing track, verify compatibility
|
|
|
|
|
- Execute track end-to-end without subprocess
|
|
|
|
|
- Verify mma_exec.py wrapper still works
|
|
|
|
|
|
|
|
|
|
## Dependencies
|
|
|
|
|
- **Depends on**: `conductor_path_configurable_20260306` for path resolution
|
|
|
|
|
|
|
|
|
|
## Out of Scope
|
|
|
|
|
- Distributed orchestration
|
|
|
|
|
- Persistent worker processes
|
|
|
|
|
- Hot-reload of track state
|
|
|
|
|
|
|
|
|
|
## Acceptance Criteria
|
|
|
|
|
- [ ] plan.md read/write works natively
|
|
|
|
|
- [ ] metadata.json managed in Python
|
|
|
|
|
- [ ] Tier delegation executes in-process
|
|
|
|
|
- [ ] No external CLI required for orchestration
|
|
|
|
|
- [ ] Existing tracks remain loadable
|
|
|
|
|
- [ ] mma_exec.py wrapper still works
|
|
|
|
|
- [ ] 1-space indentation maintained
|