feat: Add communication optimization and coordination protocol for multi-agent system

- Introduced a new specification for agent communication optimization focusing on file references instead of content transfer to enhance efficiency and reduce message size.
- Established a coordination protocol detailing communication channels, message formats, and dependency resolution strategies among agents (RA, EP, CD, VAS).
- Created a unified progress format specification for all agents, standardizing documentation structure and versioning practices.
This commit is contained in:
catlog22
2026-01-23 10:04:31 +08:00
parent 09eeb84cda
commit b1ac0cf8ff
11 changed files with 4363 additions and 0 deletions

View File

@@ -0,0 +1,423 @@
# 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/code-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/code-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

@@ -0,0 +1,391 @@
# 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`
All agents read from and write to the unified state file:
```javascript
// Every agent: Read fresh state at action start
const state = JSON.parse(Read(`.workflow/.cycle/${cycleId}.json`))
// Every agent: Write updated state at action end
Write(`.workflow/.cycle/${cycleId}.json`, JSON.stringify(state, null, 2))
```
**Protocol**:
- Read-Update-Write pattern (no lock needed, orchestrator serializes)
- Timestamp all 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 | Files |
|-------|-------|
| RA | requirements.md, edge-cases.md, changes.log |
| EP | exploration.md, architecture.md, plan.json |
| CD | implementation.md, code-changes.log, issues.md |
| VAS | validation.md, test-results.json, coverage.md, summary.md |
**Protocol**:
- Append-only pattern (no overwrites)
- Version each document independently
- Include timestamp on each update
- Maintain backward compatibility
### 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
### Build Order (Default)
```
RA (Requirements) → EP (Planning) → CD (Development) → VAS (Validation)
↓ ↓ ↓ ↓
Block EP Block CD Block VAS Block completion
```
### 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/code-changes.log
# Check coordination timeline
tail -50 .workflow/.cycle/cycle-xxx.progress/coordination/feedback.md
```

View File

@@ -0,0 +1,330 @@
# Document Versioning Strategy
文档版本管理策略:重新创建 vs 增量更新
## 推荐方案:重新创建 + 归档历史
每次迭代,**完全重写**主文档,旧版本自动归档到 `history/` 目录。
### 文件结构
```
.workflow/.cycle/cycle-v1-20260122-abc123.progress/
├── ra/
│ ├── requirements.md # v1.2.0 (当前版本,重新创建)
│ ├── edge-cases.md # v1.2.0 (当前版本,重新创建)
│ ├── changes.log # NDJSON 完整变更历史append-only
│ └── history/
│ ├── requirements-v1.0.0.md (归档)
│ ├── requirements-v1.1.0.md (归档)
│ ├── edge-cases-v1.0.0.md (归档)
│ └── edge-cases-v1.1.0.md (归档)
├── ep/
│ ├── exploration.md # v1.2.0 (当前)
│ ├── architecture.md # v1.2.0 (当前)
│ ├── plan.json # v1.2.0 (当前)
│ └── history/
│ ├── plan-v1.0.0.json
│ └── plan-v1.1.0.json
├── cd/
│ ├── implementation.md # v1.2.0 (当前)
│ ├── code-changes.log # NDJSON 完整历史
│ ├── issues.md # 当前未解决问题
│ └── history/
│ ├── implementation-v1.0.0.md
│ └── implementation-v1.1.0.md
└── vas/
├── validation.md # v1.2.0 (当前)
├── test-results.json # v1.2.0 (当前)
├── summary.md # v1.2.0 (当前)
└── history/
├── validation-v1.0.0.md
└── test-results-v1.0.0.json
```
## 文档模板优化
### Requirements.md (重新创建版本)
```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 - 完整历史)
```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"}
```
## 实现流程
### Agent 工作流RA 为例)
```javascript
// ==================== RA Agent 迭代流程 ====================
// 读取当前状态
const state = JSON.parse(Read(`.workflow/.cycle/${cycleId}.json`))
const currentVersion = state.requirements?.version || "0.0.0"
const iteration = state.current_iteration
// 如果是迭代(已有旧版本)
if (currentVersion !== "0.0.0") {
// 1. 归档旧版本
const oldFile = `.workflow/.cycle/${cycleId}.progress/ra/requirements.md`
const archiveFile = `.workflow/.cycle/${cycleId}.progress/ra/history/requirements-v${currentVersion}.md`
Copy(oldFile, archiveFile) // 归档
// 2. 读取旧版本(可选,用于理解上下文)
const oldRequirements = Read(oldFile)
// 3. 读取变更历史
const changesLog = readNDJSON(`.workflow/.cycle/${cycleId}.progress/ra/changes.log`)
}
// 4. 生成新版本号
const newVersion = bumpVersion(currentVersion, 'minor') // 1.1.0 -> 1.2.0
// 5. 生成新文档(完全重写)
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 // 用于理解历史
})
// 6. 写入新文档(覆盖旧的)
Write(`.workflow/.cycle/${cycleId}.progress/ra/requirements.md`, newRequirements)
// 7. 追加变更到 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. 更新状态
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))
```
## 优势对比
| 方面 | 增量更新 | 重新创建 + 归档 |
|------|----------|----------------|
| **文档简洁性** | ❌ 越来越长 | ✅ 始终简洁 |
| **Agent 解析** | ❌ 需要解析历史 | ✅ 只看当前版本 |
| **维护复杂度** | ❌ 高(版本标记) | ✅ 低(直接重写) |
| **文件大小** | ❌ 膨胀 | ✅ 固定 |
| **历史追溯** | ✅ 在主文档 | ✅ 在 history/ + changes.log |
| **人类可读** | ❌ 需要跳过历史 | ✅ 直接看当前 |
| **Token 使用** | ❌ 多(读取完整历史) | ✅ 少(只读当前) |
## 归档策略
### 自动归档触发时机
```javascript
function shouldArchive(currentVersion, state) {
// 每次版本更新时归档
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}.`)}`
// 确保归档目录存在
mkdir -p ${archiveDir}
// 复制(不是移动,保持当前文件直到新版本写入)
Copy(currentFile, archiveFile)
console.log(`Archived ${filename} v${currentVersion} to history/`)
}
```
### 清理策略(可选)
保留最近 N 个版本,删除更老的归档:
```javascript
function cleanupArchives(cycleId, agent, keepVersions = 3) {
const historyDir = `.workflow/.cycle/${cycleId}.progress/${agent}/history`
const archives = listFiles(historyDir)
// 按版本号排序
archives.sort((a, b) => compareVersions(extractVersion(a), extractVersion(b)))
// 删除最老的版本(保留最近 N 个)
if (archives.length > keepVersions) {
const toDelete = archives.slice(0, archives.length - keepVersions)
toDelete.forEach(file => Delete(`${historyDir}/${file}`))
}
}
```
## Changes.log 的重要性
虽然主文档重新创建,但 **changes.log (NDJSON) 永久保留完整历史**
```bash
# 查看所有变更
cat .workflow/.cycle/cycle-xxx.progress/ra/changes.log | jq .
# 查看某个需求的历史
cat .workflow/.cycle/cycle-xxx.progress/ra/changes.log | jq 'select(.id=="FR-001")'
# 按迭代查看变更
cat .workflow/.cycle/cycle-xxx.progress/ra/changes.log | jq 'select(.iteration==2)'
```
这样:
- **主文档**: 清晰简洁(当前状态)
- **Changes.log**: 完整追溯(所有历史)
- **History/**: 快照备份(按需查看)
## 推荐实施
1. ✅ 采用"重新创建"策略
2. ✅ 主文档只保留"上一版本简要说明"
3. ✅ 自动归档到 `history/` 目录
4. ✅ Changes.log (NDJSON) 保留完整历史
5. ✅ 可选:保留最近 3-5 个历史版本
这样既保持了文档简洁Agent 友好),又保留了完整历史(审计友好)。