Repository navigation
Description
親: #726
何を見つけたか
cross-refactoring の候補づくり(proposals.build_candidates)は、提案をファイル(path)・シンボル(symbol)・兆候(smell)の 3 つが完全に一致するときだけ同一視して統合する。リファクタリング計画の「同じ変更か」の判定(commands/plan.py の _merge_duplicates)も、path + symbol が文字列として一致する組の中でしか問わない。シンボルの列挙の書き方が違うだけの同じ提案は統合されず、別々の改善項目として採られる。実装担当は片方を実装した時点でもう片方にやることが無くなり、2 件目はコミットが無いため not_done で見送られる。
develop(0447ac50)で、同じ path と兆候 duplication の提案を 3 者から渡して確かめた(agy / kiro は symbol='TOTAL_ID'、codex は symbol='TOTAL_ID, LIABILITY_KIND')。出力は候補の数と「(シンボル, 提案元, group_key)」の一覧である。
$ python3 -c '... proposals.build_candidates({"agy": [p("TOTAL_ID")], "kiro": [p("TOTAL_ID")], "codex": [p("TOTAL_ID, LIABILITY_KIND")]}) ...'
2 [('TOTAL_ID', ['agy', 'kiro'], ('personal/src/ingest.py', 'TOTAL_ID')), ('TOTAL_ID, LIABILITY_KIND', ['codex'], ('personal/src/ingest.py', 'TOTAL_ID, LIABILITY_KIND'))]group_key が違うため、_merge_duplicates はこの 2 件を比べない。
最初の観測は takemi-ohama/ideabase PR #34(ndf 10.10.1)で、TOTAL_ID と LIABILITY_KIND の二重定義を models.py へ集める同じ改善が 2 項目(R3-002 と R3-003)になり、2 件目が取り消しとして記録された。
実害は差分の損失ではなく、記録と指標の汚れである。リファクタリング計画の見送った提案に not_done として並び、人が読むと「締め切りまでに終わらなかった」と読める。
どこで見つけたか
- 統合の鍵:
plugins/ndf/skills/cross-refactoring/scripts/refactor_lib/items.pyのitem_key(:26)とgroup_key(:40-42)。各値を文字列のまま比べる。proposals.pyの_merge_by_keyがitem_keyで統合する - 提案の正規化:
proposals.pyの_normalize_proposal(:48-)はsymbolの前後の空白を落とすだけで、列挙を分解しない - 同じ変更の判定:
commands/plan.pyの_merge_duplicates(:140-171)。group_keyごとの組の中だけで問い、統合したものをduplicateで見送る - 見送りの判定:
commands/implement.py。コミットの無い項目をnot_doneで見送る(結果ファイルの申告は使わず、git から取る)
直さないと何が起きるか
- 同じ改善が 2 つの項目として想定最大時間の枠を消費し、別の提案が
budgetで押し出される - 2 件目は必ず
not_doneになり、リファクタリング計画と指標にコードの理由ではない見送りが残る
修正レイヤー
提案の対象(path と symbol)の解釈(#726)。シンボルの列挙を集合として読み、item_key と group_key をその集合から作れば、build_candidates の統合と _merge_duplicates の「同じ変更か」の問いが同じ形で直る。
この課題に個別に残るのは、統合が漏れたときの受け皿である。not_done のうち、同じファイル・同じ兆候の項目が実装済みのものは duplicate として見送る(implement.py の見送りの理由を分ける)。
由来
takemi-ohama/ideabase PR #34(振り返り https://github.com/takemi-ohama/ideabase/pull/34#issuecomment-5662176693)
やらないと判断した(2026-09-26)
- 理由: 書き方の違う同じ提案が 2 項目になっても、差分は失われず、2 件目が not_done として記録に残るだけである。提案の対象の解釈を直す親の課題で同時に直る。
- 実害: 見送りの一覧に理由の違う 1 件が残る記録の汚れ。予算の枠を 1 件分使う可能性はあるが観測は ideabase の 1 件だけ
- 費用の見積り: 2〜3 ファイル(refactor_lib/items.py・commands/implement.py とテスト)
- 再び考える条件: 同じ改善が 2 項目に割れて、別の提案が予算で押し出された記録が 1 件出たとき
Activity