feat(g4): N1 input preconditions: prewrite, OAuth token, ready screen - #446
Merged
Merged
Conversation
…#444) Implements the design in docs/decisions/2026-09-13T151535_issue-444-n1- input-preconditions.md. Without any of the three, the case is unknown and no prompt is sent. - Prewrite: before every fresh/resume launch, merge hasCompletedOnboarding, theme=dark and projects.<GATE_REPO>.hasTrustDialogAccepted into $GATE_CLAUDE_CONFIG/.claude.json. Only a canonical directory inside RUN_ROOT, never through a symlink, other keys kept, atomic 0600 write, read back; the record holds the path, the keys and the read-back only. - Token: the runner only looks at CLAUDE_CODE_OAUTH_TOKEN in the environment and lets the pilot inherit it; ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are unset. Unset, empty or control characters: neither case starts a launcher (auth_token_absent). N1/auth.json and capture-environment record presence and names only. - Ready: after the binding checks, pty.raw with ANSI escapes removed must show "? for shortcuts" and never "Select login method" or "Quick safety check", within 30 s, on a CLI version the verifier has observed (2.1.268). No key is sent to get past a screen. - pilot-pty.py sets the child terminal to 120x40. Tests N1P-01..15 with synthetic credential values only. Refs #444 #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
) The stand-in launcher printed the blocking screen, slept one second, then printed the ready text. A readiness poll inside that second saw only the blocking screen, so a mutant that checks the ready text first was caught only when the poll came later: the reviewer measured 5/10 and 6/10. Both texts now arrive in one write. The priority mutant is killed 10/10 for each test and the unmutated code passes 10/10. Refs #444 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gd6MbRAYGpkDzHAk1XZroZ
This was referenced Sep 13, 2026
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 の各 case で prompt を送る前に満たす 3 つの前提を実装する。設計は
docs/decisions/2026-09-13T151535_issue-444-n1-input-preconditions.md(PR #445)にある。どれか 1 つでも確かめられなければ、prompt を送らずにunknownとする。Refs #444 #434 #407
変更
pilot-gate-isolation.py prewrite-claude-config。fresh と resume の各 launch の直前に毎回、$GATE_CLAUDE_CONFIG/.claude.jsonへ 3 つのキーを merge する。書くのは RUN_ROOT 配下の canonical なディレクトリだけで、symlink は書かない。他のキーは保ち、0600 で原子的に書き、読み戻して確かめる。N1/<mode>/claude-config-prewrite.jsonには、パス・設定したキー・読み戻しの結果だけを残すCLAUDE_CODE_OAUTH_TOKENだけで、値は継承だけで渡す。ANTHROPIC_API_KEYとANTHROPIC_AUTH_TOKENは unset する。token が未設定・空・制御文字を含む場合は、fresh も resume も launcher を起動せずauth_token_absentとする。N1/auth.jsonとcapture-environmentには、有無と変数名だけを記録するpilot-gate-isolation.py wait-n1-ready。binding の照合の後、ANSI 除去後のpty.rawを読む。? for shortcutsを観測し、かつSelect login methodとQuick safety checkを一度も観測していなければ準備完了とする。制限時間は 30 秒。確認済みの CLI 版(2.1.268)でなければ判定しない。キー入力は送らないpilot-pty.pyは子を起動する前に、PTY を 120x40 に設定するunknownになった case はN1/<mode>/reasonに理由を残し、N1 のresult.jsonにもその理由を載せる。README への影響
なし。gate harness は開発・受入用の内部ツールである。
設計書から判断した点
claude --versionの出力の先頭トークン(例:2.1.268 (Claude Code)の2.1.268)と、runner の定数N1_READY_VERIFIED_CLI_VERSIONSの完全一致で行うclaude_config_outside_run_rootとした(設計書はunknownとだけ定めている)pilot-pty.pyの端末サイズは、同じspawn()を使う I1/F1〜F3 のNativePilotにも適用される。これらの既存試験はすべて通過している試験(N1P-01〜15、合成値のみで実 token は使わない)
auth.jsonには有無と変数名だけが残るlogin_method_screen/trust_dialog_screenになり、端末への入力は 0 バイトready_not_observedready_patterns_unverified_for_cli_versionになり、prompt は 0 回capture-environmentの出力に、3 つの変数の合成値が 0 件負の対照(原本は変更せず、コピーに変異を当てた。原本 3 ファイルの sha256 は前後で一致)
9.9.9を加えるc9312aaにて修正)検証(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・pilot-binding.js・pilot profile の変更🤖 Generated with Claude Code
https://claude.ai/code/session_01QCtgi8wVJDRaMwXHZmkHqT