diff --git a/autorun/sprint-1-today/FIXES.md b/autorun/sprint-1-today/FIXES.md new file mode 100644 index 0000000..16aa17f --- /dev/null +++ b/autorun/sprint-1-today/FIXES.md @@ -0,0 +1,176 @@ +# Phase C 修正計画 — GATE の甘い部分を全て潰す + +> 検証で発見した 6 件の不具合を修正する + +--- + +## 修正 1: GATE 0 — Issue=0 で登録拒否 + +**現状**: `register --title "test"` が issue=0 でも通る +**期待**: issue > 0 でなければ登録拒否 + +**修正箇所**: `crates/miyabi-core/src/protocol.rs` の register 処理 +```rust +if task.issue == 0 { + return Err(ProtocolError::Gate("issue number must be > 0")); +} +``` + +**テスト**: +- [ ] `register --title "test"` → exit 1 (issue 未指定) +- [ ] `register --issue 0 --title "test"` → exit 1 +- [ ] `register --issue 1 --title "test"` → exit 0 + +--- + +## 修正 2: GATE 5 — ブランチ名バリデーション + +**現状**: `branch task-1 bad-name` が通る +**期待**: `feature/issue-N-*` or `fix/issue-N-*` or `hotfix/issue-N-*` のみ許可 + +**修正箇所**: `crates/miyabi-core/src/gate.rs` の branch 検証 +```rust +pub fn validate_branch_name(name: &str) -> Result<(), GateError> { + let valid = name.starts_with("feature/issue-") + || name.starts_with("fix/issue-") + || name.starts_with("hotfix/issue-"); + if !valid { + return Err(GateError::InvalidBranchName(name.to_string())); + } + Ok(()) +} +``` + +**テスト**: +- [ ] `branch task-1 bad-name` → exit 1 +- [ ] `branch task-1 feature/issue-1-test` → exit 0 +- [ ] `branch task-1 fix/issue-1-bugfix` → exit 0 +- [ ] `branch task-1 main` → exit 1 + +--- + +## 修正 3: GATE 3 — HIGH risk 承認チェック + +**現状**: `impact task-1 --risk high` の後、承認なしで assign できる +**期待**: HIGH/CRITICAL は `--approve` フラグなしで assign 拒否 + +**修正箇所**: `crates/miyabi-core/src/protocol.rs` の assign 処理 +```rust +if let Some(impact) = &task.impact { + if matches!(impact.risk_level, RiskLevel::HIGH | RiskLevel::CRITICAL) { + if task.human_approval.is_none() { + return Err(ProtocolError::Gate("HIGH/CRITICAL risk requires --approve")); + } + } +} +``` + +**修正箇所**: `crates/miyabi-core/src/protocol.rs` の impact 処理 +- `--approve` フラグが true なら `human_approval` を記録 + +**テスト**: +- [ ] `impact task-1 --risk high` → 記録成功 +- [ ] `assign task-1 ...` → exit 1 (承認なし) +- [ ] `impact task-1 --risk high --approve` → 記録 + 承認 +- [ ] `assign task-1 ...` → exit 0 (承認済み) +- [ ] `impact task-1 --risk low` → `assign` そのまま OK + +--- + +## 修正 4: GATE 7 — merge 後のロック自動解放 + +**現状**: merge 後も `locks` にファイルが残る +**期待**: merge 成功時にロック自動解放 + 後続タスクの依存解除 + +**修正箇所**: `crates/miyabi-core/src/protocol.rs` の merge 処理 +```rust +// merge 成功後 +self.lock_manager.release_lock(task_id, &snapshot_store)?; +// 後続タスクの依存チェック +for dependent_id in &task.dependents { + // dependent の state が blocked なら pending に戻す +} +``` + +**テスト**: +- [ ] register A → assign A (lock src/a.rs) → merge A → `locks` が空 +- [ ] register A, B(dep=A) → merge A → B が dispatchable に出現 + +--- + +## 修正 5: exit code 分類 + +**現状**: 不正 SHA が exit 2 (input_error) +**期待**: GATE 拒否は exit 1、入力フォーマットエラーは exit 2 + +**修正箇所**: `crates/miyabi-cli/src/main.rs` の exit code マッピング +```rust +match result { + Ok(_) => ExitCode::from(0), + Err(ProtocolError::Gate(_)) => ExitCode::from(1), // GATE 拒否 + Err(ProtocolError::Lock(_)) => ExitCode::from(1), // ロック競合 + Err(ProtocolError::DependencyBlocked(_)) => ExitCode::from(1), // 依存ブロック + Err(_) => ExitCode::from(2), // その他入力エラー +} +``` + +**テスト**: +- [ ] 不正 SHA → exit 1 (GATE 拒否) +- [ ] ロック競合 → exit 1 +- [ ] 依存ブロック → exit 1 +- [ ] 不明タスク ID → exit 2 (入力エラー) + +--- + +## 修正 6: 依存ブロック時の exit code + +**現状**: 依存未解決で assign → exit 0 (成功扱い) +**期待**: exit 1 (GATE 拒否) + +**修正箇所**: `crates/miyabi-core/src/protocol.rs` の assign 処理 +- 依存チェックを assign の冒頭で実行 +- 未解決なら `ProtocolError::DependencyBlocked` を返す + +**テスト**: +- [ ] register A, B(dep=A) → assign B → exit 1 (A が done じゃない) +- [ ] merge A → assign B → exit 0 + +--- + +## 実行順序 + +``` +修正 1 (issue=0 拒否) ← 独立、最初にやる +修正 2 (ブランチ名) ← 独立、並行可 +修正 5 (exit code) ← 独立、並行可 +修正 6 (依存 exit code) ← 修正 5 と同時にやる +修正 3 (HIGH 承認) ← protocol.rs の変更、修正 1 の後 +修正 4 (ロック解放) ← protocol.rs の変更、修正 3 の後 +``` + +## 工数 + +| 修正 | 変更行数 | テスト行数 | +|------|---------|-----------| +| 1 | ~5 | ~10 | +| 2 | ~10 | ~15 | +| 3 | ~20 | ~20 | +| 4 | ~15 | ~20 | +| 5 | ~10 | ~15 | +| 6 | ~10 | ~10 | +| **合計** | **~70** | **~90** | + +**推定時間: 15〜20分(Codex 1体)** + +## 承認ゲート + +全修正完了後: +- [ ] `cargo test --all` → GREEN +- [ ] `cargo clippy --all-targets --all-features -- -D warnings` → ゼロ +- [ ] テスト 1: issue=0 → exit 1 +- [ ] テスト 2: bad-branch → exit 1 +- [ ] テスト 3: HIGH + 承認なし → exit 1 +- [ ] テスト 4: merge 後 locks → 空 +- [ ] テスト 5: 不正 SHA → exit 1 +- [ ] テスト 6: 依存ブロック → exit 1 +- [ ] E2E: register → done の全シーケンス(全 GATE 通過) diff --git a/project_memory/.tasks.lock b/project_memory/.tasks.lock new file mode 100644 index 0000000..e69de29 diff --git a/project_memory/task-events.jsonl b/project_memory/task-events.jsonl new file mode 100644 index 0000000..21c9cdf --- /dev/null +++ b/project_memory/task-events.jsonl @@ -0,0 +1,22 @@ +{"id":"issue-51-DagChanged-1775770356183","ts":"2026-04-09T21:32:36.183917Z","type":"dag_changed","task_id":"issue-51","agent":"miyabi-cli","node":"local","payload":{"dependencies":[],"soft_dependencies":[],"title":"Add Agent mode to help documentation"},"version":3} +{"id":"issue-51-ImpactRecorded-1775770356194","ts":"2026-04-09T21:32:36.194174Z","type":"impact_recorded","task_id":"issue-51","agent":"miyabi-cli","node":"local","payload":{"affected_symbols":0,"risk_level":"LOW"},"version":4} +{"id":"issue-51-GatePassed-1775770356199","ts":"2026-04-09T21:32:36.199185Z","type":"gate_passed","task_id":"issue-51","agent":"claude","node":"macbook-pro","payload":{"detail":"all hard dependencies resolved","duration_ms":0,"gate":"gate_2"},"version":5} +{"id":"issue-51-lock-acquired-1775770356199","ts":"2026-04-09T21:32:36.199414Z","type":"lock_acquired","task_id":"issue-51","agent":"claude","node":"macbook-pro","payload":{"expires_at":"2026-04-09T21:39:36.199414Z","files":["docs/USER_MANUAL.md"],"lease_duration_sec":300},"version":5} +{"id":"issue-51-StateTransition-1775770356200","ts":"2026-04-09T21:32:36.200015Z","type":"state_transition","task_id":"issue-51","agent":"claude","node":"macbook-pro","payload":{"to":"implementing"},"version":6} +{"id":"issue-51-BranchCreated-1775770356211","ts":"2026-04-09T21:32:36.211223Z","type":"branch_created","task_id":"issue-51","agent":"miyabi-cli","node":"local","payload":{"branch_name":"feature/issue-51-agent-help-docs"},"version":7} +{"id":"issue-50-DagChanged-1775770383117","ts":"2026-04-09T21:33:03.117439Z","type":"dag_changed","task_id":"issue-50","agent":"miyabi-cli","node":"local","payload":{"dependencies":[],"soft_dependencies":[],"title":"Add progress indicator for long-running agent tasks"},"version":8} +{"id":"issue-49-DagChanged-1775770383121","ts":"2026-04-09T21:33:03.121889Z","type":"dag_changed","task_id":"issue-49","agent":"miyabi-cli","node":"local","payload":{"dependencies":[],"soft_dependencies":[],"title":"Add interactive tool approval in TUI Agent mode"},"version":9} +{"id":"issue-48-DagChanged-1775770383126","ts":"2026-04-09T21:33:03.126824Z","type":"dag_changed","task_id":"issue-48","agent":"miyabi-cli","node":"local","payload":{"dependencies":[],"soft_dependencies":[],"title":"Implement Context Manager for memory management"},"version":10} +{"id":"issue-50-ImpactRecorded-1775770394093","ts":"2026-04-09T21:33:14.093661Z","type":"impact_recorded","task_id":"issue-50","agent":"miyabi-cli","node":"local","payload":{"affected_symbols":5,"risk_level":"MEDIUM"},"version":11} +{"id":"issue-50-GatePassed-1775770394098","ts":"2026-04-09T21:33:14.098224Z","type":"gate_passed","task_id":"issue-50","agent":"codex-b","node":"macbook-pro","payload":{"detail":"all hard dependencies resolved","duration_ms":0,"gate":"gate_2"},"version":12} +{"id":"issue-50-lock-acquired-1775770394098","ts":"2026-04-09T21:33:14.098441Z","type":"lock_acquired","task_id":"issue-50","agent":"codex-b","node":"macbook-pro","payload":{"expires_at":"2026-04-09T21:40:14.098441Z","files":["crates/miyabi-tui/src/app.rs","crates/miyabi-tui/src/views.rs"],"lease_duration_sec":300},"version":12} +{"id":"issue-50-StateTransition-1775770394098","ts":"2026-04-09T21:33:14.098984Z","type":"state_transition","task_id":"issue-50","agent":"codex-b","node":"macbook-pro","payload":{"to":"implementing"},"version":13} +{"id":"issue-49-ImpactRecorded-1775770394103","ts":"2026-04-09T21:33:14.103232Z","type":"impact_recorded","task_id":"issue-49","agent":"miyabi-cli","node":"local","payload":{"affected_symbols":3,"risk_level":"MEDIUM"},"version":14} +{"id":"issue-49-GatePassed-1775770394107","ts":"2026-04-09T21:33:14.107329Z","type":"gate_passed","task_id":"issue-49","agent":"codex-c","node":"macbook-pro","payload":{"detail":"all hard dependencies resolved","duration_ms":0,"gate":"gate_2"},"version":15} +{"id":"issue-49-lock-acquired-1775770394107","ts":"2026-04-09T21:33:14.107550Z","type":"lock_acquired","task_id":"issue-49","agent":"codex-c","node":"macbook-pro","payload":{"expires_at":"2026-04-09T21:40:14.107550Z","files":["crates/miyabi-tui/src/approval_overlay.rs"],"lease_duration_sec":300},"version":15} +{"id":"issue-49-StateTransition-1775770394108","ts":"2026-04-09T21:33:14.108092Z","type":"state_transition","task_id":"issue-49","agent":"codex-c","node":"macbook-pro","payload":{"to":"implementing"},"version":16} +{"id":"issue-48-ImpactRecorded-1775770394112","ts":"2026-04-09T21:33:14.112453Z","type":"impact_recorded","task_id":"issue-48","agent":"miyabi-cli","node":"local","payload":{"affected_symbols":8,"risk_level":"HIGH"},"version":17} +{"id":"issue-48-GatePassed-1775770403160","ts":"2026-04-09T21:33:23.160709Z","type":"gate_passed","task_id":"issue-48","agent":"codex-c","node":"macbook-pro","payload":{"detail":"all hard dependencies resolved","duration_ms":0,"gate":"gate_2"},"version":18} +{"id":"issue-48-GatePassed-1775770403165","ts":"2026-04-09T21:33:23.165760Z","type":"gate_passed","task_id":"issue-48","agent":"claude-sub","node":"macbook-pro","payload":{"detail":"all hard dependencies resolved","duration_ms":0,"gate":"gate_2"},"version":18} +{"id":"issue-48-lock-acquired-1775770403165","ts":"2026-04-09T21:33:23.165977Z","type":"lock_acquired","task_id":"issue-48","agent":"claude-sub","node":"macbook-pro","payload":{"expires_at":"2026-04-09T21:40:23.165977Z","files":["crates/miyabi-core/src/conversation.rs"],"lease_duration_sec":300},"version":18} +{"id":"issue-48-StateTransition-1775770403166","ts":"2026-04-09T21:33:23.166554Z","type":"state_transition","task_id":"issue-48","agent":"claude-sub","node":"macbook-pro","payload":{"to":"implementing"},"version":19} diff --git a/project_memory/tasks.json b/project_memory/tasks.json index 86744ad..05f82fc 100644 --- a/project_memory/tasks.json +++ b/project_memory/tasks.json @@ -1,19 +1,23 @@ { - "version": 2, - "last_updated": "2026-04-10T01:30:00Z", + "version": 19, + "generated_at": "2026-04-09T21:33:23.166442Z", + "generated_from_event_id": null, "tasks": [ { "id": "phase-a", "title": "GATE + Lock + Store + Protocol(4ファイル新規)", - "github_issue_number": 0, - "state": "implementing", + "current_state": "implementing", "dependencies": [], - "dependents": ["phase-b", "phase-c"], + "dependents": [ + "phase-b", + "phase-c" + ], "soft_dependencies": [], "lock": { "locked_by": "codex-a@macbook-pro", "locked_at": "2026-04-10T01:30:00Z", - "ttl_secs": 3600, + "lease_duration_sec": 3600, + "last_heartbeat": "2026-04-10T01:30:00Z", "affected_files": [ "crates/miyabi-core/src/gate.rs", "crates/miyabi-core/src/lock.rs", @@ -25,56 +29,243 @@ "risk_level": "LOW", "affected_symbols": 0, "depth1": [], - "analyzed_at": "2026-04-10T01:25:00Z" + "analyzed_at": "2026-04-10T01:25:00Z", + "analyzed_commit": null, + "input_hash": null }, "branch_name": null, - "pr_number": null, - "merge_commit": null, + "github_evidence": null, + "completion_mode": "github_pr", + "human_approval": null, + "priority": 0, "created_at": "2026-04-10T01:30:00Z", "updated_at": "2026-04-10T01:30:00Z" }, { "id": "phase-b", "title": "CLI サブコマンド追加", - "github_issue_number": 0, - "state": "pending", - "dependencies": ["phase-a"], - "dependents": ["phase-c"], + "current_state": "pending", + "dependencies": [ + "phase-a" + ], + "dependents": [ + "phase-c" + ], "soft_dependencies": [], "lock": null, "impact": null, "branch_name": null, - "pr_number": null, - "merge_commit": null, + "github_evidence": null, + "completion_mode": "github_pr", + "human_approval": null, + "priority": 0, "created_at": "2026-04-10T01:30:00Z", "updated_at": "2026-04-10T01:30:00Z" }, { "id": "phase-c", "title": "GitHub Evidence + E2E テスト", - "github_issue_number": 0, - "state": "pending", - "dependencies": ["phase-a", "phase-b"], + "current_state": "pending", + "dependencies": [ + "phase-a", + "phase-b" + ], "dependents": [], "soft_dependencies": [], "lock": null, "impact": null, "branch_name": null, - "pr_number": null, - "merge_commit": null, + "github_evidence": null, + "completion_mode": "github_pr", + "human_approval": null, + "priority": 0, "created_at": "2026-04-10T01:30:00Z", "updated_at": "2026-04-10T01:30:00Z" + }, + { + "id": "issue-51", + "title": "Add Agent mode to help documentation", + "current_state": "implementing", + "dependencies": [], + "dependents": [], + "soft_dependencies": [], + "lock": { + "locked_by": "claude@macbook-pro", + "locked_at": "2026-04-09T21:32:36.199414Z", + "lease_duration_sec": 300, + "last_heartbeat": "2026-04-09T21:32:36.199414Z", + "affected_files": [ + "docs/USER_MANUAL.md" + ] + }, + "impact": { + "risk_level": "LOW", + "affected_symbols": 0, + "depth1": [], + "analyzed_at": "2026-04-09T21:32:36.193830Z", + "analyzed_commit": null, + "input_hash": null + }, + "branch_name": "feature/issue-51-agent-help-docs", + "github_evidence": null, + "completion_mode": "github_pr", + "human_approval": null, + "priority": 0, + "created_at": "2026-04-09T21:32:36.183108Z", + "updated_at": "2026-04-09T21:32:36.210553Z" + }, + { + "id": "issue-50", + "title": "Add progress indicator for long-running agent tasks", + "current_state": "implementing", + "dependencies": [], + "dependents": [], + "soft_dependencies": [], + "lock": { + "locked_by": "codex-b@macbook-pro", + "locked_at": "2026-04-09T21:33:14.098441Z", + "lease_duration_sec": 300, + "last_heartbeat": "2026-04-09T21:33:14.098441Z", + "affected_files": [ + "crates/miyabi-tui/src/app.rs", + "crates/miyabi-tui/src/views.rs" + ] + }, + "impact": { + "risk_level": "MEDIUM", + "affected_symbols": 5, + "depth1": [], + "analyzed_at": "2026-04-09T21:33:14.093332Z", + "analyzed_commit": null, + "input_hash": null + }, + "branch_name": null, + "github_evidence": null, + "completion_mode": "github_pr", + "human_approval": null, + "priority": 0, + "created_at": "2026-04-09T21:33:03.117158Z", + "updated_at": "2026-04-09T21:33:14.098828Z" + }, + { + "id": "issue-49", + "title": "Add interactive tool approval in TUI Agent mode", + "current_state": "implementing", + "dependencies": [], + "dependents": [], + "soft_dependencies": [], + "lock": { + "locked_by": "codex-c@macbook-pro", + "locked_at": "2026-04-09T21:33:14.107550Z", + "lease_duration_sec": 300, + "last_heartbeat": "2026-04-09T21:33:14.107550Z", + "affected_files": [ + "crates/miyabi-tui/src/approval_overlay.rs" + ] + }, + "impact": { + "risk_level": "MEDIUM", + "affected_symbols": 3, + "depth1": [], + "analyzed_at": "2026-04-09T21:33:14.103055Z", + "analyzed_commit": null, + "input_hash": null + }, + "branch_name": null, + "github_evidence": null, + "completion_mode": "github_pr", + "human_approval": null, + "priority": 0, + "created_at": "2026-04-09T21:33:03.121698Z", + "updated_at": "2026-04-09T21:33:14.107940Z" + }, + { + "id": "issue-48", + "title": "Implement Context Manager for memory management", + "current_state": "implementing", + "dependencies": [], + "dependents": [], + "soft_dependencies": [], + "lock": { + "locked_by": "claude-sub@macbook-pro", + "locked_at": "2026-04-09T21:33:23.165977Z", + "lease_duration_sec": 300, + "last_heartbeat": "2026-04-09T21:33:23.165977Z", + "affected_files": [ + "crates/miyabi-core/src/conversation.rs" + ] + }, + "impact": { + "risk_level": "HIGH", + "affected_symbols": 8, + "depth1": [], + "analyzed_at": "2026-04-09T21:33:14.112255Z", + "analyzed_commit": null, + "input_hash": null + }, + "branch_name": null, + "github_evidence": null, + "completion_mode": "github_pr", + "human_approval": null, + "priority": 0, + "created_at": "2026-04-09T21:33:03.126596Z", + "updated_at": "2026-04-09T21:33:23.166407Z" } ], "file_locks": { - "crates/miyabi-core/src/gate.rs": "phase-a", - "crates/miyabi-core/src/lock.rs": "phase-a", - "crates/miyabi-core/src/protocol.rs": "phase-a", - "crates/miyabi-core/src/store.rs": "phase-a" - }, - "dag_levels": [ - ["phase-a"], - ["phase-b"], - ["phase-c"] - ] -} + "crates/miyabi-core/src/gate.rs": { + "task_id": "phase-a", + "agent": "codex-a", + "node": "macbook-pro", + "expires_at": "2026-04-10T02:30:00Z" + }, + "crates/miyabi-tui/src/views.rs": { + "task_id": "issue-50", + "agent": "codex-b", + "node": "macbook-pro", + "expires_at": "2026-04-09T21:40:14.098441Z" + }, + "crates/miyabi-core/src/lock.rs": { + "task_id": "phase-a", + "agent": "codex-a", + "node": "macbook-pro", + "expires_at": "2026-04-10T02:30:00Z" + }, + "crates/miyabi-tui/src/approval_overlay.rs": { + "task_id": "issue-49", + "agent": "codex-c", + "node": "macbook-pro", + "expires_at": "2026-04-09T21:40:14.107550Z" + }, + "crates/miyabi-core/src/protocol.rs": { + "task_id": "phase-a", + "agent": "codex-a", + "node": "macbook-pro", + "expires_at": "2026-04-10T02:30:00Z" + }, + "crates/miyabi-core/src/store.rs": { + "task_id": "phase-a", + "agent": "codex-a", + "node": "macbook-pro", + "expires_at": "2026-04-10T02:30:00Z" + }, + "crates/miyabi-tui/src/app.rs": { + "task_id": "issue-50", + "agent": "codex-b", + "node": "macbook-pro", + "expires_at": "2026-04-09T21:40:14.098441Z" + }, + "crates/miyabi-core/src/conversation.rs": { + "task_id": "issue-48", + "agent": "claude-sub", + "node": "macbook-pro", + "expires_at": "2026-04-09T21:40:23.165977Z" + }, + "docs/USER_MANUAL.md": { + "task_id": "issue-51", + "agent": "claude", + "node": "macbook-pro", + "expires_at": "2026-04-09T21:39:36.199414Z" + } + } +} \ No newline at end of file