Skip to content

feat(autonomy): 自律実行の全体 kill-switch を追加 (WP-17 PR 1, ADR-066) - #347

Merged
aloekun merged 4 commits into
masterfrom
feat/wp17-pr1-autonomy-kill-switch
Aug 2, 2026
Merged

feat(autonomy): 自律実行の全体 kill-switch を追加 (WP-17 PR 1, ADR-066)#347
aloekun merged 4 commits into
masterfrom
feat/wp17-pr1-autonomy-kill-switch

Conversation

@aloekun

@aloekun aloekun commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • 自律実行の可否を機械判定する cli-autonomy-gate を新設。repo config [autonomy] enabled
    外部フラグ AUTONOMY_ENABLED の AND で評価し、欠損・parse 失敗・型違い・ゴミ値はすべて停止に倒す
  • fail-closed を I/O を持たない純粋判定コア 1 関数へ集約し、呼び手による env/config 直読みを禁止
    (片方の呼び手だけが unwrap_or(true) を書いて無音で fail-open する drift の防止)
  • 背圧契約を操作クラス別に実装。draft-pr は未マージ draft 数の背圧 (WP-18) が入るまで構造的に deny
  • deny は loud ([AUTONOMY_OFF] + 全ソース状態行) + ADR-055 telemetry。無音 no-op を禁止
  • ADR-066 を起票し、フラグ台帳 (全 12 フラグの極性・欠損時挙動) で極性混在を文書化された在庫へ変換
  • WP-17 の作業計画を 4 PR 分割で確定 (計画書)

Context

Why: ADR-052 原則 5 は「config opt-in と kill-switch の両方が接続され機能していること」を
自動実行可クラス有効化の前提条件と定めるが、その実体が無かった。既存 kill-switch はすべて機能個別で、
全自律動作を止める単一フラグが存在しない。

Trigger: 2026-08-02 の WP-17 着手前レビュー。計画書の依存グラフは全体 kill-switch を WP-19
(最後尾・WP-18 依存) に置いており、無人 fix push (WP-17) が先に来る順序だった。このまま進むと
ADR-052 原則 5 に違反した状態で自動実行可クラスが有効化されるため、kill-switch を WP-17 の先頭
PR へ前倒しすることをユーザー承認のうえ決定した。

設計レビューでの訂正: 着手時の案は「既存はすべて負極性の *_DISABLE、本フラグは極性が逆」
だったが、棚卸しの結果この前提が不正確と判明。本リポジトリには既に正極性の opt-in 家系
([telemetry] enabled / CLOUD_HARNESS) があり、本フラグはその合流である。負極性案は
(a) Actions の vars が未定義を空文字列に評価するため削除・typo・移行漏れが無音で「許可」に倒れる、
(b) ADR-060 が訓練済みの「変数削除 = 停止」と操作反射が逆になる、の 2 点で退けた。

Scope decision: 呼び手 (Phase B の無人 fix push) は PR 2 で実装するため本 PR には含めない。
autonomy-config.tomlenabledfalse のままで、マージしても運用挙動は一切変わらない。
ADR-052 原則 5 が kill-switch の先行を前提条件として要求しているための意図的な順序。

Validation

  • cargo test --workspace: 全 crate pass (失敗 0)。うち cli-autonomy-gate は 21 件
    (判定コア 9 / sources 6 / 引数解析 6)。1 件は external 9 種 × repo config 3 種 × operation 2 種
    = 54 組合せを走査し「許可されるのは 3 条件が揃った場合だけ」を網羅的に固定
  • cargo clippy --workspace --all-targets -- -D warnings: 緑
  • pnpm lint:docs / pnpm lint:md (119 ファイル): 0 error
  • 実 exe による kill-switch drill 8 シナリオ: 外部フラグ未設定 / 非 truthy (maybe) / config 不在 /
    config false → 全て exit 1 + [AUTONOMY_OFF]、全ソース有効 + fix-push → exit 0、
    全ソース有効 + draft-pr → exit 1 (背圧未接続)、--config 省略 → exit 2。全て設計どおり
  • pnpm push pre-push review: verdict=APPROVE (anomaly scan 6 カテゴリすべて指摘なし、3m20s)

References

Summary by CodeRabbit

  • 新機能

    • 自律実行の全体キルスイッチを追加しました。
    • リポジトリ設定と環境設定の両方が有効な場合のみ、自律操作を許可します。
    • 現在の既定値は無効です。
  • 安全性の向上

    • 設定の欠落・不正値・読み取り失敗時は自動的に拒否します。
    • 操作直前に毎回判定し、拒否理由と状態を明確に表示します。
    • fix-push のみ許可対象とし、未接続の操作は拒否します。
  • ドキュメント

    • キルスイッチの運用方針、検証手順、今後の計画を追加・更新しました。

aloekun and others added 4 commits August 2, 2026 17:12
2026-08-02 の着手前レビュー (依存検証 + ユーザー確認 + kill-switch 設計レビュー)
の結果を計画書へ反映し、実装セッションが WP-17 節のみで着手できる自己完結記述に
書き換えた。

決定 3 件:
- WP-19 step 1 (全体 kill-switch) を WP-17 PR 1 へ前倒し。ADR-052 原則 5 が
  「config opt-in と kill-switch の接続」を自動実行可クラス有効化の前提条件と
  しており、計画書の依存欄 (WP-17 → WP-09/10/11) と食い違っていたため
- ADR-064 検証残は PR 3 の wakeup 廃止に伴い移し替え ((a) park 実観測は moot、
  (b) 判定文の保留保証は Actions 経路の検証残として引き継ぎ)
- Claude GitHub App は未インストール。routine 移行 (PR 4) はユーザーの Web UI
  作業とセットのため最後に回す

PR 1 の設計は正極性の単一フラグ ([autonomy] enabled + Actions variable
AUTONOMY_ENABLED、default OFF) を採用し、負極性 (*_KILL=1 で停止) は退けた。
GitHub Actions の vars は未定義 variable を空文字列に評価するため、負極性条件では
変数の削除・typo・移行漏れが無音で「許可」に倒れ ADR-052 原則 5 に違反する。
あわせて ADR-060 の CLOUD_HARNESS が訓練済みの「変数削除 = 停止」と操作反射も揃う。

検証で判明した既存記述の stale:
- ADR-052 実装スコープ節の「gate.rs の docs-only 判定は pub(crate) 内部限定、
  将来 lib へ切り出す」は ADR-057 の副産物として完了済み (lib-docs-policy)。
  PR 2 で訂正する旨を計画書に記載

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ADR-052 原則 5 の「config opt-in と kill-switch の両方が接続され機能していること」を
自動実行可クラスの前提条件として機械判定する exe を新設する。呼び手 (Phase B の無人
fix push、夜間ループ、cloud routine) は操作の直前に本 exe を呼び、exit コードで許可を
受け取る。

正極性の単一フラグ (AND 合成):
- リポジトリ内 config `[autonomy] enabled` (bool)
- 外部フラグ env AUTONOMY_ENABLED (CI では Actions variable を写す)
どちらか一方でも欠損・非 truthy なら deny。「未設定 = 停止」なので変数の削除が
そのまま緊急停止になり、ADR-060 の CLOUD_HARNESS と操作反射が揃う。

背圧契約を操作クラス別に表現 (ADR-052 原則 5):
- fix-push: 背圧は cli-pr-monitor の有界 retry。接続済み
- draft-pr: 背圧は未マージ draft 数で WP-18 まで未接続 → 常に deny。kill-switch だけ
  有効化して draft の山を積む経路を構造的に塞ぐ (placeholder ではなく現時点の正解)

構成:
- decision.rs: I/O を持たない純粋判定コア。fail-closed をこの 1 関数へ集約し、
  呼び手が env/config を直読みして独自に真偽を組み立てる drift を禁止する
- sources.rs: config/env 読み取り。エラーは一律 None へ潰す (区別しても判定は
  変わらず、「この Err なら通してよい」の誤読余地を作らないため)
- main.rs: 引数解析と loud 出力。allow/deny のどちらでも全ソース状態と読み取り先
  config パスを出す (無音 no-op 禁止)。deny は ADR-055 telemetry へ理由コードのみ記録

exit コードは 0=許可 / 1=拒否 / 2=引数不正。呼び手は非ゼロを全て拒否として扱う契約
(2 を通すと引数ミスで fail-open するため module doc に明記)。

テスト 21 件。うち 1 件は external 9 種 × repo config 3 種 × operation 2 種の全 54
組み合わせを走査し、「許可されるのは 3 条件が揃った場合だけ」を網羅的に固定する。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
cli-autonomy-gate が読む autonomy-config.toml をリポジトリルートに新設し、
build:all / autonomy-status を package.json へ配線する。

専用ファイルにした理由 (pr-monitor-config.toml へ相乗りしない):
- cli-pr-monitor 専用ではない横断フラグ (Phase B / 夜間ループ / cloud routine が共有)
- CI からは master ref の写しを読ませる必要があり、小さい専用ファイルの方が
  workflow 側の抽出が 1 パスで済み監査しやすい
- toml parse 失敗は fail-closed (自律停止) に倒れるため、無関係な section の typo が
  自律動作を止めないよう blast radius を分離する
計画書は「pr-monitor-config.toml への section 追加が第一候補、実装時判断可」としていた
ので、その判断枠内での選択。根拠は ADR に記録する。

初期値は enabled = false。呼び手 (Phase B の無人 fix push) は PR 2 で実装されるため
現時点で true にしても作用する経路が無く、マージしても運用挙動が変わらない。
PR 2 で経路と drill を揃えてから true へ倒す。

templates/autonomy-config.toml は「コピーは任意」と明記した。派生プロジェクトは
ファイルが無ければ常に deny = 安全側 default になるため、deploy-hooks.ts の
「見つからなければ作成を促す」警告対象には**しない** (必須 config ではない)。

実 exe による kill-switch drill 8 シナリオを実施し全て設計どおりを確認:
- 外部フラグ未設定 / 非 truthy ("maybe") / config 不在 / config false → 全て exit 1 +
  [AUTONOMY_OFF] マーカー + 全ソース状態行
- 全ソース有効 + fix-push → exit 0 + [AUTONOMY_ALLOW]
- 全ソース有効 + draft-pr → exit 1 (背圧未接続)
- 引数不正 → exit 2

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kill-switch の設計判断を永続成果物へ移管する。計画書 (ephemeral) の PR 1 節は
ADR 参照 + 残作業のみへ縮約した (順位 117 の知識移管 3 ステップ: permanent 先行作成
→ 参照付け替え → ephemeral から削除)。

ADR-066 が記録する主な決定:
- 統一原則は「フラグの極性」ではなく「入力の欠損・読み取り不能・解釈不能は、その機構の
  安全状態へ解決する」。ゲートの安全状態 = ゲート有効 (負極性の緊急バイパス env 家系)、
  自律 actor の安全状態 = 停止 (正極性の opt-in 家系)。混在はこの原則の下で整合する
- 正極性の単一フラグ (repo config + 外部フラグの AND)。負極性を退けた根拠は
  (a) Actions の vars が未定義を空文字列に評価するため負極性条件は削除・typo・移行漏れが
  無音で「許可」に倒れる、(b) ADR-060 の CLOUD_HARNESS が訓練済みの「変数削除 = 停止」と
  操作反射が逆になりインシデント時の人為ミスを招く
- 実行コンテキスト別の権威マッピング。CI では master ref の写しを読む契約 (PR ブランチの
  checkout を読むと自律 actor が自己解除でき、ADR-054 と同型の穴になる)
- 背圧接続は操作クラス別の前提条件 (ADR-052 原則 5 の曖昧さを解消)
- フラグ台帳: 全 12 フラグの極性・欠損時挙動を一覧化し、混在を暗黙の慣習から
  文書化された在庫へ変える。正極性=有効化 (未設定は安全側) / 負極性=緊急バイパス
  (未設定は現状維持) の 2 家系に分類し、未設定が「許可」に倒れる経路が無いことを示す

bounded lifetime: Phase B 稼働後の自律 fix push 3-5 run で有効時通過・フラグ倒しで
停止・deny 理由の切り分け可能性を確認したら本採用。2026-11-02 までに未判定なら
延長/却下を判断する。

検証: cargo clippy --workspace -D warnings 緑、cargo test --workspace 緑 (失敗 0)、
pnpm lint:docs / lint:md 緑。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f64079e3-9d74-4234-bb56-5fb192e9d075

📥 Commits

Reviewing files that changed from the base of the PR and between d680a54 and 680fa82.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • CLAUDE.md
  • Cargo.toml
  • autonomy-config.toml
  • docs/adr/adr-066-autonomy-global-kill-switch.md
  • docs/harness-improvement-plan.md
  • package.json
  • src/cli-autonomy-gate/Cargo.toml
  • src/cli-autonomy-gate/src/decision.rs
  • src/cli-autonomy-gate/src/main.rs
  • src/cli-autonomy-gate/src/sources.rs
  • templates/autonomy-config.toml

📝 Walkthrough

Walkthrough

自律実行用の全体 kill-switch を追加しました。設定と環境変数を AND 判定し、cli-autonomy-gate が操作ごとの許可・拒否、出力、終了コード、テレメトリを管理します。Cargo workspace、ビルドスクリプト、ADR、計画文書も更新しました。

Changes

自律実行ゲート

Layer / File(s) Summary
ポリシーと設定契約
autonomy-config.toml, templates/autonomy-config.toml, docs/adr/..., docs/harness-improvement-plan.md, CLAUDE.md
[autonomy].enabledAUTONOMY_ENABLED の AND 判定を定義しました。欠落、不正値、parse 失敗では deny します。fix-pushdraft-pr の背圧条件、信頼境界、終了コード、運用計画を文書化しました。
設定読み取りと判定コア
src/cli-autonomy-gate/Cargo.toml, src/cli-autonomy-gate/src/sources.rs, src/cli-autonomy-gate/src/decision.rs
TOML 設定と環境変数を読み取ります。FixPush の許可条件、DraftPr の deny、拒否理由コード、診断値のサニタイズ、判定テストを追加しました。
CLI 実行とビルド統合
src/cli-autonomy-gate/src/main.rs, Cargo.toml, package.json
--operation--config を解析します。allow/deny の出力、終了コード、拒否テレメトリを実装しました。Cargo workspace と build:all にゲートを追加し、autonomy-status を登録しました。

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI as cli-autonomy-gate
  participant Sources as sources
  participant Decision as decision::evaluate
  participant Telemetry as lib-telemetry

  CLI->>Sources: 設定ファイルと AUTONOMY_ENABLED を読み取る
  Sources-->>CLI: GateInputs を返す
  CLI->>Decision: 操作種別と GateInputs を評価する
  Decision-->>CLI: Allowed または Denied を返す
  CLI->>Telemetry: deny 理由コードを記録する
  CLI-->>CLI: stdout/stderr と終了コードを出力する
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルは、自律実行の全体 kill-switch の追加という変更の主目的を明確かつ簡潔に示しています。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/wp17-pr1-autonomy-kill-switch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

🤖 PR Monitor 分析 (GitHub Actions バックストップ)

  • トリガー: issue_comment (created) / 実行 run
  • CI: rust (ubuntu-latest) IN_PROGRESS / rust (windows-latest) IN_PROGRESS / CodeRabbit PENDING(いずれも未完了、mergeStateStatus は UNSTABLE)
  • レビュー状況: CodeRabbit はレビュー未着("Currently processing new changes..." のプレースホルダコメントのみ)。人間レビューも未提出(reviews 0 件、インラインコメント 0 件)
  • Verdict: user_decision(CI・CodeRabbit レビューとも未完了で、判定材料が揃っていない)

Applicable Findings (Critical / High / Major)

該当なし(レビュー未着のため指摘 0 件)

Applicable Findings (Medium 以下)

(該当なし)

Filtered (not applicable)

(該当なし)

次のアクション

  • CI(rust ubuntu/windows)と CodeRabbit レビューの完了を待ち、完了後に再度この監視を発火させる(新規レビュー/インライン指摘/CI状態変化があれば次回分析対象)
  • 本 PR は WP-17 PR 1(ADR-066: 自律実行の全体 kill-switch)で、新規 crate cli-autonomy-gateautonomy-config.toml の追加が中心(12 files changed, 概算 +1000/-10 行)。設計意図は ADR-066 で確認可能なため、レビュー到着後の fitness filter 判定時に参照すること

@aloekun
aloekun merged commit 811a3db into master Aug 2, 2026
3 checks passed
@aloekun
aloekun deleted the feat/wp17-pr1-autonomy-kill-switch branch August 2, 2026 09:19
aloekun added a commit that referenced this pull request Aug 2, 2026
PR #347 マージ後の実績を計画書へ反映する。ADR-066 側には検証記録・bounded
lifetime とも記載済みで永続成果物に欠落は無く、不足していたのは ephemeral な
計画書側の進捗追跡のみだった。

反映した 3 点:
- 全体像の表: WP-17 の状態に PR 番号とマージ日を記録 (他の WP 行と同じ運用。
  「実装済」だけでは master に入ったか作業中かが本ファイルから判別できなかった)
- PR 1 節: 見出しに PR #347 / マージ日を追加。マージ時点の状態 (enabled = false +
  呼び手なしのため運用挙動の変化ゼロ、各レビュー指摘ゼロ) と、§ 0 の状態遷移
  規約に沿った現在地 (`実装済`、`観測中` へ進むのは PR 2 で呼び手が生まれてから。
  観測は ADR-066 の bounded lifetime が管理) を明記
- 受け入れ基準: 「PR 1-2」の 1 項目を PR 1 (exe 単体 drill = 充足済) と
  PR 2 (Phase B 経路 = 未充足) に分割。残作業がどちらの PR のものか読み取れる
  ようにした

本コミットは docs-only 差分のため単独 PR にせず WP-17 PR 2 系の PR に同梱する
(ユーザー承認済み。doc 変更をマイルストーンでまとめる運用方針に従う)。
なお WP-17 PR 2 はその後 PR size gate (1613 行 > block 1500) により 2a / 2b へ
分割され、本コミットは 2a 側に載っている。

検証: pnpm lint:docs / lint:md (119 ファイル) ともに 0 error。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aloekun added a commit that referenced this pull request Aug 3, 2026
…350)

* docs(harness-plan): WP-17 の実行状況と再分割計画 (2a/2b/2c) を反映

ここまでの実行状況を master 版計画書へ反映し、WP-17 PR 2 の再分割を別セッションの
Opus がドキュメントのみで実施できる自己完結記述にする。

反映した実行状況:
- PR 1 (ADR-066 / #347): 完了。exe 単体 drill 充足済、観測中への遷移は 2c 後
- PR 2: 実装済・未 land。incident (gut-revert) と事前整備 2 本
  (ADR-068 / #348、ADR-069 / #349 = マージ済) の経緯を 3 行で要約
- Actions variable AUTONOMY_ENABLED 設定済みの事実と、2c マージで Phase B が
  即 live になる帰結 (マージ前の variable 削除推奨) を明記

再分割計画 (2a/2b/2c) の要点:
- 資産表: ローカル jj コミット 8 件を change_id で列挙 (rebase 耐性のため
  commit_id ではなく change_id を正とする旨を明記)、実在確認コマンド付き
- 2a: 計画書 (本コミット) + rename パーサ修正。mxzwmsyp は gut-revert 混入のため
  rebase 不可 — tests.rs は restore、diff.rs は #348 の pub(crate) 変更と重なるため
  hunk 単位の手適用、という回収手順を明記
- 2b: lib 抽出 + cli-fix-push-gate を同一 PR (ADR-044 充足 = incident の失敗の裏返し)。
  ADR-069 chain 宣言の本文を計画書に事前記載し、2b の diff に載せる手順と
  「初回 dogfood の実測結果を ADR-069 へ記帳」まで指示
- 2c: workflow + config 有効化 + ADR-067。マージ後の実走スモーク段 0-2 (ユーザー
  操作込み) を順序付きで記載
- jj 運用の注意: describe 適用先事故 (本セッションで 3 回発生) の予防として
  「編集前に必ず jj new」を明記。ADR-016 / ADR-028 / VSCode での draft 提示方法も記載

受け入れ基準を再分割構成に合わせて更新 (PR 1 / 2b drill = 充足済、2c = 実走スモーク)。

本コミットは未 push (master の local 子)。再分割 2a の先頭コミットとして次セッションが
流用する (計画書 § 2a 手順 1 に記載)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(cli-push-runner): rename summary の波括弧形式をパースできるよう修正 (WP-17 2a)

`jj diff --summary` の rename / copy 行を誤ってパースし、**rename を含む PR が一律
push 不能** になっていた不具合を修正する。WP-17 PR 2a の push が exit 5 で停止して
顕在化した。

## 実測書式と旧実装のずれ

jj (0.42.0 / Windows) は共通 prefix / suffix を括り出した波括弧形式で出す:

    R src\{cli-autonomy-gate => lib-autonomy-policy}\src\decision.rs

旧実装は `<status> <old> <new>` の 3 トークン空白区切りを前提に rsplit_once(' ')
していたため、上の行から `lib-autonomy-policy}\src\decision.rs` という壊れたパスを
取り出していた。これが `--git` 側の `b/src/lib-autonomy-policy/src/decision.rs` と
一致せず、常に「未収録」と判定されていた。

判定は block 側に倒れるので fail-closed ではあるが、正当な push を止める誤検知。

## 根拠が fixture だった問題

3 トークン形式を前提にした根拠は、コード内コメントが引用していた lib_docs_policy の
`"R docs/a.md docs/b.md"` というテスト文字列だった。これは jj の出力を観測したもの
ではなく手で作った fixture で、実挙動の証拠になっていない。dev-conventions の
「外部 fixture 参照テストは値まで assert」が想定する失敗そのもの。本コミットの
テストは実測値を定数 OBSERVED_RENAME_SUMMARY として持ち、それを assert する。

## 修正方針

個別ケースを潰すのではなく、rename 行の入力空間を 1 バッチで固定する
(dev-conventions: パーサ修正は全 branch を一度に堅牢化):
- 波括弧形式: prefix + new + suffix を結合して復元
- 矢印形式 (共通部分なし): `old => new` の new 側
- 上記以外 (旧 3 トークン形式・閉じ括弧欠落・矢印欠落) は None → Err で fail-closed

空白区切りへの fallback は残さない。波括弧のパースに失敗した行が fallback で
「それらしいパス」に化けると書式変化を検知できず gate が沈黙するため
(既存方針「未知は明示的に reject」と同じ)。

波括弧の全 branch (中間 rename / 上位移動 `{sub/ => }` / 下位移動 `{ => sub/}` /
ファイル名のみ / copy) をテーブル駆動で固定した。

## 回収経緯

本修正の実装は 2026-08-02 の incident コミット (mxzwmsyp) に lib 抽出の gut-revert と
混在していたため、rebase / duplicate では回収できなかった。tests.rs は master 未変更の
ため restore、diff.rs は #348 の `parse_git_diff_paths` pub(crate) 化と衝突するため
`summary_line_new_path` の R/C 分岐と `rename_new_path` 追加だけを手で適用している
(計画書 § WP-17 2a 手順 2)。`summary_line_new_path` の doc は「末尾トークン」前提の
記述が本修正で stale になるため現状に合わせて更新した。

検証: cargo test -p cli-push-runner 291 件 pass、clippy -D warnings 緑。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(cli-push-runner): rename パーサの空白扱いを両分岐で揃える + 計画書の前提を明記 (WP-17 2a)

PR #350 の CodeRabbit 指摘 3 件への対応。

## 1. rename_new_path の矢印分岐から冗長な trim を削除

指摘: 「パスから空白を除去しないでください」(diff.rs、Minor)。

矢印分岐だけが `new.trim()` していて波括弧分岐 (`format!` で結合、trim なし) と
非対称だった。呼び出し元 `summary_line_new_path` が既に `rest.trim()` 済みの文字列を
渡す唯一の呼び手なので、この trim は冗長でもある。

**これはバグ修正ではなく対称性の回復である**: 現実的な入力では両者の結果は一致し、
削除による挙動変化は観測できない (だからこそ安全に削除できる)。狙いは「同じパスが
分岐によって違う結果になり得る」状態を残さないこと。

なお post-pr-review の分析は本指摘を false positive と判定していたが、根拠が誤り
だった (指摘位置を `path.replace('\', "/")` と読み「バックスラッシュ変換であって
空白除去ではない」とした)。CodeRabbit は複数行コメントを範囲末尾に anchor するため
実際の対象は関数全体で、trim は確かに存在した。結論 (非ブロッキング) は一致するが
理由が違うので、指摘の芯を採用して直す。

テストには空白を含むパスのケースを 2 件追加した (波括弧 / 矢印の両分岐)。区切りの
`" => "` と紛れる位置に空白があっても内部の空白が保持され、両分岐が同じ結果を返す
ことを固定する。

## 2. tests.rs restore の前提を明記 (docs)

指摘: 「復元前に tests.rs の復元前提を明記してください」(計画書 L164、Minor)。

`jj restore` で丸ごと上書きしてよいのは「master 側が未変更」の間だけ。前提の確認
コマンドと、崩れていた場合の切り替え先 (diff.rs と同じ hunk 単位の手適用) を書いた。
前提を確認せず restore すると master 側の変更を無言で巻き戻すため、確認手順まで含めて
残す。

## 3. workflow_dispatch の ref 選択を明記 + スモーク段 0.5 を追加 (docs)

指摘: 「workflow_dispatch は PR head branch を受け取ると記載してください」
(計画書 L193、Minor)。

dispatch は起動時に ref を選べ、選んだ ref 版の workflow 定義で走る。これは 2c の
実走スモークの前提として重要で、計画書が「マージ後の実走スモーク」としか書いて
いなかったのは記述不足だった。fix job はマージ前に 2c ブランチ ref に対して実走できる。

これを踏まえ段 0.5 (マージ前 dispatch) を追加した。gate と config は master ref から
調達される (ADR-066 決定 3) ため、マージ前は config が `enabled = false` のままで
fix job は config 層で停止する = **deny 経路 (kill-switch が効く側) をマージ前に検証でき、
allow 経路だけがマージ後に残る**。`AUTONOMY_ENABLED` が既に true で「2c マージ = 即 live」
の一発勝負になる状況に対する段階化として意味がある。

手順 4 (マージ前に variable を削除して段階を踏む案) は段 0.5 が variable 層を通す必要が
あるため順序が矛盾していた。削除するとしても段 0.5 の後、と順序を明記して整合させた。

検証: cargo test -p cli-push-runner 291 件 pass、clippy -D warnings 緑。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant