Repository navigation
Description
具体例
昇格だけの周回では、本番のプランの前に検査のステージが無い。{queue_prs} は今の queue の items からしか埋まらないので、record のステップが置き換えられずに落ち、まとめのプランが流されない(#2568)。検査のプランを途中から流し直すと、件数は最後の実行の state.json からしか写らないので、stats の findings が null になる(#2569)。
依頼(原文)
carulプロジェクトから大量のissueが届きました。
プロジェクトの進行に影響がある課題が多いので、そちらも1レーン使って対応します
ただし、いくつかの根本原因がトリガーのようですので、ひとつづつ直すのではなく根本原因を見つけて対処してください
阻害要因になっている上限の撤廃、保存先の永続化の問題、周回の問題が大きいようです
(書き手: 利用者、日付: 2026-11-06。親の課題 #2648 の本文から引用した)
次の文は課題を起票した AI の本文で、利用者の指示の原文ではない。
#2648(束 B)のうち、プランの差し込みの値と検査の件数を、今の起動の中の値でなく参照で解決する。
#2344(プランは値でなく参照を持つ。PR #2482 が版数・記録の PR・実行条件・流し直しを実装)の形に揃える。#2344 の範囲は広げず、この課題が同じ形で足す。
- 検査のステージを含まない queue で流した本番のプランで、
{queue_prs}がスプリントの PR で埋まり、record のステップが落ちない- 検査のプランを途中から流し直しても、検査の記録の行の findings が null にならず、全実行の件数になる
- 1 と 2 をそれぞれ縛るテストがある
- 昇格だけの周回で、昇格のプランの record が {queue_prs} を置き換えずに落ち、まとめのプランが流されない #2568・検査のプランを途中から流し直すと、検査の記録の行に前の実行のレビューの件数が入らず、stats の findings が null になる #2569 の再現の手順を 1 回ずつ通し、消えたものは理由を添えて閉じ、残ったものは理由を本文に書く
(書き手: 起票者、日付: 2026-11-06)
この要求の整理の指示(書き手: AI の起動指示、日付: 2026-11-06):
人へ問わずに進め、決められない点は前提か未決として課題の本文へ書く。
解釈: 利用者が求めているのは、carul の開発ループで周回が止まる原因を、課題ごとの手当てでなく原因の層で直すことである。この課題は、値の取り先が「今の queue・最後の実行」に限られている 2 か所({queue_prs} の差し込みと検査の件数)を直す。
起票者の推定
題・本文のうち、利用者の指示の原文に無く、起票者が推して足した条件。S7〜S10 はこの要求の整理で足した。承認ゲート 1 で利用者が確かめるまで、利用者の決定として扱わない。
| # | 条件 | 推した出所 | この要求での扱い |
|---|---|---|---|
| S1 | {queue_prs} はスプリントの記録から引く |
#2663 の本文の表 | 改めた。取り先はスプリントの記録だけでは足りない。carul の周回 3 のスプリント状態(lap-3/state.json)の計画の行はまとめのプラン 1 行だけで、PR の値は空だった。検査の PR #143 は周回 2 の記録にある。受け入れ条件 1・2 は、計画の課題を閉じる PR が集合に入ることを求める |
| S2 | 検査の件数は同じ計画の全実行から引く | #2663 の本文の表 | 受け入れ条件 8。「全実行の件数」は足し合わせでなく、ステップごとに件数を持つ最後の実行の値と読む(S8) |
| S3 | PR #2482 が #2344 の版数・記録の PR・実行条件・流し直しを実装した | #2663 の本文 | 事実と異なる。前提 1 に確かめた内容を書いた。PR #2482 は要求と設計の文書だけを足す PR で、#2344 は OPEN のままである |
| S4 | #2344 の形(refs と {ref:<名前>})に揃える |
#2663 の本文 | 採らない。参照の部品がまだ無いため、今の差し込みの仕組みの中で実行の直前に解決する(前提 1)。#2344 の設計は QUEUE_PRS を移行関数で読み替えるので、この課題の差し込みも同じ経路で移せる |
| S5 | 昇格だけの周回では差し込みの元になる検査のプランの結果が同じ周回に無い | #2568 の起票者の推定 | 確かめた。下の「調べた事実」の 1 |
| S6 | record はその実行の counts だけを写し、前の実行の件数を足していない |
#2569 の起票者の推定 | 確かめた。下の「調べた事実」の 3 |
| S7 | 埋める集合は「今の queue の items から集めた PR」と「計画の課題を閉じる PR」の和にする | この要求の整理。まとめのプランの記録の PR の解決(find_record)が、記録の スプリント: に課題を閉じる PR を求めるため |
受け入れ条件 1〜3・5。誤ると record が通ってもまとめのプランが止まる |
| S8 | 同じステップの件数が複数の実行にあれば、足さずに最後の実行の値を採る | cross-review と cross-refactoring の結果の件数は、PR ごとの状態ファイルから数える(各 drive.py の説明と rounds の集計)。同じ状態を読む 2 回の実行を足すと二重に数える可能性がある |
受け入れ条件 9 |
| S9 | 頭から流し直した実行は検査のやり直しとして扱い、その実行より前の件数を読まない | この要求の整理。既存の前の実行の範囲(RunState.prior_rows)と同じ区切り |
受け入れ条件 10 |
| S10 | 差し込みの解決は queue だけでなく、supervise.py run <プラン> --from <ステップ> でも働かせる |
下の「調べた事実」の 1。#2663 の受け入れ条件 1 は「queue で流した本番のプラン」と書くが、carul の周回 3 の昇格のプランは queue を通っていない | 受け入れ条件 1・2。queue だけを直すと #2568 の経路に効かない |
調べた事実
- 周回 3 の昇格のプランは queue を通らず、
runで流れた。 carul のloop.jsonの周回 3 の問いの記録のfinish.pipelineはsupervise.py run .../5-promote.json --from verify && supervise.py queue .../1-close.json ...である。周回 3 に状態ディレクトリがあるプランは昇格だけで、検査のプランは流れていない(lap-3/sprint/の一覧)。recordはerror: argument --prs: invalid int value: '{queue_prs}'で終了コード 2 になった(lap-3/sprint/5-promote-state/run-stderr.log)。 {queue_prs}は残っても止まらない。plan.py:219のQUEUE_NAMEDは{queue_pr:<名>}・{queue_state:<名>}・{queue_record}だけを検出し、{queue_prs}を含まない。queue でも先頭のステージではfill_stageがprs = Noneにして埋めない(queue.py:224)。runは差し込みを解決しない(fill_stageの呼び出しはflow.py:289の queue の経路だけ)。そのため文字列のままコマンドへ渡り、配布が済んだ後のステップで落ちる。- 前の実行の件数は記録に残らない。 carul の周回 2 の
4-check-state/state.jsonの log は最後の実行の 3 ステップ(merge-gate・merge・record)だけで、countsは持たない。実行の始まりごとにstate.jsonは書き直される。進捗ログ(progress.jsonl)は追記だが、ステップの行に件数が無い(state.py:225step_line)。出力のファイル(NN-<ステップ>.out)は番号が実行ごとに 1 から振り直され、同じ番号と名前なら上書きされる。 - 課題を閉じる PR は GitHub から引ける。 周回 3 のまとめのプランの止まった理由は「課題 docs: Codex と Kiro の発動実測を単独条件で完了させる #110 Docs: cross-refactoring の実施計画と CLI 実機検証、Skill 一覧の計測修正 #114 feat: 全 Skill の description を新書式へ圧縮する(平均 237 → 150 文字) #102 を閉じる PR Task 3: ndf の統合が前提とする 3 つの仕様を実測する #143 を読んだが、本番か配布なしの段階のリリース記録が無い」であり(
lap-3/done-2.json)、find_recordは周回をまたいで Task 3: ndf の統合が前提とする 3 つの仕様を実測する #143 に届いている。
目的
- 昇格だけの周回でも、配布の後のリリース記録が人の手当て無しで残り、まとめのプランが流れる状態にする
- 検査のプランを途中から流し直しても、検査の記録の行に指摘の件数が残り、
pace: fastのトリガーの閾値を見直す材料に使える状態にする
前提
- 前提 1: プランは値でなく参照を持ち、実行の直前に解決して照合する #2344 の仕組みは未実装である。
git ls-tree -r --name-only origin/develop plugins/ndf/scripts/libにref_kindsを含むパスは 0 件(2026-11-06、origin/developは 742ef62)。PR プランの参照: プランを作り直さずに版・記録の PR を流す直前の値で使い、承認時の値と食い違えば止まる(#2344) #2482 の本文は「この PR は文書だけを変更します」と書く。プランは値でなく参照を持ち、実行の直前に解決して照合する #2344 と、その実装の前提になる 内部データに型と版を持たせ、同じ意味の値を 1 つの名前にそろえる #2339・入口の引数・環境変数・設定の受け取り方を 1 つの読み込み部品にそろえる #2341・実行の持ち主と後片付けを核に持たせ、残骸と並行の衝突で止まらないようにする #2342 はいずれも OPEN である。したがって、この課題は今の差し込みの処理(supervise_lib/queue.py・supervise_lib/queue_fill.py)へ足す - 前提 2: プランに
{queue_prs}が使われる経路は、昇格の record(delivery_templates.py:101)、本番の配布(release_templates.py:351)、承認ゲート 2 のプラン(sprint_routes.py:146)、配布の依頼(sprint.py:70)である。解決は差し込みの処理の中で行うため、どの経路にも同じ規則が効く - 前提 3: プランの
課題の欄は開発ループでも保たれる(carul の5-promote.jsonは[110, 114, 102]) - 前提 4: 既にある検査の記録の行と、この変更より前の進捗ログは書き換えない。過去の行の件数は null のままである
対象範囲
含む:
{queue_prs}の差し込みの取り先を、今の queue の items と計画の課題を閉じる PR の和にすること- 差し込みが queue の先頭のステージと、
supervise.py runでも働くこと - 置き換わらずに残った
{queue_prs}を、コマンドを打たずに止めること - ステップの件数を実行をまたいで読める形で残し、検査の記録の行へ写すこと
plan.pyの説明と、docs/specifications/のうち差し込みの規則を書いた箇所の更新
含まない:
- プランは値でなく参照を持ち、実行の直前に解決して照合する #2344 の参照の仕組み(
refs・{ref:<名前>})の実装と、その範囲を広げること - 問いの当て先と再開の位置(carul の根本原因 B-2: 問いの当て先と再開の位置を、今の周回の外から参照で解決する #2664)、次の周回の設計の起点(carul の根本原因 B-3: 次の周回の設計の起点を、設計 PR の状態から決める #2665)
- 単独の queue の
pace: fastで、MVV 判定を打たずに承認ゲートへ落とす扱い(development-workflowのreferences/pace.md)の見直し {queue_prs:<名>}の差し込みの変更- 過去の検査の記録の行を埋め直すこと
{queue_pr:<名>}・{queue_state:<名>}・{queue_record}をrunで解決すること(今と同じく、残っていれば止まる)
ドメインイベント
| # | イベント | 引き金 | 失敗したとき | 順序の前提 |
|---|---|---|---|---|
| E1 | 検査のプランがスプリントの PR をマージした | 前の周回の検査 | この課題の範囲外 | — |
| E2 | 周回が本番のプランを run --from か queue で流し始めた |
前の周回で配布が止まった課題を次の周回が流す | この課題の範囲外 | E1 |
| E3 | 本番のプランの {queue_prs} が解決された |
プランを流す直前 | 受け入れ条件 4: 流さずに理由を残す | E1 |
| E4 | record のステップがリリース記録を書いた | 昇格か配布の後 | 受け入れ条件 6: {queue_prs} が残っていればコマンドを打たずに止まる |
E3 |
| E5 | まとめのプランの記録の PR が解決した | まとめのステージの直前 | 既存のまま: 流さずに理由を残す | E4 |
| E6 | 検査のステップが件数を記録した | ステップの終わり | 受け入れ条件 11: 読めない行は飛ばして読む | — |
| E7 | 検査のプランを途中から流し直した | 利用者か conductor の --from・--resume |
この課題の範囲外 | E6 |
| E8 | record が件数を検査の記録の行へ写した | 検査のプランの最後のステップ | 受け入れ条件 11: 記録が無い項目は今と同じく null | E6・E7 |
用語
| 用語 | 意味 |
|---|---|
| 差し込み | プランの文字列に置いた {queue_prs} などの目印を、プランを流す前に値へ置き換える仕組み |
| 昇格だけの周回 | 課題の検査が前の周回で済み、本番のプランから始まる開発ループの周回 |
| 課題を閉じる PR | 本文の closing keywords か閉じる予定の参照が、その課題を指す Pull Request(record_find.py の手順 2 と同じ定義) |
受け入れ条件
差し込みの値:
- 1. 前提: 計画の
課題が docs: Codex と Kiro の発動実測を単独条件で完了させる #110・Docs: cross-refactoring の実施計画と CLI 実機検証、Skill 一覧の計測修正 #114・feat: 全 Skill の description を新書式へ圧縮する(平均 237 → 150 文字) #102 で、それらを閉じる PR が Task 3: ndf の統合が前提とする 3 つの仕様を実測する #143 である(GitHub の読み出しはテストで差し替える)。操作:{queue_prs}を持つ昇格のプランだけのステージを queue で流す。結果: record のコマンドの引数が--prs 143になり、終了コード 2 で落ちない - 2. 1 と同じ前提で、
supervise.py run <プラン> --from verifyで流すと、record のコマンドの引数が--prs 143になる - 3. 1 か 2 の後に、同じ課題のまとめのプランの
{queue_record}が、そのリリース記録を置いた PR の番号で埋まる - 4.
{queue_prs}を持つプランで、集合が空か GitHub を読めないとき、queue はそのプランを流さず、項目に流さなかった・unfilled: true・理由を残す。runは最初のステップを打たずにstoppedで返る。理由は、空か読めないかを区別する - 5. 前のステージの PR と課題を閉じる PR が重なるとき、
--prsの値は重ねず番号の昇順である。前のステージの PR が release: 配布物をプラグインごとの単一ディレクトリへ統合する(ndf v9.0.0) #140・Task 3: ndf の統合が前提とする 3 つの仕様を実測する #143 で閉じる PR が Task 3: ndf の統合が前提とする 3 つの仕様を実測する #143 なら140 143になる - 6. それでも
{queue_prs}が残ったコマンドのステップは、run でも queue でもコマンドを打たずに止まる - 7.
実行の条件を持つプランは、集合が空でも止めず、今と同じく条件に判断を任せる(退行しない)。
前提の確認:pytest plugins/ndf/scripts/tests/test_supervise.py -k "queue_then or prs_from_queue"→ 4 件通過(2026-11-06)。空の集合で流す分岐はqueue.py:96-102で読み、対応するテストの有無は未確認のため、この課題で足す
検査の件数:
- 8. 前提: 1 回目の実行の review が件数(
rounds4・fixed8)を持って終了コード 6 で終わった。操作:--from base-syncで流し直し、record まで終える。結果: 検査の記録の行のfindingsのroundsが 4、fixedが 8 である - 9. 同じステップが 2 回の実行で件数を持つとき(1 回目
fixed3、2 回目fixed5)、行の値は最後の実行の 5 である - 10. 頭から流し直した実行では、その実行より前の件数を読まない。頭からの実行で review が件数を持たなければ、行に
fixedは無い - 11. 進捗ログが無い・読めない行を含むときも record は落ちず、読めない項目は今と同じく null である(退行しない)
- 12. 1 回の実行だけの検査の行は、今と同じ
findingsになる(退行しない)。
前提の確認:plugins/ndf/scripts/tests/のfindings_ofのテスト(test_findings_copy_unconfirmed_of_a_refactor_step_that_did_not_pass_the_final_gateほか)を実装の前後で通す
確かめと記録:
- 13. 1〜12 の条件ごとに、それを縛るテストがある
- 14. 昇格だけの周回で、昇格のプランの record が {queue_prs} を置き換えずに落ち、まとめのプランが流されない #2568・検査のプランを途中から流し直すと、検査の記録の行に前の実行のレビューの件数が入らず、stats の findings が null になる #2569 の再現の手順を 1 回ずつ通し、消えたものは理由を添えて閉じ、残ったものは理由をその課題の本文に書く
非機能の条件
| 大項目 | 条件 |
|---|---|
| 性能・拡張性 | GitHub の読み出しは、{queue_prs} を持つプランを埋めるときだけ行う。{queue_prs} を持たないプランのステージでは呼ばない |
| 運用・保守性 | 差し込みで止まったときの理由に、計画の課題の番号と、空か読めないかの区別が出る |
影響
| 対象 | 影響 |
|---|---|
| 公開インタフェース | 変わらない。{queue_prs} の記法、check-trigger.py record の引数と行の形は同じである |
| データ | 進捗ログのステップの行に項目を足す形が候補である(形は設計で決める)。移行は無い。足した項目が無い行は読み飛ばす |
| 既存の振る舞い | queue の先頭のステージと run の {queue_prs} が埋まる。残った {queue_prs} は止まる。途中から流し直した検査の行に前の実行の件数が入る |
検証手段
| 項目 | 手段 |
|---|---|
| 起動 | python3 plugins/ndf/scripts/supervise.py queue と run を、GitHub の読み出しを差し替えたテストの中で流す |
| テスト | uv run --frozen --project . --all-extras pytest plugins/ndf/scripts/tests -q -n 4 |
| 静的解析・型検査 | uv run --frozen --project . --all-extras ruff check plugins/ndf/scripts、python3 plugins/ndf/scripts/spec-copy.py check 2663 issues/issue-2663-requirements.md |
| 手動確認 | リリース後テストで、開発対象リポジトリの次の昇格だけの周回か検査の流し直しの記録を読み、リリース記録と check-trigger.py stats の findings を確かめる。該当する周回が無ければ未確認として残す |
前提とする取り決め
| 項目 | 参照先 / 決めたこと |
|---|---|
| プロジェクト構造 | 変更は plugins/ndf/scripts/ に置く。factory/ は変えない(AGENTS.md) |
| コーディング規約 | AGENTS.md の最小限のコード実装。外部コマンドと入出力の形は書く前に実行して確かめる |
| テスト戦略 | plugins/ndf/scripts/tests/ の単体テストとキューのテストで担保する。.md の文言を照合するテストは書かない |
境界
| 区分 | 内容 |
|---|---|
| 常に行う | 既存テストの実行、ruff の適用、{queue_prs} の経路すべてへの同じ規則の適用 |
| 確認してから行う | 進捗ログの行の形の変更(設計を承認ゲート 1 で見る) |
| 行わない | #2344 の参照の部品の先行実装、過去の記録の書き換え、#2664・#2665 の範囲の変更 |
未決
| 項目 | 誰が決めるか | 期限 |
|---|---|---|
| ステップの件数を残す先(進捗ログのステップの行に足すか、別のファイルか) | design の工程 |
設計 PR |
find_record の課題を閉じる PR を探す処理を、差し込みと共有する形 |
design の工程 |
設計 PR |
この課題の後の #2344 の設計文書の扱い(queue.fill_queue_prs を移す記述の更新の要否) |
design の工程 |
設計 PR |
関連
進行
モード: —
- 要求と受け入れ条件 — 2026-11-06 04:49
- 作業場所の用意
- 設計 — 2026-11-06 04:59
- 素材の収集と出典の確定
- ドキュメント再構成 — 2026-11-06 05:14
- ドキュメントレビュー
- 計画
- 実装
- 構造改善
- 実装レビュー
- 完了判定
- Pull Request
- 確定仕様化
- 後片付け
- 配布
- 体裁レビュー
- リリース後テスト
- 振り返り
- 棚卸し
人の判断待ち(開発ループ lcarul2)
- 判定: unknown(承認ゲート 1)
- 理由: 判定を読めない
- 根拠の項目: —
- 設計 Pull Request: 差し込みの値と検査の件数: 昇格だけの周回と途中からの流し直しでも、記録が欠けずに残る(#2663) #2669
- 答え: approved
- 答え方:
python3 /work/ai-plugins/plugins/ndf/scripts/sprint-state.py loop answer lcarul2 2663 --approved|--rejected|--revise --note <指摘ファイル>
Activity
Docs: #2663 の設計の件数の読み出しと途中再開の止まり方を揃える
Docs: #2663 の決定 8 の失敗の条件を #2344 の不変条件に揃える