Skip to content

[Fix] filter無しoptional sync_fileのバージョンドリフト検知を修正#179

Merged
BlueEventHorizon merged 1 commit into
developfrom
fix/175-version-drift-filter-less-optional-sync-file
Jul 7, 2026
Merged

[Fix] filter無しoptional sync_fileのバージョンドリフト検知を修正#179
BlueEventHorizon merged 1 commit into
developfrom
fix/175-version-drift-filter-less-optional-sync-file

Conversation

@BlueEventHorizon

Copy link
Copy Markdown
Owner

概要

背景

Issue #157 / PR #170update_version_files.py に drift(更新漏れ)と not-applicable(対象パターン無し)を区別する仕組みを --filter 経路(_update_with_filter)に導入した。
しかし filter 無し経路(_update_with_path / _replace_first)にはこの区別が実装されておらず、--optional 併用時は従来通り一律 status: skipped に分類され続けていた。本リポジトリの .version-config.yaml は全 sync_files に filter が設定されているため現状は顕在化しないが、filter 無しの optional sync_file を持つ下流プロジェクトでは Issue #157 と同型のサイレントドリフトが再発しうる。

やったこと

  • _update_with_path()(filter 無し・version_path 使用の path モード)に、filter モードと同型のドリフト検出(VersionDriftError と対象外の ValueError の分離)を追加
  • ネストパスの親キー解決を parts[-2](直近1階層のみ)から親キーチェーン全体(parts[:-1])を順にたどる方式に一般化し、3階層以上のパスで同名の中間キーが複数存在する場合の誤更新を修正(単独修正レビューで検出)
  • field_pattern / parent_pattern に語境界(\b)を追加し、other_version のような無関係なキーへの誤マッチを防止(単独修正レビューで検出)
  • --optional 指定時のファイル不在を status: "skipped" として扱うよう修正し、DES-023 §5.2 で定義されている「sync_file 不在 + optional: true → スキップ」との非対称を解消
  • get_version_status.py の手製 YAML パーサーが optional: false を文字列 "false" のまま返し、契約テストの bool(sync.get("optional")) が常に True になっていたバグを修正(_is_optional_flag() ヘルパーを追加)
  • 契約テスト(tests/common/test_version_sync_drift.py)の FilterNotFoundError を optional の有無を問わず一律 continue していた不備を修正し、optional: false の必須エントリで filter が消失した場合はテスト失敗として検出するようにした
  • docs/specs/forge/design/DES-023_version_management_workflow_design.md を上記の実装変更に合わせて更新

やらないこと(このプルリクエストのスコープ外とすること)

  • _replace_first()(simple モード)のドリフト検出は対象外。フィールド名という手がかりが存在しないため「対象外」と「ドリフト」を安全に区別する判定基準を構造的に持てず、ヒューリスティックな探索は誤検知の温床になる(plugins/forge/docs/review_priorities_spec.md §3.4 の比例性確認に照らして過剰と判断)。現状 update_optional_dependent.py(filter なし・optional 可)は常にこの simple モードを経由するため、この経路のサイレント skip 化は本 PR では解消しない
  • ネストパス解決の JSON 波括弧・TOML セクション境界の追跡(AST 的な構文解析)は行わない。テキストベース置換の設計原則(DES-023 §1)を維持し、親キーチェーンを順にたどる軽量な一般化に留めた
  • sync_files スキーマへの version_path フィールド追加(filter 無し・ネストJSON対応)は行わない

レビュー観点

  • _update_with_path() のドリフト検出・親キーチェーン解決の変更が、既存の呼び出し元(update_main_version.py 等)の挙動を壊していないか
  • get_version_status.py_strip_quotes() / パーサー変更が既存の .version-config.yaml の解釈を変えていないか(全1292テスト green で確認済み)
  • DES-023 の記述が実装と一致しているか

レビューレベル

  • Lv0: まったく見ないでAcceptする
  • Lv1: ぱっとみて違和感がないかチェックしてAcceptする
  • Lv2: 仕様レベルまで理解して、仕様通りに動くかある程度検証してAcceptする
  • Lv3: 実際に環境で動作確認したうえでAcceptする

備考

Closes #175

/forge:review code --diff --interactive --codex による Codex エンジンレビューを実施し、検出された3件の🔴致命的指摘(すべて実際にコード実行で再現確認済み)をすべて修正した。単独修正レビューで追加検出された2件の副次的問題(語境界不足・親キーチェーン未対応)も同時に修正済み。

- _update_with_path() (filter無し path モード) にドリフト検出を追加
  (VersionDriftError と対象外の ValueError を分離)
- 親キーチェーン全体を辿るよう一般化し、3階層以上のパスで同名の
  中間キーが複数存在する場合の誤更新を修正
- field_pattern/parent_pattern に語境界 (\b) を追加し、
  "other_version" 等の無関係なキーへの誤マッチを防止
- --optional 指定時のファイル不在を status: skipped として扱うよう修正
  (DES-023 §5.2 との非対称を解消)
- get_version_status.py の手製 YAML パーサーが optional: false を
  文字列 "false" のまま返し bool() で True になるバグを修正
- 契約テストの FilterNotFoundError 一律 continue を optional 限定に修正
  (必須エントリの filter 消失を見逃していた)
- DES-023 設計書を上記変更に合わせて更新

Closes #175

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@BlueEventHorizon BlueEventHorizon self-assigned this Jul 7, 2026
@BlueEventHorizon
BlueEventHorizon marked this pull request as ready for review July 7, 2026 01:46
@BlueEventHorizon
BlueEventHorizon merged commit 7fb983e into develop Jul 7, 2026
1 check passed
@BlueEventHorizon
BlueEventHorizon deleted the fix/175-version-drift-filter-less-optional-sync-file branch July 7, 2026 01:46
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