# instinct: vvv-botsの無効ボット判定はDB(scraper_bot_schedule.enabled)が真実。bot_registryのenabledキーは不完全(1件のみ明示)。両者がズレるとQAが無効ボットを叩き0件Issueを無限起票する

vvv-bots でボットが「有効か無効か」を判定するときは、**DB の `scraper_bot_schedule.enabled` を真実とする**。`bot_registry.py` の `enabled` キーは後付けで不完全。

**Why:** 2026-06-07、退役ボットがQAパイプライン(`tools/qa_pipeline.py`)で毎日0件Issueを自動起票する不具合(#307/#283)を調査した結果:
- DB で `enabled=false` のボットは **15件**(203/218/229/236/246/251/252/306/309-313/501/503)
- だが `bot_registry.py` で `enabled: False` 明示は **bscareer(218) 1件のみ**
- 残り14件(freeconsul/lapras/levtech/sokudan等)は registry 上「有効」扱い=二重管理でズレていた
- スケジューラ(scheduler_tick→tick API)が実際に見るのは **DB の enabled**。registry はコード側のマーカーに過ぎない

**How to apply:**
1. 「このボットは動いているか/無効か」を確認するなら **DB を見る**: `psql "host=/var/run/postgresql dbname=vvv_prod user=ubuntu" -c "SELECT group_id, enabled FROM scraper_bot_schedule WHERE group_id=NNN"`
2. ボットを退役/無効化するときは **DB の enabled=false が必須**(registry の enabled:False は補助的・必須ではない)
3. qa_pipeline は DB の enabled を参照済み(PR #310・`_db_disabled_group_ids()` でDB優先・接続失敗時registryフォールバック)
4. `scraper_bot_schedule` に `is_active` カラムは**存在しない**(enabled が正・vvv-bots CLAUDE.md記載)。bot_name→group_id は `bot_registry.BOTS` で引く

**「bscareer等の0件取得Issue」が来たら**: DB で enabled=false なら退役済み=即クローズ可([[project_bscareer_retired]])。ただし qa_pipeline がまた起票したなら、そのボットの group_id が `scraper_bot_schedule` で本当に false か確認する(PR #310で恒久対策済みだが、新規無効ボットがregistryにgroup_idを持たない場合は取りこぼす)。

**⚠️ 0件Issueが「DBではenabled=false済みなのに」再発したら、bot_registryのキー名ズレを疑え(2026-06-11 #334/#343/#345)**: `_is_bot_disabled()` は bots/ のディレクトリ名(例: `assign_navi`)で `bot_registry.BOTS` を直引きするが、**registryキーが別名のことがある**(dir=`assign_navi`→キー=`assignnavi` / dir=`levtech_freelance`→キー=`levtech`)。entry が空dictになり group_id が取れず、DB無効リストと突合できずQAが無効ボットを毎日診断→0件Issue起票。PR #345 で「キー直引き失敗時に registry の `dir` フィールドで逆引き」する恒久対策を入れた。**判定が怪しい時は `next((v for v in BOTS.values() if v.get('dir')==name), {})` で逆引きして確認**。WAFブロック等でサイト側が原因なら enabled=false 無効化が正解でコード修正は不能([[instinct_scraper_zero_items_site_block]])。

関連: vvv-bots#307(bscareer)/#283/#308/#310/#334/#343/#345 / [[project_bscareer_retired]] / [[instinct_group_id_range_hardcode]] / [[instinct_scraper_zero_items_site_block]]

---
(migrated from local memory/instinct_bot_disabled_db_is_truth.md)