3行まとめ
状態。
参照。
検証。
戻し。
feature flag cleanupは、不要if文の削除ではなくrelease後処理です。
- feature flag cleanupは、不要なif文を消す作業ではありません。ON/OFFどちらの挙動を残すか、環境ごとの状態、fallback、rollbackを先に決めます。
- Codexには、flag key、owner、参照箇所、最終挙動、許可する編集、禁止する編集をまとめたcleanup packetを渡します。
- 削除後はtoggleで戻せなくなるため、unit/integration/release checkと、戻す時のPRやdeploy手順を確認します。
feature flagは、releaseを安全にするための便利な仕組みです。段階公開、A/B test、kill switch、権限別の出し分け、実験。どれも開発速度を上げてくれます。
一方で、使い終わったflagを放置すると、コードが読みにくくなります。ON側とOFF側の分岐が残る。testが両方を見続ける。設定画面に古いflagが残る。ドキュメントやrunbookに古い説明が残る。数か月後には、誰も消してよいか分からなくなります。
この記事では、Codexにfeature flag cleanupを任せる前に、何を決めて渡すかを整理します。release前の確認は、公開済み記事のCodexにリリース前チェックを任せる前に決めることで扱いました。ここでは、release後にstale flagを安全に畳む作業へ絞ります。
この記事でわかること
棚卸し。
挙動。
依頼。
確認。
Codexへ渡す前に、最終挙動と消してよい範囲を決めます。
- feature flag cleanupをrelease後処理として扱う理由
- flag inventoryに入れるkey、owner、default、environment
- client、server、tests、docsの参照箇所を分ける方法
- ON固定、OFF固定、percentage rollout、segmentを確認する理由
- Codexへ渡すcleanup packetの型
- PRをdead branch、config、tests、docsへ分ける考え方
- 削除後の検証とrollbackの見方
- stale flag cleanupでよくある失敗
flagは、入れる時より消す時のほうが難しいことがあります。理由は簡単です。入れる時は目的が明確ですが、消す時には背景を覚えている人が減っているからです。
前提知識
| 項目 | 内容 | 見方 |
|---|---|---|
| Key | 識別。 | |
| Eval | 判定。 | |
| Target | 対象。 | |
| Default | 既定。 |
flagはコード、設定、targeting、default valueが合わさった仕組みです。
OpenFeatureは、feature flaggingのvendor-neutral APIを目指すCNCF projectです。provider、evaluation context、hooksなどの概念を持ち、アプリケーション側のflag評価を抽象化します。LaunchDarklyのdocsにも、stale flagsやtechnical debtを減らすために、flagのライフサイクルを管理する考え方が示されています。
GitHubのCODEOWNERSは、pathごとのreview ownerを指定できます。flag cleanupでは、feature owner、platform owner、QA owner、code ownerの確認を分けると安全です。
feature flagはif文だけではない
feature flagは、コード上のif文だけではありません。
flag key、default value、環境ごとの設定、targeting rule、segment、SDK初期化、fallback、analytics、dashboard、docs、runbook、test fixtureが関係します。
コードだけ消しても、設定やdocsが残れば混乱します。逆に設定だけ消してコードが残ると、defaultやfallbackで思わぬ挙動になります。
cleanupはrelease作業の一部
cleanupは、release後の片付けです。
featureを出した時点で終わりではありません。十分に安定したら、flagを畳み、残す挙動を1つにし、testとdocsを更新します。
この時、toggleで戻せた状態から、通常のrollbackやrevertで戻す状態へ変わります。だから、cleanupは軽い掃除ではなくrelease後の変更として扱います。
flag inventoryを作る
| 項目 | 内容 | 見方 |
|---|---|---|
| Key | 名前。 | |
| Owner | 担当。 | |
| Default | 既定。 | |
| Env | 環境。 |
棚卸しがないcleanupは、どの挙動を残すのか曖昧になります。
最初に作るのはflag inventoryです。
Codexに「このflagを消して」と頼む前に、対象flagの情報を集めます。
flag key
flag keyは、対象の識別子です。
似た名前のflag、古いalias、環境ごとに違うkey、SDK側の定数名があるかもしれません。Codexには、文字列検索だけでなく、定数、wrapper、test fixture、docsまで探させます。
owner
ownerは、削除判断をする人です。
feature owner、service owner、design owner、QA owner、security ownerなど、flagの性質で変わります。CODEOWNERSがあるなら、関連pathのownerも見ます。
ownerが不明なflagは、削除を急がず、まず所有者を決めます。
default
default valueは、flag評価に失敗した時の挙動です。
flag providerへ接続できない時、SDK初期化前、test環境、local環境、未ログイン時にどちらへ倒れるかを見ます。cleanup時にdefaultの意味を取り違えると、想定外の挙動になります。
environments
environmentごとの状態も見ます。
productionではON、stagingではOFF、localではdefault、特定customerだけON、ということがあります。cleanup前に、どの環境でどの挙動を残すかを決めます。
参照箇所を4種類に分ける
画面。
API。
検証。
文書。
flag keyはコードだけでなくtest、docs、configにも残ります。
flag keyの参照は、コードだけではありません。
Codexには、client、server、tests、docsを分けて探させます。
client
client側では、画面表示、component state、routing、analytics、local storage、experimentsが関係します。
client flagを消す時は、UIの表示、loading、empty、error、accessibilityも見ます。ON側を残すのか、OFF側を残すのかで画面の意味が変わります。
server
server側では、API response、business rule、permission、billing、notification、queue、batch jobなどが関係します。
server flagを消す時は、data migrationや外部連携も見ます。単にbranchを削るだけでなく、defaultやfallbackがどこに残るかを確認します。
tests
testsには、flag両側のcaseが残っていることがあります。
cleanup後は、残す挙動のtestを強くし、消す挙動のtestを削除または更新します。ただし、test削除だけ先にやると危険です。先に最終挙動を固定します。
docs
docsには、release note、runbook、support FAQ、admin manual、feature spec、onboarding guideが含まれます。
flagを消したのにdocsが残ると、後から調査する人が混乱します。Codexには、docs内のflag keyや機能名も探させます。
削除前に状態を固定する
| 項目 | 内容 | 見方 |
|---|---|---|
| All on | ON。 | |
| All off | OFF。 | |
| Rollout | 割合。 | |
| Segment | 対象。 |
cleanupでは、どのbranchを正とするかを先に決めます。
cleanup前に、残す状態を固定します。
ここが曖昧なまま削除すると、ON側とOFF側を取り違えます。
all on
all onは、全員に新機能を出す状態です。
多くのcleanupでは、ON側を残してOFF側を削ります。ただし、例外があります。特定segmentだけONだった場合や、experimentで負けたvariantだった場合は、ON側を残すとは限りません。
all off
all offは、機能を出さない状態です。
失敗した実験や撤退した機能では、OFF側を残します。コード上ではOFF branchが古い本線であることもあります。
percentage rollout
percentage rolloutは、割合公開です。
100%になったから消してよいとは限りません。100%がいつからか、エラー率が落ち着いたか、supportへの影響がないか、rollback期間が過ぎたかを見ます。
segment
segmentは、特定のuser、organization、region、planへの出し分けです。
segmentが残っているflagは慎重に扱います。全員ONに見えても、特定segmentだけOFFの例外が残っていることがあります。
Codexへ渡すcleanup packet
| 項目 | 内容 | 見方 |
|---|---|---|
| Flag | 対象。 | |
| Final | 最終。 | |
| Allowed | 許可。 | |
| Forbidden | 禁止。 |
packetがあると、Codexがflag周辺を広く作り替えるのを防げます。
Codexへは、cleanup packetを渡します。
これは「消して」ではなく、「この最終挙動へ寄せるために、この範囲を安全に整理して」という依頼です。
target flag
target flagには、flag key、関連定数、dashboard名、owner、環境状態を書きます。
例: checkout_redesign_v2、production 100% ON、staging ON、local default OFF、owner checkout team。
expected final behavior
expected final behaviorには、削除後に残す挙動を書きます。
例: 「新checkout UIを常時表示する」「旧CSV exportを残す」「adminだけの例外を消さない」。ここがcleanupの中心です。
allowed edits
allowed editsには、編集してよい範囲を書きます。
例: 対象component、flag wrapper、test fixture、docs、runbook。広く触るほどreviewが重くなるため、最初のPRでは範囲を絞ります。
forbidden edits
forbidden editsには、触らないものを書きます。
例: unrelated refactor、design変更、analytics event名変更、permission変更、billing logic変更、他のflag削除。Codexは近い改善を見つけると広げがちなので、禁止範囲が効きます。
PRを小さく分ける
- 1Branch
分岐。
- 2Config
設定。
- 3Tests
検証。
- 4Docs
文書。
一度に全部消さず、reviewできる単位へ分けます。
feature flag cleanupは、PRを小さく分けるとreviewしやすくなります。
全部を1PRで消すと、branch削除、config削除、test更新、docs更新が混ざります。
dead branch
dead branch PRでは、残さないbranchを削ります。
ON側を残すならOFF branchを消す。OFF側を残すならON branchを消す。ここでは、最終挙動を確認するtestを必ず残します。
config
config PRでは、flag dashboard、environment設定、SDK config、local defaultsを整理します。
vendor側の設定削除は、権限や監査が関係することがあります。自動で削除するか、人間作業にするかを決めます。
tests
tests PRでは、残す挙動のtestを更新します。
消したbranchのtestを消すだけでは弱いです。残すbranchが本当に動くことをunitやintegrationで確認します。
docs
docs PRでは、runbook、support、release note、admin guideを更新します。
flagが消えた後に「このflagをOFFにして回避」と書かれたrunbookが残ると危険です。
検証とrollbackを見る
| 項目 | 内容 | 見方 |
|---|---|---|
| Unit | 関数。 | |
| Integration | 連携。 | |
| Release | 公開。 | |
| Rollback | 戻し。 |
flag削除後は、戻す方法がflag toggleではなくなる点に注意します。
cleanup後は、toggleで戻せないことを意識します。
削除前はflag OFFで戻せたかもしれません。削除後は、revert、hotfix、deploy rollback、config restoreが必要です。
unit
unit testでは、残す挙動を固定します。
flag evaluatorをmockするtestが残っているなら、cleanup後に不要になります。代わりに、最終挙動の入力と出力を確認します。
integration
integration testでは、client/server/API/DB/queueなどのつながりを確認します。
flagがserver responseやpermissionに関係する場合は、画面だけでなくAPIの挙動も見ます。
release check
release checkでは、productionに近い環境で、主要flow、monitoring、support影響、rollback手順を確認します。
flag cleanupは見た目が小さくても、本番挙動を変えることがあります。
rollbackできない削除
rollbackできない削除は、riskとして明記します。
たとえば、dashboard側のflagを完全削除した、configを消した、DB migrationを伴う、old pathのcodeを大きく消した場合です。この時は、revert手順とownerを残します。
よくある失敗
担当なし。
逆削除。
設定残り。
戻せない。
stale flagは、消すbranchを間違えると本番挙動が変わります。
よくある失敗は、ON側を残すつもりでOFF側を残すことです。
1つ目は、productionの状態だけ見て、stagingやlocalのdefaultを見ないことです。
2つ目は、コードだけ消して、dashboardやdocsを残すことです。
3つ目は、testを削りすぎることです。flag両側のtestが不要になっても、最終挙動のtestは必要です。
4つ目は、rollbackを考えないことです。flag削除後はtoggleで戻せません。
FAQ
| 項目 | 内容 | 見方 |
|---|---|---|
| いつ消す? | 安定後。 | |
| 誰が承認? | owner。 | |
| test? | 両側。 | |
| 戻す? | PRで。 |
迷ったら、flagを消した後に同じ挙動を説明できるかを見ます。
いつflagを消せばいいですか
新しい挙動が十分に安定し、ownerが残すbranchを承認し、supportやmonitoringで問題がないことを確認してからです。
期間だけで決めず、error、support ticket、rollback期間、例外segmentを見ます。
Codexにdashboard側の削除まで任せてよいですか
最初はコード側のcleanupから始めるのが安全です。
dashboardやvendor設定の削除は、権限、監査、rollbackに関わります。自動化する場合も、dry-runや承認を挟みます。
flagが複数絡む場合はどうしますか
1つずつ消します。
flag同士に依存がある場合は、依存関係を図にし、削除順を決めます。複数flagを同じPRで消すと、挙動変化の原因が追いにくくなります。
testはどこまで残しますか
消したbranchのtestは整理しますが、残す挙動のtestは強くします。
特にpermission、billing、data migration、external integrationに関係するflagは、integrationやmanual QAも残します。
参照した主な情報源
- OpenFeature Specification
- OpenFeature Concepts
- LaunchDarkly Docs: Technical debt and stale flags
- About code owners | GitHub Docs
- Codex Use Cases | OpenAI Developers
次に読むなら
更新履歴
- 2026.05.31
初版。
feature flag基盤の仕様は、導入時に公式docsで見直します。
- 2026.05.31 初版公開。
