Repository navigation
Description
大方針 #2335(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集める)の柱の 1 本(柱の記号: P2)。#2335 の設計(issues/issue-2335-design.md)が決めた実行の記録の形・置き場・寿命を前提にし、この課題はそれを満たしたと言える条件を決める。
依頼(原文)
異常系処理とログ出力、異常時の回復処理が統一されていないから起こる不具合・課題が多い。1 件ずつ対処してもきりがない
(書き手: 利用者、日付: 2026-11-01。#2335 の「調べ方」の節が引用した利用者の指摘)
#2338。人へ問わずに進め、決められない点は前提か未決として課題の本文へ書く。
(書き手: AI の起動指示、日付: 2026-11-04)
この課題の初版の本文(「何をするか」「受け入れ条件」1〜4「進め方」)は、起票者(課題を書いた AI)が 2026-11-01 の組み直しで書いた文で、利用者の指示の原文として扱わない。初版から読み取った条件は「起票者の推定」に並べる。
解釈: 利用者が求めているのは、ログ出力の不統一から生まれる不具合を 1 件ずつでなくまとめて無くすことである。この柱では、1 回の起動で何が起き、なぜ止まったかを、1 つの記録から後で確かめられる状態にする。
起票者の推定
題・初版の本文のうち、上の利用者の原文に無く、起票者が推して足した条件。承認ゲート 1 で利用者が確かめるまで、利用者の決定として扱わない。
| # | 条件 | 推した出所 | この要求での扱い |
|---|---|---|---|
| S1 | 実行の識別子は実行の核が振る | 初版「何をするか」1 文目 | 受け入れ条件 1・前提 1 |
| S2 | 開始・終了・判断・失敗を 1 つの形の JSON Lines へ書く | 初版「何をするか」1 文目 | 受け入れ条件 1・1c |
| S3 | 標準エラーへの診断も同じ関数を通し、print(..., file=sys.stderr) などの直書きを残さない |
初版「何をするか」2 文目・受け入れ条件 2 | 受け入れ条件 2・2a(シェルは核が受ける形にした。前提 4) |
| S4 | 止まった理由は切らずに残す | 初版「何をするか」3 文目・受け入れ条件 3 | 受け入れ条件 3・3a |
| S5 | 使用量の帳簿もこの記録から数える | 初版「何をするか」4 文目 | 前提 3(帳簿は今の置き場に残し、行に実行の識別子を足してつなぐ。帳簿の集計を実行の記録から数え直さない)・受け入れ条件 1d |
| S6 | 子の課題は 1 件ずつ直さず、柱を入れた後に再現の手順を 1 回ずつ通して閉じるか残すかを決める | 初版「進め方」・受け入れ条件 4 | 受け入れ条件 4・境界の「行わない」 |
| S7 | 設計は #2335 の設計の後に、柱ごとに行う | 初版「進め方」 | 前提 1 |
目的
- NDF のスクリプトの 1 回の起動について、始まり・判断・診断・失敗・終わりと止まった理由を、実行の識別子 1 つで 1 つのファイルから追える状態にする
- 標準エラーへの診断を書く経路を 1 つにし、記録に残らない診断と、途中で切れた理由を無くす
- 記録とログの不統一が原因の課題(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の型 B)を、仕組みを入れた後にまとめて確かめて閉じる
前提
- 前提 1: 柱 P1(結果の契約をそろえ、失敗・未収束・判定できないを ok で返す経路を無くす #2337 結果の契約と核のスケルトン)がマージされ、入口が実行の核(
lib/run_core.pyのmain)を通っている。この課題の実装は P1 のマージの後に始める。2026-11-04 時点で 結果の契約をそろえ、失敗・未収束・判定できないを ok で返す経路を無くす #2337 は未完了(gh issue view 2337の state が OPEN)で、plugins/ndf/scripts/lib/にrun_core.pyは無い(ls plugins/ndf/scripts/lib/ | grep run_の結果はrun_metrics.py・run_owner.py・run_state.py・run_state_kinds.pyの 4 件) - 前提 2: 実行の記録の行の形・置き場・寿命は 異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の設計に従う。行は
run_id・parent_id・at・event・entry・fieldsを持ち、置き場は${NDF_STATE_DIR:-~/.local/state/ndf}/runs/<リポジトリ>/<UTC の日付>/<起点の実行の識別子>.jsonl、寿命は 30 日である(issues/issue-2335-design.mdの「実行の記録の行」「非機能の実現方式」、決定 6) - 前提 3: 使用量の帳簿・プランの状態の記録(
progress.jsonl)・問い合わせの記録(ask.jsonl)は、今の置き場と形のまま業務のデータとして残し、行に実行の識別子を足して実行の記録とつなぐ(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 決定 6)。帳簿の集計を実行の記録から数え直す変更はこの課題に含めない - 前提 4: シェルの入口は、異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の設計どおり実行の核が子として起こし直す(
rc_enter)。シェルの本体が標準エラーへ書いた行は、核が受けて実行の記録へ診断として書く。シェルの本体の>&2は書き換えの対象にしない - 前提 5: 対象は
plugins/ndf/scriptsとplugins/ndf/skills/*/scriptsの、テスト・実験版(plugins/ndf/scripts/experimental/)・hook を除く入口とステップである(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の対象範囲) - 前提 6: 実行の記録へ書けないとき(始まりでも途中でも)、核は標準エラーへ理由を出し、結果を
stoppedにする(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の不変条件 I3) - 前提 7: SIGKILL で終わった実行には終わりの行が無い。終わりの行が無いことを「途中で強制終了した」と読む
- 前提 8: 1 スプリントで出す入口の移し替えは 3 本の Pull Request までとし、残りは同じ柱の次のスプリントへ送る(
issues/issue-2335-design-pillars.mdの「移す順序と大きさ」)
対象範囲
含む:
- 実行の記録の書き口(
lib/run_log.py)と、核からの呼び出し(始まり・判断・診断・失敗・終わり) - 子の実行が親の実行の識別子を受けて同じファイルへ書くこと
- 標準エラーへの診断の経路を 1 つにすること(Python は実行の文脈の書き口、シェルは核が受ける)と、直書きを落とす構造チェック
- 止まった理由を切る処理を外すこと
- 使用量の帳簿とプランの状態の記録の行へ実行の識別子を足すこと
- 記録の寿命(30 日)の掃除
- 子の課題 8 件(設計のプランで作成者 t <a@b>・題 tmp のコミットが設計ブランチに入り、worker の報告に出ない #1687・cross-refactoring の見送った提案(budget・not_done)が起票されず、マージの後に振り返りが改修計画を読むまで残らない #1839・後片付けを終えても課題の工程表の「後片付け」の行が未チェックのまま残る #1893・使用量の帳簿が同じ message.id の最後の usage を捨て、続けたサブエージェントを 2 回数え、日をまたぐ会話を丸ごと採るか落とす → 会話の記録の合計と一致させる #1979・監視が先に別の早期の警告を出していると、非致命にした permission_denials の件数を警告に残さない #2059・開発ループの周回の created[] を書く経路が無く、周回の中で起票した課題が記録に残らない #2132・cross-refactoring の効果(採用・取り消し・時間・トークン)を版ごとに集計するスクリプトを作る #2205・検査の記録の集計で閾値を見直せない: トリガーの評価が 0 回・落ちた工程が「不明」・流出不具合の記録が 0 行 #2300)の再現の手順を通し、閉じるか残すかを本文へ記録すること
含まない:
- hook を核へ移すこと、hook が書く問い合わせの記録の形を変えること(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の対象範囲の外)
- 使用量の帳簿・プランの状態の記録・問い合わせの記録を実行の記録へ吸い込むこと(前提 3)
- 子の課題を 1 件ずつ直す Pull Request
- 人へ見せる Markdown の報告の形(柱 P7 機械が読む出力を 1 行 JSON にそろえ、Markdown と本文の見出しから判定しない #2340)
- 持ち主の記録の取り合い(柱 P3 実行の持ち主と後片付けを核に持たせ、残骸と並行の衝突で止まらないようにする #2342)と、入力の出所の記録(柱 P8 入口の引数・環境変数・設定の受け取り方を 1 つの読み込み部品にそろえる #2341)。どちらも実行の記録の書き口を使うが、行を書く処理はそれぞれの柱が足す
- 実行の記録を読んで集計する道具(集計の手段は子の課題の判断で決める)
ドメインイベント
| # | イベント | 引き金 | 失敗したとき | 順序の前提 |
|---|---|---|---|---|
| E1 | 実行の識別子を振った | 核の起動。環境変数 NDF_RUN_ID があれば親の識別子として受ける |
— | 入力の解決(#2335 の E2)の後 |
| E2 | 記録の置き場を決め、始まりの行を書いた | E1 | 書けない: 標準エラーへ理由を出して stopped(前提 6) |
E1 |
| E3 | 30 日を超えた日付のディレクトリを消した | 核の起動 | 消せない: 診断を書いて続ける(前提として受け入れ条件 1e) | E2 |
| E4 | 本体が判断・診断を書いた | 本体の ctx.log |
書けない: 前提 6 | E2 |
| E5 | シェルの本体が標準エラーへ書いた行を、診断として記録へ書いた | シェルの本体の出力 | 書けない: 前提 6 | E2 |
| E6 | 子の実行が親の識別子を持ち、同じファイルへ行を書いた | 核を通る入口が別の入口を子プロセスで起こした | 書けない: 前提 6。並行に書いた行が混ざる: 受け入れ条件 1b | 親の E2 |
| E7 | 使用量の帳簿・プランの状態の記録の行へ実行の識別子を書いた | 帳簿・状態の記録の追記 | 識別子が無い(核の外の起動): 空のまま書く | E1 |
| E8 | 本体が止まった理由(例外・stopped・SIGTERM・時間切れ)を核が受けた |
本体の終わり方 | — | E2 |
| E9 | 終わりの行(結果 JSON の全体と終了コード)を書いた | E8 か正常の終わり | SIGKILL: 書かれない(前提 7) | E8 |
用語
| 用語 | 意味 |
|---|---|
| 実行の核 | 入口・ステップが必ず通る共通の実行の仕組み(#2335) |
| 実行の識別子 | 1 回の入口の実行に実行の核が振る識別子(run_id) |
| 実行の記録 | 1 回の起動(子の実行を含む)の始まりから終わりまでを、実行の識別子つきで書く JSON Lines のファイル |
| 実行の文脈 | 実行の核が本体へ渡す 1 つの値。記録の書き口(ctx.log)を持つ |
| 起点の実行 | 親の実行の識別子を持たない実行。実行の記録のファイル名になる |
| 子の実行 | 核を通る入口が子プロセスとして起こした、核を通る入口の実行。親の実行の識別子を持つ |
| 診断 | スクリプトが人へ向けて標準エラーへ出す文(警告・進み具合・失敗の理由)。結果 JSON とは別の出力 |
| 使用量の帳簿 | NDF が起動したエージェントの呼び出しごとの使用量を追記する JSON Lines |
受け入れ条件
1 つの記録で追える
- 1. 核を通る入口を正常・例外・SIGTERM・時間切れの 4 つの終わり方で起動すると、どの場合も実行の記録の 1 ファイルに、同じ実行の識別子を持つ行が始まりの行(
event: start)から終わりの行(event: end)まで並ぶ。すべての行がrun_id・at(UTC の ISO 8601)・event・entry・fieldsを持つ - 1a. 核を通る入口が別の入口を子プロセスで起こすと、子の行は親と同じファイルに書かれ、子の行の
parent_idが親のrun_idと一致する - 1b. 子の実行が親と並行に同じファイルへ書いても、ファイルのすべての行が 1 行ずつ JSON として読める
- 1c. 本体が下した判断(
event: decision)と、止まった理由(例外の理由・stoppedのsummaryとgaps)が行として残る。終わりの行のfieldsは、標準出力へ出した結果 JSON と終了コードを持つ - 1d. 核を通る起動の中で追記された使用量の帳簿の行とプランの状態の記録(
progress.jsonl)の行が、その実行の識別子を持つ。核の外の起動で書いた行は、実行の識別子を持たないまま今と同じ形で読める - 1e. 核の起動が、30 日を超えた日付のディレクトリを実行の記録の置き場から消す。消せなかったときは診断を書いて本体を続ける
- 1f. 実行の記録の置き場を書けない場所にして起動すると、標準エラーに書けなかった理由が出て、結果が
stoppedになる
診断の経路が 1 つ
- 2. 対象(前提 5)の Python の入口とステップで、標準エラーへの出力が実行の文脈の書き口(
ctx.log("diag", ...)に当たる関数)1 つを通る。print(..., file=sys.stderr)とsys.stderr.writeの直書きを構造チェック(scripts/check-script-structure.py)が落とす。2026-11-04 の時点の直書きは 131 か所(print(..., file=sys.stderr)126 か所・63 ファイル、sys.stderr.write5 か所。下の「調べ方」のコマンド) - 2a. 書き口を通した診断は、標準エラーと実行の記録(
event: diag)の両方に出る。シェルの本体が標準エラーへ書いた行も、実行の記録にevent: diagで残る - 2b. 移す途中は、まだ直書きを持つファイルを例外リストに載せ、例外リストに行を足す変更を構造チェックが落とす(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の受け入れ条件 1a と同じ扱い)
止まった理由が切れない
- 3. 本体が渡した止まった理由の文字列(
summary・gaps・例外の理由)が、結果 JSON と実行の記録の終わりの行に、途中で切られずに同じ文字列で残る。2026-11-04 の時点で理由・出力を先頭 N 字で切っている 10 か所(下の「調べ方」のコマンド)を、実行の記録へ全文を書いた後に人へ見せる表示だけを短くする形にする - 3a. 外部コマンドの失敗の出力のように 1 行の上限(未決 1)を超える理由は、全文を記録からたどれる(全文の置き場のパスと長さが行に残る)
子の課題
- 4. 子の課題 8 件(設計のプランで作成者 t <a@b>・題 tmp のコミットが設計ブランチに入り、worker の報告に出ない #1687・cross-refactoring の見送った提案(budget・not_done)が起票されず、マージの後に振り返りが改修計画を読むまで残らない #1839・後片付けを終えても課題の工程表の「後片付け」の行が未チェックのまま残る #1893・使用量の帳簿が同じ message.id の最後の usage を捨て、続けたサブエージェントを 2 回数え、日をまたぐ会話を丸ごと採るか落とす → 会話の記録の合計と一致させる #1979・監視が先に別の早期の警告を出していると、非致命にした permission_denials の件数を警告に残さない #2059・開発ループの周回の created[] を書く経路が無く、周回の中で起票した課題が記録に残らない #2132・cross-refactoring の効果(採用・取り消し・時間・トークン)を版ごとに集計するスクリプトを作る #2205・検査の記録の集計で閾値を見直せない: トリガーの評価が 0 回・落ちた工程が「不明」・流出不具合の記録が 0 行 #2300)それぞれについて、柱の仕組みを入れた後に再現の手順を 1 回通し、閉じた(解消を確かめた)か残した(理由つき)かをこの課題の本文の「子の課題の判定」の節へ記録する
起きてはいけないこと
- 5. 実行の記録に、秘密(トークン・鍵・認証情報)の値が書かれない。秘密を入れた環境変数で起動し、本体がその値を診断と例外の理由へ入れても、ファイルに値が出ない(異常系・ログ・回復とデータ・入出力の形を 1 つの実行の核へ集め、異常系の課題 103 件を型ごとにまとめて解く #2335 の受け入れ条件 13・不変条件 I9)
- 6. 利用者の端末に出る診断の文が、移す前と同じ文で標準エラーへ出る(記録へ書くことで端末の出力が消えない)
- 7. 既存の全体テストが、この柱の各 Pull Request のマージの前後で通る
子の課題の見込み
実装の前の見込みで、判定は受け入れ条件 4 の再現の手順で決める。
| 課題 | 内容 | 見込み |
|---|---|---|
| #1687 | 設計のプランの途中で、作成者 t <a@b>・題 tmp のコミットが入り、worker の報告に出ない |
記録から作った操作をたどれるかを確かめる。試しのコミットを止める検査は核の外で、残る見込み |
| #1839 | cross-refactoring の見送った提案が起票されない | 見送りの判断が記録に残るかを確かめる。起票の経路は核の外で、残る見込み |
| #1893 | 後片付けを終えても工程表の「後片付け」の行が未チェック | 進捗記録(projects-sync.sh)は課題の本文への記録で、実行の記録とは別。残る見込み |
| #1979 | 使用量の帳簿の数え方の誤り | 帳簿の数え方の誤りで、前提 3 により残る見込み |
| #2059 | 先に別の警告を出すと、非致命の拒否の件数の警告が出ない | 診断が種類ごとに記録へ残るかを確かめる。解消の候補 |
| #2132 | 開発ループの周回の created[] を書く経路が無い |
起票の判断が記録に残るかを確かめる。記録の項目の書き手は核の外で、残る見込み |
| #2205 | cross-refactoring の効果を版ごとに集計するスクリプト | 記録が子の実行までつながれば集計の元が 1 つになる。集計のスクリプト自体は残る見込み |
| #2300 | 検査の記録の集計で、落ちた工程が「不明」になる | 落ちたステップが記録に残るかを確かめる。解消の候補(ほかの 2 点は残る見込み) |
非機能の条件
| 大項目 | 条件 |
|---|---|
| 運用・保守性 | 1 回の起動を実行の識別子 1 つで、始まりから終わりまで 1 ファイルから追える(受け入れ条件 1)。記録の寿命は 30 日(前提 2) |
| 移行性 | 移す対象: Python の入口の標準エラーへの直書き。順序: #2335 の部品の順(supervise のプラン・判定・キュー → cross-refactoring → 課題を閉じる処理 → リリース → 外部 CLI の監視 → 使用量の帳簿 → 残り)。並走: 例外リストに載った入口は直書きのまま動く。切り戻し: Pull Request ごとの revert で前の形へ戻る。実行の識別子を持たない既存の帳簿と状態の記録の行は、そのまま読める(受け入れ条件 1d) |
| セキュリティ | 受け入れ条件 5。秘密の扱い(C1)と認証・認可(C2)は変えない |
| システム環境 | Claude Code と Codex の両方の配布で同じ核が動く。シェルの入口は bash で動く |
影響
| 対象 | 影響 |
|---|---|
| 公開インタフェース | 変わらない。結果 JSON の鍵は足すだけで、標準エラーの診断の文は変えない(受け入れ条件 6) |
| データ | 実行の記録のファイルを状態の置き場(${NDF_STATE_DIR}/runs/)に新しく書く。使用量の帳簿とプランの状態の記録の行に、任意の鍵として実行の識別子を足す |
| 既存の振る舞い | 記録の置き場へ書けない場合は、今は動く入口が stopped で止まる(受け入れ条件 1f)。理由を短く切って表示していた箇所で、記録には全文が残る |
検証手段
| 項目 | 手段 |
|---|---|
| テスト | uv run --frozen --project . --all-extras pytest . -q -n 4(全体テスト)。核の終わり方(正常・例外・SIGTERM・時間切れ)ごとに、1 ファイルに start から end まで同じ run_id が並ぶことを見るテスト。子の実行を並行に起こし、全行が JSON として読めることを見るテスト。置き場を書けない場所にして stopped を見るテスト。秘密を入れた環境変数で起動し、ファイルに値が無いことを見るテスト |
| 静的解析・構造の検査 | python3 scripts/check-script-structure.py(CI のジョブ script-structure)。直書きの検査と例外リストの増加の検査をここへ足す |
| 配布物の検証 | claude plugin validate . |
| 手動確認(マージ前) | 子の課題 8 件の再現の手順を 1 回ずつ通し、結果を受け入れ条件 4 の節へ書く |
前提とする取り決め
| 項目 | 参照先 / 決めたこと |
|---|---|
| プロジェクト構造 | 書き口は plugins/ndf/scripts/lib/run_log.py に置く。既定で働くため実験版に置かない。factory/ を参照しない(AGENTS.md の「マーケットプレイスの構造」、#2335 の設計の「置き場所」) |
| コーディング規約 | AGENTS.md の「最小限のコード実装」と、外部コマンドを書く前に実行して確かめる決まり |
| テスト戦略 | 書き口と核の終わり方は単体テストで担保する。入口の移し替えは構造チェックで担保する。子の課題は再現の手順で確かめる。.md の文言を照合するテストは書かない(AGENTS.md の DON'T) |
境界
| 区分 | 内容 |
|---|---|
| 常に行う | 実行の記録へ書く前に秘密を伏せる。移した入口を例外リストから消す。柱の Pull Request ごとに全体テストと構造チェックを通す |
| 確認してから行う(承認ゲート 1・2 で人が見る) | 標準エラーの診断の文を変える変更。使用量の帳簿とプランの状態の記録の形を変える変更 |
| 行わない | 子の課題を 1 件ずつ直す Pull Request。hook を核へ移す。例外リストに行を足す。帳簿を実行の記録へ吸い込む |
未決
| 項目 | 誰が決めるか | 期限 |
|---|---|---|
| 1. 実行の記録の 1 行の大きさの上限と、上限を超える理由の全文の置き場(受け入れ条件 3a) | この柱の設計 | 設計 Pull Request |
| 2. 並行に書く子の実行の行が混ざらない書き方(1 行の追記の単位・排他の要否。受け入れ条件 1b) | この柱の設計 | 設計 Pull Request |
3. hook が書く問い合わせの記録(ask.jsonl)の行に実行の識別子が入るか。核が起動した claude の hook が環境変数 NDF_RUN_ID を受け取れるかは未確認 |
この柱の設計(実際に起動して確かめる) | 設計 Pull Request |
4. 本体の途中で記録へ書けなくなったとき、本体を止めるか、終わりまで続けて結果だけを stopped にするか(前提 6 の具体化) |
この柱の設計 | 設計 Pull Request |
調べ方
2026-11-04 に、このリポジトリの develop(729dcbe40)で打った。
# 受け入れ条件 2 の数(テストと実験版を除く)
P="plugins/ndf/scripts plugins/ndf/skills"
grep -rEn 'file=sys\.stderr' $P --include=*.py | grep -v '/tests/' | grep -v experimental | wc -l # 126
grep -rEl 'file=sys\.stderr' $P --include=*.py | grep -v '/tests/' | grep -v experimental | wc -l # 63
grep -rEn 'sys\.stderr\.write' $P --include=*.py | grep -v '/tests/' | grep -v experimental | wc -l # 5
grep -rEn '>&2' $P --include=*.sh | grep -v '/tests/' | grep -v experimental | wc -l # 203(24 ファイル。前提 4 により対象外)
# 受け入れ条件 3 の数(理由・出力を先頭 N 字で切る箇所)
grep -rEn '(reason|summary|stderr|tail|message|detail|err)[a-z_]*\)?\[ ?:-? ?[0-9]{2,4}\]' $P --include=*.py \
| grep -v /tests/ | grep -v experimental | wc -l # 10切る箇所の 10 件は project-mvv.py:184・supervise_lib/actuals.py:46・supervise_lib/engine.py:422・supervise_lib/slow.py:202・merged_lib/merge.py:317・lib/sprint_loop_gate.py:127・lib/sprint_loop_gate.py:128・lib/monitor_loop.py:120・lib/monitor_loop.py:240・release-steps.py:141(いずれも plugins/ndf/scripts/ の下)。この正規表現に当たらない書き方(変数名が違う・textwrap.shorten など)で切る箇所は数えておらず、未確認として残る。
進行
モード: —
- 要求と受け入れ条件 — 2026-11-04 15:21
- 作業場所の用意
- 設計 — 2026-11-04 15:25
- 素材の収集と出典の確定
- ドキュメント再構成 — 2026-11-04 22:18
- ドキュメントレビュー
- 計画
- 実装
- 構造改善
- 実装レビュー
- 完了判定
- Pull Request
- 確定仕様化
- 後片付け
- 配布
- 体裁レビュー
- リリース後テスト
- 振り返り
- 棚卸し
設計の承認ゲート 1 での利用者の指摘(直して出し直す)
(書き手: 利用者の答えをオーガナイザーが写した、日付: 2026-11-05。出し直しの設計はこの節を満たすように直す。満たせない項目は理由を設計に書く。この節は上書きしない)
範囲を、実際に起きた不具合 #2059(別の警告に拒否の件数の警告が消される)と #2300(落ちた工程が「不明」になる)に絞る(#2342・#2344 と同じく、起きた不具合に根拠の無い範囲を外す。MVV 版 5 の量の上限・縮めるを既定)。
残すもの: 実行の識別子・1 つの記録(JSON Lines)・子の実行・理由を切らずに記録する・秘密を伏せる仕組みと、lib/monitor_loop.py(#2059)・check-trigger.py(#2300)の移し替え。
外すもの: 60 ファイル・125 か所の移し替え(G1〜G6)、直接書きを落とす構造チェック、関係しない理由の切り詰めの書き換え、使用量の記録への識別子の追加。外した子の課題 6 件は理由を付けて残す。
1 スプリント・PR 1〜2 本に収める。実装の開始は #2337 のマージ後と設計に明記する。PR 本文の要求の検査の記述は再検査の結果に直す。
利用者の追加の指示(2026-11-06、出力先の切り替え)
ログについても同様です。手元はファイル、FactoryならCloudWatch Logsなど、ログの出力方法は統一した上で切り替えられるようにする必要があります
(書き手: 利用者、日付: 2026-11-06。オーガナイザーが写した。「同様」は、NDF の状態を手元はファイル・Factory はサーバー側の DB で持つと決めた #2608 を指す)
この柱への影響: 承認ゲート 1 の答えで絞った範囲(実行の識別子・1 つの記録・子の実行・理由を切らない・秘密を伏せる)の書き口を、出力先を差し替えられる形にする。手元の既定はファイル(JSON Lines)のままとし、出力先は書き口の中で 1 つの設定(環境変数か .ndf/ の宣言)から決める。手順書でなくスクリプトで固定する(#2600 の原則)。CloudWatch Logs への出力の実装は Factory の課題 #2608 が受け持ち、この柱では差し替えの口と既定のファイルの出力だけを作る。
- 1g. 実行の記録の書き口が、出力先を 1 つの設定で切り替えられる。設定が無ければ今のファイルへ書く。別の出力先(テストでは差し替えの偽物)を設定すると、同じ行(
run_id・at・event・entry・fields)がその出力先へ届き、ファイルには書かれない。どの出力先でも、秘密を伏せる処理(受け入れ条件 5)を通る - 前提 2 の置き場
${NDF_STATE_DIR:-~/.local/state/ndf}/runs/は、コンテナでは再起動で消える場所にある(リポジトリの外の置き場を寿命(永続・実行の間・使い捨て)で分け、コンテナと Factory の ECS で永続化する #2606 の実測)。既定のファイルの置き場は リポジトリの外の置き場を寿命(永続・実行の間・使い捨て)で分け、コンテナと Factory の ECS で永続化する #2606 の寿命の区分(実行の記録は「永続」か「実行の間」か)に従って決め直す
人の判断待ち(開発ループ lroot3)
- 判定: unknown(承認ゲート 1)
- 理由: 判定を読めない
- 根拠の項目: —
- 設計 Pull Request: NDF のスクリプト: 1 回の起動を実行の識別子 1 つで、1 つの記録から始まりから終わりまで追えるようにする(#2338) #2497
- 答え: rejected
- 答え方:
python3 /persistent/ai/.claude/plugins/cache/ai-plugins/ndf/10.27.18/scripts/sprint-state.py loop answer lroot3 2338 --approved|--rejected|--revise --note <指摘ファイル>
Activity
Docs: #2338 の設計で、シグナルの受け手・テストの置き場・記録の失敗時の結果・標準エラーのパイプ化の扱いを直す
Docs: #2338 の設計で、シグナルの印を立てる時点・保留の経路の終わらせ方・プラグイン側のテストの状態の置き場を決める
Docs: #2338 の設計で、テストの状態の置き場が処理の流れのどこで動くかを図に描かない要素の表へ足す
Docs: #2338 の設計文書を組み直す(エントリポイントへそろえ、処理の流れを小見出しへ分け、長い文を分ける)
docs(#2338): 診断の端末出力・終わりの行の失敗・部分書き込みの扱いを設計に明記
Docs: #2338 の設計文書を組み直す(長い文を分け、40 行を超える章へ小見出しを足し、用語集と意味の重なる語を言い換える)
docs(#2338): end を書き始めた後のシグナルと診断の改行の扱いを設計に明記
docs(#2338): diag へ渡す文と 200 字の表示に行末の改行を持たせる規則を設計に明記