Repository navigation
Use native Codex v2 plaintext assignments for smart routing - #1052
Conversation
f73a23a to
3968193
Compare
Adapt the existing collaboration namespace on the Responses wire so native v2 tools can supply readable assignments to the existing routing hook. Restore native response namespaces and plaintext markers, preserve replay, and reject encrypted or malformed collaboration payloads. Keep the transport and provider URL session-local. Add protocol, lifecycle, streaming and installed-agent coverage without changing the native spawning workflow or introducing another routing tool or model turn.
042c486 to
b91d692
Compare
Polly AI ReviewBlocking issues
Security vulnerabilitiesNone demonstrated in the changed code. The session-control read failure aborts before writing, and native approval remains required. Native security behavior was not independently exercised. Non-blocking notes
ApproachThe Codex approach fits the existing launch overlay, native hooks, and direct-TUI/interposer split. No new proxy is needed. Reusing the existing upgrade flow would make version handling more consistent. SummaryDiff size (computed): 24 files; +689 / -70 lines (759 changed text lines); 0 binary files.
Shares use additions + deletions, including generated text and lockfiles. Binary files have no line count. Tests include fixtures/helpers under test paths and colocated test/spec files; categories are path-based, not coverage measurements. ChangesThe intended outcome is readable native Codex v2 assignments for smart routing while preserving user settings and native permissions. The diff includes launch configuration and guidance, a routing-specific version floor, UTF-8 hook input, approval guidance, workflow pins, test support, regression coverage, and documentation. It introduces no dependency or lockfile changes. The Codex changes are proportional to that outcome. Separating the independent Claude recovery production/test/documentation hunks is the concrete reduction; the test-to-code ratio alone does not justify trimming coverage. TestsTest-by-test assessmentAll changed test/support files are assessed below. No test function is deleted; the local snapshot helper is moved into shared support.
Coverage limits: existing coverage supports version predicates, startup precedence, request matching, and persistent-state comparisons. Concrete gaps are the exact launch overlay, launch-boundary rejection, permission-denied control reads, and approval-parser rejection cases noted above. The frozen checksum and both trusted policies were verified. Offline, in-memory checks exercised version predicates, approval parsing, evidence matching, UTF-8 decoding, and toggle configuration. These are not pytest or native-agent passes. PR-head pytest, lint, typecheck, and live runs remain independently unverified; the reported CI results are author-provided evidence. The named revision objects were unavailable locally, although relevant trusted-context blobs matched the diff’s old-side IDs. For verification in a provisioned PR-head checkout, run: uv run --no-sync pytest tests/test_agent_codex.py tests/test_codex_smart_routing_v2.py tests/test_claude_pty_replay.py tests/test_cuj_evidence.py tests/test_integration_managed.pyFor human verification, run the documented ScopeThe Claude first-prompt Escape recovery is an independent, pre-existing outcome: The remaining Codex configuration, version pins, UTF-8 input, approval guidance, and integration support fit the stated outcome. No other clearly unrelated changes were found. Automated review by Polly · workflow run |
lilly-luo
left a comment
There was a problem hiding this comment.
Reviewed at 160d46ac. Lint, ty, and the focused unit suites (test_agent_codex, test_codex_smart_routing_v2, test_smart_router, the integration-evidence tests) pass locally. I didn't run live Codex 0.164+ or the integration/e2e_cuj journeys.
The main open question is the fail-closed rollout for managed smart routing on Codex <0.164 (inline at codex.py:1616). The rest are non-blocking.
Outside the diff: cli.py:2944 (claude_router_hook_cmd) and cli.py:2592 (cowork_hook_cmd) still decode stdin with the locale encoding, which is the same bug this PR fixes for the Codex hook at cli.py:2871. On Windows, a non-ASCII prompt gets swallowed by except ValueError: return. Fine as a follow-up.
Before:
payload = json.loads(sys.stdin.read() or "{}")After:
payload = json.loads(sys.stdin.buffer.read() or b"{}")
What did you change, and why?
Native Codex v2 can encrypt delegated assignments before
PreToolUse, leaving Smart Router with only a task label. Smart-routed launches now enable readable native v2 assignments and matching root/child guidance through session-only-coverrides. The router and child receive the complete assignment. This adds no gateway proxy; subagent-only routing launches the native TUI, and first-prompt routing uses the existing app-server interposer.Compatibility change for existing managed workspaces: Codex 0.145–0.163 users with managed smart routing enabled must upgrade to 0.164.0 or newer, or explicitly run
ug codex --disable-smart-routing. Known-old versions get the existing upgrade offer and are checked again before launch. Declined, failed, or insufficient upgrades keep routing blocked; UG does not silently disable it. The README highlights this migration in the launch instructions and compatibility note. Ordinary launches retain the 0.145.0 minimum; 0.154.0 remains the general CI baseline, with 0.165.0 limited to native routing cases and CUJ4. Polly uses 0.165.0.An inconclusive version probe gets one longer attempt. If the version remains unknown, UG reports
codex --versiondiagnostics without offering or running an update. The native-v2 overrides intentionally take precedence over saved values for the session; tests preserve conflicting saved settings byte-for-byte.Denied session-control reads and writes report native-approval guidance without changing controls. Other write errors retain their cause. Codex decision records store an assignment hash and character count, with each rationale capped at 1,000 characters. Router/hook text stays complete. Rationale text may still quote sensitive content; Claude's audit format is unchanged. Hook input preserves UTF-8, the integration driver approves only exact local toggle commands, and persistent-state comparisons exclude disposable Codex executable links.
The Codex integration driver waits for an initialized session before typing. The native startup draft can appear before hook review; the driver handles visible review and requires the model/directory footer, preserving the task and plaintext assertions.
Independent Claude recovery fixes remain in #1397. Land that companion first to retain its first-prompt recovery in the combined rollout.
How do you know it works?
scripts/run_integration.pyretains two pre-existing TID251 findings outside the repository'sjust lintgate.