feat(PLAN62): 機密の置き場に書いた DEVBASE_ACCOUNT_GROUP を注入しない (#185) - #206
Conversation
置き場の値はアカウントグループの決定に使われないため、書いても使われない値を新たに 作らない。_open_target_env より前に返すので、書き込み・ファイルの作成・fresh の読み出し・ --group の検査のどれも起きず、どの宛先でも終了コード 1 で env ファイルへ書くよう案内する。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…書く (#185) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Preserve secret values and origins when project env reading raises PermissionError. Item-Id: R1-001 Round: 1 Impl-Runtime: codex Impl-Model: default
改修計画 — devbasex/devbase #206
ラウンド 1(実装 codex / レビュー agy / kiro)R1-001 —
|
| 兆候・経路 | 手法・階層 | 重要度 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|
| error | unit | — | codex / kiro | 採用 | 1 |
なぜ: _project_env_overrides の OSError 分岐 (projects//env を read_bytes できないとき警告を出して {} を返し、上書きを無視する) が固定されていない。隣の UnicodeDecodeError 分岐は test_invalid_utf8_project_env_preserves_secret_values_and_origins で固定済みだが、読み取り不能の分岐は resolve のどの経路でも固定されていない
手順: 1. 共通機密に TOKEN=secret、プロジェクト機密に PROJECT_ONLY=p を返すストアの疑似実装を用意し、環境変数には TOKEN=override を設定する。
2. projects/web/env がファイルとして存在すると判定され、そのパスの読み取りだけが PermissionError を送出するようファイルI/O境界をスタブ化する。OSの権限や実行ユーザーには依存させない。
3. 公開入口 resolve(root, "web", store=store) を実行して現在の結果を記録する。
4. 例外にならず values が TOKEN=secret と PROJECT_ONLY=p を保持し、global_names・project_names・names の集合も機密の由来に一致することを固定する。内部関数の直接呼び出しや表示文言の完全一致は使わない。
R1-002 — lib/devbase/env/runtime.py#inject
| 兆候・経路 | 手法・階層 | 重要度 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|
| error | unit | — | codex | 検証中 | 1 |
なぜ: 既存テストは注入成功後の解除・再注入・マッピング間の分離を固定しているが、共通機密を取得した後にプロジェクト機密の取得が失敗する経路は固定していない。現状は例外を伝播し、注入対象と既存の復元履歴を変更しないため、合成と注入の構造改善時に部分的な注入を検出できるようにする。
手順: 1. 共通参照には TOKEN=new-secret を返し、プロジェクト参照で DevbaseError を送出するストアの疑似実装を用意する。内部関数は置き換えず store 引数で渡す。
2. 初回注入の場合と、別の正常なストアで TOKEN=old-secret を注入済みの場合をパラメータ化する。注入前の対象辞書には TOKEN=shell と無関係なキーを設定する。
3. 公開入口 inject(root, "web", environ=target, store=failing_store) を実行し、実測した例外型と対象辞書の不変を固定する。
4. 公開入口 clear_injected(target) を呼び、初回失敗なら空の解除結果、注入済みなら TOKEN の解除結果となり、いずれも TOKEN=shell と無関係なキーが残る現状を固定する。private な履歴にはアクセスしない。
見送った項目
(なし)
共通機密の取得後にプロジェクト機密の取得が失敗する経路の現状を固定する。 例外を伝播し、対象マッピングと既存の復元履歴を変更しないこと、初回失敗では clear_injected が空、注入済みでは TOKEN を注入前へ戻すこと、いずれも TOKEN=shell と無関係なキーが残ることを記録する。 Item-Id: R1-002 Round: 1 Impl-Runtime: kiro Impl-Model: default
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | APPROVE
置き場の DEVBASE_ACCOUNT_GROUP を読み取り直後の 1 か所 (_without_account_group) で外す設計は合成経路 (resolve → inject/child_env/列挙) を一元化できており、重ね順 3 の非破壊も names 基準の values 構成で保たれている。env set の事前拒否・警告のプロセス単位デデュープ・env delete ヒントの 3 軸対応、docs/CHANGELOG も実装と一致。受け入れ条件 1〜5 と警告・拒否がテストで固定され、対象 3 ファイルの 92 件が pass。修正を要する指摘なし。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | agy | APPROVE
PLAN62 の受け入れ条件(機密置き場からの除外・置き場ごとの重複抑止警告・env set の拒否・文書更新)および R1-001 / R1-002 の現状固定テストが要件通り実装され、テストが全て通過することを確認しました。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | kiro | APPROVE
読み取り境界(resolve 内の load)でキーを外す実装で、inject / child_env / コンテナ列挙の共通経路を 1 か所で押さえられており、重ね順 3(projects/<name>/env)も壊していない。env set 拒否と env delete 許可・警告の消し方ヒントが整合し、受け入れ条件 1〜9 と警告の重複抑止・空値・グループ付き参照まで 92 件のテストで固定されている。round1 の候補(読み取り不能な project env / プロジェクト機密取得失敗時の注入)も本 PR の新規テストで固定済み。修正提案なし。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | codex | REQUEST_CHANGES
追加テストの環境変数の復元について修正をお願いします(minor 1 件)。
PLAN62 で足したテストは environ を渡さずに runtime.inject() を呼ぶため、 機密 (TOKEN / K) が本物の os.environ へ載ったまま残り、後続テストとその 子プロセスへ漏れていた。_isolate_injection_state は注入履歴を差し替える だけで、環境変数は戻さない。 account_group_root を yield 付きにし、注入履歴が monkeypatch の後始末で 戻るより前に runtime.clear_injected() を通す。autouse の _isolate_injection_state が先に組み立てられるので、この fixture の後始末 はそれより先に走る。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🔧 /ndf:fix サマリ (round 2)対応件数: critical=0 / major=0 / minor=1 (合計 1 件) 詳細
修正前はファイル末尾に残留検査を足すと 検証
未解決スレッド残数: 0 |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 3 | codex | APPROVE
新規の修正指摘はありません。関連テスト 137 件と git diff --check が通過しました。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 3 | agy | APPROVE
PLAN62 の受け入れ条件・仕様変更・テスト(round 2 の account_group_root クリーンアップを含む)をすべて確認しました。指摘事項はありません。
検証結果(quality-gates / standard)
構造改善: cross-refactoring(提案 3 件 → 採用 2 件、テスト整備ラウンドで現状固定テスト 2 件を追加、最終ゲートの全体テストを通過) 受け入れ条件(issues/PLAN62_inject-account-group.md): 9/9 満たす。条件ごとの検証手段は同ファイルのチェックリストに記載(テスト名つき)。 未検証の項目: 警告の見え方(CLI の標準エラーと TUI の画面で操作の出力に埋もれずに読めるか)→ リリース後テストで確かめる
|
…ount-group # Conflicts: # CHANGELOG.md
|
main を取り込み(CHANGELOG のコンフリクトは両方の項目を残す形で解消)、マージ後の状態で全体テストを回し直した: |
Summary
機密の置き場(
.env/ age / OpenBao)に書いたDEVBASE_ACCOUNT_GROUPを機密の合成(runtime.resolve)から外し、プロセスの環境変数・子プロセス・コンテナの列挙のどれにも載せない。version: 1でも外す。devbase env delete DEVBASE_ACCOUNT_GROUP [-p] [--user] [--group])を添えて 1 プロセスに 1 回警告する(値は出さない)devbase env set DEVBASE_ACCOUNT_GROUP=...は置き場を開く前に拒否し、envファイルへ書くよう案内する(終了コード 1)要求と受け入れ条件:
issues/PLAN62_inject-account-group.md(9 件、検証手段つき)/ 設計:issues/PLAN62_inject-account-group-design.md(#205 でマージ済み)Closes #185
Test plan
uv run --locked pytest -q tests/→2717 passed、exit=0uvx ruff check --select=E9,F63,F7,F82 lib→ exit=0devbase psで警告が出ること、devbase env setが拒否することを実機で見る🤖 Generated with Claude Code