Add end-to-end tests for Graph Explorer, History, Orchestrator, and Project features

- Implemented E2E tests for code relationship visualization in Graph Explorer.
- Added tests for archived session management in History, including search, filter, restore, and delete functionalities.
- Created tests for workflow orchestration in Orchestrator, covering node creation, connection, deletion, and workflow management.
- Developed tests for project statistics and timeline visualization in Project, including error handling and internationalization checks.
This commit is contained in:
catlog22
2026-02-06 23:45:33 +08:00
parent 62a1c9ab21
commit 5b48bcff64
72 changed files with 8645 additions and 3492 deletions

View File

@@ -1,385 +0,0 @@
# Parallel Dev Cycle Skill
Multi-agent parallel development cycle using Codex subagent pattern with continuous iteration support.
## Overview
This skill implements a **single-file-per-agent** development workflow:
- **RA**: `requirements.md` (all requirements + edge cases + history)
- **EP**: `exploration.md`, `architecture.md`, `plan.json` (codebase exploration + architecture + structured tasks)
- **CD**: `implementation.md` (progress + files + decisions + testing)
- **VAS**: `summary.md` (validation + test results + recommendations)
Each file is **completely rewritten** on each iteration, with old versions auto-archived to `history/`.
## Installation
Files are in `.codex/skills/parallel-dev-cycle/`:
```
.codex/skills/parallel-dev-cycle/
├── SKILL.md # Main skill definition
├── README.md # This file
├── phases/
│ ├── orchestrator.md # Multi-agent coordination
│ ├── state-schema.md # Unified state structure
│ └── agents/
│ ├── requirements-analyst.md # RA role
│ ├── exploration-planner.md # EP role
│ ├── code-developer.md # CD role
│ └── validation-archivist.md # VAS role
└── specs/
├── coordination-protocol.md # Agent communication
└── versioning-strategy.md # Version management
```
## Quick Start
### Launch New Cycle
```bash
/parallel-dev-cycle TASK="Implement OAuth authentication"
```
Creates:
```
.workflow/.cycle/cycle-v1-20260122-abc123.progress/
├── ra/
│ ├── requirements.md (v1.0.0)
│ └── changes.log (NDJSON)
├── ep/
│ ├── exploration.md (v1.0.0)
│ ├── architecture.md (v1.0.0)
│ ├── plan.json (v1.0.0)
│ └── changes.log (NDJSON)
├── cd/
│ ├── implementation.md (v1.0.0)
│ └── changes.log (NDJSON)
└── vas/
├── summary.md (v1.0.0)
└── changes.log (NDJSON)
```
### Continue With Extension (XX-1 Pattern)
User adds requirement: "Also support Google OAuth"
```bash
/parallel-dev-cycle --cycle-id=cycle-v1-20260122-abc123 --extend="Add Google OAuth"
```
Automatically:
1. Archives old `requirements.md (v1.0.0)``history/requirements-v1.0.0.md`
2. Rewrites `requirements.md (v1.1.0)` - complete file replacement
3. Appends change to `changes.log` (NDJSON audit trail)
### Next Iteration (XX-2)
```bash
/parallel-dev-cycle --cycle-id=cycle-v1-20260122-abc123 --extend="Add GitHub provider"
```
All files update to v1.2.0, previous versions archived.
## Execution Flow
### Phase 1: Parallel Agent Execution
```
Time RA EP CD VAS
──── ── ── ── ──
0ms [spawned] [spawned] [spawned] [spawned]
↓ ↓ ↓ ↓
Analyzing Exploring Reading plan Waiting
task codebase from EP...
5min Outputs req. Outputs plan Requirements
v1.0.0 ✓ v1.0.0 ✓ unclear - BLOCKED
10min Clarifies req Updates plan ✓ Ready
v1.0.1 ✓ v1.0.1 ✓ Implementing...
15min ✓ Complete ✓ Complete ✓ Code done [waiting for CD]
20min [starts tests]
25min Outputs summary
v1.0.0 ✓
```
### Phase 2: Version Transition
When iteration completes, next extends to v1.1.0:
```
Current State (v1.0.0)
├── requirements.md (v1.0.0)
├── plan.json (v1.0.0)
├── implementation.md (v1.0.0)
└── summary.md (v1.0.0)
User: "Add GitHub provider"
Archive Old Write New
├── history/requirements-v1.0.0.md → requirements.md (v1.1.0) - REWRITTEN
├── history/plan-v1.0.0.json → plan.json (v1.1.0) - REWRITTEN
├── history/impl-v1.0.0.md → implementation.md (v1.1.0) - REWRITTEN
└── history/summary-v1.0.0.md → summary.md (v1.1.0) - REWRITTEN
Append to changes.log (NDJSON)
```
## Session Files
```
.workflow/.cycle/{cycleId}.progress/
ra/ - Requirements Analyst
├── requirements.md # v1.2.0 (current, complete rewrite)
├── changes.log # NDJSON audit trail
└── history/
├── requirements-v1.0.0.md
└── requirements-v1.1.0.md
ep/ - Exploration & Planning
├── exploration.md # v1.2.0 (codebase exploration)
├── architecture.md # v1.2.0 (architecture design)
├── plan.json # v1.2.0 (structured task list, current)
├── changes.log # NDJSON audit trail
└── history/
├── plan-v1.0.0.json
└── plan-v1.1.0.json
cd/ - Code Developer
├── implementation.md # v1.2.0 (current)
├── changes.log # NDJSON audit trail
└── history/
├── implementation-v1.0.0.md
└── implementation-v1.1.0.md
vas/ - Validation & Archival
├── summary.md # v1.2.0 (current)
├── changes.log # NDJSON audit trail
└── history/
├── summary-v1.0.0.md
└── summary-v1.1.0.md
```
## Versioning Strategy
### Semantic Versioning
- **1.0.0**: Initial cycle
- **1.1.0**: User extends with new requirement
- **1.2.0**: Another iteration with more requirements
### What Gets Versioned
**Main Document File**
- Completely rewritten each iteration
- Auto-archived to `history/`
- No inline version history (stays clean)
**Changes.log (NDJSON)**
- Append-only (never deleted)
- Complete audit trail of all changes
- Used to trace requirement origins
**Historical Snapshots**
- Auto-created in `history/` directory
- Keep last N versions (default: 5)
- For reference when needed
### Key Principle
> **主文档简洁清晰** ← Agent 只关注当前版本
>
> **完整历史记录** ← Changes.log 保留每个变更
>
> **版本快照归档** ← History/ 备份旧版本
## File Maintenance
### Each Agent
| Agent | File | Contains | Size |
|-------|------|----------|------|
| **RA** | requirements.md | All FR, NFR, edge cases, history summary | ~2-5KB |
| **EP** | exploration.md + architecture.md + plan.json | Codebase exploration, architecture design, structured task list | ~5-10KB total |
| **CD** | implementation.md | Completed tasks, files changed, decisions, tests | ~4-10KB |
| **VAS** | summary.md | Test results, coverage, issues, recommendations | ~5-12KB |
### Changes.log (Shared)
NDJSON format - one line per change:
```jsonl
{"timestamp":"2026-01-22T10:00:00+08:00","version":"1.0.0","agent":"ra","action":"create","change":"Initial requirements","iteration":1}
{"timestamp":"2026-01-22T11:00:00+08:00","version":"1.1.0","agent":"ra","action":"update","change":"Added Google OAuth","iteration":2}
{"timestamp":"2026-01-22T12:00:00+08:00","version":"1.2.0","agent":"ra","action":"update","change":"Added GitHub, MFA","iteration":3}
```
## Accessing History
### Current Version
```bash
# View latest requirements
cat .workflow/.cycle/cycle-xxx.progress/ra/requirements.md
# Quick check - version is in header
head -5 requirements.md # "# Requirements Specification - v1.2.0"
```
### Version History
```bash
# View previous version
cat .workflow/.cycle/cycle-xxx.progress/ra/history/requirements-v1.1.0.md
# Audit trail - all changes
cat .workflow/.cycle/cycle-xxx.progress/ra/changes.log | jq .
# Changes in specific iteration
cat changes.log | jq 'select(.iteration==2)'
# Trace requirement history
cat changes.log | jq 'select(.change | contains("OAuth"))'
```
## Codex Pattern Implementation
### Multi-Agent Parallel
```javascript
// Create 4 agents in parallel
const agents = {
ra: spawn_agent({ message: raRoleAndTask }),
ep: spawn_agent({ message: epRoleAndTask }),
cd: spawn_agent({ message: cdRoleAndTask }),
vas: spawn_agent({ message: vasRoleAndTask })
}
// Wait for all 4 in parallel
const results = wait({ ids: [agents.ra, agents.ep, agents.cd, agents.vas] })
```
### Role Path Passing
Each agent reads its own role definition:
```javascript
spawn_agent({
message: `
## MANDATORY FIRST STEPS
1. Read role: ~/.codex/agents/requirements-analyst.md
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
## TASK
${taskDescription}
`
})
```
### Deep Interaction
Use `send_input` for iteration refinement:
```javascript
// First output
const initial = wait({ ids: [agent] })
// User feedback
send_input({
id: agent,
message: `
## Feedback
${feedback}
## Next Steps
Update ${filename} based on feedback. Increment version.
Output PHASE_RESULT when complete.
`
})
// Updated output
const revised = wait({ ids: [agent] })
// Only close when done
close_agent({ id: agent })
```
## Error Handling
| Situation | Recovery |
|-----------|----------|
| Agent timeout | send_input requesting convergence or retry |
| State corrupted | Rebuild from changes.log NDJSON |
| Version mismatch | Agent checks version in state before reading |
| Blocked dependency | Orchestrator sends updated file path |
## Best Practices
1. **Let agents rewrite** - Don't maintain incremental history in main doc
2. **Trust changes.log** - NDJSON is the source of truth for history
3. **Archive on version bump** - Automatic, no manual versioning needed
4. **Keep files focused** - Each file should be readable in 5 minutes
5. **Version header always present** - Makes version obvious at a glance
## Integration
This skill works standalone or integrated with:
- Dashboard Loop Monitor (API triggers)
- CCW workflow system
- Custom orchestration
### API Trigger
```bash
POST /api/cycles/start
{
"task": "Implement OAuth",
"mode": "auto"
}
→ Returns cycle_id
GET /api/cycles/{cycle_id}/status
→ Returns agents status and progress
```
## Architecture Diagram
```
User Task
Orchestrator (main coordinator)
├─→ spawn_agent(RA)
├─→ spawn_agent(EP)
├─→ spawn_agent(CD)
└─→ spawn_agent(VAS)
wait({ ids: [all 4] })
All write to:
- requirements.md (v1.x.0)
- exploration.md, architecture.md, plan.json (v1.x.0)
- implementation.md (v1.x.0)
- summary.md (v1.x.0)
- changes.log (NDJSON append)
[Automatic archival]
- history/requirements-v1.{x-1}.0.md
- history/plan-v1.{x-1}.0.json
- etc...
Orchestrator: Next iteration?
- Yes: send_input with feedback
- No: close_agent, report summary
```
## License
MIT

View File

@@ -1,28 +1,18 @@
---
name: Parallel Dev Cycle
description: Multi-agent parallel development cycle with requirement analysis, exploration planning, code development, and validation. Supports continuous iteration with markdown progress documentation.
argument-hint: TASK="<task description>" | --cycle-id=<id> [--extend="<extension>"] [--auto] [--parallel=<count>]
name: parallel-dev-cycle
description: Multi-agent parallel development cycle with requirement analysis, exploration planning, code development, and validation. Supports continuous iteration with markdown progress documentation. Triggers on "parallel-dev-cycle".
allowed-tools: Task, AskUserQuestion, TodoWrite, Read, Write, Edit, Bash, Glob, Grep
---
# Parallel Dev Cycle - Multi-Agent Development Workflow
# Parallel Dev Cycle
Multi-agent parallel development cycle using Codex subagent pattern with four specialized workers:
1. **Requirements Analysis & Extension** (RA) - Requirement analysis and self-enhancement
2. **Exploration & Planning** (EP) - Exploration and planning
2. **Exploration & Planning** (EP) - Codebase exploration and implementation planning
3. **Code Development** (CD) - Code development with debug strategy support
4. **Validation & Archival Summary** (VAS) - Validation and archival summary
Each agent **maintains one main document** (e.g., requirements.md, plan.json, implementation.md) that is completely rewritten per iteration, plus auxiliary logs (changes.log, debug-log.ndjson) that are append-only. Supports versioning, automatic archival, and complete history tracking.
## Arguments
| Arg | Required | Description |
|-----|----------|-------------|
| TASK | One of TASK or --cycle-id | Task description (for new cycle, mutually exclusive with --cycle-id) |
| --cycle-id | One of TASK or --cycle-id | Existing cycle ID to continue (from API or previous session) |
| --extend | No | Extension description (only valid with --cycle-id) |
| --auto | No | Auto-cycle mode (run all phases sequentially) |
| --parallel | No | Number of parallel agents (default: 4, max: 4) |
Each agent **maintains one main document** (e.g., requirements.md, plan.json, implementation.md) that is completely rewritten per iteration, plus auxiliary logs (changes.log, debug-log.ndjson) that are append-only.
## Architecture Overview
@@ -70,93 +60,273 @@ Each agent **maintains one main document** (e.g., requirements.md, plan.json, im
6. **File References**: Use short file paths instead of content passing
7. **Self-Enhancement**: RA agent proactively extends requirements based on context
## Arguments
| Arg | Required | Description |
|-----|----------|-------------|
| TASK | One of TASK or --cycle-id | Task description (for new cycle, mutually exclusive with --cycle-id) |
| --cycle-id | One of TASK or --cycle-id | Existing cycle ID to continue (from API or previous session) |
| --extend | No | Extension description (only valid with --cycle-id) |
| --auto | No | Auto-cycle mode (run all phases sequentially without user confirmation) |
| --parallel | No | Number of parallel agents (default: 4, max: 4) |
## Auto Mode
When `--auto`: Run all phases sequentially without user confirmation between iterations. Use recommended defaults for all decisions. Automatically continue iteration loop until tests pass or max iterations reached.
## Execution Flow
```
Input Parsing:
└─ Parse arguments (TASK | --cycle-id + --extend)
└─ Convert to structured context (cycleId, state, progressDir)
Phase 1: Session Initialization
└─ Ref: phases/01-session-init.md
├─ Create new cycle OR resume existing cycle
├─ Initialize state file and directory structure
└─ Output: cycleId, state, progressDir
Phase 2: Agent Execution (Parallel)
└─ Ref: phases/02-agent-execution.md
├─ Tasks attached: Spawn RA → Spawn EP → Spawn CD → Spawn VAS → Wait all
├─ Spawn RA, EP, CD, VAS agents in parallel
├─ Wait for all agents with timeout handling
└─ Output: agentOutputs (4 agent results)
Phase 3: Result Aggregation & Iteration
└─ Ref: phases/03-result-aggregation.md
├─ Parse PHASE_RESULT from each agent
├─ Detect issues (test failures, blockers)
├─ Decision: Issues found AND iteration < max?
│ ├─ Yes → Send feedback via send_input, loop back to Phase 2
│ └─ No → Proceed to Phase 4
└─ Output: parsedResults, iteration status
Phase 4: Completion & Summary
└─ Ref: phases/04-completion-summary.md
├─ Generate unified summary report
├─ Update final state
├─ Close all agents
└─ Output: final cycle report with continuation instructions
```
**Phase Reference Documents** (read on-demand when phase executes):
| Phase | Document | Purpose |
|-------|----------|---------|
| 1 | [phases/01-session-init.md](phases/01-session-init.md) | Session creation/resume and state initialization |
| 2 | [phases/02-agent-execution.md](phases/02-agent-execution.md) | Parallel agent spawning and execution |
| 3 | [phases/03-result-aggregation.md](phases/03-result-aggregation.md) | Result parsing, feedback generation, iteration handling |
| 4 | [phases/04-completion-summary.md](phases/04-completion-summary.md) | Final summary generation and cleanup |
## Data Flow
```
User Input (TASK | --cycle-id + --extend)
[Parse Arguments]
↓ cycleId, state, progressDir
Phase 1: Session Initialization
↓ cycleId, state, progressDir (initialized/resumed)
Phase 2: Agent Execution
↓ agentOutputs {ra, ep, cd, vas}
Phase 3: Result Aggregation
↓ parsedResults, hasIssues, iteration count
↓ [Loop back to Phase 2 if issues and iteration < max]
Phase 4: Completion & Summary
↓ finalState, summaryReport
Return: cycle_id, iterations, final_state
```
## Session Structure
```
.workflow/.cycle/
+-- {cycleId}.json # Master state file
+-- {cycleId}.progress/
+-- ra/
| +-- requirements.md # Current version (complete rewrite)
| +-- changes.log # NDJSON complete history (append-only)
|-- history/
| +-- requirements-v1.0.0.md # Archived snapshot
| +-- requirements-v1.1.0.md # Archived snapshot
+-- ep/
| +-- exploration.md # Codebase exploration report
| +-- architecture.md # Architecture design
| +-- plan.json # Structured task list (current version)
| +-- changes.log # NDJSON complete history
| └-- history/
| +-- plan-v1.0.0.json
| +-- plan-v1.1.0.json
+-- cd/
| +-- implementation.md # Current version
| +-- debug-log.ndjson # Debug hypothesis tracking
| +-- changes.log # NDJSON complete history
|-- history/
| +-- implementation-v1.0.0.md
| +-- implementation-v1.1.0.md
+-- vas/
| +-- summary.md # Current version
| +-- changes.log # NDJSON complete history
| └-- history/
| +-- summary-v1.0.0.md
| +-- summary-v1.1.0.md
└-- coordination/
+-- timeline.md # Execution timeline
+-- decisions.log # Decision log
├── {cycleId}.json # Master state file
├── {cycleId}.progress/
├── ra/
├── requirements.md # Current version (complete rewrite)
├── changes.log # NDJSON complete history (append-only)
── history/ # Archived snapshots
├── ep/
│ ├── exploration.md # Codebase exploration report
│ ├── architecture.md # Architecture design
├── plan.json # Structured task list (current version)
├── changes.log # NDJSON complete history
│ └── history/
├── cd/
├── implementation.md # Current version
│ ├── debug-log.ndjson # Debug hypothesis tracking
├── changes.log # NDJSON complete history
│ └── history/
├── vas/
├── summary.md # Current version
├── changes.log # NDJSON complete history
── history/
└── coordination/
├── timeline.md # Execution timeline
└── decisions.log # Decision log
```
## State Management
State schema is defined in [phases/state-schema.md](phases/state-schema.md). The master state file (`{cycleId}.json`) tracks:
Master state file: `.workflow/.cycle/{cycleId}.json`
- Cycle metadata (id, title, status, iterations)
- Agent states (status, output files, version)
- Shared context (requirements, plan, changes, test results)
- Coordination data (feedback log, decisions, blockers)
## Versioning Workflow
### Initial Version (v1.0.0)
```bash
/parallel-dev-cycle TASK="Implement OAuth login"
```json
{
"cycle_id": "cycle-v1-20260122T100000-abc123",
"title": "Task title",
"description": "Full task description",
"status": "created | running | paused | completed | failed",
"created_at": "ISO8601", "updated_at": "ISO8601",
"max_iterations": 5, "current_iteration": 0,
"agents": {
"ra": { "status": "idle | running | completed | failed", "output_files": [] },
"ep": { "status": "idle", "output_files": [] },
"cd": { "status": "idle", "output_files": [] },
"vas": { "status": "idle", "output_files": [] }
},
"current_phase": "init | ra | ep | cd | vas | aggregation | complete",
"completed_phases": [],
"requirements": null, "plan": null, "changes": [], "test_results": null,
"coordination": { "feedback_log": [], "blockers": [] }
}
```
Generates:
```
requirements.md (v1.0.0)
exploration.md (v1.0.0)
architecture.md (v1.0.0)
plan.json (v1.0.0)
implementation.md (v1.0.0) - if applicable
summary.md (v1.0.0) - if applicable
**Recovery**: If state corrupted, rebuild from `.progress/` markdown files and changes.log.
## TodoWrite Pattern
### Phase-Level Tracking (Tasks Attached)
```json
[
{"content": "Phase 1: Session Initialization", "status": "completed"},
{"content": "Phase 2: Agent Execution", "status": "in_progress"},
{"content": " → Spawn RA Agent", "status": "completed"},
{"content": " → Spawn EP Agent", "status": "completed"},
{"content": " → Spawn CD Agent", "status": "in_progress"},
{"content": " → Spawn VAS Agent", "status": "pending"},
{"content": "Phase 3: Result Aggregation", "status": "pending"},
{"content": "Phase 4: Completion & Summary", "status": "pending"}
]
```
### Iteration Versions (v1.1.0, v1.2.0)
### Phase-Level Tracking (Collapsed)
```bash
/parallel-dev-cycle --cycle-id=cycle-v1-xxx --extend="Add GitHub support"
```json
[
{"content": "Phase 1: Session Initialization", "status": "completed"},
{"content": "Phase 2: Agent Execution (4 agents completed)", "status": "completed"},
{"content": "Phase 3: Result Aggregation", "status": "in_progress"},
{"content": "Phase 4: Completion & Summary", "status": "pending"}
]
```
**Automatic handling**:
1. Read current `requirements.md (v1.0.0)`
2. Auto-archive to `history/requirements-v1.0.0.md`
3. Recreate `requirements.md (v1.1.0)` - complete overwrite
4. Append changes to `changes.log` (NDJSON)
### Iteration Loop Tracking
## Changes.log Format (NDJSON)
Permanent audit log (append-only, never deleted):
```jsonl
{"timestamp":"2026-01-22T10:00:00+08:00","version":"1.0.0","agent":"ra","action":"create","change":"Initial requirements","iteration":1}
{"timestamp":"2026-01-22T11:00:00+08:00","version":"1.1.0","agent":"ra","action":"update","change":"Added Google OAuth requirement","iteration":2}
{"timestamp":"2026-01-22T11:30:00+08:00","version":"1.0.0","agent":"ep","action":"create","change":"Initial implementation plan","iteration":1}
```json
[
{"content": "Phase 1: Session Initialization", "status": "completed"},
{"content": "Iteration 1: Agent Execution + Aggregation", "status": "completed"},
{"content": "Iteration 2: Feedback → Re-execution → Aggregation", "status": "in_progress"},
{"content": "Phase 4: Completion & Summary", "status": "pending"}
]
```
## Versioning
- **1.0.0**: Initial cycle → **1.x.0**: Each iteration (minor bump)
- Each iteration: archive old → complete rewrite → append changes.log
```
Archive: copy requirements.md → history/requirements-v1.0.0.md
Rewrite: overwrite requirements.md with v1.1.0 (complete new content)
Append: changes.log ← {"timestamp","version":"1.1.0","action":"update","description":"..."}
```
| Agent Output | Rewrite (per iteration) | Append-only |
|-------------|------------------------|-------------|
| RA | requirements.md | changes.log |
| EP | exploration.md, architecture.md, plan.json | changes.log |
| CD | implementation.md, issues.md | changes.log, debug-log.ndjson |
| VAS | summary.md, test-results.json | changes.log |
## Coordination Protocol
**Execution Order**: RA → EP → CD → VAS (dependency chain, all spawned in parallel but block on dependencies)
**Agent → Orchestrator**: Each agent outputs `PHASE_RESULT:` block:
```
PHASE_RESULT:
- phase: ra | ep | cd | vas
- status: success | failed | partial
- files_written: [list]
- summary: one-line summary
- issues: []
```
**Orchestrator → Agent**: Feedback via `send_input` (file refs + issue summary, never full content):
```
## FEEDBACK FROM [Source]
[Issue summary with file:line references]
## Reference
- File: .progress/vas/test-results.json (v1.0.0)
## Actions Required
1. [Specific fix]
```
**Rules**: Only orchestrator writes state file. Agents read state, write to own `.progress/{agent}/` directory only.
## Core Rules
1. **Start Immediately**: First action is TodoWrite initialization, then Phase 1 execution
2. **Progressive Phase Loading**: Read phase docs ONLY when that phase is about to execute
3. **Parse Every Output**: Extract PHASE_RESULT data from each agent for next phase
4. **Auto-Continue**: After each phase, execute next pending phase automatically
5. **Track Progress**: Update TodoWrite dynamically with attachment/collapse pattern
6. **Single Writer**: Only orchestrator writes to master state file; agents report via PHASE_RESULT
7. **File References**: Pass file paths between agents, not content
8. **DO NOT STOP**: Continuous execution until all phases complete or max iterations reached
## Error Handling
| Error Type | Recovery |
|------------|----------|
| Agent timeout | send_input requesting convergence, then retry |
| State corrupted | Rebuild from progress markdown files and changes.log |
| Agent failed | Re-spawn agent with previous context |
| Conflicting results | Orchestrator sends reconciliation request |
| Missing files | RA/EP agents identify and request clarification |
| Max iterations reached | Generate summary with remaining issues documented |
## Coordinator Checklist
### Before Each Phase
- [ ] Read phase reference document
- [ ] Check current state for dependencies
- [ ] Update TodoWrite with phase tasks
### After Each Phase
- [ ] Parse agent outputs (PHASE_RESULT)
- [ ] Update master state file
- [ ] Collapse TodoWrite sub-tasks
- [ ] Determine next action (continue / iterate / complete)
## Reference Documents
| Document | Purpose |
|----------|---------|
| [roles/](roles/) | Agent role definitions (RA, EP, CD, VAS) |
## Usage
```bash
@@ -172,23 +342,3 @@ Permanent audit log (append-only, never deleted):
# Auto mode
/parallel-dev-cycle --auto TASK="Add OAuth authentication"
```
## Key Benefits
- **Simple**: Each agent maintains only 1 file + changes.log
- **Efficient**: Version rewrite without complex version marking
- **Traceable**: Complete history in `history/` and `changes.log`
- **Fast**: Agent reads current version quickly (no history parsing needed)
- **Auditable**: NDJSON changes.log fully traces every change
- **Self-Enhancing**: RA agent proactively extends requirements
- **Debug-Ready**: CD agent supports hypothesis-driven debugging
## Reference Documents
| Document | Purpose |
|----------|---------|
| [phases/orchestrator.md](phases/orchestrator.md) | Orchestrator logic |
| [phases/state-schema.md](phases/state-schema.md) | State structure definition |
| [phases/agents/](phases/agents/) | Four agent role definitions |
| [specs/coordination-protocol.md](specs/coordination-protocol.md) | Communication protocol |
| [specs/versioning-strategy.md](specs/versioning-strategy.md) | Version management |

View File

@@ -0,0 +1,159 @@
# Phase 1: Session Initialization
Create or resume a development cycle, initialize state file and directory structure.
## Objective
- Parse user arguments (TASK, --cycle-id, --extend, --auto, --parallel)
- Create new cycle with unique ID OR resume existing cycle
- Initialize directory structure for all agents
- Create master state file
- Output: cycleId, state, progressDir
## Execution
### Step 1.1: Parse Arguments
```javascript
const { cycleId: existingCycleId, task, mode = 'interactive', extension } = options
// Validate mutual exclusivity
if (!existingCycleId && !task) {
console.error('Either --cycle-id or task description is required')
return { status: 'error', message: 'Missing cycleId or task' }
}
```
### Step 1.2: Utility Functions
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
function readCycleState(cycleId) {
const stateFile = `.workflow/.cycle/${cycleId}.json`
if (!fs.existsSync(stateFile)) {
return null
}
return JSON.parse(Read(stateFile))
}
```
### Step 1.3: New Cycle Creation
When `TASK` is provided (no `--cycle-id`):
```javascript
// Generate unique cycle ID
const timestamp = getUtc8ISOString().replace(/[-:]/g, '').split('.')[0]
const random = Math.random().toString(36).substring(2, 10)
const cycleId = `cycle-v1-${timestamp}-${random}`
console.log(`Creating new cycle: ${cycleId}`)
```
#### Create Directory Structure
```bash
mkdir -p .workflow/.cycle/${cycleId}.progress/{ra,ep,cd,vas,coordination}
mkdir -p .workflow/.cycle/${cycleId}.progress/ra/history
mkdir -p .workflow/.cycle/${cycleId}.progress/ep/history
mkdir -p .workflow/.cycle/${cycleId}.progress/cd/history
mkdir -p .workflow/.cycle/${cycleId}.progress/vas/history
```
#### Initialize State File
```javascript
function createCycleState(cycleId, taskDescription) {
const stateFile = `.workflow/.cycle/${cycleId}.json`
const now = getUtc8ISOString()
const state = {
// Metadata
cycle_id: cycleId,
title: taskDescription.substring(0, 100),
description: taskDescription,
max_iterations: 5,
status: 'running',
created_at: now,
updated_at: now,
// Agent tracking
agents: {
ra: { status: 'idle', output_files: [] },
ep: { status: 'idle', output_files: [] },
cd: { status: 'idle', output_files: [] },
vas: { status: 'idle', output_files: [] }
},
// Phase tracking
current_phase: 'init',
completed_phases: [],
current_iteration: 0,
// Shared context (populated by agents)
requirements: null,
exploration: null,
plan: null,
changes: [],
test_results: null
}
Write(stateFile, JSON.stringify(state, null, 2))
return state
}
```
### Step 1.4: Resume Existing Cycle
When `--cycle-id` is provided:
```javascript
const cycleId = existingCycleId
const state = readCycleState(cycleId)
if (!state) {
console.error(`Cycle not found: ${cycleId}`)
return { status: 'error', message: 'Cycle not found' }
}
console.log(`Resuming cycle: ${cycleId}`)
// Apply extension if provided
if (extension) {
console.log(`Extension: ${extension}`)
state.description += `\n\n--- ITERATION ${state.current_iteration + 1} ---\n${extension}`
}
```
### Step 1.5: Control Signal Check
Before proceeding, verify cycle status allows continuation:
```javascript
function checkControlSignals(cycleId) {
const state = readCycleState(cycleId)
switch (state?.status) {
case 'paused':
return { continue: false, action: 'pause_exit' }
case 'failed':
return { continue: false, action: 'stop_exit' }
case 'running':
return { continue: true, action: 'continue' }
default:
return { continue: false, action: 'stop_exit' }
}
}
```
## Output
- **Variable**: `cycleId` - Unique cycle identifier
- **Variable**: `state` - Initialized or resumed cycle state object
- **Variable**: `progressDir` - `.workflow/.cycle/${cycleId}.progress`
- **TodoWrite**: Mark Phase 1 completed, Phase 2 in_progress
## Next Phase
Return to orchestrator, then auto-continue to [Phase 2: Agent Execution](02-agent-execution.md).

View File

@@ -0,0 +1,309 @@
# Phase 2: Agent Execution (Parallel)
Spawn four specialized agents in parallel and wait for all to complete with timeout handling.
## Objective
- Spawn RA, EP, CD, VAS agents simultaneously using Codex subagent pattern
- Pass cycle context and role references to each agent
- Wait for all agents with configurable timeout
- Handle timeout with convergence request
- Output: agentOutputs from all 4 agents
## Agent Role References
Each agent reads its detailed role definition at execution time:
| Agent | Role File | Main Output |
|-------|-----------|-------------|
| RA | [roles/requirements-analyst.md](../roles/requirements-analyst.md) | requirements.md |
| EP | [roles/exploration-planner.md](../roles/exploration-planner.md) | exploration.md, architecture.md, plan.json |
| CD | [roles/code-developer.md](../roles/code-developer.md) | implementation.md |
| VAS | [roles/validation-archivist.md](../roles/validation-archivist.md) | summary.md |
## Execution
### Step 2.1: Spawn RA Agent (Requirements Analyst)
```javascript
function spawnRAAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/requirements-analyst.md
2. Read: .workflow/project-tech.json (if exists)
3. Read: .workflow/project-guidelines.json (if exists)
4. Read: .workflow/.cycle/${cycleId}.progress/coordination/feedback.md (if exists)
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/ra/
- **Current Iteration**: ${state.current_iteration}
- **Task Description**: ${state.description}
## CURRENT REQUIREMENTS STATE
${state.requirements ? JSON.stringify(state.requirements, null, 2) : 'No previous requirements'}
## YOUR ROLE
Requirements Analyst - Analyze and refine requirements throughout the cycle.
## RESPONSIBILITIES
1. Analyze initial task description
2. Generate comprehensive requirements specification
3. Identify edge cases and implicit requirements
4. Track requirement changes across iterations
5. Maintain requirements.md and changes.log
## DELIVERABLES
Write files to ${progressDir}/ra/:
- requirements.md: Full requirements specification
- edge-cases.md: Edge case analysis
- changes.log: NDJSON format change tracking
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: ra
- status: success | failed
- files_written: [list]
- summary: one-line summary
- issues: []
\`\`\`
`
})
}
```
### Step 2.2: Spawn EP Agent (Exploration & Planning)
```javascript
function spawnEPAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/exploration-planner.md
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
4. Read: ${progressDir}/ra/requirements.md
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/ep/
- **Requirements**: See requirements.md
- **Current Plan**: ${state.plan ? 'Existing' : 'None - first iteration'}
## YOUR ROLE
Exploration & Planning Agent - Explore architecture and generate implementation plan.
## RESPONSIBILITIES
1. Explore codebase architecture
2. Map integration points
3. Design implementation approach
4. Generate plan.json with task breakdown
5. Update or iterate on existing plan
## DELIVERABLES
Write files to ${progressDir}/ep/:
- exploration.md: Codebase exploration findings
- architecture.md: Architecture design
- plan.json: Implementation plan (structured)
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: ep
- status: success | failed
- files_written: [list]
- summary: one-line summary
- plan_version: X.Y.Z
\`\`\`
`
})
}
```
### Step 2.3: Spawn CD Agent (Code Developer)
```javascript
function spawnCDAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/code-developer.md
2. Read: ${progressDir}/ep/plan.json
3. Read: ${progressDir}/ra/requirements.md
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/cd/
- **Plan Version**: ${state.plan?.version || 'N/A'}
- **Previous Changes**: ${state.changes?.length || 0} files
## YOUR ROLE
Code Developer - Implement features based on plan and requirements.
## RESPONSIBILITIES
1. Implement features from plan
2. Track code changes
3. Handle integration issues
4. Maintain code quality
5. Report implementation progress and issues
## DELIVERABLES
Write files to ${progressDir}/cd/:
- implementation.md: Implementation progress and decisions
- changes.log: NDJSON format, each line: {file, action, timestamp}
- issues.md: Development issues and blockers
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: cd
- status: success | failed | partial
- files_changed: [count]
- summary: one-line summary
- blockers: []
\`\`\`
`
})
}
```
### Step 2.4: Spawn VAS Agent (Validation & Archival)
```javascript
function spawnVASAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/validation-archivist.md
2. Read: ${progressDir}/cd/changes.log
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/vas/
- **Changes Count**: ${state.changes?.length || 0}
- **Iteration**: ${state.current_iteration}
## YOUR ROLE
Validation & Archival Specialist - Validate quality and create documentation.
## RESPONSIBILITIES
1. Run tests on implemented features
2. Generate coverage reports
3. Create archival documentation
4. Summarize cycle results
5. Generate version history
## DELIVERABLES
Write files to ${progressDir}/vas/:
- validation.md: Test validation results
- test-results.json: Detailed test results
- coverage.md: Coverage report
- summary.md: Cycle summary and recommendations
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: vas
- status: success | failed
- test_pass_rate: X%
- coverage: X%
- issues: []
\`\`\`
`
})
}
```
### Step 2.5: Launch All Agents & Wait
```javascript
// Spawn all 4 agents in parallel
console.log('Spawning agents...')
const agents = {
ra: spawnRAAgent(cycleId, state, progressDir),
ep: spawnEPAgent(cycleId, state, progressDir),
cd: spawnCDAgent(cycleId, state, progressDir),
vas: spawnVASAgent(cycleId, state, progressDir)
}
// Wait for all agents to complete
console.log('Waiting for all agents...')
const results = wait({
ids: [agents.ra, agents.ep, agents.cd, agents.vas],
timeout_ms: 1800000 // 30 minutes
})
```
### Step 2.6: Timeout Handling
```javascript
if (results.timed_out) {
console.log('Some agents timed out, sending convergence request...')
Object.entries(agents).forEach(([name, id]) => {
if (!results.status[id].completed) {
send_input({
id: id,
message: `
## TIMEOUT NOTIFICATION
Execution timeout reached. Please:
1. Output current progress to markdown file
2. Save all state updates
3. Return completion status
`
})
}
})
}
```
## Output
- **Variable**: `agents` - Map of agent names to agent IDs
- **Variable**: `results` - Wait results with completion status for each agent
- **Variable**: `agentOutputs` - Collected outputs from all 4 agents
- **TodoWrite**: Mark Phase 2 completed, Phase 3 in_progress
## Next Phase
Return to orchestrator, then auto-continue to [Phase 3: Result Aggregation & Iteration](03-result-aggregation.md).

View File

@@ -0,0 +1,230 @@
# Phase 3: Result Aggregation & Iteration
Parse agent outputs, detect issues, generate feedback, and manage the iteration loop.
## Objective
- Parse PHASE_RESULT from each agent's output
- Aggregate results into unified state
- Detect issues (test failures, blockers)
- Generate targeted feedback for affected agents
- Manage iteration loop (continue or proceed to completion)
- Output: parsedResults, iteration decision
## Execution
### Step 3.1: Collect Agent Outputs
```javascript
// Collect outputs from all 4 agents
const agentOutputs = {
ra: results.status[agents.ra].completed,
ep: results.status[agents.ep].completed,
cd: results.status[agents.cd].completed,
vas: results.status[agents.vas].completed
}
```
### Step 3.2: Parse PHASE_RESULT
Each agent outputs a structured PHASE_RESULT block. Parse it to extract status and data:
```javascript
function parseAgentOutputs(agentOutputs) {
const results = {
ra: parseOutput(agentOutputs.ra, 'ra'),
ep: parseOutput(agentOutputs.ep, 'ep'),
cd: parseOutput(agentOutputs.cd, 'cd'),
vas: parseOutput(agentOutputs.vas, 'vas')
}
return results
}
function parseOutput(output, agent) {
const result = {
agent: agent,
status: 'unknown',
data: {}
}
// Parse PHASE_RESULT block
const match = output.match(/PHASE_RESULT:\s*([\s\S]*?)(?:\n\n|$)/)
if (match) {
const lines = match[1].split('\n')
for (const line of lines) {
const m = line.match(/^-\s*(\w+):\s*(.+)$/)
if (m) {
result[m[1]] = m[2].trim()
}
}
}
return result
}
```
### Step 3.3: Update State with Results
```javascript
// Update agent states
state.agents.ra.status = 'completed'
state.agents.ep.status = 'completed'
state.agents.cd.status = 'completed'
state.agents.vas.status = 'completed'
// Update shared context from parsed results
state.requirements = parsedResults.ra.requirements
state.exploration = parsedResults.ep.exploration
state.plan = parsedResults.ep.plan
state.changes = parsedResults.cd.changes
state.test_results = parsedResults.vas.test_results
state.completed_phases.push(...['ra', 'ep', 'cd', 'vas'])
state.updated_at = getUtc8ISOString()
// Persist state
Write(`.workflow/.cycle/${cycleId}.json`, JSON.stringify(state, null, 2))
```
### Step 3.4: Issue Detection
```javascript
const hasIssues = parsedResults.vas.test_results?.passed === false ||
parsedResults.cd.issues?.length > 0
if (hasIssues && iteration < maxIterations) {
console.log('Issues detected, preparing for next iteration...')
// → Proceed to Step 3.5 (Feedback Generation)
} else if (!hasIssues) {
console.log('All phases completed successfully')
// → Proceed to Phase 4
} else if (iteration >= maxIterations) {
console.log(`Reached maximum iterations (${maxIterations})`)
// → Proceed to Phase 4 with issues documented
}
```
### Step 3.5: Feedback Generation
Generate targeted feedback based on issue type:
```javascript
function generateFeedback(parsedResults) {
const feedback = {}
// Check VAS results → feedback to CD
if (parsedResults.vas.test_pass_rate < 100) {
feedback.cd = `
## FEEDBACK FROM VALIDATION
Test pass rate: ${parsedResults.vas.test_pass_rate}%
## ISSUES TO FIX
${parsedResults.vas.data.issues || 'See test-results.json for details'}
## NEXT STEP
Fix failing tests and update implementation.md with resolution.
`
}
// Check CD blockers → feedback to RA
if (parsedResults.cd.blockers?.length > 0) {
feedback.ra = `
## FEEDBACK FROM DEVELOPMENT
Blockers encountered:
${parsedResults.cd.blockers.map(b => `- ${b}`).join('\n')}
## NEXT STEP
Clarify requirements or identify alternative approaches.
Update requirements.md if needed.
`
}
return feedback
}
```
### Step 3.6: Send Feedback via send_input
```javascript
const feedback = generateFeedback(parsedResults)
// Send feedback to relevant agents
if (feedback.ra) {
send_input({
id: agents.ra,
message: feedback.ra
})
}
if (feedback.cd) {
send_input({
id: agents.cd,
message: feedback.cd
})
}
// Wait for agents to process feedback and update
const updatedResults = wait({
ids: [agents.ra, agents.cd].filter(Boolean),
timeout_ms: 900000 // 15 minutes for fixes
})
console.log('Agents updated, continuing...')
```
### Step 3.7: Iteration Loop Decision
```javascript
// After feedback processing, decide next action:
//
// Option A: Issues remain AND iteration < max
// → Loop back to Phase 2 (re-spawn or continue agents)
//
// Option B: No issues remaining
// → Proceed to Phase 4 (Completion)
//
// Option C: Max iterations reached
// → Proceed to Phase 4 with issues documented
if (hasIssues && iteration < maxIterations) {
// Continue iteration loop
iteration++
state.current_iteration = iteration
// → Back to Phase 2
} else {
// Exit loop → Phase 4
continueLoop = false
}
```
## Iteration Flow Diagram
```
Phase 2: Agent Execution
Phase 3: Result Aggregation
┌─ Issues detected?
│ ├─ No → Phase 4 (Complete)
│ └─ Yes
│ ├─ iteration < max?
│ │ ├─ Yes → Generate feedback → send_input → Wait → Back to Phase 2
│ │ └─ No → Phase 4 (Complete with issues)
```
## Output
- **Variable**: `parsedResults` - Parsed results from all 4 agents
- **Variable**: `hasIssues` - Boolean indicating if issues were found
- **Variable**: `continueLoop` - Boolean indicating if iteration should continue
- **TodoWrite**: Mark Phase 3 completed, Phase 4 in_progress (or loop)
## Next Phase
If iteration continues: Return to Phase 2.
If iteration completes: Return to orchestrator, then auto-continue to [Phase 4: Completion & Summary](04-completion-summary.md).

View File

@@ -0,0 +1,109 @@
# Phase 4: Completion & Summary
Generate unified summary report, update final state, close all agents, and provide continuation instructions.
## Objective
- Generate comprehensive cycle summary report
- Update master state file with final status
- Close all agent sessions
- Provide continuation instructions for future iterations
- Output: final cycle report
## Execution
### Step 4.1: Generate Final Summary
```javascript
function generateFinalSummary(cycleId, state) {
const summaryFile = `.workflow/.cycle/${cycleId}.progress/coordination/summary.md`
const summary = `# Cycle Summary - ${cycleId}
## Metadata
- Cycle ID: ${cycleId}
- Started: ${state.created_at}
- Completed: ${state.completed_at}
- Iterations: ${state.current_iteration}
- Status: ${state.status}
## Phase Results
- Requirements Analysis: ✓ Completed
- Exploration & Planning: ✓ Completed
- Code Development: ✓ Completed
- Validation & Archival: ✓ Completed
## Key Deliverables
- Requirements: ${state.requirements ? '✓' : '✗'}
- Architecture Plan: ${state.plan ? '✓' : '✗'}
- Code Changes: ${state.changes?.length || 0} files
- Test Results: ${state.test_results?.pass_rate || '0'}% passing
## Generated Files
- .workflow/.cycle/${cycleId}.progress/ra/requirements.md
- .workflow/.cycle/${cycleId}.progress/ep/plan.json
- .workflow/.cycle/${cycleId}.progress/cd/changes.log
- .workflow/.cycle/${cycleId}.progress/vas/summary.md
## Continuation Instructions
To extend this cycle:
\`\`\`bash
/parallel-dev-cycle --cycle-id=${cycleId} --extend="New requirement or feedback"
\`\`\`
This will spawn agents for iteration ${state.current_iteration + 1}.
`
Write(summaryFile, summary)
}
```
### Step 4.2: Update Final State
```javascript
state.status = 'completed'
state.completed_at = getUtc8ISOString()
Write(`.workflow/.cycle/${cycleId}.json`, JSON.stringify(state, null, 2))
```
### Step 4.3: Close All Agents
```javascript
Object.values(agents).forEach(id => {
try {
close_agent({ id })
} catch (e) {
console.warn(`Failed to close agent ${id}`)
}
})
```
### Step 4.4: Return Result
```javascript
console.log('\n=== Parallel Dev Cycle Orchestrator Finished ===')
return {
status: 'completed',
cycle_id: cycleId,
iterations: iteration,
final_state: state
}
```
## Output
- **File**: `.workflow/.cycle/{cycleId}.progress/coordination/summary.md`
- **File**: `.workflow/.cycle/{cycleId}.json` (final state)
- **TodoWrite**: Mark Phase 4 completed (all tasks done)
## Completion
Parallel Dev Cycle has completed. The cycle report is at `.workflow/.cycle/{cycleId}.progress/coordination/summary.md`.
To continue iterating:
```bash
/parallel-dev-cycle --cycle-id={cycleId} --extend="Additional requirements or feedback"
```

View File

@@ -1,696 +0,0 @@
# Orchestrator - Multi-Agent Coordination (Codex Pattern)
Orchestrate parallel dev cycle using Codex subagent pattern with continuous iteration support.
## Role
Coordinate four specialized agents → Manage state → Support continuous iteration → Generate unified documentation.
## Codex Pattern Overview
```
Main Orchestrator Flow:
┌─── spawn_agent (orchestrator role) ────────────────────────────┐
│ │
│ Phase 1: INIT (Check control signals) │
│ ↓ │
│ wait() → Parse cycle state │
│ ↓ │
│ Phase 2: AGENT ORCHESTRATION │
│ ↓ │
│ spawn_agent(RA) | spawn_agent(EP) │
│ spawn_agent(CD) | spawn_agent(VAS) │
│ ↓ │
│ wait({ ids: [RA, EP, CD, VAS] }) → Collect all results │
│ ↓ │
│ Phase 3: ITERATION HANDLING │
│ ↓ │
│ [If extension needed] │
│ send_input to affected agents │
│ wait() for updated results │
│ ↓ │
│ Phase 4: AGGREGATION │
│ ↓ │
│ Merge all outputs → Generate unified documentation │
│ ↓ │
│ Update cycle state │
│ ↓ │
│ [Loop if more iterations] │
│ ↓ │
│ close_agent() when complete │
│ │
└─────────────────────────────────────────────────────────────────┘
```
## State Management
### Read Cycle State
```javascript
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
function readCycleState(cycleId) {
const stateFile = `.workflow/.cycle/${cycleId}.json`
if (!fs.existsSync(stateFile)) {
return null
}
return JSON.parse(Read(stateFile))
}
```
### Create New Cycle State
```javascript
function createCycleState(cycleId, taskDescription) {
const stateFile = `.workflow/.cycle/${cycleId}.json`
const now = getUtc8ISOString()
const state = {
// Metadata
cycle_id: cycleId,
title: taskDescription.substring(0, 100),
description: taskDescription,
max_iterations: 5,
status: 'running',
created_at: now,
updated_at: now,
// Agent tracking
agents: {
ra: { status: 'idle', output_files: [] },
ep: { status: 'idle', output_files: [] },
cd: { status: 'idle', output_files: [] },
vas: { status: 'idle', output_files: [] }
},
// Phase tracking
current_phase: 'init',
completed_phases: [],
current_iteration: 0,
// Shared context (populated by agents)
requirements: null,
exploration: null,
plan: null,
changes: [],
test_results: null
}
// Create directories
mkdir -p `.workflow/.cycle/${cycleId}.progress/{ra,ep,cd,vas,coordination}`
Write(stateFile, JSON.stringify(state, null, 2))
return state
}
```
## Main Execution Flow (Codex Subagent)
```javascript
async function runOrchestrator(options = {}) {
const { cycleId: existingCycleId, task, mode = 'interactive', extension } = options
console.log('=== Parallel Dev Cycle Orchestrator Started ===')
// 1. Determine cycleId and initial state
let cycleId
let state
if (existingCycleId) {
// Continue existing cycle
cycleId = existingCycleId
state = readCycleState(cycleId)
if (!state) {
console.error(`Cycle not found: ${cycleId}`)
return { status: 'error', message: 'Cycle not found' }
}
console.log(`Resuming cycle: ${cycleId}`)
if (extension) {
console.log(`Extension: ${extension}`)
state.description += `\n\n--- ITERATION ${state.current_iteration + 1} ---\n${extension}`
}
} else if (task) {
// Create new cycle
const timestamp = getUtc8ISOString().replace(/[-:]/g, '').split('.')[0]
const random = Math.random().toString(36).substring(2, 10)
cycleId = `cycle-v1-${timestamp}-${random}`
console.log(`Creating new cycle: ${cycleId}`)
state = createCycleState(cycleId, task)
} else {
console.error('Either --cycle-id or task description is required')
return { status: 'error', message: 'Missing cycleId or task' }
}
const progressDir = `.workflow/.cycle/${cycleId}.progress`
// 2. Main orchestration loop
let iteration = state.current_iteration || 0
const maxIterations = state.max_iterations || 5
let continueLoop = true
while (continueLoop && iteration < maxIterations) {
iteration++
state.current_iteration = iteration
console.log(`\n========== ITERATION ${iteration} ==========`)
// 3. Spawn four agents in parallel
console.log('Spawning agents...')
const agents = {
ra: spawnRAAgent(cycleId, state, progressDir),
ep: spawnEPAgent(cycleId, state, progressDir),
cd: spawnCDAgent(cycleId, state, progressDir),
vas: spawnVASAgent(cycleId, state, progressDir)
}
// 4. Wait for all agents to complete
console.log('Waiting for all agents...')
const results = wait({
ids: [agents.ra, agents.ep, agents.cd, agents.vas],
timeout_ms: 1800000 // 30 minutes
})
if (results.timed_out) {
console.log('Some agents timed out, sending convergence request...')
Object.entries(agents).forEach(([name, id]) => {
if (!results.status[id].completed) {
send_input({
id: id,
message: `
## TIMEOUT NOTIFICATION
Execution timeout reached. Please:
1. Output current progress to markdown file
2. Save all state updates
3. Return completion status
`
})
}
})
continue
}
// 5. Collect all agent outputs
const agentOutputs = {
ra: results.status[agents.ra].completed,
ep: results.status[agents.ep].completed,
cd: results.status[agents.cd].completed,
vas: results.status[agents.vas].completed
}
// 6. Parse and aggregate results
const parsedResults = parseAgentOutputs(agentOutputs)
// Update state with agent results
state.agents.ra.status = 'completed'
state.agents.ep.status = 'completed'
state.agents.cd.status = 'completed'
state.agents.vas.status = 'completed'
state.requirements = parsedResults.ra.requirements
state.exploration = parsedResults.ep.exploration
state.plan = parsedResults.ep.plan
state.changes = parsedResults.cd.changes
state.test_results = parsedResults.vas.test_results
state.completed_phases.push(...['ra', 'ep', 'cd', 'vas'])
state.updated_at = getUtc8ISOString()
// Save state
Write(`.workflow/.cycle/${cycleId}.json`, JSON.stringify(state, null, 2))
// 7. Check for issues and determine next iteration
const hasIssues = parsedResults.vas.test_results?.passed === false ||
parsedResults.cd.issues?.length > 0
if (hasIssues && iteration < maxIterations) {
console.log('Issues detected, preparing for next iteration...')
// Generate feedback for agents
const feedback = generateFeedback(parsedResults)
// Send feedback to relevant agents
if (feedback.ra) {
send_input({
id: agents.ra,
message: feedback.ra
})
}
if (feedback.cd) {
send_input({
id: agents.cd,
message: feedback.cd
})
}
// Wait for updates
const updatedResults = wait({
ids: [agents.ra, agents.cd].filter(Boolean),
timeout_ms: 900000
})
console.log('Agents updated, continuing...')
} else if (!hasIssues) {
console.log('All phases completed successfully')
continueLoop = false
} else if (iteration >= maxIterations) {
console.log(`Reached maximum iterations (${maxIterations})`)
continueLoop = false
}
}
// 8. Generate unified summary
console.log('Generating final summary...')
generateFinalSummary(cycleId, state)
// 9. Update final state
state.status = 'completed'
state.completed_at = getUtc8ISOString()
Write(`.workflow/.cycle/${cycleId}.json`, JSON.stringify(state, null, 2))
// 10. Cleanup
Object.values(agents).forEach(id => {
try {
close_agent({ id })
} catch (e) {
console.warn(`Failed to close agent ${id}`)
}
})
console.log('\n=== Parallel Dev Cycle Orchestrator Finished ===')
return {
status: 'completed',
cycle_id: cycleId,
iterations: iteration,
final_state: state
}
}
```
## Agent Spawning Functions
### Spawn RA Agent
```javascript
function spawnRAAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/requirements-analyst.md
2. Read: .workflow/project-tech.json (if exists)
3. Read: .workflow/project-guidelines.json (if exists)
4. Read: .workflow/.cycle/${cycleId}.progress/coordination/feedback.md (if exists)
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/ra/
- **Current Iteration**: ${state.current_iteration}
- **Task Description**: ${state.description}
## CURRENT REQUIREMENTS STATE
${state.requirements ? JSON.stringify(state.requirements, null, 2) : 'No previous requirements'}
## YOUR ROLE
Requirements Analyst - Analyze and refine requirements throughout the cycle.
## RESPONSIBILITIES
1. Analyze initial task description
2. Generate comprehensive requirements specification
3. Identify edge cases and implicit requirements
4. Track requirement changes across iterations
5. Maintain requirements.md and changes.log
## DELIVERABLES
Write files to ${progressDir}/ra/:
- requirements.md: Full requirements specification
- edge-cases.md: Edge case analysis
- changes.log: NDJSON format change tracking
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: ra
- status: success | failed
- files_written: [list]
- summary: one-line summary
- issues: []
\`\`\`
`
})
}
```
### Spawn EP Agent
```javascript
function spawnEPAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/exploration-planner.md
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
4. Read: ${progressDir}/ra/requirements.md
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/ep/
- **Requirements**: See requirements.md
- **Current Plan**: ${state.plan ? 'Existing' : 'None - first iteration'}
## YOUR ROLE
Exploration & Planning Agent - Explore architecture and generate implementation plan.
## RESPONSIBILITIES
1. Explore codebase architecture
2. Map integration points
3. Design implementation approach
4. Generate plan.json with task breakdown
5. Update or iterate on existing plan
## DELIVERABLES
Write files to ${progressDir}/ep/:
- exploration.md: Codebase exploration findings
- architecture.md: Architecture design
- plan.json: Implementation plan (structured)
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: ep
- status: success | failed
- files_written: [list]
- summary: one-line summary
- plan_version: X.Y.Z
\`\`\`
`
})
}
```
### Spawn CD Agent
```javascript
function spawnCDAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/code-developer.md
2. Read: ${progressDir}/ep/plan.json
3. Read: ${progressDir}/ra/requirements.md
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/cd/
- **Plan Version**: ${state.plan?.version || 'N/A'}
- **Previous Changes**: ${state.changes?.length || 0} files
## YOUR ROLE
Code Developer - Implement features based on plan and requirements.
## RESPONSIBILITIES
1. Implement features from plan
2. Track code changes
3. Handle integration issues
4. Maintain code quality
5. Report implementation progress and issues
## DELIVERABLES
Write files to ${progressDir}/cd/:
- implementation.md: Implementation progress and decisions
- changes.log: NDJSON format, each line: {file, action, timestamp}
- issues.md: Development issues and blockers
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: cd
- status: success | failed | partial
- files_changed: [count]
- summary: one-line summary
- blockers: []
\`\`\`
`
})
}
```
### Spawn VAS Agent
```javascript
function spawnVASAgent(cycleId, state, progressDir) {
return spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/validation-archivist.md
2. Read: ${progressDir}/cd/changes.log
---
## CYCLE CONTEXT
- **Cycle ID**: ${cycleId}
- **Progress Dir**: ${progressDir}/vas/
- **Changes Count**: ${state.changes?.length || 0}
- **Iteration**: ${state.current_iteration}
## YOUR ROLE
Validation & Archival Specialist - Validate quality and create documentation.
## RESPONSIBILITIES
1. Run tests on implemented features
2. Generate coverage reports
3. Create archival documentation
4. Summarize cycle results
5. Generate version history
## DELIVERABLES
Write files to ${progressDir}/vas/:
- validation.md: Test validation results
- test-results.json: Detailed test results
- coverage.md: Coverage report
- summary.md: Cycle summary and recommendations
## OUTPUT FORMAT
\`\`\`
PHASE_RESULT:
- phase: vas
- status: success | failed
- test_pass_rate: X%
- coverage: X%
- issues: []
\`\`\`
`
})
}
```
## Result Parsing
```javascript
function parseAgentOutputs(agentOutputs) {
const results = {
ra: parseOutput(agentOutputs.ra, 'ra'),
ep: parseOutput(agentOutputs.ep, 'ep'),
cd: parseOutput(agentOutputs.cd, 'cd'),
vas: parseOutput(agentOutputs.vas, 'vas')
}
return results
}
function parseOutput(output, agent) {
const result = {
agent: agent,
status: 'unknown',
data: {}
}
// Parse PHASE_RESULT block
const match = output.match(/PHASE_RESULT:\s*([\s\S]*?)(?:\n\n|$)/)
if (match) {
const lines = match[1].split('\n')
for (const line of lines) {
const m = line.match(/^-\s*(\w+):\s*(.+)$/)
if (m) {
result[m[1]] = m[2].trim()
}
}
}
return result
}
```
## Feedback Generation
```javascript
function generateFeedback(parsedResults) {
const feedback = {}
// Check VAS results
if (parsedResults.vas.test_pass_rate < 100) {
feedback.cd = `
## FEEDBACK FROM VALIDATION
Test pass rate: ${parsedResults.vas.test_pass_rate}%
## ISSUES TO FIX
${parsedResults.vas.data.issues || 'See test-results.json for details'}
## NEXT STEP
Fix failing tests and update implementation.md with resolution.
`
}
// Check CD blockers
if (parsedResults.cd.blockers?.length > 0) {
feedback.ra = `
## FEEDBACK FROM DEVELOPMENT
Blockers encountered:
${parsedResults.cd.blockers.map(b => `- ${b}`).join('\n')}
## NEXT STEP
Clarify requirements or identify alternative approaches.
Update requirements.md if needed.
`
}
return feedback
}
```
## Summary Generation
```javascript
function generateFinalSummary(cycleId, state) {
const summaryFile = `.workflow/.cycle/${cycleId}.progress/coordination/summary.md`
const summary = `# Cycle Summary - ${cycleId}
## Metadata
- Cycle ID: ${cycleId}
- Started: ${state.created_at}
- Completed: ${state.completed_at}
- Iterations: ${state.current_iteration}
- Status: ${state.status}
## Phase Results
- Requirements Analysis: ✓ Completed
- Exploration & Planning: ✓ Completed
- Code Development: ✓ Completed
- Validation & Archival: ✓ Completed
## Key Deliverables
- Requirements: ${state.requirements ? '✓' : '✗'}
- Architecture Plan: ${state.plan ? '✓' : '✗'}
- Code Changes: ${state.changes?.length || 0} files
- Test Results: ${state.test_results?.pass_rate || '0'}% passing
## Generated Files
- .workflow/.cycle/${cycleId}.progress/ra/requirements.md
- .workflow/.cycle/${cycleId}.progress/ep/plan.json
- .workflow/.cycle/${cycleId}.progress/cd/changes.log
- .workflow/.cycle/${cycleId}.progress/vas/summary.md
## Continuation Instructions
To extend this cycle:
\`\`\`bash
/parallel-dev-cycle --cycle-id=${cycleId} --extend="New requirement or feedback"
\`\`\`
This will spawn agents for iteration ${state.current_iteration + 1}.
`
Write(summaryFile, summary)
}
```
## Control Signal Checking
```javascript
function checkControlSignals(cycleId) {
const state = readCycleState(cycleId)
switch (state?.status) {
case 'paused':
return { continue: false, action: 'pause_exit' }
case 'failed':
return { continue: false, action: 'stop_exit' }
case 'running':
return { continue: true, action: 'continue' }
default:
return { continue: false, action: 'stop_exit' }
}
}
```
## Error Recovery Strategies
| Error Type | Recovery |
|------------|----------|
| Agent timeout | send_input requesting convergence |
| State corrupted | Rebuild from progress markdown files |
| Agent failed | Re-spawn agent with previous context |
| Conflicting results | Orchestrator sends reconciliation request |
| Missing files | RA/EP agents identify and request clarification |
## Codex Best Practices Applied
1. **Single Orchestrator**: One main agent manages all phases
2. **Parallel Workers**: Four specialized agents execute simultaneously
3. **Batch wait()**: Wait for all agents with `wait({ ids: [...] })`
4. **Deep Interaction**: Use send_input for iteration and refinement
5. **Delayed close_agent**: Only after all phases and iterations complete
6. **Role Path Passing**: Each agent reads its own role definition
7. **Persistent Context**: Cycle state shared across all agents

View File

@@ -1,436 +0,0 @@
# State Schema - Parallel Dev Cycle
Unified cycle state structure for multi-agent coordination and iteration support.
## State File Location
**Location**: `.workflow/.cycle/{cycleId}.json` (unified state, all agents access)
**Format**: JSON
## Cycle State Interface
```typescript
interface CycleState {
// =====================================================
// CORE METADATA
// =====================================================
cycle_id: string // Unique cycle identifier
title: string // Task title (first 100 chars)
description: string // Full task description
task_history: string[] // All task descriptions across iterations
// =====================================================
// STATUS & TIMING
// =====================================================
status: 'created' | 'running' | 'paused' | 'completed' | 'failed'
created_at: string // ISO8601 format
updated_at: string // ISO8601 format
completed_at?: string // ISO8601 format
max_iterations: number // Maximum iteration limit
current_iteration: number // Current iteration count
failure_reason?: string // If failed, why
// =====================================================
// MULTI-AGENT TRACKING
// =====================================================
agents: {
ra: AgentState // Requirements Analyst
ep: AgentState // Exploration Planner
cd: AgentState // Code Developer
vas: AgentState // Validation Archivist
}
// =====================================================
// PHASE TRACKING
// =====================================================
current_phase: 'init' | 'ra' | 'ep' | 'cd' | 'vas' | 'aggregation' | 'complete'
completed_phases: string[]
phase_errors: Array<{
phase: string
error: string
timestamp: string
}>
// =====================================================
// SHARED CONTEXT (Populated by agents)
// =====================================================
requirements?: {
version: string // e.g., "1.0.0", "1.1.0"
specification: string // Full spec from requirements.md
edge_cases: string[]
last_updated: string
}
exploration?: {
version: string
architecture_summary: string
integration_points: string[]
identified_risks: string[]
last_updated: string
}
plan?: {
version: string
tasks: PlanTask[]
total_estimated_effort: string
critical_path: string[]
last_updated: string
}
changes?: {
total_files: number
changes: ChangeLog[]
iteration_markers: Record<number, string> // Iteration timestamps
}
test_results?: {
version: string
pass_rate: number // 0-100
coverage: number // 0-100
failed_tests: string[]
total_tests: number
last_run: string
}
// =====================================================
// ITERATION TRACKING
// =====================================================
iterations: IterationRecord[]
// =====================================================
// COORDINATION DATA
// =====================================================
coordination: {
feedback_log: FeedbackEntry[]
pending_decisions: Decision[]
blockers: Blocker[]
}
}
// =====================================================
// SUPPORTING TYPES
// =====================================================
interface AgentState {
status: 'idle' | 'running' | 'waiting' | 'completed' | 'failed'
started_at?: string
completed_at?: string
output_files: string[]
last_message?: string
error?: string
iterations_completed: number
}
interface PlanTask {
id: string // e.g., "TASK-001"
description: string
effort: 'small' | 'medium' | 'large'
depends_on: string[]
status: 'pending' | 'in_progress' | 'completed' | 'blocked'
assigned_to?: string // Agent name
files: string[]
}
interface ChangeLog {
timestamp: string
file: string
action: 'create' | 'modify' | 'delete'
iteration: number
agent: string // which agent made change
description: string
}
interface IterationRecord {
number: number
extension?: string // User feedback/extension for this iteration
started_at: string
completed_at: string
agent_results: Record<string, {
status: string
files_modified: number
}>
issues_found: string[]
resolved: boolean
}
interface FeedbackEntry {
timestamp: string
source: string // Agent or 'user'
target: string // Recipient agent
content: string
type: 'requirement_update' | 'bug_report' | 'issue_fix' | 'clarification'
}
interface Decision {
id: string
description: string
options: string[]
made_by?: string
chosen_option?: string
status: 'pending' | 'made' | 'implemented'
}
interface Blocker {
id: string
description: string
reported_by: string
status: 'open' | 'resolved' | 'workaround'
resolution?: string
}
```
## Initial State (New Cycle)
When creating a new cycle:
```json
{
"cycle_id": "cycle-v1-20260122T100000-abc123",
"title": "Implement OAuth authentication",
"description": "Add OAuth2 login support with Google and GitHub providers",
"task_history": [
"Implement OAuth authentication"
],
"status": "created",
"created_at": "2026-01-22T10:00:00+08:00",
"updated_at": "2026-01-22T10:00:00+08:00",
"max_iterations": 5,
"current_iteration": 0,
"agents": {
"ra": { "status": "idle", "output_files": [], "iterations_completed": 0 },
"ep": { "status": "idle", "output_files": [], "iterations_completed": 0 },
"cd": { "status": "idle", "output_files": [], "iterations_completed": 0 },
"vas": { "status": "idle", "output_files": [], "iterations_completed": 0 }
},
"current_phase": "init",
"completed_phases": [],
"phase_errors": [],
"iterations": [],
"coordination": {
"feedback_log": [],
"pending_decisions": [],
"blockers": []
}
}
```
## State Transitions
### Iteration 1: Initial Execution
```json
{
"status": "running",
"current_iteration": 1,
"current_phase": "ra",
"agents": {
"ra": { "status": "running", "started_at": "2026-01-22T10:05:00+08:00" },
"ep": { "status": "idle" },
"cd": { "status": "idle" },
"vas": { "status": "idle" }
},
"requirements": {
"version": "1.0.0",
"specification": "...",
"edge_cases": ["OAuth timeout handling", "PKCE validation"],
"last_updated": "2026-01-22T10:15:00+08:00"
},
"iterations": [{
"number": 1,
"started_at": "2026-01-22T10:00:00+08:00",
"agent_results": {
"ra": { "status": "completed", "files_modified": 3 },
"ep": { "status": "completed", "files_modified": 2 },
"cd": { "status": "partial", "files_modified": 5 },
"vas": { "status": "pending", "files_modified": 0 }
}
}]
}
```
### After Phase Completion
```json
{
"current_phase": "aggregation",
"completed_phases": ["ra", "ep", "cd", "vas"],
"plan": {
"version": "1.0.0",
"tasks": [
{
"id": "TASK-001",
"description": "Setup OAuth application credentials",
"effort": "small",
"status": "completed",
"files": ["src/config/oauth.ts"]
}
]
},
"changes": {
"total_files": 12,
"iteration_markers": {
"1": "2026-01-22T10:30:00+08:00"
}
},
"test_results": {
"version": "1.0.0",
"pass_rate": 85,
"coverage": 78,
"failed_tests": ["test: OAuth timeout retry"],
"total_tests": 20
}
}
```
### Iteration 2: User Extension
User provides feedback: "Also add multi-factor authentication"
```json
{
"status": "running",
"current_iteration": 2,
"task_history": [
"Implement OAuth authentication",
"Also add multi-factor authentication"
],
"description": "Add OAuth2 login support with Google and GitHub providers\n\n--- ITERATION 2 ---\nAlso add multi-factor authentication",
"agents": {
"ra": { "status": "running", "iterations_completed": 1 },
"ep": { "status": "idle", "iterations_completed": 1 },
"cd": { "status": "idle", "iterations_completed": 1 },
"vas": { "status": "idle", "iterations_completed": 1 }
},
"requirements": {
"version": "1.1.0",
"specification": "...",
"last_updated": "2026-01-22T11:00:00+08:00"
},
"iterations": [
{ "number": 1, "completed_at": "..." },
{
"number": 2,
"extension": "Also add multi-factor authentication",
"started_at": "2026-01-22T10:45:00+08:00",
"agent_results": {}
}
],
"coordination": {
"feedback_log": [{
"timestamp": "2026-01-22T10:45:00+08:00",
"source": "user",
"target": "ra",
"content": "Add multi-factor authentication to requirements",
"type": "requirement_update"
}]
}
}
```
## Version Tracking
Each component tracks its version:
- **Requirements**: `1.0.0``1.1.0``1.2.0` (each iteration)
- **Plan**: `1.0.0``1.1.0` (updated based on requirements)
- **Code**: Changes appended with iteration markers
- **Tests**: Results tracked per iteration
## File Sync Protocol
State changes trigger file writes:
| State Change | File Sync |
|--------------|-----------|
| `requirements` updated | `.progress/ra/requirements.md` + version bump |
| `plan` updated | `.progress/ep/plan.json` + version bump |
| `changes` appended | `.progress/cd/changes.log` + iteration marker |
| `test_results` updated | `.progress/vas/test-results.json` + version bump |
| Full iteration done | `.progress/coordination/timeline.md` appended |
## Control Signal Checking
Agents check status before each action:
```javascript
function checkControlSignals(cycleId) {
const state = JSON.parse(Read(`.workflow/.cycle/${cycleId}.json`))
if (state.status === 'paused') {
return { continue: false, action: 'pause' }
}
if (state.status === 'failed') {
return { continue: false, action: 'stop' }
}
if (state.status === 'running') {
return { continue: true, action: 'continue' }
}
return { continue: false, action: 'unknown' }
}
```
## State Persistence
### Write Operations
After each agent completes or phase transitions:
```javascript
Write(
`.workflow/.cycle/${cycleId}.json`,
JSON.stringify(state, null, 2)
)
```
### Read Operations
Agents always read fresh state before executing:
```javascript
const currentState = JSON.parse(
Read(`.workflow/.cycle/${cycleId}.json`)
)
```
## State Rebuild (Recovery)
If master state corrupted, rebuild from markdown files:
```javascript
function rebuildState(cycleId) {
const progressDir = `.workflow/.cycle/${cycleId}.progress`
// Read markdown files
const raMarkdown = Read(`${progressDir}/ra/requirements.md`)
const epMarkdown = Read(`${progressDir}/ep/plan.json`)
const cdChanges = Read(`${progressDir}/cd/changes.log`)
const vasResults = Read(`${progressDir}/vas/test-results.json`)
// Reconstruct state from files
return {
requirements: parseMarkdown(raMarkdown),
plan: JSON.parse(epMarkdown),
changes: parseNDJSON(cdChanges),
test_results: JSON.parse(vasResults)
}
}
```
## Best Practices
1. **Immutable Reads**: Never modify state during read
2. **Version Bumps**: Increment version on each iteration
3. **Timestamp Accuracy**: Use UTC+8 consistently
4. **Append-Only Logs**: Never delete history
5. **Atomic Writes**: Write complete state, not partial updates
6. **Coordination Tracking**: Log all inter-agent communication

View File

@@ -1,423 +0,0 @@
# Agent Communication Optimization
优化 agent 通信机制:使用简短的产出文件引用而不是内容传递。
## 背景
在多 agent 系统中,传递完整的文件内容会导致:
- 消息体积过大
- 上下文使用量增加
- 通信效率低下
- 容易引入上下文断层
**优化方案**: 使用文件路径引用,让 agent 自动读取需要的文件。
## 优化原则
### 原则 1: 文件引用而非内容传递
**错误做法**(传递内容):
```javascript
send_input({
id: agents.cd,
message: `
Requirements:
${requirements_content} // 完整内容 - 浪费空间
Plan:
${plan_json} // 完整 JSON - 重复信息
`
})
```
**正确做法**(引用文件):
```javascript
send_input({
id: agents.cd,
message: `
## Feedback from Validation
Test failures found. Review these outputs:
## Reference
- Requirements: .workflow/.cycle/${cycleId}.progress/ra/requirements.md (v1.0.0)
- Plan: .workflow/.cycle/${cycleId}.progress/ep/plan.json (v1.0.0)
- Test Results: .workflow/.cycle/${cycleId}.progress/vas/test-results.json
## Issues Found
${summary_of_issues} // 只传递摘要
## Actions Required
1. Fix OAuth token refresh (test line 45)
2. Update implementation.md with fixes
`
})
```
### 原则 2: 摘要而非全文
**错误**
```javascript
// 传递所有文件内容
RA输出: "requirements.md (2000 lines) + edge-cases.md (1000 lines) + changes.log (500 lines)"
EP读取: 全文解析所有内容浪费token
```
**正确**
```javascript
// 只传递关键摘要
RA输出:
- 10个功能需求
- 5个非功能需求
- 8个边界场景
- 文件路径用于完整查看
EP读取: 读取摘要 + 需要时查看完整文件高效
```
### 原则 3: 文件版本跟踪
每个引用必须包含版本:
```javascript
send_input({
id: agents.cd,
message: `
Requirements: .workflow/.cycle/${cycleId}.progress/ra/requirements.md (v1.1.0)
^^^^^^^ 版本号
Plan: .workflow/.cycle/${cycleId}.progress/ep/plan.json (v1.0.0)
^^^^^^^ 版本号
`
})
```
**好处**:
- 避免使用过期信息
- 自动检测版本不匹配
- 支持多版本迭代
## 实现模式
### Pattern 1: 通知 + 引用
Agent 向其他 agent 通知输出,而非传递内容:
```javascript
// RA 输出摘要
const raSummary = {
requirements_count: 10,
edge_cases_count: 8,
version: "1.0.0",
output_file: ".workflow/.cycle/${cycleId}.progress/ra/requirements.md",
key_requirements: [
"FR-001: OAuth authentication",
"FR-002: Multi-provider support",
"..." // 只列出标题,不传递完整内容
]
}
// 更新状态,让其他 agent 读取
state.requirements = {
version: raSummary.version,
output_file: raSummary.output_file,
summary: raSummary.key_requirements
}
// EP agent 从状态读取
const requiredDetails = state.requirements
const outputFile = requiredDetails.output_file
const requirements = JSON.parse(Read(outputFile)) // EP 自己读取完整文件
```
### Pattern 2: 反馈通知
Orchestrator 发送反馈时只传递摘要和行号:
```javascript
// ❌ 错误:传递完整测试结果
send_input({
id: agents.cd,
message: `
Test Results:
${entire_test_results_json} // 完整 JSON - 太大
`
})
// ✅ 正确:引用文件 + 问题摘要
send_input({
id: agents.cd,
message: `
## Test Failures
Full results: .workflow/.cycle/${cycleId}.progress/vas/test-results.json (v1.0.0)
## Quick Summary
- Failed: oauth-refresh (line 45, expected token refresh)
- Failed: concurrent-login (line 78, race condition)
## Fix Instructions
1. Review test cases at referenced lines
2. Fix implementation
3. Re-run tests
4. Update implementation.md
Reference previous file paths if you need full details.
`
})
```
### Pattern 3: 依赖链路
Agent 通过文件引用获取依赖:
```javascript
// EP agent: 从状态读取 RA 输出路径
const raOutputPath = state.requirements?.output_file
if (raOutputPath && exists(raOutputPath)) {
const requirements = Read(raOutputPath)
// 使用 requirements 生成计划
}
// CD agent: 从状态读取 EP 输出路径
const epPlanPath = state.plan?.output_file
if (epPlanPath && exists(epPlanPath)) {
const plan = JSON.parse(Read(epPlanPath))
// 根据 plan 实现功能
}
// VAS agent: 从状态读取 CD 输出路径
const cdChangesPath = state.changes?.output_file
if (cdChangesPath && exists(cdChangesPath)) {
const changes = readNDJSON(cdChangesPath)
// 根据 changes 生成测试
}
```
## 状态文件引用结构
优化后的状态文件应该包含文件路径而不是内容:
```json
{
"cycle_id": "cycle-v1-20260122-abc123",
"requirements": {
"version": "1.0.0",
"output_files": {
"specification": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/ra/requirements.md",
"edge_cases": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/ra/edge-cases.md",
"changes_log": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/ra/changes.log"
},
"summary": {
"functional_requirements": 10,
"edge_cases": 8,
"constraints": 5
}
},
"exploration": {
"version": "1.0.0",
"output_files": {
"exploration": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/ep/exploration.md",
"architecture": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/ep/architecture.md"
},
"summary": {
"key_components": ["Auth Module", "User Service"],
"integration_points": 5,
"identified_risks": 3
}
},
"plan": {
"version": "1.0.0",
"output_file": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/ep/plan.json",
"summary": {
"total_tasks": 8,
"critical_path": ["TASK-001", "TASK-003", "TASK-004"],
"estimated_hours": 16
}
},
"implementation": {
"version": "1.0.0",
"output_files": {
"progress": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/cd/implementation.md",
"changes": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/cd/changes.log",
"issues": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/cd/issues.md"
},
"summary": {
"tasks_completed": 3,
"files_modified": 5,
"blockers": 0
}
},
"validation": {
"version": "1.0.0",
"output_files": {
"validation": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/vas/validation.md",
"test_results": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/vas/test-results.json",
"coverage": ".workflow/.cycle/cycle-v1-20260122-abc123.progress/vas/coverage.md"
},
"summary": {
"pass_rate": 92,
"coverage": 87,
"failures": 4
}
}
}
```
## Agent 通信模板优化
### 优化前: 完整内容传递
```javascript
send_input({
id: agents.cd,
message: `
## Requirements (Complete Content)
${fs.readFileSync(requirementsFile, 'utf8')} // 2000+ lines
## Plan (Complete JSON)
${fs.readFileSync(planFile, 'utf8')} // 1000+ lines
## Test Results (Complete)
${fs.readFileSync(testResultsFile, 'utf8')} // 500+ lines
## Your Task
Fix the implementation...
` // 总消息体: 4000+ 行
})
```
### 优化后: 文件引用 + 摘要
```javascript
send_input({
id: agents.cd,
message: `
## Test Failures - Action Required
Full Test Report: .workflow/.cycle/${cycleId}.progress/vas/test-results.json (v1.0.0)
## Summary of Failures
- oauth-refresh: Expected token refresh, got error (test line 45)
- concurrent-login: Race condition in session writes (test line 78)
## Implementation Reference
- Current Code: .workflow/.cycle/${cycleId}.progress/cd/implementation.md (v1.0.0)
- Code Changes: .workflow/.cycle/${cycleId}.progress/cd/changes.log (v1.0.0)
## Action Required
1. Review failing tests in referenced test results file
2. Fix root causes (race condition, token handling)
3. Update implementation.md with fixes
4. Re-run tests
## Context
- Requirement: .workflow/.cycle/${cycleId}.progress/ra/requirements.md (v1.0.0)
- Plan: .workflow/.cycle/${cycleId}.progress/ep/plan.json (v1.0.0)
Output PHASE_RESULT when complete.
` // 总消息体: <500 行,高效传递
})
```
## 版本控制最佳实践
### 版本不匹配检测
```javascript
function validateVersionConsistency(state) {
const versions = {
ra: state.requirements?.version,
ep: state.plan?.version,
cd: state.implementation?.version,
vas: state.validation?.version
}
// 检查版本一致性
const allVersions = Object.values(versions).filter(v => v)
const unique = new Set(allVersions)
if (unique.size > 1) {
console.warn('Version mismatch detected:')
console.warn(versions)
// 返回版本差异,让 orchestrator 决定是否继续
}
return unique.size === 1
}
```
### 文件存在性检查
```javascript
function validateReferences(state, cycleId) {
const checks = []
// 检查所有引用的文件是否存在
for (const [agent, data] of Object.entries(state)) {
if (data?.output_files) {
for (const [name, path] of Object.entries(data.output_files)) {
if (!fs.existsSync(path)) {
checks.push({
agent: agent,
file: name,
path: path,
status: 'missing'
})
}
}
}
}
return checks
}
```
## 好处总结
| 方面 | 改进 |
|------|------|
| 消息体积 | 减少 80-90% |
| Token 使用 | 减少 60-70% |
| 读取速度 | 无需解析冗余内容 |
| 版本控制 | 清晰的版本跟踪 |
| 上下文清晰 | 不会混淆版本 |
| 可维护性 | 文件变更不需要修改消息 |
## 迁移建议
### 第一步: 更新状态结构
```json
// 从这样:
"requirements": "完整内容"
// 改为这样:
"requirements": {
"version": "1.0.0",
"output_file": "path/to/file",
"summary": {...}
}
```
### 第二步: 更新通信模板
所有 `send_input` 消息改为引用路径。
### 第三步: Agent 自动读取
Agent 从引用路径自动读取所需文件。
### 第四步: 测试版本检测
确保版本不匹配时有警告。

View File

@@ -1,406 +0,0 @@
# Coordination Protocol - Multi-Agent Communication
Inter-agent communication protocols and patterns for parallel-dev-cycle skill.
## Overview
The coordination protocol enables four parallel agents (RA, EP, CD, VAS) to communicate efficiently while maintaining clear responsibilities and avoiding conflicts.
## Communication Channels
### 1. Shared State File (Primary)
**Location**: `.workflow/.cycle/{cycleId}.json`
**Access Pattern**:
- **Agents**: READ ONLY - check dependencies and status
- **Orchestrator**: READ-WRITE - updates state after each phase
```javascript
// Every agent: Read state to check dependencies
const state = JSON.parse(Read(`.workflow/.cycle/${cycleId}.json`))
const canProceed = checkDependencies(state)
// Agent outputs PHASE_RESULT (reports to orchestrator, NOT writes directly)
console.log("PHASE_RESULT: ...")
// Only Orchestrator writes to state file after receiving PHASE_RESULT
// Write(`.workflow/.cycle/${cycleId}.json`, JSON.stringify(updatedState, null, 2))
```
**Protocol**:
- Only orchestrator writes to state file (no concurrent writes, no lock needed)
- Agents read state to understand dependencies
- Timestamp all orchestrator updates with ISO8601 format
- Never delete existing data, only append
### 2. Progress Markdown Files (Async Log)
**Location**: `.workflow/.cycle/{cycleId}.progress/{agent}/`
Each agent writes progress to dedicated markdown files:
| Agent | Main Documents (Rewrite) | Logs (Append-Only) |
|-------|--------------------------|-------------------|
| RA | requirements.md | changes.log |
| EP | exploration.md, architecture.md, plan.json | changes.log |
| CD | implementation.md, issues.md | changes.log, debug-log.ndjson |
| VAS | validation.md, summary.md, test-results.json | changes.log |
**Protocol**:
- **Main documents**: Complete rewrite per iteration, archived to `history/`
- **Log files**: Append-only (changes.log, debug-log.ndjson) - never delete
- **Version synchronization**: All main documents share same version (e.g., all v1.1.0 in iteration 2)
- Include timestamp on each update
### 3. Orchestrator send_input (Synchronous)
**When**: Orchestrator needs to send feedback or corrections
```javascript
// Example: CD agent receives test failure feedback
send_input({
id: agents.cd,
message: `
## FEEDBACK FROM VALIDATION
Test failures detected: ${failures}
## REQUIRED ACTION
Fix the following:
${actionItems}
## NEXT STEP
Update implementation.md with fixes, then re-run tests.
Output PHASE_RESULT when complete.
`
})
```
**Protocol**:
- Only orchestrator initiates send_input
- Clear action items and expected output
- Single message per iteration (no rapid-fire sends)
### 4. Coordination Log
**Location**: `.workflow/.cycle/{cycleId}.progress/coordination/`
Centralized log for inter-agent decisions and communication:
**feedback.md**:
```markdown
# Feedback & Coordination Log - Version X.Y.Z
## Timeline
- [10:00:00] Orchestrator: Created cycle
- [10:05:00] RA: Requirements analysis started
- [10:10:00] RA: Requirements completed, v1.0.0
- [10:10:01] EP: Starting exploration (depends on RA output)
- [10:15:00] EP: Architecture designed, plan.json v1.0.0
- [10:15:01] CD: Starting implementation (depends on EP plan)
- [10:30:00] CD: Implementation progressing, found blocker
- [10:31:00] RA: Clarified requirement after CD blocker
- [10:31:01] CD: Continuing with clarification
- [10:40:00] CD: Implementation complete
- [10:40:01] VAS: Starting validation
- [10:45:00] VAS: Testing complete, found failures
- [10:45:01] Orchestrator: Sending feedback to CD
- [10:46:00] CD: Fixed issues
- [10:50:00] VAS: Re-validation, all passing
- [10:50:01] Orchestrator: Cycle complete
## Decision Records
- [10:31:00] RA Clarification: OAuth optional vs required?
- Decision: Optional (can use password)
- Rationale: More flexible for users
- Impact: Affects FR-003 implementation
## Blockers & Resolutions
- [10:30:00] Blocker: Database migration for existing users
- Reported by: CD
- Resolution: Set oauth_id = null for existing users
- Status: Resolved
## Cross-Agent Dependencies
- EP depends on: RA requirements (v1.0.0)
- CD depends on: EP plan (v1.0.0)
- VAS depends on: CD code changes
```
## Message Formats
### Agent Status Update
Each agent updates state with its status:
```json
{
"agents": {
"ra": {
"status": "completed",
"started_at": "2026-01-22T10:05:00+08:00",
"completed_at": "2026-01-22T10:15:00+08:00",
"output_files": [
".workflow/.cycle/cycle-xxx.progress/ra/requirements.md",
".workflow/.cycle/cycle-xxx.progress/ra/edge-cases.md",
".workflow/.cycle/cycle-xxx.progress/ra/changes.log"
],
"iterations_completed": 1
}
}
}
```
### Feedback Message Format
When orchestrator sends feedback via send_input:
```text
## FEEDBACK FROM [Agent Name]
[Summary of findings or issues]
## REFERENCED OUTPUT
File: [path to agent output]
Version: [X.Y.Z]
## REQUIRED ACTION
1. [Action 1 with specific details]
2. [Action 2 with specific details]
## SUCCESS CRITERIA
- [ ] Item 1
- [ ] Item 2
## NEXT STEP
[What agent should do next]
Output PHASE_RESULT when complete.
## CONTEXT
Previous iteration: [N]
Current iteration: [N+1]
```
### Phase Result Format
Every agent outputs PHASE_RESULT:
```text
PHASE_RESULT:
- phase: [ra|ep|cd|vas]
- status: success | failed | partial
- files_written: [list of files]
- summary: [one-line summary]
- [agent-specific fields]
- issues: [list of issues if any]
PHASE_DETAILS:
[Additional details or metrics]
```
## Dependency Resolution
**Execution Model**: All four agents are spawned in parallel, but execution blocks based on dependencies. Orchestrator manages dependency resolution via shared state.
### Build Order (Default)
```
RA (Requirements) → EP (Planning) → CD (Development) → VAS (Validation)
↓ ↓ ↓ ↓
Block EP Block CD Block VAS Block completion
```
**Explanation**:
- All agents spawned simultaneously
- Each agent checks dependencies in shared state before proceeding
- Blocked agents wait for dependency completion
- Orchestrator uses `send_input` to notify dependent agents when ready
### Parallel Opportunities
Some phases can run in parallel:
```
RA + FrontendCode (independent)
EP + RA (not blocking)
CD.Task1 + CD.Task2 (if no dependencies)
```
### Dependency Tracking
State file tracks dependencies:
```json
{
"agents": {
"ep": {
"depends_on": ["ra"],
"ready": true, // RA completed
"can_start": true
},
"cd": {
"depends_on": ["ep"],
"ready": true, // EP completed
"can_start": true
},
"vas": {
"depends_on": ["cd"],
"ready": false, // CD not yet complete
"can_start": false
}
}
}
```
## Iteration Flow with Communication
### Iteration 1: Initial Execution
```
Time Agent Action State Update
──────────────────────────────────────────────────────
10:00 Init Create cycle status: running
10:05 RA Start analysis agents.ra.status: running
10:10 RA Complete (v1.0.0) agents.ra.status: completed
10:10 EP Start planning agents.ep.status: running
(depends on RA completion)
10:15 EP Complete (v1.0.0) agents.ep.status: completed
10:15 CD Start development agents.cd.status: running
(depends on EP completion)
10:30 CD Found blocker coordination.blockers.add()
10:31 RA Clarify blocker requirements.v1.1.0 created
10:35 CD Continue (with fix) agents.cd.status: running
10:40 CD Complete agents.cd.status: completed
10:40 VAS Start validation agents.vas.status: running
(depends on CD completion)
10:45 VAS Tests failing coordination.feedback_log.add()
10:45 Orch Send feedback agents.cd.message: "Fix these tests"
10:46 CD Resume (send_input) agents.cd.status: running
10:48 CD Fix complete agents.cd.status: completed
10:50 VAS Re-validate agents.vas.status: running
10:55 VAS All pass agents.vas.status: completed
11:00 Orch Complete cycle status: completed
```
## Conflict Resolution
### Conflict Type 1: Unclear Requirement
**Scenario**: CD needs clarification on FR-X
**Resolution Flow**:
1. CD reports blocker in issues.md
2. Orchestrator extracts blocker
3. Orchestrator sends message to RA
4. RA updates requirements with clarification
5. RA outputs new requirements.md (v1.1.0)
6. Orchestrator sends message to CD with clarification
7. CD resumes and continues
### Conflict Type 2: Test Failure
**Scenario**: VAS finds test failures
**Resolution Flow**:
1. VAS reports failures in validation.md
2. VAS outputs test-results.json with details
3. Orchestrator extracts failure details
4. Orchestrator categorizes failures
5. If blocker: Orchestrator sends to CD/RA for fixes
6. CD/RA fix and report completion
7. Orchestrator sends CD/VAS to retry
8. VAS re-validates
### Conflict Type 3: Plan Mismatch
**Scenario**: CD realizes plan tasks are incomplete
**Resolution Flow**:
1. CD reports in issues.md
2. Orchestrator extracts issue
3. Orchestrator sends to EP to revise plan
4. EP updates plan.json (v1.1.0)
5. EP adds new tasks or dependencies
6. Orchestrator sends to CD with updated plan
7. CD implements remaining tasks
## Escalation Path
For issues that block resolution:
```
Agent Issue
Agent reports blocker
Orchestrator analyzes
Can fix automatically?
├─ Yes: send_input to agent with fix
└─ No: Escalate to user
User provides guidance
Orchestrator applies guidance
Resume agents
```
## Communication Best Practices
1. **Clear Timestamps**: All events timestamped ISO8601 format
2. **Structured Messages**: Use consistent format for feedback
3. **Version Tracking**: Always include version numbers
4. **Audit Trail**: Maintain complete log of decisions
5. **No Direct Agent Communication**: All communication via orchestrator
6. **Document Decisions**: Record why decisions were made
7. **Append-Only Logs**: Never delete history
## State Consistency Rules
1. **Single Writer Per Field**: Only one agent updates each field
- RA writes: requirements, edge_cases
- EP writes: exploration, plan
- CD writes: changes, implementation
- VAS writes: test_results, summary
2. **Read-Write Serialization**: Orchestrator ensures no conflicts
3. **Version Synchronization**: All versions increment together
- v1.0.0 → v1.1.0 (all docs updated)
4. **Timestamp Consistency**: All timestamps in state file UTC+8
## Monitoring & Debugging
### State Inspection
```javascript
// Check agent status
const state = JSON.parse(Read(`.workflow/.cycle/${cycleId}.json`))
console.log(state.agents) // See status of all agents
// Check for blockers
console.log(state.coordination.blockers)
// Check feedback history
console.log(state.coordination.feedback_log)
```
### Log Analysis
```bash
# Check RA progress
tail .workflow/.cycle/cycle-xxx.progress/ra/changes.log
# Check CD changes
grep "TASK-001" .workflow/.cycle/cycle-xxx.progress/cd/changes.log
# Check coordination timeline
tail -50 .workflow/.cycle/cycle-xxx.progress/coordination/feedback.md
```

View File

@@ -1,331 +0,0 @@
# Document Versioning Strategy
Document version management strategy: Complete Rewrite + Archive History
## Recommended Approach: Complete Rewrite + Archive History
For each iteration, **completely rewrite** the main document, and automatically archive the old version to the `history/` directory.
### File Structure
```
.workflow/.cycle/cycle-v1-20260122-abc123.progress/
├── ra/
│ ├── requirements.md # v1.2.0 (current version, complete rewrite)
│ ├── edge-cases.md # v1.2.0 (current version, complete rewrite)
│ ├── changes.log # NDJSON complete change history (append-only)
│ └── history/
│ ├── requirements-v1.0.0.md (archived)
│ ├── requirements-v1.1.0.md (archived)
│ ├── edge-cases-v1.0.0.md (archived)
│ └── edge-cases-v1.1.0.md (archived)
├── ep/
│ ├── exploration.md # v1.2.0 (current)
│ ├── architecture.md # v1.2.0 (current)
│ ├── plan.json # v1.2.0 (current)
│ └── history/
│ ├── plan-v1.0.0.json
│ └── plan-v1.1.0.json
├── cd/
│ ├── implementation.md # v1.2.0 (current)
│ ├── changes.log # NDJSON complete history
│ ├── debug-log.ndjson # Debug hypothesis tracking
│ ├── issues.md # Current unresolved issues
│ └── history/
│ ├── implementation-v1.0.0.md
│ └── implementation-v1.1.0.md
└── vas/
├── validation.md # v1.2.0 (current)
├── test-results.json # v1.2.0 (current)
├── summary.md # v1.2.0 (current)
└── history/
├── validation-v1.0.0.md
└── test-results-v1.0.0.json
```
## Optimized Document Template
### Requirements.md (Complete Rewrite Version)
```markdown
# Requirements Specification - v1.2.0
## Document Metadata
| Field | Value |
|-------|-------|
| Version | 1.2.0 |
| Previous | 1.1.0 (Added Google OAuth) |
| Changes | Added MFA, GitHub provider |
| Date | 2026-01-23T10:00:00+08:00 |
| Cycle | cycle-v1-20260122-abc123 |
| Iteration | 3 |
---
## Functional Requirements
### FR-001: OAuth Authentication
**Description**: Users can log in using OAuth providers.
**Supported Providers**: Google, GitHub
**Priority**: High
**Status**: ✓ Implemented (v1.0.0), Enhanced (v1.1.0, v1.2.0)
**Success Criteria**:
- User can click provider button
- Redirect to provider
- Return with valid token
- Session created
---
### FR-002: Multi-Provider Support
**Description**: System supports multiple OAuth providers simultaneously.
**Providers**:
- Google (v1.1.0)
- GitHub (v1.2.0)
**Priority**: High
**Status**: ✓ Implemented
---
### FR-003: Multi-Factor Authentication
**Description**: Optional MFA for enhanced security.
**Method**: TOTP (Time-based One-Time Password)
**Priority**: Medium
**Status**: 🆕 New in v1.2.0
**Success Criteria**:
- User can enable MFA in settings
- TOTP QR code generated
- Verification on login
---
## Non-Functional Requirements
### NFR-001: Performance
Response time < 500ms for all OAuth flows.
**Status**: ✓ Met (v1.0.0)
---
## Edge Cases
### EC-001: OAuth Provider Timeout
**Scenario**: Provider doesn't respond in 5 seconds
**Expected**: Display error, offer retry
**Status**: ✓ Handled
---
### EC-002: Invalid MFA Code (NEW v1.2.0)
**Scenario**: User enters incorrect TOTP code
**Expected**: Display error, max 3 attempts, lock after
**Status**: 🔄 To be implemented
---
## Constraints
- Must use existing JWT session management
- No new database servers
- Compatible with existing user table
---
## Assumptions
- Users have access to authenticator app for MFA
- OAuth providers are always available
---
## Version History Summary
| Version | Date | Summary |
|---------|------|---------|
| 1.0.0 | 2026-01-22 | Initial OAuth login (Google only implicit) |
| 1.1.0 | 2026-01-22 | + Explicit Google OAuth support |
| 1.2.0 | 2026-01-23 | + GitHub provider, + MFA (current) |
**Detailed History**: See `history/` directory and `changes.log`
```
### Changes.log (NDJSON - Complete History)
```jsonl
{"timestamp":"2026-01-22T10:00:00+08:00","iteration":1,"version":"1.0.0","action":"create","type":"requirement","id":"FR-001","description":"Initial OAuth requirement"}
{"timestamp":"2026-01-22T10:05:00+08:00","iteration":1,"version":"1.0.0","action":"create","type":"requirement","id":"NFR-001","description":"Performance requirement"}
{"timestamp":"2026-01-22T11:00:00+08:00","iteration":2,"version":"1.1.0","action":"update","type":"requirement","id":"FR-001","description":"Clarified Google OAuth support"}
{"timestamp":"2026-01-22T11:05:00+08:00","iteration":2,"version":"1.1.0","action":"create","type":"requirement","id":"FR-002","description":"Multi-provider support"}
{"timestamp":"2026-01-23T10:00:00+08:00","iteration":3,"version":"1.2.0","action":"create","type":"requirement","id":"FR-003","description":"MFA requirement"}
{"timestamp":"2026-01-23T10:05:00+08:00","iteration":3,"version":"1.2.0","action":"update","type":"requirement","id":"FR-002","description":"Added GitHub provider"}
```
## Implementation Flow
### Agent Workflow (RA Example)
```javascript
// ==================== RA Agent Iteration Flow ====================
// Read current state
const state = JSON.parse(Read(`.workflow/.cycle/${cycleId}.json`))
const currentVersion = state.requirements?.version || "0.0.0"
const iteration = state.current_iteration
// If iteration (old version exists)
if (currentVersion !== "0.0.0") {
// 1. Archive old version
const oldFile = `.workflow/.cycle/${cycleId}.progress/ra/requirements.md`
const archiveFile = `.workflow/.cycle/${cycleId}.progress/ra/history/requirements-v${currentVersion}.md`
Copy(oldFile, archiveFile) // Archive
// 2. Read old version (optional, for context understanding)
const oldRequirements = Read(oldFile)
// 3. Read change history
const changesLog = readNDJSON(`.workflow/.cycle/${cycleId}.progress/ra/changes.log`)
}
// 4. Generate new version number
const newVersion = bumpVersion(currentVersion, 'minor') // 1.1.0 -> 1.2.0
// 5. Generate new document (complete rewrite)
const newRequirements = generateRequirements({
version: newVersion,
previousVersion: currentVersion,
previousSummary: "Added Google OAuth support",
currentChanges: "Added MFA and GitHub provider",
iteration: iteration,
taskDescription: state.description,
changesLog: changesLog // For understanding history
})
// 6. Write new document (overwrite old)
Write(`.workflow/.cycle/${cycleId}.progress/ra/requirements.md`, newRequirements)
// 7. Append change to changes.log
appendNDJSON(`.workflow/.cycle/${cycleId}.progress/ra/changes.log`, {
timestamp: getUtc8ISOString(),
iteration: iteration,
version: newVersion,
action: "create",
type: "requirement",
id: "FR-003",
description: "Added MFA requirement"
})
// 8. Update state
state.requirements = {
version: newVersion,
output_file: `.workflow/.cycle/${cycleId}.progress/ra/requirements.md`,
summary: {
functional_requirements: 3,
edge_cases: 2,
constraints: 3
}
}
Write(`.workflow/.cycle/${cycleId}.json`, JSON.stringify(state, null, 2))
```
## Advantages Comparison
| Aspect | Incremental Update | Complete Rewrite + Archive |
|--------|-------------------|---------------------------|
| **Document Conciseness** | ❌ Gets longer | ✅ Always concise |
| **Agent Parsing** | ❌ Must parse history | ✅ Only read current version |
| **Maintenance Complexity** | ❌ High (version marking) | ✅ Low (direct rewrite) |
| **File Size** | ❌ Bloats | ✅ Fixed |
| **History Tracking** | ✅ In main document | ✅ In history/ + changes.log |
| **Human Readability** | ❌ Must skip history | ✅ Direct current view |
| **Token Usage** | ❌ More (read complete history) | ✅ Less (only read current) |
## Archive Strategy
### Auto-Archive Trigger
```javascript
function shouldArchive(currentVersion, state) {
// Archive on each version update
return currentVersion !== state.requirements?.version
}
function archiveOldVersion(cycleId, agent, filename, currentVersion) {
const currentFile = `.workflow/.cycle/${cycleId}.progress/${agent}/${filename}`
const archiveDir = `.workflow/.cycle/${cycleId}.progress/${agent}/history`
const archiveFile = `${archiveDir}/${filename.replace('.', `-v${currentVersion}.`)}`
// Ensure archive directory exists
mkdir -p ${archiveDir}
// Copy (not move, keep current file until new version written)
Copy(currentFile, archiveFile)
console.log(`Archived ${filename} v${currentVersion} to history/`)
}
```
### Cleanup Strategy (Optional)
Keep most recent N versions, delete older archives:
```javascript
function cleanupArchives(cycleId, agent, keepVersions = 3) {
const historyDir = `.workflow/.cycle/${cycleId}.progress/${agent}/history`
const archives = listFiles(historyDir)
// Sort by version number
archives.sort((a, b) => compareVersions(extractVersion(a), extractVersion(b)))
// Delete oldest versions (keep most recent N)
if (archives.length > keepVersions) {
const toDelete = archives.slice(0, archives.length - keepVersions)
toDelete.forEach(file => Delete(`${historyDir}/${file}`))
}
}
```
## Importance of Changes.log
Although main document is completely rewritten, **changes.log (NDJSON) permanently preserves complete history**:
```bash
# View all changes
cat .workflow/.cycle/cycle-xxx.progress/ra/changes.log | jq .
# View history of specific requirement
cat .workflow/.cycle/cycle-xxx.progress/ra/changes.log | jq 'select(.id=="FR-001")'
# View changes by iteration
cat .workflow/.cycle/cycle-xxx.progress/ra/changes.log | jq 'select(.iteration==2)'
```
This way:
- **Main Document**: Clear and concise (current state)
- **Changes.log**: Complete traceability (all history)
- **History/**: Snapshot backups (view on demand)
## Recommended Implementation
1. ✅ Adopt "Complete Rewrite" strategy
2. ✅ Main document only keeps "previous version summary"
3. ✅ Auto-archive to `history/` directory
4. ✅ Changes.log (NDJSON) preserves complete history
5. ✅ Optional: Keep most recent 3-5 historical versions
This approach keeps documents concise (agent-friendly) while preserving complete history (audit-friendly).