fix(db): CM_ROOT_DIR 由来の幽霊リポジトリ行を掃除する (#1339)#1374
Merged
Conversation
#1328 以前の getRepositoryPaths() は CM_ROOT_DIR を単一のリポジトリパスとして 返しており、ensureEnvRepositoriesRegistered() がそれを is_env_managed=1 の行と して registered していた。CM_ROOT_DIR はリポジトリを格納するコンテナであって リポジトリではないため git worktree list は 0 件を返し、worktree 行が作られない まま リポジトリ行だけが残る。#1328 は自動発見自体は削除したが既存行は残す判断を したため、既存利用者の DB に worktreeCount:0 の幽霊行が残置されている。 マイグレーション v43 で削除する。 削除条件は次のすべてを満たす行のみとし、判定はいずれも「残す」側へ倒す: 1. CM_ROOT_DIR (legacy MCBD_ROOT_DIR) が明示的に設定されている 2. 解決済みパスが WORKTREE_REPOS のエントリに含まれない 3. その path を持つ worktrees 行が 1 件も無い 4. is_env_managed = 1 実機同等の再現で検証済み: v42 DB に実際の ensureEnvRepositoriesRegistered() で 幽霊を作り、getAllRepositoriesWithWorktreeCount()(GET /api/repositories の実装) が Issue 記載どおり name:"repos"/worktreeCount:0 を返すことを確認したうえで、 v43 適用後に幽霊のみが消え、実リポジトリと利用者が無効化した行が enabled=false の まま残ることを確認した。各ガードは個別に破壊して対応テストが落ちることも確認済み。 --- Issue 本文の記載に対する補足(本文は orchestrator 管理のため未編集)--- Issue の案A(「is_env_managed=1 かつ worktree 行を持たない行を削除」)は採用して いない。誤爆が無害ではないため: ensureEnvRepositoriesRegistered() は行が無ければ enabled:true で再作成するので (db-repository.ts:469)、利用者が意図的に無効化した WORKTREE_REPOS リポジトリを 消すと無効化が解除されて復活し、visible / display_name も失われる。案A は 「一時的に worktree が 0 件のリポジトリ」でこれを踏む。Issue 本文が併記していた 安全側の案(CM_ROOT_DIR 完全一致に限定)を採った。 環境変数を getEnv() 経由で読まないのも同じ理由による。getEnv() は CM_ROOT_DIR 未設定時に process.cwd() へフォールバックする (env.ts:218) ため、DELETE の狙いが サーバーの起動ディレクトリ(実在のリポジトリでありうる)に向いてしまう。未設定は 「対象なし」として skip する。この退行はテストで固定した。 --- 委任時の事前調査に対する補足 --- 「マイグレーション追加時に更新が必要な 3 箇所」に加えて、4 箇所目があった: tests/unit/lib/db-migrations.test.ts:37 が CURRENT_SCHEMA_VERSION を 42 と ハードコードしており、43 へ上げると落ちる(実際に full suite で 1 件失敗を確認)。 併せて更新した。事前調査で安全と確認されていた tests/unit/db/future-schema-guard.test.ts は import して使っているため指摘どおり無変更で通る。 また CHANGELOG の #1353 エントリ内 "CURRENT_SCHEMA_VERSION(現在 42)" が本変更で 不正確になるため 43 に更新した(同一 Unreleased 節のため未リリース)。 なお disableRepository() が作る is_env_managed=0 の幽霊行は別個体であり本修正の 対象外(#1346)。 品質ゲート(exit code で判定): lint=0 / tsc=0 / build=0 / CI=true test:unit=0(587 files, 9960 tests passed, Errors 行なし) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-repo-rows # Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
Closes #1339
#1328 以前の
getRepositoryPaths()はCM_ROOT_DIRを単一のリポジトリパスとして返し、ensureEnvRepositoriesRegistered()がそれをis_env_managed=1の行として登録していた。CM_ROOT_DIR はリポジトリを格納するコンテナであってリポジトリではないためgit worktree listは 0 件を返し、worktree を1つも持たない幽霊行だけが残る。#1328 は自動発見を削除したが既存行は残置していた(本 PR がその後始末)。マイグレーション v43
スコープ:
pathが CM_ROOT_DIR と完全一致するis_env_managed=1行のみ。誤爆させないための3重ガード(すべて「残す側」に倒れる)
正当な env 管理行を消すのは無害ではない。
ensureEnvRepositoriesRegistered()は行が無いとenabled: trueで再作成する(db-repository.ts:469)ため、誤削除は利用者が無効化したリポジトリを黙って再有効化し、visible/display_nameも失わせる。NOT EXISTS (worktrees WHERE repository_path = ?)★実装時に発見した罠(Issue 未記載)
getEnv()を使ってはいけない。src/lib/env.ts:218はと CM_ROOT_DIR 未設定時に
process.cwd()へフォールバックする。これを使うと DELETE がサーバーの起動ディレクトリ(dev 環境では実在のリポジトリ)を狙うことになる。process.envを直接読み、未設定は「スキップ」であって「cwd を対象」ではないことを保証している。あわせてMCBD_ROOT_DIR(#76 以前の名称・現在も ENV_MAPPING でサポート)も見る。後方互換
幽霊行が無い DB(#1328 以前を動かしたことがない利用者=通常ケース)は何にもマッチせず no-op。
downは no-op(削除した行は利用者データを持たず、復元すると本 PR が直した欠陥そのものを戻すため。v35/v40 に倣う)。★CURRENT_SCHEMA_VERSION の更新(必須)
runner.ts:27を 42 → 43 に更新した。これを忘れると #1353 で入れた将来版ガードが自分自身の DB を「将来版」と誤検知して起動不能になる。版数をハードコードしていた既存テスト(db-migrations.test.ts)も更新済み。なおfuture-schema-guard.test.ts(#1353)は定数を import しており影響なし。テスト
tests/unit/db/migration-v43-cm-root-dir-ghost-repository.test.tsを新規追加(幽霊行の削除 / 3ガードそれぞれの非削除 / no-op ケース / 冪等性)。品質チェック(exit code 実測)
CI=truenpm run test:unit関連
disableRepository()が作るis_env_managed=falseの行で、本 PR の対象とは別個体。本 PR は触れていない🤖 Generated with Claude Code