[FIX] Rectify: CodexBackend Command Builder Env Contract Immunity#3394
Merged
Trecek merged 8 commits intoMay 31, 2026
Merged
Conversation
3f12541 to
1af5947
Compare
…Backend Adds per-session-type REQUIRED_ENV frozensets and wires them through EnvPolicy.build_env at every build site, closing the silent drift between CodexBackend and ClaudeCodeBackend env injection. Fixes filtered base env in Codex headless/resume commands, adds sandbox flag to resume cmd, resolves NotImplementedError stubs, and adds cross-backend parametrized contract tests that structurally prevent future env var drift. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…NV reinjection MAX_MCP_OUTPUT_TOKENS is in _HEADLESS_EXCLUSIVE_VARS but legitimately re-injected via _SESSION_BASELINE_ENV extras in build_resume_cmd. The leak assertions must exclude intentionally re-injected keys. Also fixes ruff import ordering in core/__init__.pyi. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…heck Replace `assert isinstance(result, list)` with `assert result == []` in TestCodexStubMethods to pin the actual stub return value and catch regressions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tract file Remove test_resume_cmd_env_uses_filtered_base, test_resume_cmd_has_sandbox_flag, and test_headless_cmd_uses_filtered_base — all duplicate assertions already in test_codex_backend.py. Clean up unused imports. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both SKILL_SESSION_REQUIRED_ENV and ORCHESTRATOR_SESSION_REQUIRED_ENV now include MCP_CONNECTION_NONBLOCKING, matching the mandatory status already enforced by test_all_session_builders_inject_mcp_connection_nonblocking. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n Codex tests Import from autoskillit.execution.commands (the canonical re-export) instead of the private autoskillit.execution.backends._claude_prompt module, consistent with all other env-boundary tests in the repo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…headless_cmd Pre-merging env_extras into filtered_base subjected them to the CodexEnvPolicy denylist, silently dropping matching keys. Pass them as extras= instead, consistent with build_skill_session_cmd and build_food_truck_cmd which bypass the denylist for extras. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…verage tests MCP_CONNECTION_NONBLOCKING is always injected fresh via extras (never read from os.environ), so it belongs in the always_injected exemption set alongside AGENT_BACKEND_ENV_VAR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1af5947 to
b34d0d9
Compare
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
The
CodexBackendcommand builder methods (build_food_truck_cmd,build_resume_cmd,build_headless_cmd) silently diverge fromClaudeCodeBackendin which environment variables they inject. The root cause is that theCodingAgentBackendProtocol specifies only method signatures — it says nothing about which env vars each method must produce.The architectural fix: define per-session-type
REQUIRED_ENVfrozensets in_type_constants_env.py, wire them throughEnvPolicy.build_env(required=...)at every build site, and add cross-backend parametrized contract tests that assert env var parity across all backends in the registry.Key changes:
SKILL_SESSION_REQUIRED_ENV,ORCHESTRATOR_SESSION_REQUIRED_ENV, andRESUME_SESSION_BASELINE_KEYSfrozensets to_type_constants_env.pyrequiredthrough allbuild_*_cmdmethods in bothCodexBackendandClaudeCodeBackendCodexBackend.build_resume_cmdto use filtered base env (remove_HEADLESS_EXCLUSIVE_VARSleakage) and add missing sandbox flagsAGENT_BACKEND_ENV_VAR,AUTOSKILLIT_HEADLESS_AUTO_GATE,MCP_CONNECTION_NONBLOCKING) toCodexBackend.build_food_truck_cmdCodexBackendNotImplementedErrorstubs (validate_skill_content,list_plugins) with safe returnsArchitecture Impact
module-dependency Diagram
classDiagram direction TB class CodexBackend { +build_food_truck_cmd() +build_resume_cmd() +build_headless_cmd() +validate_skill_content() +list_plugins() } class ClaudeCodeBackend { +build_food_truck_cmd() +build_resume_cmd() +build_headless_cmd() } class EnvPolicy { +build_env(required) } class CodingAgentBackend { <<Protocol>> } CodexBackend ..|> CodingAgentBackend ClaudeCodeBackend ..|> CodingAgentBackend CodexBackend --> EnvPolicy ClaudeCodeBackend --> EnvPolicyprocess-flow Diagram
flowchart TD A[build_food_truck_cmd] --> B[EnvPolicy.build_env required=SKILL_SESSION_REQUIRED_ENV] C[build_resume_cmd] --> D[EnvPolicy.build_env required=RESUME_SESSION_BASELINE_KEYS] E[build_headless_cmd] --> F[EnvPolicy.build_env required=ORCHESTRATOR_SESSION_REQUIRED_ENV] B --> G[CodexBackend food truck process] D --> H[CodexBackend resume process] F --> I[CodexBackend headless process]security Diagram
flowchart LR A[_HEADLESS_EXCLUSIVE_VARS] -->|filtered out| B[build_resume_cmd base env] C[missing sandbox flags] -->|added| D[CodexBackend.build_resume_cmd] E[AGENT_BACKEND_ENV_VAR MCP_CONNECTION_NONBLOCKING AUTOSKILLIT_HEADLESS_AUTO_GATE] -->|added| F[CodexBackend.build_food_truck_cmd] G[NotImplementedError stubs] -->|replaced| H[safe returns]Closes #3383
Implementation Plan
Plan file:
.autoskillit/temp/rectify/rectify_codex_env_contract_immunity_2026-05-30_215500.md🤖 Generated with Claude Code via AutoSkillit
Token Usage Summary
* Step used a non-Anthropic provider; caching behavior may differ.
Token Efficiency
Model Usage Breakdown