mergegate/autorun/sprint-1-today/FIXES.md
林 駿甫 (Shunsuke Hayashi) 1f9fb248cf [文書] 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>
2026-04-10 06:36:57 +09:00

5.5 KiB
Raw Blame History

Phase C 修正計画 — GATE の甘い部分を全て潰す

検証で発見した 6 件の不具合を修正する


修正 1: GATE 0 — Issue=0 で登録拒否

現状: register --title "test" が issue=0 でも通る 期待: issue > 0 でなければ登録拒否

修正箇所: crates/miyabi-core/src/protocol.rs の register 処理

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 検証

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 処理

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 lowassign そのまま OK

修正 4: GATE 7 — merge 後のロック自動解放

現状: merge 後も locks にファイルが残る 期待: merge 成功時にロック自動解放 + 後続タスクの依存解除

修正箇所: crates/miyabi-core/src/protocol.rs の merge 処理

// 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 マッピング

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