Repository navigation
スプリント m8e - #495
スプリント m8e#495
Conversation
Remote-SSH で DEVBASE_EDITOR_SSH_HOST を空にしたときのフラット URI のテストで、 project_name・workdir と URI の末尾のアサーションに作成者の個人のプロジェクト名が 残っていた。#294 の置き換えの表に足した myapp-ml へ揃える。確かめる内容は変えない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#365 を実装する(スプリント m8e)
#463 で VS Code Server のボリュームが共通の 1 本になり、project_name は どこからも読まれていなかった。呼び出し元とテストの引数の受け渡しの期待を 合わせて直す。ボリュームの名前・作る順・作る数は変わらない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
devbase_prune_vscode_server_bin にあった 3 つの選別規則(古い版の削除・ 入れ子の本体の削除・展開の途中のディレクトリの削除)を、それぞれの関数へ 分ける。devbase_prune_vscode_server_bin の名前・引数・出力・消す対象は 変わらない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#490 を実装する(スプリント m8e)
R9・R10 で _devbase_completions の分岐を関数へ移す前に、既存のテストが 見ていない分岐(env のフラグ・plugin と snapshot の引数・container scale・ プラグイン名とリポジトリ名など)の候補を、変更の前のコードで通る形で縛る。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- R1: cmd_env_keygen の中の DevbaseError の取り込み直しを消す - R2: _aws_plan_for_selection の選んだプロファイルの計画を先頭で 1 回だけ組む - R3: 丸ごとの計画を _aws_whole_plan に置き、_aws_sync_plan と _aws_plan_for_unregistered が呼ぶ - R5: manager.py に CONTAINER_HOME を置き、VS Code Server の 2 つの定数と compose.py の _DEPRECATED_TARGET をそれから作る(値は同じ) - R9: devbase_root の解決を _devbase_resolve_root に置く - R10: _devbase_completions を語の位置の振り分けにし、位置 2〜4 の分岐を グループごとの関数へ移す(候補は同じ) tests/ は変えていない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- R11: 補完を実行する補助を tests/cli/conftest.py の run_bash_completion・ bash_complete に置き、3 つのファイルが使う - R12: DEVBASE_MANAGED を tests/volume/conftest.py へ移す(値は同じ) - R13: _Handler.do_GET を拒否と注入の _refuse_read と、応答の組み立ての _read_secret に分ける(段の順は同じ) - R14: RUN ブロックへ分ける手順を dockerfile_parse.run_blocks に置く - R15: Docker とイメージの有無を調べる手順を docker_images.image_unavailable に置き、4 つのファイルが接尾(建て方の案内)だけを渡す(飛ばす理由の文は同じ) テスト関数の assert は変えていない。補助の中の assert は文字列のまま移した。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#452 を実装する(スプリント m8e)
…_build_scaled_services dev のインスタンスへ同じ形で当てる group_volume・dev_environment・vscode_volume・ host_gateway_environment を frozen な _DevInstanceSpec にまとめ、 generate_scaled_compose で組んで _build_scaled_services・_build_dev_instance へ そのまま渡す。振る舞いは変えない。 Item-Id: I-001 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ase_complete_env_args `-` で始まるときだけフラグを候補にする if を env・snapshot・plugin の 11 か所で 書いていたのを、同じ振る舞いの _devbase_complete_flags "<flags>" "$cur" に 寄せる。plugin list は条件が違うので触らない。振る舞いは変えない。 Item-Id: I-002 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
reset のときの「退避を作り、作れなければ中止、作れたら全キーを消す」を _reset_env_file に、registry の発見と集め手の順の実行を _run_collectors に 抜き出す。見出しの表示は host_import.resolve のログより前に出す順を保つため cmd_env_init に残す。振る舞いは変えない。 Item-Id: I-003 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mpletions 進みが止まるまで待つループを _wait_until_stalled に、外側と内側の zsh の子孫を 終える後始末を _reap に、完了の記録から行ごとの結果を並べる部分を _line_results に抜き出す。後始末は finally に残す。振る舞いは変えない。 Item-Id: I-004 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
改修計画 — devbasex/devbase #495
改善項目I-001 —
|
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_parameter_list | introduce_parameter_object | major | high | claude / codex / kiro | 採用 | 1 |
なぜ: _build_scaled_services は引数が 10、_build_dev_instance は 8 ある。group_volume・vscode_volume・dev_environment・host_gateway_environment は generate_scaled_compose → _build_scaled_services → _build_dev_instance と毎回組で渡り、新しい dev の設定(#295・#463 で 1 つずつ増えた)のたびに 3 つの関数のシグネチャを直している
手順: 1. compose.py に frozen な dataclass _DevInstanceSpec(group_volume, dev_environment, vscode_volume, host_gateway_environment) を置く
2. _build_dev_instance(dev_service, dev_service_name, index, spec, secret_env_names) に変え、本体で spec の各値を読む
3. _build_scaled_services(services, dev_service, dev_service_name, scale, spec, secret_names, secret_services) に変え、_build_dev_instance へ spec をそのまま渡す
4. generate_scaled_compose で spec を組み、_build_scaled_services へ渡す(_build_volumes_section へは spec.group_volume・spec.vscode_volume を渡す)
5. tests/volume の compose 生成のテスト(非公開関数を直に呼ぶテストは無い)を打つ
I-002 — etc/devbase-completion.bash#_devbase_complete_env_args
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | consolidate_duplication | minor | high | claude / codex / kiro | 採用 | 1 |
なぜ: if [[ "$cur" == -* ]]; then COMPREPLY=($(compgen -W "..." -- "$cur")); fi が env(init・list・set|delete|edit・export・import)・snapshot(create・restore・rotate)・plugin(install・install の後・repo add)で 11 回書かれている。第 3 引数なしの _devbase_complete_flags "" "$cur" と同じ振る舞いで、補助があるのに使われていない
手順: 1. _devbase_complete_env_args の 5 か所を _devbase_complete_flags "" "$cur" にする
2. _devbase_complete_snapshot_args の 3 か所を同様にする
3. _devbase_complete_plugin_args の install と _devbase_complete_plugin_after_args の install・repo add を同様にする(plugin list は -* の条件が無いので触らない)
4. tests/cli/test_completion.py(c6ac5fd で各分岐の候補を固定済み)を打つ。ShellCheck を devbase-base:latest で打つ
I-003 — lib/devbase/commands/env.py#cmd_env_init
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | minor | medium | claude / codex / kiro | 採用 | 1 |
なぜ: 保存先の解決・既存設定の退避と削除・対話 collector の発見と実行・保存・メタデータ更新が同居している。collector の実行は独立したまとまりで、host_import 属性による呼び分けを含む。test_env_host_import.py と test_env_store_switch.py が入口を通している。
手順: 1. reset のときの「退避を作り、作れなければ中止、作れたら全キーを消す」を _reset_env_file(env_file) -> bool に抽出する(中止のログはそのまま中へ移す)
2. 見出しの表示と registry の発見・集め手の順の実行を _run_collectors(env_file, host) に抽出する
3. cmd_env_init は両者を呼ぶだけにする
4. tests/commands/test_env_user_axis.py(reset の成功・中止)・test_env_host_import.py・test_env_init_group.py を打つ
I-004 — tests/cli/zsh_completion_harness.py#run_completions
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| long_method | extract_method | minor | medium | claude / codex | 採用 | 1 |
なぜ: zsh の起動・進捗監視・子孫プロセスの終了・完了行からの結果復元が1関数にある。特に後半の done/ready/pending/stuck 判定と LineResult の構築は、プロセス制御と別の責務である。test_zsh_completion_run.py は正常補完・時間切れ・プロセス後始末を確認している。
手順: 1. 進みが止まるまで待つループを _wait_until_stalled(proc, outdir, timeout) -> bool に抽出する
2. finally の中の後始末(外側の子孫と inner_pid の子孫を終える)を _reap(proc, outdir, pids) -> tuple[bytes, bytes] に抽出する
3. done・ready・stuck から LineResult を並べる部分を _line_results(lines, progress, outdir, timed_out) に抽出する
4. zsh の補完のテスト(tests/cli の zsh を使うもの)を打つ。zsh の無い環境では skip されるので、手元で走ったことを確かめる
レビューで確かめるテストの差分: tests/cli/zsh_completion_harness.py(機械で期待値が変わったか決まらなかった)
指標の測定
- 状態: written / 言語とツールの対応: 既定(.ndf/code-metrics.json は無い) / 所要: 9.4 秒(使えた時間 90 秒 / 上限 90 秒)
- 指標のファイル: /var/folders/qz/qxt0p_y15xv5jg4x77zmtxj80000gp/T/ndf-worktrees/devbasex--devbase/rf495/work/.cross_refactoring/code-metrics-rf495.md
| 言語 | ツール | 版 | ランナー | ファイル | 秒 | 結果 |
|---|---|---|---|---|---|---|
| python | ruff-complexipy | ruff 0.16.9 / complexipy 8.0.1 | uvx | 215 | 1.0 | 測った |
| shell | — | — | — | 2 | — | unsupported_language |
| 重複: python | symilar | pylint 4.0.9 | uvx | 215 | 7.1 | 測った(1 箇所) |
| 重複: shell | jscpd | jscpd 4.3.0 | npx | 2 | 0.9 | 測った(0 箇所) |
時間の上限
| 値 | 中身 |
|---|---|
| 提案の枠の終わり(監視の上限 = 残り + 余裕) | 2026-10-15T18:36:28+09:00 |
| 改修計画の枠の終わり(同上) | 2026-10-15T18:39:28+09:00 |
| テストの追加の終わり = 実装の終わり − Σ(採っていて未検証の項目の実装の見積り) | 2026-10-15T18:39:27+09:00 |
| 実装の終わり = 最終ゲートの修正の打ち切り − バッファ − Σ(採っていて未検証の項目の検証の見積り) | 2026-10-15T18:42:37+09:00 |
| 直しの試行の打ち切り | 2026-10-15T18:50:29+09:00 |
| 想定最大時間の終わり H(子プロセスはすべてここまでに止まる) | 2026-10-15T18:58:14+09:00 |
| 確かめの開始の締め切り = H − 確かめの見込み(最終ゲート修正と打ち切りの後の取り消しもここまで) | 2026-10-15T18:55:59+09:00 |
| 確かめの見込み(秒。最終ゲートの確かめ 1 回。バッファの最終ゲートの全体テスト) | 135 |
| 最終ゲート修正 1 回の見込み(秒。バッファの final_fix。起動は今 + この値が確かめの開始の締め切り以前のときだけ) | 330 |
| 指標の測定の上限(秒。提案の枠の中から割く) | 90 |
| 着手前のテスト 1 回の上限(秒) | 420 |
| 範囲テスト 1 回の上限(秒) | 405 |
| 手元の全体テスト 1 回の上限(秒) | 420 |
| CI の待ちの上限(秒) | 324 |
| 余裕(秒。手順の上限と CLI の上限に足す) | 90 |
入力: 予算 30 分 / 全体テストの所要 w 139.8(ndf-record) / 着手前の実測 x 134.9 / CI の壁時計 c 108.0 / 範囲テストの所要 s None(—) / 戦略 local-full
無音の打ち切りは手順の監視の上限と同じ値である。項目ごとの期限は持たない(実装を止めるのは実装の終わりだけ)。
見送った提案
| 対象 | 兆候 | 理由 | 根拠(MVV) | 補足 |
|---|---|---|---|---|
lib/devbase/volume/manager.py#get_volume_for_index |
dead_code | budget | Vision | 見積り 0.8 分が残りに入らない |
lib/devbase/commands/container.py#_run_scale_pipeline |
magic_value | budget | Vision | 見積り 1.1 分が残りに入らない |
lib/devbase/volume/manager.py#get_ai_volume_for_index |
inconsistent_naming | budget | Vision | 見積り 1.1 分が残りに入らない |
tests/volume/test_compose_secret_env.py#_clear_devbase_env |
duplication | budget | Vision | 見積り 1.1 分が残りに入らない |
lib/devbase/commands/container.py#_devbase_root |
duplication | budget | Vision | 見積り 1.2 分が残りに入らない |
lib/devbase/commands/container.py#cmd_down |
duplication | budget | Vision | 見積り 1.2 分が残りに入らない |
lib/devbase/volume/manager.py#VolumeManager |
duplication | budget | Vision | 見積り 1.2 分が残りに入らない |
lib/devbase/commands/container.py#cmd_up |
conditional_chain | budget | Vision | 見積り 1.2 分が残りに入らない |
lib/devbase/commands/container.py#_compose_run |
duplication | budget | Vision | 見積り 1.5 分が残りに入らない |
lib/devbase/commands/container.py#cmd_scale |
duplication | budget | Vision | 見積り 1.5 分が残りに入らない |
lib/devbase/volume/compose.py#_build_dev_instance |
duplication | budget | Vision | 見積り 1.5 分が残りに入らない |
lib/devbase/volume/compose.py#generate_scaled_compose |
scattered_config | budget | Vision | 見積り 2.7 分が残りに入らない |
containers/base/entrypoint.sh#devbase_setup_aws_config |
long_method | budget | Value 2 / P1 / Vision | 見積り 2.2 分が残りに入らない |
lib/devbase/volume/compose.py#_drop_missing_env_files_for_all |
inconsistent_naming | budget | Value 3 | 見積り 1.0 分が残りに入らない |
tests/volume/test_compose_dev_environment.py#generated |
duplication | budget | Vision | 見積り 1.1 分が残りに入らない |
tests/volume/test_compose_secret_env.py#_without_managed |
duplication | budget | 根拠なし | 見積り 1.1 分が残りに入らない |
etc/devbase-completion.bash#_devbase_complete_plugin_args |
inconsistent_naming | budget | 根拠なし | 見積り 1.2 分が残りに入らない |
lib/devbase/volume/compose.py#_apply_dev_environment |
duplication | budget | 根拠なし | 見積り 1.2 分が残りに入らない |
lib/devbase/volume/manager.py#get_work_volume_for_index |
dead_code | budget | Vision | 見積り 1.4 分が残りに入らない |
lib/devbase/commands/container.py#_run_post_start |
data_clump | budget | Mission / Value 2 | 見積り 1.4 分が残りに入らない |
lib/devbase/commands/env.py#_record_aws_source |
long_method | budget | Vision | 見積り 1.5 分が残りに入らない |
tests/containers/test_base_shellcheck_ci.py#_shellcheck_commands |
deep_nesting | budget | Vision | 見積り 1.5 分が残りに入らない |
lib/devbase/volume/manager.py#VolumeManager.get_work_volume_for_index |
duplication | budget | Vision / Value 2 | 見積り 1.9 分が残りに入らない |
etc/devbase-completion.bash#_devbase_completions |
scattered_config | budget | Vision | 見積り 2.7 分が残りに入らない |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | APPROVE
指定範囲の27ファイルを確認し、指摘基準に該当する修正事項はありません。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | APPROVE
27 ファイルすべてを読んだ。純粋なリファクタリング PR で、公開 API・補完の振る舞い・片付けの規則・退避の安全(PLAN51 設計 2)はいずれも保存されている。ensure_volumes/VolumeManager の project_name 削除は全呼び出し元(本体・テスト)が追従済みで、group を位置引数で渡していた経路は無い。_DevInstanceSpec・CONTAINER_HOME・env.py の抽出・entrypoint.sh の prune 分割・completion.bash の統合は、確認した範囲で等価だった。critical / major に当たる指摘(利用者経路の破壊・秘密/認可/データ/不可逆操作・設計文書との食い違い)は見つからなかった。
🔧 /ndf:fix サマリ | commit (なし)対応件数: critical=0 / major=0 / minor=0(合計 0 件) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LkjRFAtXSWFASUJ9yUe6Rs
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | claude | APPROVE
範囲の 28 ファイルを確認した。entrypoint.sh の片付けの 3 分割(残した版を標準出力で渡す形を含む)、補完の関数への移し替え、ensure_volumes/VolumeManager からの project_name の削除(呼び出し元はすべて追従済み)、_DevInstanceSpec、env.py の抽出はいずれも元の振る舞いと等価で、critical / major に当たる指摘は無い。
リリース後テスト対象の版: main 実のイメージで確かめた形(#490)手元の
合否: 合格(受け入れ条件 26 件のうち 25 件合格。#490 の 5「建て直したイメージでの確かめ」は保留=base の建て直しの承認待ち。分割した関数の振る舞いは実のイメージの中で確かめ済み) |
振り返り(2026-10-15)対象: issue #365 / issue #452 / issue #490 / PR #495 スプリント m8e は、テストの例に残っていた作成者の個人のプロジェクト名の置き換え(#365)、PR #450 の構造改善で見送った 15 件の片付け(#452。直す 11・直さない 4)、PR #488 で見送った 2 件(#490。使われない 何が起きたか
context window の大きさ
承認ゲートの差し戻し関門 1 が 0 件・関門 2 が 0 件。 MVV を見直すか版 1。覆し 0(閾値 3)・判定できない 0(閾値 5、続けて 0)・流出不具合 0(閾値 3)。兆候が無いため問わない(2026-10-13 の利用者の決定)。 次に変えること
前回(m8d)の振り返りの「次に変えること」(変えない)は、利用者の判断のとおり変えていない。 途中で起票した課題無し( |
スプリント m8e の課題を main へ取り込む。
利用者向けの変化
移行の手順
課題と設計
env syncの AWS の経路・bash の補完・偽の OpenBao・テストの補助に、同じ式の重なりと長い関数が 15 件残る → 11 件を振る舞いを変えずに直し、4 件は直さない理由を残す(#452) #491コミット
変更の統計
テスト(supervise.py の run のステップ)
集めた実装の PR
閉じる課題
Closes #365
Closes #452
Closes #490
検査の結果(conductor が足した)
/ndf:cross-refactoring): 採用 4・取り消し 0・見送り 0(最終ゲート passed)。記録は PR のコメント/ndf:cross-review): round 1 は codex・kiro、round 2 は claude(1 ラウンドでの収束は担当の取りこぼしがあるため、claude を足して回した)。指摘 0・未解決 0、全員承認docs/specifications/vscode-server-volume.mdのテストの表を PR #488 の構造改善で取り消し・見送った 2 件(使われない project_name の引数・VS Code Server の片付けの関数の分割) #490(ensure_volumesからproject_nameを外した)に合わせて直した(7b95548。#490 を実装する(スプリント m8e) #493 の残した事項)containers/base/entrypoint.shの分割(PR #488 の構造改善で取り消し・見送った 2 件(使われない project_name の引数・VS Code Server の片付けの関数の分割) #490)を建て直したイメージで確かめるのはリリース後テストで行う(実のイメージ+使い捨てボリュームのdocker run。devbase upは使わない)モード: standard / 通した工程: 実装 → Pull Request
🤖 Generated with Claude Code
配布の記録
段階: 本番(2026-10-15 22:21 JST、
mainへのマージで反映。承認ゲート 2 を同日利用者が承認)版: 4.1.0 → 版数を上げない(
main=94b5431を配布、確定仕様化 #496 で886d552。タグ・GitHub Release は利用者の判断で切らない)スプリント: PR #492 / #493 / #494 / #495
install.shがmainを取得する)。利用者はdevbaseの更新で受け取る。補完はシェルを開き直すまで前の内容が残るmainへ打ち消しの Pull Request を出す