区間の切れ目の再起動と次のコマンドの入力を前景の中継で自動にする(#895) - #921
Merged
Merged
Conversation
- relay.py を新設(run / stop / mark / install)。claude を擬似端末の子として起動し、 Stop hook が写した ndf-next のブロックを受けて /exit・プラグインの更新・次の区間の起動を行う - 中継が要らない起動(-p・副命令・パイプ・中継の下)は本物の claude を exec して素通しする - SessionStart で中継を安定した場所へ置き直し、bash / zsh の設定へ alias を 1 度だけ足す - 文脈量の hook は中継の直接の子の conductor で 1 度の通しをやめ、理由を ndf-next の形にする - context-window.md に ndf-next のブロックの形を定め、relay.md を新設する - 実装で決めた 5 件を決定の記録へ追記する Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
takemi-ohama
commented
Sep 23, 2026
takemi-ohama
left a comment
Contributor
Author
There was a problem hiding this comment.
🤖 cross-review | round 1 | codex | APPROVE
修正必須の指摘はありません。
takemi-ohama
commented
Sep 23, 2026
takemi-ohama
left a comment
Contributor
Author
There was a problem hiding this comment.
🤖 cross-review | round 1 | kiro | COMMENT
relay.py と token-guard.sh の設計・テストは決定 1〜25 と AC に密に対応しており、擬似端末上の統合テストも網羅的である。ブロッキングな欠陥は見つからなかった。以下は小さな 2 点の修正提案。
- relay.py の _is_self は開けないファイルで False を返す。設計(先頭 4 KB に relay.py を 含むものだけを飛ばす)に合わせ、実行だけできる正規の claude を飛ばして 127 になるのを防ぐ。 飛ばし損ねた繰り返しは NDF_RELAY_DEPTH が止める - token-guard.sh の guard_context で relayed を local の宣言に加える Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
Contributor
Author
🔧 /ndf:fix サマリ | commit 90054b0対応件数: critical=0 / major=0 / minor=0(合計 0 件) |
HOME を共有する 2 つの中継では t.rows() が相手の記録も含むため、負けた側の stop の行を勝った側も拾って待ちを抜けていた。勝った側の子が starts.jsonl へ 書く前に抜けると [1, 1] になる(CI の run 35870357441)。自分の中継の記録だけを 見て、両方が「2 つ目の起動」か「stop」に決まるまで待つ。 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
takemi-ohama
marked this pull request as ready for review
September 23, 2026 14:10
要求・設計・決定の記録・実装計画の 4 本を確定仕様へ畳み、元の 4 本は issues/old/milestone-26-relay-restart/ へ退避した。中継は副命令 5 つ・状態のファイル 6 つ・ 記録の形・install の 7 段を持つ独立した機能のため、新しい仕様書を 1 本作った。 - ndf-relay-segment-restart.md(新設): 用語、構成要素、決定と理由(決定 1〜25 の結論と理由)、 常に成り立つ条件、副命令の契約、素通しの条件、本物の claude の解決、中継の状態遷移と各段、 上限と止め方、mark の判定、目標の判定の記録、文脈の上限で切る、install の I1〜I7、 作業ディレクトリ・印・記録・環境変数、前提にした Claude Code の振る舞い、テスト観点 (受け入れ条件の言い換え、通しの確かめの結果、実機で確かめていない 3 点) - ndf-token-waits-and-context-cut.md: 文脈量の判定に「中継の直接の子では 1 度の通しをしない」、 引き継ぎの 1 行を ndf-next のブロックで出すこと、用語・hook の出力・運用・テスト観点・関連リンク - docs/specifications/README.md に 1 行、issues/old/README.md に 1 行 - relay.md の末尾の参照を確定仕様のパスへ向けた。元の 4 本を指す参照は退避先の外に無かった Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy
12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/goal /ndf:development-workflowの区間の切れ目で人が行っていた「/exit・起動し直し・次のコマンドの貼り付け」を、端末の前景に常駐する中継(plugins/ndf/scripts/relay.py)が行うようにした。人が入力するのは関門の答えだけになる。中継が使えないとき・止まると決めたときは、ndf-relay:の 1 行を出して今までどおりの運用へ落ちる。relay.py(新設):run(claude を擬似端末の子として起動する。印を受けたら子へ/exitを入力し、プラグインを更新して次の区間を起動する。-p・副命令・パイプ・中継の下の起動は、本物の claude を exec して素通しする)/stop/mark(Stop hook の本体)/install(SessionStart hook の本体。安定した場所へ置き直し、bash / zsh の設定へ alias を 1 度だけ足す)hooks/claude.json: Stop にmark、SessionStart にinstallを 1 件ずつ足した。Codex / agy の hook の定義は変えていないtoken-guard.sh: 中継の直接の子の conductor では、1 度だけ通す扱いをやめ、上限を超えている限り止め続ける。止めたときの理由の文をndf-nextの形に直したcontext-window.mdにndf-nextのブロックの形を定めた(形の定義はここ 1 か所)。relay.mdを新設し、SKILL.mdとREADME.mdから参照を張った/goalは位置引数で働く / 背景のサブエージェントもbackground_tasksにrunningで載る / 目標の判定は記録のattachment.type: goal_statusに書かれる計画:
issues/issue-895-plan.md。設計:issues/issue-895-design.md(設計 PR #908)。関連する issue: Closes #895
Test plan
uv run --project plugins/playwright-kit/skills/playwright-kit-ops --with pytest pytest . -q -n 4→ exit=0(5443 passed。head fd7a2a4 で再実行)。-n autoはメモリの制約のため使わず、-n 4で実行したpython3 scripts/check-skill-frontmatter.py→ exit=0python3 scripts/check-doc-staleness.py→ exit=0python3 scripts/check-markdown-links.py --root .→ exit=0python3 scripts/check-skill-repo-assumptions.py→ exit=0claude plugin validate .→ exit=0(既知のpolicy/interfaceの警告だけ)plugins/ndf/scripts/tests/test_relay.py(72 件)とtest_token_guard.py(中継の下の 4 件を追加): AC3〜AC4b・AC6〜AC15・AC19〜AC21・AC23・AC24・AC26。子の claude は擬似端末の上で動く試験用のプログラム(tests/fixtures/relay_fake_claude.py)に差し替えた。installは一時の HOME だけで動かし、本物の~/.bashrcは変えていないinstallの足し直し・ロック・写しの比較の 10 か所)git diff origin/develop -- plugins/ndf/hooks/codex.json plugins/ndf/dev.agyが空。installを呼ぶのはhooks/claude.jsonの SessionStart だけnext.jsonが書かれた)通しの確かめ(2026-09-23 13:13〜13:39 UTC)
AskUserQuestionの答えだけで、3 つ目の区間まで起動した。log.jsonlにstart3 行とended_by: markのend2 行が残ったnext.jsonが無かった。答えた 1.9 秒後に印が現れ、11.4 秒後に区間 2 へ切り替わったNDF_CONTEXT_LIMIT=30000で、実装: #895の Agent の起動を 2 回とも止めた(文脈量 39,796 / 40,147)。claude がndf-nextのブロックを出し、区間 2 が起動したrunningのあいだは、ブロック付きの応答でもnext.jsonが書かれなかった(80 秒見た)log.jsonl(AC17 の通し。作業ディレクトリのパスは省いた):{"event": "start", "at": "2026-09-23T13:18:09.642Z", "section": 1, "pid": 4187, "command": "", "from_session": "", "plugin_version": "10.17.3", "cwd": "…/runA/work"} {"event": "end", "at": "2026-09-23T13:18:53.891Z", "section": 1, "pid": 4187, "seconds": 34.732, "ended_by": "mark"} {"event": "start", "at": "2026-09-23T13:18:53.901Z", "section": 2, "pid": 8405, "command": "区間2: README2.md を読んで指示に従ってください", "from_session": "34fbad01-8e00-447b-bd08-a88b131b17db", "plugin_version": "10.17.3", "cwd": "…/runA/work"} {"event": "end", "at": "2026-09-23T13:19:12.835Z", "section": 2, "pid": 8405, "seconds": 9.726, "ended_by": "mark"} {"event": "start", "at": "2026-09-23T13:19:12.845Z", "section": 3, "pid": 11983, "command": "区間3: README3.md を読んで指示に従ってください", "from_session": "8aa69353-4dde-4e59-a9fe-d49845b288dd", "plugin_version": "10.17.3", "cwd": "…/runA/work"} {"event": "end", "at": "2026-09-23T13:19:55.718Z", "section": 3, "pid": 11983, "seconds": 42.873, "ended_by": "no-mark"}(最後の
no-markは、確かめを終えるときに/exitで閉じた区間 3 のもの)未確認の項目の実測(設計の「未確認のまま残ること」):
Resume this session with: claude --resume <id>と区切りの 1 行だけになる。会話の記録は残る/goalの判定がmet: falseで止めを拒むと、続いた応答がブロックを出さずに印が消え、中継は待ち続けた(設計の想定どおり)未検証の項目:
psの経路)は実機で確かめていないclaude plugin updateを挟んだ切り替え(古い版のディレクトリが消える場合)は確かめていない。確かめの中ではラッパーが受けた既存の失敗: 無し
範囲外と判断したもの:
endの行が書かれない(子の claude は擬似端末が閉じて後から終わる)。設計はendを「区間の claude が実際に終わったとき」に書くと定めており、中継が先に終わる場合の行は求めていない工程の記録
/ndf:cross-review 921(codex + kiro、agy は--exclude agy)が 1 ラウンドで収束(codex=APPROVE / kiro=COMMENT で minor 2 件)。最終スイープで 2 件とも修正した(90054b09:_is_selfは読めないファイルを中継と見なさない、relayedをlocalにする)。未解決の指摘は 0 件(verify-sweepで確認)test_run_max_starts_race_one_winsが 1 度落ちた。原因はテストの待ちで、HOME を共有する 2 つの中継のうち相手のstopの行で抜けていた。起動を遅らせる包みで 5/5 再現し、各中継の自分の記録だけを見て両方が決まるまで待つ形に直した(fd7a2a4c、遅延付きで 20/20 通過)。relay.pyは変えていないclaude plugin validate .)がすべて exit=0影響範囲
alias claude=...を 1 度だけ足す(NDF_RELAY_AUTO=0で止まる)。-p・副命令・パイプは素通しで今までと同じ版を上げる必要があるか
要る。hook と利用者のシェル設定への書き込みを足す機能の追加で、まとまりのマージが終わった後に
/ndf:releaseで上げる。🤖 Generated with Claude Code
https://claude.ai/code/session_01DhcogXCb1x3eStK4VoDDCy