Repository navigation
スプリント m7a - #381
スプリント m7a#381
Conversation
- リンクの段を共通のボリュームのルートへの flock で 1 つずつ順に走らせる (待ち時間の上限 10 秒、flock が無ければロックなしで進む。ロックはサブシェルの fd でだけ持つ) - 共有のリンクの張り替えを「消す → ln -sn → 読み直す」の試行にし、成否を読み直しで決める(上限 20 回) - 退避とプレースホルダは排他の作成(noclobber / perl の mkdir)で作れた 1 つのプロセスだけが書く - Docker を使わない同時実行のテストと、base イメージのコンテナ 8 個の同時起動のテストを足す Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
env ファイルを「中身は任意」とし、グループを「未設定なら default」と書いていた。 4.0.0(#315)から宣言は必須で default は予約語のため、宣言の書き方と止まる条件を書く。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- project.yml 移行の行に ">=3.0.0" を明記し、同じ文書の推奨と揃える - 3.6.0〜4.0.0 から Plugin が依存しうる機能(base イメージの道具・~/.shellrc.d)の行と、 4.0.0 のアカウントグループの宣言を Plugin の env に持つ行を足す - 機能を足した PR が表へ 1 行足すことを表の下と PR テンプレートの動作確認に書く Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#215 を実装する(スプリント m7a)
wait_for_containers_ready は起動できなかった番号があっても残りの番号を制限まで待ち、 起動できた番号と、起動できなかった番号ごとの理由(終了した・見つからない・時間切れ)と ログの末尾を持つ ContainerStartupError を投げる。決まった番号へは問い合わせ直さない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- _run_post_start: 後処理の対象の番号へ、不足リポジトリの報告 → ./deploy → token の配布 → 窓のタイトルの設定を行う。up / scale / project post-start が共有する - scale は増やしたインスタンスのうち起動できたものへ、up と同じ並びで行う (不足リポジトリの報告と窓のタイトルの設定が加わり、./deploy と token の順が up に揃う) - 起動できなかったインスタンスがあっても、起動できたものへ後処理を行い、名前・理由と 補う手順を出して 1 で終える。開く番号が起動できなければエディタを開かない - devbase project post-start: 動いていて entrypoint の完了を確かめられたインスタンスへ、 ./deploy を除く 3 つをやり直す - test_container_scale_order の 2 件を、順の入れ替えと対象の渡し方の変更に合わせて書き換えた Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
project グループへ post-start [name] [--context NAME] を足す。前方一致・ラッパーの [name] の 解決・入口の振り分け・bash / zsh の補完に入れる。トップレベルの短縮形と container グループ、 TUI には足さない(設計の決定 2)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLI リファレンス(up・scale・post-start の節と [name] の一覧)、コンテナ操作ガイド、環境変数ガイドの ウィンドウタイトルの節、確定仕様(compose-profiles・cli-argument-resolution・secret-backend)、 CHANGELOG の [Unreleased] を更新した。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 方法 2・方法 3 の AWS_DEFAULT_REGION を _collect_region で決める。skip と断ったときは ホストの ~/.aws/config を読まず、ask で確認を出さなかったときはホストの region を既定の値として見せる - GCP の鍵ファイルの発見を google.find_credential_files にまとめ、出力を持たない形にする。 正規化と衝突の警告は取り込むと決めた名前についてだけ 1 回出す - env.py の _gcp_profile_files を消し、sync と控えの更新も同じ発見の結果で引く Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#334 を実装する(スプリント m7a)
- 同時に始める合図を空回りの待ちから名前付きパイプへ替え、待つ間に CPU を使わないようにした - 繰り返す回数を ROUNDS_PAIR 15→4・ROUNDS 8→4 にした。修正前の entrypoint.sh に当てると、 受け入れ条件 1・2 のケースは負荷の無いとき macOS・Linux とも 1〜2 回目で落ちた。その倍を取る - 性能のケースは、子プロセスの CPU 時間 (ユーザーとシステムの和) で修正前と比べる - base イメージのテストは同時起動を 10→2 回、道具の確認を 5→3 回にした macOS でリポジトリ全体の pytest tests/ -q は 106 秒 (以前は関連の 3 ファイルだけで 200 秒)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md
#357 を実装する(スプリント m7a)
Item-Id: I-004 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cmd_up と cmd_scale が別々に持っていた「パイプラインを呼び ContainerStartupError を 部分起動の結果へ組み直す」手順を _start_or_partial へ、「起動の失敗があれば最後に 報告して 1 を返す」手順を _finish_partial へ抽出した。振る舞いは変えない。 Item-Id: I-001 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y#_collect_profile_and_region 方法 1 の入力の文言と既定値に直書きしていた 'ap-northeast-1' を、#334 で定義した DEFAULT_REGION へ置き換えた。振る舞いは変えない。 Item-Id: I-002 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y#_ENTRYPOINT_READY_FILE entrypoint の完了の印 '/tmp/entrypoint-ready' を utils/docker.py の ENTRYPOINT_READY_FILE 1 か所に置き、wait_for_containers_ready の既定引数と post-start の確認の両方がそれを使うようにした。振る舞いは変えない。 Item-Id: I-003 Impl-Runtime: claude Impl-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…etions ps / logs / open のフラグ候補を関数内の名前付き変数へ集め、「cur が - で始まれば フラグ候補、names 指定ならそれ以外でプロジェクト名」という候補生成を _devbase_complete_flags へ抽出した。旧 container/ct は名前を補完しない呼び方の まま残し、位置・グループの判定は各呼び出し側に置いた。関数の終了状態も変えない。 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 #381
改善項目I-001 —
|
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | extract_method | major | high | claude | 採用 | 1 |
なぜ: cmd_up と cmd_scale が、パイプラインを try で呼び ContainerStartupError を捕まえて startup_error / override_file=_SCALE_COMPOSE_FILE / started=list(e.ready) を組み、_run_post_start の後に startup_error があれば _report_startup_failure して 1 を返す、という同じ手順を別々に持つ(#371 で両方に足された)。部分起動の扱いを変えるたびに 2 か所を揃える必要がある
手順: 1. 起動の結果を表す小さな組 (override_file, started, startup_error) を返す _start_or_partial(run_pipeline, scale) を抽出する。pipeline 呼び出しを受け取り、成功なら (file, [1..scale], None)、ContainerStartupError なら (_SCALE_COMPOSE_FILE, list(e.ready), e) を返す
2. cmd_up の内側 try/except をこの呼び出しに置き換える(_warn_partial_start は cmd_up 側に残す)
3. cmd_scale も同じ呼び出しに置き換える。override_file is None で 1 を返す分岐は呼び出し側に残す
4. 末尾の『startup_error があれば _report_startup_failure(label, …) して 1』を _finish_partial(label, error, project_name) として抽出し両方から呼ぶ
5. tests/commands/test_container_post_start.py・test_container_up_order.py・test_container_scale_order.py を流す
締め切り: 実装の着手 2026-10-02T16:33:13+09:00
I-002 — lib/devbase/env/collectors/aws.py#_collect_profile_and_region
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| magic_value | introduce_named_constant | minor | high | claude | 採用 | 1 |
なぜ: #334 で DEFAULT_REGION = "ap-northeast-1" を定義したが、_collect_profile_and_region(方法 1)はまだ文字列 'ap-northeast-1' を入力の文言と既定値に 2 回直書きしている
手順: 1. _collect_profile_and_region の safe_input を f"{keys.AWS_DEFAULT_REGION} (デフォルト: {DEFAULT_REGION}): ", DEFAULT_REGION に置き換える
2. tests/env/test_aws_region_policy.py と env 関連テストを流す
締め切り: 実装の着手 2026-10-02T16:34:14+09:00
I-003 — lib/devbase/commands/container.py#_ENTRYPOINT_READY_FILE
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| magic_value | centralize_configuration | minor | high | claude | 採用 | 1 |
なぜ: entrypoint の完了の印 '/tmp/entrypoint-ready' を container.py の _ENTRYPOINT_READY_FILE と utils/docker.py の wait_for_containers_ready の既定引数が別々に持つ。片方だけ変えると post-start が完了を確かめられなくなる
手順: 1. utils/docker.py に ENTRYPOINT_READY_FILE = '/tmp/entrypoint-ready' を定義し、wait_for_containers_ready の既定引数をそれにする
2. container.py の _ENTRYPOINT_READY_FILE を削り、docker から import して使う
3. test_container_post_start.py と test_wait_for_containers.py を流す
締め切り: 実装の着手 2026-10-02T16:34:39+09:00
I-004 — etc/devbase-completion.bash#_devbase_completions
| 兆候 | 手法 | 重要度 | 等級 | 提案元 | 状態 | コミット |
|---|---|---|---|---|---|---|
| duplication | extract_method | minor | medium | claude / codex / kiro | 採用 | 2 |
なぜ: ps/logs のフラグ候補と compgen 呼び出しが旧 container/ct の第3引数と project の第4引数で重複する。top-level/project の open・ps にも同じ候補生成がある。同じ CLI オプション変更を複数箇所へ反映する必要がある。旧 container は名前を補完しないため、グループ全体を統合してはいけない。
手順: 1. tests/cli/test_completion.py で container/ct の ps/logs、名前入力位置と名前入力後、空文字とハイフンの候補を現状固定する。
2. ps/logs/open の候補文字列を関数内の名前付き変数へ集め、同一のフラグ候補生成だけを小さな補助関数へ抽出する。
3. 位置・グループ判定と名前補完の有無は各呼び出し側に残し、元と同じ条件で補助関数を呼ぶ。
4. completion と post-start の既存テスト、bash -n を実行する。
締め切り: テストの追加の着手 2026-10-02T16:32:33+09:00 / 実装の着手 2026-10-02T16:35:26+09:00
指標の測定
- 状態: written / 言語とツールの対応: 既定(.ndf/code-metrics.json は無い) / 所要: 11.1 秒(使えた時間 90 秒 / 上限 90 秒)
- 指標のファイル: /var/folders/qz/qxt0p_y15xv5jg4x77zmtxj80000gp/T/ndf-worktrees/devbasex--devbase/rf381/work/.cross_refactoring/code-metrics-rf381.md
| 言語 | ツール | 版 | ランナー | ファイル | 秒 | 結果 |
|---|---|---|---|---|---|---|
| python | ruff-complexipy | ruff 0.16.9 / complexipy 8.0.1 | uvx | 234 | 1.0 | 測った |
| shell | — | — | — | 4 | — | unsupported_language |
| 重複: python | symilar | pylint 4.0.9 | uvx | 234 | 8.7 | 測った(2 箇所) |
| 重複: shell | jscpd | jscpd 4.3.0 | npx | 4 | 1.0 | 測った(2 箇所) |
時間の上限
| 値 | 中身 |
|---|---|
| 提案の枠の終わり(監視の上限 = 残り + 余裕) | 2026-10-02T16:28:52+09:00 |
| 改修計画の枠の終わり(同上) | 2026-10-02T16:31:52+09:00 |
| テストの追加の終わり = 最後の項目の完了の締め切り | 2026-10-02T16:33:13+09:00 |
| 実装の終わり = 最後の項目の完了の締め切り | 2026-10-02T16:36:27+09:00 |
| 直しの試行の打ち切り | 2026-10-02T16:43:32+09:00 |
| 最終ゲートの修正の打ち切り(想定最大時間の終わり) | 2026-10-02T16:52:52+09:00 |
| 最終ゲートの修正の 1 回目に必ず渡す長さ(秒。予備時間の final_fix) | 330 |
| 指標の測定の上限(秒。提案の枠の中から割く) | 90 |
| 着手前のテスト 1 回の上限(秒) | 190 |
| 範囲テスト 1 回の上限(秒) | 345 |
| 手元の全体テスト 1 回の上限(秒) | 190 |
| CI の待ちの上限(秒) | 246 |
| 余裕(秒。手順の上限と CLI の上限に足す) | 90 |
入力: 予算 30 分 / 全体テストの所要 w 63.1(ndf-record) / 着手前の実測 x 114.7 / CI の壁時計 c 82.0 / 戦略 local-full
無音の打ち切りは手順の監視の上限と同じ値である。項目ごとの締め切りは各項目の節にある。
見送った提案
| 対象 | 兆候 | 理由 | 根拠(MVV) | 補足 |
|---|---|---|---|---|
lib/devbase/editor/window_title.py#strip_jsonc |
long_method | no_target | Value 2 / Vision | 範囲テストを組み立てられない(test_targets が --scope のテストの置き場所に無いか、雛形を持つ suite が無い) |
lib/devbase/plugin/syncer.py#sync_projects |
long_method | no_target | Value 3 | 範囲テストを組み立てられない(test_targets が --scope のテストの置き場所に無いか、雛形を持つ suite が無い) |
lib/devbase/env/collectors/google.py#collect_google_credentials |
long_method | budget | Value 3 | 見積り 2.1 分が残りに入らない |
lib/devbase/commands/container.py#_push_bao_token |
dead_code | budget | Vision | 見積り 0.6 分が残りに入らない |
lib/devbase/commands/container.py#_run_post_start |
long_parameter_list | budget | Vision | 見積り 0.6 分が残りに入らない |
lib/devbase/commands/container.py#cmd_post_start |
duplication | budget | Vision | 見積り 1.0 分が残りに入らない |
lib/devbase/commands/container.py#_SCALE_COMPOSE_FILE |
duplication | budget | Vision | 見積り 1.4 分が残りに入らない |
lib/devbase/commands/container.py#cmd_post_start |
long_method | budget | Vision | 見積り 1.4 分が残りに入らない |
lib/devbase/utils/docker.py#wait_for_containers_ready |
long_method | budget | Vision | 見積り 1.4 分が残りに入らない |
lib/devbase/commands/env.py#_target_group |
circular_dependency | budget | Value 3 / Vision | 見積り 1.2 分が残りに入らない |
tests/cli/test_open_command.py#_run_wrapper |
test_coupled_to_internals | budget | Vision / Value 3 | 見積り 1.2 分が残りに入らない |
lib/devbase/commands/env_backend.py#cmd_env_backend_migrate |
long_method | budget | C1 / Value 3 / C2 | 見積り 1.4 分が残りに入らない |
lib/devbase/commands/env_ops.py#_check_backend |
long_method | budget | Value 3 / C1 | 見積り 1.4 分が残りに入らない |
lib/devbase/env/aws_profiles.py#_split |
long_method | budget | Value 3 / C1 | 見積り 1.4 分が残りに入らない |
tests/containers/test_lfm_base_settings.py#summarize |
long_method | budget | Value 1 / Vision | 見積り 1.4 分が残りに入らない |
lib/devbase/commands/env_backend.py#cmd_env_backend_migrate |
magic_value | budget | Value 2 | 見積り 0.8 分が残りに入らない |
lib/devbase/env/aws_profiles.py#profiles_in_value |
duplication | budget | Value 2 | 見積り 1.0 分が残りに入らない |
lib/devbase/utils/docker.py#StartupFailure |
primitive_obsession | budget | Vision | 見積り 1.2 分が残りに入らない |
lib/devbase/commands/env.py#_sync_source |
long_parameter_list | budget | Value 3 / Vision | 見積り 1.2 分が残りに入らない |
lib/devbase/commands/env.py#_record_gcp_source |
duplication | budget | Vision | 見積り 1.4 分が残りに入らない |
lib/devbase/env/compose_migrate.py#enable |
long_method | budget | Value 2 / Value 3 | 見積り 1.4 分が残りに入らない |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | REQUEST_CHANGES
修正が必要な指摘は major 1 件です。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | APPROVE
4 件の挙動保存リファクタ(container.py の _start_or_partial/_finish_partial 抽出、aws.py と docker.py の定数化、completion.bash の _devbase_complete_flags 抽出)と現状固定テストの追加。cmd_up / cmd_scale の分岐(override_file is None の早期 return、_warn_partial_start の位置、ContainerStartupError 捕捉時の started=list(e.ready))、定数 DEFAULT_REGION / ENTRYPOINT_READY_FILE の値とスコープ、bash 補完の各位置(container/ct=旗のみ、project/トップレベル=旗+名前)がいずれも元と一致することを git show / grep / ソース精読で確認した。critical / major の基準(利用者経路の破壊・秘密/認可/データ/不可逆操作・設計文書の食い違い)に当たる指摘は見つからなかった。
docker start で再起動したコンテナに前回の /tmp/entrypoint-ready が残り、 post-start が今回の初期化の途中でも完了と読んで token 配布などを進めていた。 entrypoint の冒頭で印を消し、最後に作り直す。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔧 /ndf:fix サマリ | round 1 | commit a756a31対応件数: critical=0 / major=1 / minor=0(合計 1 件) |
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | claude | APPROVE
critical / major に当たる指摘なし。a756a31 の完了の印の削除は関数定義の直後・最初の初期化処理の前にあり、_start_or_partial / _finish_partial の抽出、定数化、補完の補助関数抽出はいずれも元の分岐と一致する。
takemi-ohama
left a comment
There was a problem hiding this comment.
🤖 cross-review | round 2 | kiro | APPROVE
entrypoint の完了の印を起動ごとに消す修正 (a756a31) と、round 1 のリファクタ 4 件 (container.py の _start_or_partial/_finish_partial 抽出、aws.py / docker.py の定数化、completion.bash の _devbase_complete_flags 抽出) を精査した。entrypoint.sh の rm -f は lib-only ガードの後・最初の setup の前に置かれ、touch は exec 直前に残る(test_entrypoint_ready_marker.py が guard<remove<first_setup<touch<exec を固定)。これにより docker start で再起動したコンテナの再初期化中に post-start / wait_for_containers_ready が前回の印を完了と誤読する既存の指摘が解消される。ENTRYPOINT_READY_FILE は docker.py・container.py・entrypoint.sh で同一値に揃い、現状固定テストが一致を確認する。completion.bash の抽出はフラグのみ経路(container/ct)と名前補完あり経路(project/top-level)を分けて再現し、test_completion.py が container ps '' → 空集合、project ps '' → 名前集合で挙動保存を固定する。利用者経路の破壊・秘密/認可/データ/不可逆操作・設計文書の食い違いに当たる critical/major の指摘は見つからなかった。CHANGELOG が明記する「base イメージを建て直した後のコンテナから効く」制約は正確で、既存コンテナは旧 entrypoint を焼き込んでいるため当然の挙動であり欠陥ではない。
🔧 /ndf:fix サマリ | commit (なし)対応件数: critical=0 / major=0 / minor=0(合計 0 件) |
振り返り(2026-10-03)対象: PR #381(スプリント m7a: #357 #215 #224 #371 #334)と、同じ機会に行った #311(operation。記録は PR #384) スプリント m7a では、次の 4 つを main へ入れた。
確定仕様は PR #383 で 何が起きたか
context window の大きさこの会話(#311・リリース後テスト・確定仕様化・振り返り)の測定。スプリントの前半のセッションは含まない。
MVV を見直すか
main へのマージの扱いには食い違いがある。MVV の補足は main へのマージを「必ず人の承認が要る操作」に含めていない。一方、 次に変えること
運用の知見のうち、 途中で起票した課題
|
スプリント m7a の課題を main へ取り込む。
関連: #357 #215 #224 #371 #334
利用者向けの変化
課題と設計
コミット
変更の統計
テスト(supervise.py の run のステップ)
モード: standard / 通した工程: 実装 → Pull Request
🤖 Generated with Claude Code