feat(container): AI 設定を共通 / アカウントグループの 2 層に分ける (PLAN39 PR2) - #124
Merged
Merged
Conversation
entrypoint の symlink 機構を 2 系統にし、認証と会話履歴 (分類 B) を /persistent/group へ、契約に紐づかない共通資産 (分類 A) を /persistent/ai へ 振り分ける。あわせて入れ子パスの不具合を直す。 - `~/.claude` の既定をグループ側へ倒す。symlink である点は現行と同じで、 向き先だけを /persistent/group/.claude に変え、その配下へ共通資産 5 件 (plugins / skills / commands / CLAUDE.md / settings.json) の symlink を張る。 実機の `~/.claude` には子要素が 30 件あり、列挙方式では projects (1.1GB の 会話ログ) のような未列挙の子が黙って揮発するため (プラン 前提 20) - 入れ子パス対応 — link 側と実体側の**双方**で親ディレクトリを作る。以前は 実体側の作成が No such file or directory で落ち、壊れた symlink が残っていた - ファイル / ディレクトリの判定を拡張子 (`*.json`) から明示の一覧へ改める。 `.jsonl` がマッチせず history.jsonl がディレクトリとして作られていた - default グループの初回シード — 共通側の分類 B を**コピー**して初期化する (move ではないので切り戻し時に元が残る)。非 default では走らせない。 `.claude` のシードは分類 A の 5 件を除外する - 空の named volume は root 所有で作られるため、書けなければ chown する プラン文書の不変条件・AC6・分類表・Task 4・切り戻し手順を、この設計変更に 合わせて更新した。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5oA2PqY6UX2Ca3t78886t
takemi-ohama
commented
Aug 29, 2026
takemi-ohama
left a comment
Contributor
Author
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | APPROVE
変更内容に対する修正提案はありません。
takemi-ohama
commented
Aug 29, 2026
takemi-ohama
left a comment
Contributor
Author
There was a problem hiding this comment.
🤖 cross-review | round 1 | gemini | APPROVE
設計・後方互換性・テストともに堅牢です。1点だけ、既存実装から引き継がれている初期設定ファイル(settings.json)の揮発についてインラインで指摘しました。
Dockerfile が書き込む hooks 設定 (~/.claude/settings.json) は、symlink 張り替えの rm -rf で消えていた。settings.json を共通側の永続化対象に加えたことで、代わりに 空のプレースホルダが /persistent/ai へ残る形になる。張り替えの前に共通側へ コピーして、初回起動で hooks が失われないようにする。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5oA2PqY6UX2Ca3t78886t
Contributor
Author
🔧 /ndf:fix 最終スイープ サマリ最終 APPROVE ラウンド(gemini)に残っていたインライン指摘 1 件を処理し、open review thread を 0 件にしました。 対応件数: critical=0 / major=1 / minor=0 (合計 1 件) 詳細
修正の要点
スコープ外として扱ったものなし(今回のスイープでは gcloud/gws・snapshot/status 関連の未解決指摘は残っていませんでした)。 残 open thread: 0 件 |
This was referenced Aug 29, 2026
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.
Pull Request
概要
PLAN39 の 2 本目。entrypoint の symlink 機構を 2 系統にし、認証情報と会話履歴(分類 B)を
PR1 で用意したグループボリューム
/persistent/groupへ、契約やテナントに紐づかない共通資産(分類 A)を従来どおり
/persistent/aiへ振り分けます。あわせて入れ子パスの不具合を直します。設計判断は
issues/PLAN39_account-group-volume-separation.md(モード:architecture)に残しています。この PR でプランの不変条件を 1 つ反転させたので、その理由を下に書きます。
関連 Issue
プランからの設計変更(不変条件の反転)
プランは「
~/.claudeを実ディレクトリにし、その配下に A / B 双方の symlink を並べる」と書いていましたが、実機を見て反転しました。
稼働中コンテナ (
carmo-ai-dev-1) の/persistent/ai/.claudeの子要素は 30 件あり、プランの分類表が名指ししているのは 7 件だけです。
実ディレクトリ + 列挙方式にすると、列挙外の子(
projects= 1.1GB の会話ログ、sessions、tasks等)がコンテナ再作成のたびに揮発します。プラン自身が「会話履歴には顧客情報が入りうる」として
history.jsonlを分類 B にしている以上、これは意図に反します。Claude Code は版が上がるたびに新しい子ディレクトリを作るため、列挙漏れは今後も起きます。
そこで既定を反転しました。
~/.claude/persistent/group/.claude)~/.claudeが symlink であること自体は現行mainと同じで、変わるのは向き先だけです。AC4(
readlink -f ~/.claude/pluginsが共通側を指す)は 2 段の symlink を経由して満たします。プラン文書の不変条件 / AC6 / 分類表 / Task 4 / 切り戻し手順を、この変更に合わせて更新しました
(前提 20 として実測を追記)。
変更点
containers/base/entrypoint.shsymlink 処理を関数へ切り出し、
DEVBASE_ENTRYPOINT_LIB_ONLY=1でテストから直接呼べるようにしました。エントリの分類は 3 つの配列で表します。
DEVBASE_SHARED_SETTINGS.codex.serena.ssh.kiroshare/persistent/ai/<entry>DEVBASE_GROUP_SETTINGS.claude.json.claude.gemini/persistent/group/<entry>DEVBASE_SHARED_CLAUDE_SETTINGSpluginsskillscommandsCLAUDE.mdsettings.json/persistent/group/.claude/<x>→/persistent/ai/.claude/<x>入れ子パスの不具合 2 件を修正(プラン 前提 5):
.credentials.jsonが壊れた symlink になるtouchがNo such file or directoryで落ちるmkdir -p "$(dirname ...)"history.jsonlがディレクトリとして作られ Claude Code が追記できない*.jsonグロブで.jsonlにマッチしないDEVBASE_FILE_ENTRIESの明示列挙にするdefaultグループの初回シード: グループ側に実体が無いエントリだけ、/persistent/aiからコピーして初期化します(move ではないので切り戻し時に元が残る)。非
defaultでは走らせません(走らせると分離の意味が失われる)。
.claudeのシードでは分類 A の 5 件を除外します(除外しないと直後の symlink 生成が消すだけの無駄なコピーになる)。
空の named volume は root 所有で作られ uid 1000 では書けないため、書けなければ
chownします(プラン 前提 18)。テストのように最初から書ける場所では
sudoを呼びません。tests/containers/test_entrypoint_ai_settings.py(新規・21 件)Docker に依存せず、一時ディレクトリを
/persistent/ai//persistent/group/$HOMEに見立てて関数を直接呼びます。2 系統の振り分け・入れ子パス・既存状態からの張り替え・
初回シードの 4 グループ。
やらないこと(スコープ外)
CLOUDSDK_CONFIG/GOOGLE_WORKSPACE_CLI_CONFIG_DIRとGCP_AUTH_MODE— PR3devbase status表示・ボリューム構造のドキュメント — PR4満たす受け入れ条件
readlink -f ~/.claude/pluginsが同一実体)history.jsonlがディレクトリにならないdefaultは初回シードで再ログインが発生しない影響と互換性
devbase build --no-cache)。devbase up単体ではentrypoint の変更が反映されません
defaultグループでは/persistent/aiから/persistent/groupへのコピーが 1 回だけ走ります。実機の実測で 1.3GB 程度あるため初回だけ起動が伸びます
(2 回目以降は何もしません)
defaultグループはgcloud/gwsを含め初回 1 回の認証が必要です(AC8 の但し書き)動作確認
uv run pytestが greenbash -n containers/base/entrypoint.shが passdevbase build --no-cache後の確認は PR3 とまとめて release PR で行う自動テスト
🤖 Generated with Claude Code
https://claude.ai/code/session_01S5oA2PqY6UX2Ca3t78886t