Wire the Codex turn-flip hooks (M3.6: completes the AgentCLI seam) - #387
Merged
Conversation
Fill the last Codex adapter stubs so a codex task tracks the turn ball like a claude task. `write_settings` now merges codex's `[hooks]` `Stop` / `UserPromptSubmit` block into `config.toml`, invoking the shared callback (`python -m panopticon.container.hook`): Stop hands the turn to the user (guarded by the background-task check), UserPromptSubmit takes it back and prints the phase briefing + provisioning nudge. `has_live_background_task` parses the Stop payload. Resolves ADR 0014 flags 2/6/7 against codex's real hooks schema: - flag 6 (yes): codex feeds a UserPromptSubmit hook's stdout back as developer context, so the briefing/nudge ride the same channel as claude. - flag 2: codex's Stop payload has no `background_tasks` array, so the flip degrades to the plain hand-back (claude's behaviour when the field is absent); the parser still lights up if a future codex build adds one. - flag 7: codex has no AskUserQuestion tool and Stop/UserPromptSubmit take no matcher, so we wire no PreToolUse/PostToolUse pair — the turn stays on the agent until the next Stop (documented degradation). The hook callback (`container/hook.py`) is already CLI-agnostic, so no control-plane change; the work is confined to the codex adapter + its test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codex's Stop payload has no background-task array, so has_live_background_task is simply always False. Remove the future-proofing parse loop, the unused _TERMINAL_STATUSES constant, and the hypothetical "lights up" test; keep the documented reason it's always False. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tildesrc
pushed a commit
that referenced
this pull request
Aug 24, 2026
…r, alt-screen Four fixes to make Codex spawn reliably without an operator in the container: - `features.apps = false` in config.toml disables the built-in apps connector, which cannot start in a container and stalls every spawn on its 30 s MCP timeout. The `[mcp_servers.codex_apps] enabled = false` alternative is invalid config that crash-loops Codex — the feature flag is the only safe disable. - `--dangerously-bypass-hook-trust` added to launch_argv (first run and resume): since PR #387 wired Stop/UserPromptSubmit hooks into config.toml, Codex prompts interactively to trust each hook hash; with no operator this hangs indefinitely. - Bypass flags moved after the `resume` subcommand (`codex resume --last --flags`), matching the reference implementation's required argument order. - `--no-alt-screen` on every launch so Codex renders into tmux scrollback instead of the alternate screen, keeping `tmux attach` history accessible. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tildesrc
added a commit
that referenced
this pull request
Aug 24, 2026
…r, alt-screen (#392) Four fixes to make Codex spawn reliably without an operator in the container: - `features.apps = false` in config.toml disables the built-in apps connector, which cannot start in a container and stalls every spawn on its 30 s MCP timeout. The `[mcp_servers.codex_apps] enabled = false` alternative is invalid config that crash-loops Codex — the feature flag is the only safe disable. - `--dangerously-bypass-hook-trust` added to launch_argv (first run and resume): since PR #387 wired Stop/UserPromptSubmit hooks into config.toml, Codex prompts interactively to trust each hook hash; with no operator this hangs indefinitely. - Bypass flags moved after the `resume` subcommand (`codex resume --last --flags`), matching the reference implementation's required argument order. - `--no-alt-screen` on every launch so Codex renders into tmux scrollback instead of the alternate screen, keeping `tmux attach` history accessible. Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
Completes the Codex adapter (ADR 0014, ROADMAP M3.6) by filling the last two hook seam stubs, so a codex task tracks the agent↔user turn ball exactly like a claude task.
What changed
CodexAgentCLI.write_settingsnow merges codex's[hooks]block intoconfig.toml(the[[hooks.Stop]]→[[hooks.Stop.hooks]]{type="command", command=…}shape), wiring the two turn-flip events to the shared, already-CLI-agnostic callbackpython -m panopticon.container.hook:Stop→hook user stop— hands the turn to the user, guarded by the background-task check; the callback prints nothing on this path, satisfying codex's "plain-text stdout invalid for Stop" rule.UserPromptSubmit→hook agent prompt— takes the turn back and prints the phase briefing + provisioning nudge.CodexAgentCLI.has_live_background_taskparses the Stop payload (mirrors the claude adapter's err-toward-live logic).config.toml.ADR 0014 flags resolved against codex's real hooks schema
UserPromptSubmithook's stdout back as developer context, so the briefing + provisioning nudge ride the same channel claude uses — no alternate channel needed.background_tasksarray (fields aresession_id/transcript_path/cwd/hook_event_name/model/permission_mode/turn_id/stop_hook_active/last_assistant_message), so the flip degrades to the plain hand-back — claude's exact behaviour when the field is absent. The parser still lights up if a future codex build adds the field.AskUserQuestiontool, andStop/UserPromptSubmittake nomatcher, so we wire noPreToolUse/PostToolUsepair — the "agent is asking" turn state stays on the agent until the nextStop(accepted documented degradation).Scope
The hook callback (
container/hook.py) was already CLI-agnostic (resolves the adapter, callsread_hook_payload/has_live_background_task), so there is no control-plane change — the work is confined to the codex adapter and its test. Docs updated: ADR 0014 flags 2/6/7 marked resolved, AGENTS.md module map, and the shared callback comment.