[文書] Phase C 修正計画 + GitHub Issue 6件起票 + ラベル設定

検証で発見した GATE の甘い部分 6 件:
  #52: Issue=0 で登録拒否されない
  #53: ブランチ名バリデーションがない
  #54: HIGH risk で承認なしに assign できる
  #55: merge 後にロックが解放されない
  #56: 不正 SHA の exit code が 2 だが 1 が正しい
  #57: 依存未解決の assign が exit 0

ラベル: dtp, gate-fix, phase-c を作成・付与
autorun/sprint-1-today/FIXES.md に修正計画を記載

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
林 駿甫 (Shunsuke Hayashi) 2026-04-10 06:36:57 +09:00
parent 6cc892347b
commit 1f9fb248cf
4 changed files with 420 additions and 31 deletions

View file

@ -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 通過)

View file

View file

@ -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}

View file

@ -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 + Protocol4ファイル新規",
"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"
"crates/miyabi-core/src/gate.rs": {
"task_id": "phase-a",
"agent": "codex-a",
"node": "macbook-pro",
"expires_at": "2026-04-10T02:30:00Z"
},
"dag_levels": [
["phase-a"],
["phase-b"],
["phase-c"]
]
"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"
}
}
}