fix(g4): judge N1 argv only after the launcher has exec'ed claude - #451
Open
kappaseijin4claude wants to merge 1 commit into
Open
fix(g4): judge N1 argv only after the launcher has exec'ed claude#451kappaseijin4claude wants to merge 1 commit into
kappaseijin4claude wants to merge 1 commit into
Conversation
N1 sampled the launcher PID's command line once, right after the binding. The launcher still runs its claim, roster and digest checks after publishing the binding, so that sample could be the launcher itself, which never carries --session-id and was judged a fail. Implements docs/decisions/2026-09-13T164649_issue-448-n1-exec-observation.md: - isolation observe-n1-exec polls ps every 0.2 s for up to 10 s from the binding observation and classifies launcher / claude / unrecognized / absent (an unreaped <defunct> launcher is absent). The existing argv rule, now process_argv_matches, runs only on claude: match is pass, mismatch is the only fail; exec_not_observed, launcher_exited_before_exec and process_identity_unrecognized are unknown. - exec-observation.json records elapsed seconds, class transitions and the binding mtime. When claude is not reached, launcher-stat.txt, process-command.raw and launcher-output-tail.txt (pty.raw tail) are kept, and exec_not_observed adds a 5 s late observation that never changes the verdict. - runner: N1_EXEC_TIMEOUT_SECONDS=10, N1_EXEC_POLL_SECONDS=0.2; the one-shot record_process_command is removed; the case reason is carried into the N1 result. Tests N1E-01..08 (bats) and classification unit tests. Refs #448 #434 #407 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gd6MbRAYGpkDzHAk1XZroZ
This was referenced Sep 13, 2026
Collaborator
Author
Collaborator
Author
凍結解除の判断スケジュール(ユーザー決定 2026-09-13)fork→公式agmsg切替・agguild_pool移行が完了(2026-09-13)したことを受け、
2026-09-20頃、新環境(agguild経由)の運用実績に問題がなければ、このissue/PRを 親issue: #373 |
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.
概要
N1 は launcher PID のコマンドラインを 1 回だけ採り、exec する前の launcher 自身を「args 不一致の fail」と判定していた。これを、binding を観測した後に別枠の上限時間まで exec を観測する方式に変える。設計は
docs/decisions/2026-09-13T164649_issue-448-n1-exec-observation.md(PR #449)にある。Refs #448 #434 #407
変更
pilot-gate-isolation.py observe-n1-execps -ww -o command=を採り、launcher/claude/unrecognized/absentに分類する。claudeは argv[0] がCLAUDE_BINと文字列で一致するか、canonical path がCLAUDE_BIN_CANONICALと一致するときとするclaudeに分類した後にだけ照合する(既存の規則をprocess_argv_matchesとして切り出し、そのまま再利用)。一致すれば pass、不一致だけが fail。exec_not_observed/launcher_exited_before_exec/process_identity_unrecognizedは unknownexec-observation.jsonに、経過秒・分類の遷移・binding の mtime・観測回数を残す。claude に到達しなかった場合は、さらにlauncher-stat.txt・process-command.raw・launcher-output-tail.txt(pty.rawの末尾 4096 byte、ANSI 除去)を残す。exec_not_observedのときだけ、判定を変えない 5 秒の遅延観測をexec-late-observation.jsonに残すN1_EXEC_TIMEOUT_SECONDS=10とN1_EXEC_POLL_SECONDS=0.2を追加した。1 回だけ採るrecord_process_commandと、その前にあった生存確認は削除した(どちらも観測の中で扱う)。「binding は exec の直前に書かれる」というコメントは実態に合わせて直した。case の reason はN1/<mode>/reasonと N1 の結果に載せる設計書から判断した点
psに<defunct>(statZ)と表示される。これをabsentとして扱う(設計書 §3 の「PID が生きていない」にあたる)。macOS で実測し、単体試験を足したclaudeに分類したのに args を判定できない場合(照合規則が exit 2 を返す場合)は、process_identity_unrecognizedの unknown とした。設計書の表にこの場合の定めは無いbindingObservedElapsedFromLauncherStartは、bash のSECONDSの差(整数秒)で記録するREADME への影響
なし。gate harness は内部ツールである。
試験
elapsedSecondsToClaudeが 0.8〜5 秒exec_not_observed、証跡 4 ファイルがあり、fail にならない--settingsが別パスの claudeclaude_args_mismatchlauncher_exited_before_exec、出力の末尾に launcher のエラー文、stat はabsentsleep 60process_identity_unrecognizedを即座に返す(観測 3 回以下、遅延観測なし)exec_not_observed、遅延観測でclaudeclaude_args_mismatchCLAUDE_BINが symlink。argv[0] が symlink のパスの場合と、実体のパスの場合stub は実際に
exec -aで argv[0] を差し替えるので、PID のコマンドラインは本物と同じように変わる。N1E の 8 件は 3 回続けて全件通過した。負の対照(原本は変更せず、コピーに当てた。時間差を含むので、変異ごとに 3 回ずつ実行。原本の sha256 は前後で一致)
absentを待ち続けるunrecognizedを待ち続ける<defunct>をabsentにしない検証(clean worktree)
tests/test_pilot_gate_runner.batstests/test_pilot_launcher.batskill -0規約(instance_id)/ close_fdstests/test_pilot_gate_*.py全 12 モジュールtests/test_pilot_pty.pycheck-enforced-assertions.sh扱わない範囲
pilot-launcher.shの変更🤖 Generated with Claude Code
https://claude.ai/code/session_01QCtgi8wVJDRaMwXHZmkHqT