Skip to content

Codex qe-court seat stall: action plan #108

Description

@pacphi

Codex qe-court seat stall: action plan

  • Status: Proposed living plan
  • Published: 2026-08-03
  • Last updated: 2026-08-03
  • Decision owner: pacphi/agentic-kit maintainers
  • Incident scope: Claude Code → Codex MCP seats used during an agentic-qe qe-court
  • Evidence cutoff: 2026-08-03 America/Los_Angeles

This document separates confirmed evidence from hypotheses. It does not itself change an
accepted architecture decision. Implementation that changes managed projections or execution
behavior must update the affected agentic-kit ADRs in the same change.

Table of contents

1. Executive brief

Three Codex-routed prosecutor seats stalled during a qe-court run. The initial correlation with
prompts requesting Cargo under a read-only sandbox was real, but controlled reproduction disproved
Cargo as the direct trigger. The three stalled rollouts never reached Cargo or a shell command;
each stopped while a Codex code-mode turn awaited a nested mcp__ruflo__memory_search call. A
plugin-enabled memory-only reproduction also exceeded a 90-second external deadline. In contrast,
an isolated Codex configuration returned normally, direct Ruflo memory search completed in tens of
milliseconds, and plugin-free Cargo controls failed fast under read-only plus never.

The confirmed fault boundary is therefore an unbounded Codex MCP/code-mode session interacting
with nested MCP machinery, not Cargo writes alone. Existing public reports show related classes of
Codex MCP sessions stalling around approvals, elicitation, or sandbox setup, but none proves the
exact local mechanism (Codex #11816, Codex #18243,
codex-plugin-cc #258).

The recommended response has three layers:

  1. Contain now: treat raw Claude → Codex MCP seats as inspection-only, forbid nested MCP and
    build commands in that profile, and impose an operator-visible deadline.
  2. Fix agentic-kit: replace the bare managed codex mcp-server projection with a guarded stdio
    bridge that injects policy, rejects incompatible requests, enforces an absolute timeout, and
    terminates the child process tree. Add a scoped Codex PreToolUse circuit breaker only after
    proving its bridge-only scope; Codex documents hooks as useful guardrails rather than complete
    enforcement boundaries (Codex hooks).
  3. Coordinate upstream: file a sanitized Codex issue for the nested MCP/code-mode stall and two
    agentic-qe issues for the incomplete qe-court asset plus missing execution-policy preflight.
    Route build-capable seats through supervised ak run or agentic-qe's bounded provider path.

2. Actions at a glance

  • Today: publish operator guidance and a known-issue warning; use diff-only prompts for the raw
    read-only bridge. See Phase 0.
  • Today–next business day: file one Codex issue and two agentic-qe issues using sanitized,
    minimal reproductions. See Phase 1.
  • Within three business days: implement the agentic-kit guarded bridge, external deadline,
    cleanup, status diagnostics, and explicit direct-mode escape hatch. See
    Phase 2.
  • Within four business days: add court-aware compatibility preflight and send build/test work to
    ak run rather than the raw seat bridge. See
    Phase 3.
  • Before release: pass the full bounded-reproduction matrix, pnpm run check, Markdown lint,
    link checks, and ADR reconciliation. See exit criteria.
  • Week 2: review upstream responses and decide whether a scoped PreToolUse rule is proven safe
    enough to enable by default. See open questions.

3. Recommended course of action

3.1 Immediate containment

Keep the bridge available, because peer-host delegation is a core ambidextrous capability. Change
its default contract from “arbitrary autonomous worker” to “bounded inspection seat” until the
nested-call failure is understood.

  • Add an explicit developer instruction: no builds, tests, package resolution, edits, or nested MCP
    calls under the read-only seat profile; return a clear limitation instead.
  • Require build/test requests to select workspace-write through supervised ak run, with network
    policy and timeout stated by the activity route.
  • Set a temporary 120-second outer deadline for raw court seats. This is intentionally much shorter
    than the 35-minute incident stalls and can be tuned after telemetry exists.
  • Preserve a deliberate direct mode for debugging, but warn that it bypasses agentic-kit
    supervision.

3.2 Guarded bridge as the agentic-kit default

Agentic-kit owns the project-scoped Claude → Codex projection, so it is the correct place for the portable workaround. Claude Code supports project-scoped stdio MCP definitions in .mcp.json (Claude Code MCP scopes); agentic-kit should project its own wrapper command there instead of projecting bare codex mcp-server. Because this makes agentic-kit responsible for a new supervised boundary, implementation requires an ADR-0020 amendment or a new ADR before the guarded projection becomes the default.

The wrapper should:

  1. Spawn the real codex mcp-server and transparently proxy stdio JSON-RPC.
  2. Intercept codex tool requests before forwarding them.
  3. Inject bridge-specific developer-instructions and a trace marker.
  4. Reject read-only prompts that explicitly require mutation or build output, with a structured
    remediation message.
  5. Apply an absolute per-request deadline and terminate the whole child process tree on expiry.
  6. Emit bounded diagnostics without copying prompt or repository contents by default.
  7. Expose guarded/direct mode and drift in ak status and repair it through ak sync.

The wrapper must not claim it can disable user-owned Codex plugins per request. That override was not effective in the observed Codex 0.146.0 child sessions. Plugin state remains externally owned.

3.3 Upstream fixes and coordination

  • OpenAI Codex: request a minimal per-turn timeout/cancel contract for mcp-server, reliable
    cancellation of nested code-mode tool promises, and documented propagation of per-call config.
    The official Agents SDK example places a timeout on the MCP client, which supports the need for
    caller-side bounding but does not solve child cleanup by itself
    (Codex MCP server guide).
  • agentic-qe: ship qe-court's referee and schema as self-contained installed assets, then add a
    seat execution policy that validates sandbox/command compatibility and applies a deadline.
    Upstream ADR-124 is still marked Proposed at the cited revision despite implementation artifacts
    being present (ADR-124).
  • Ruflo/RuvNet Brain: do not assign root cause based on the current evidence. Direct Ruflo memory
    search was healthy. Engage these maintainers only if a direct server-level reproduction or a
    plugin hook contribution is isolated.
  • Anthropic Claude Code: no root-cause issue is recommended now. The handoff to a background
    tool call worked. Consider a client-side timeout/lifecycle feature request after the agentic-kit
    wrapper proves the desired semantics.

3.4 Completely avert: Claude + OpenRouter court

Use this profile when avoiding the incident path is more important than preserving Codex as a
court participant. It removes every Codex seat and disables agentic-kit's managed Claude ↔ Codex
bridge. Claude remains the driving host; court inference uses only the bounded claude-code and
openrouter providers through agentic-qe's ProviderManager.

1. Load the OpenRouter key from a shell profile or secret manager. Keep
OPENROUTER_API_KEY out of kit.json, .agentic-qe/llm-config.json, and the court config.

2. Apply the part agentic-kit owns with existing commands:

ak host pick \
  --host claude \
  --primary-host claude \
  --aqe-provider claude-code \
  --aqe-fallback none
ak sync

--host claude is the complete desired host set. It disables Codex and removes only the two
Codex MCP registrations owned by agentic-kit. --aqe-fallback none records that this court must
not silently substitute one provider for another. If an older agentic-kit-managed
.agentic-qe/llm-config.json still contains fallbackChain, remove that stale block or set its
entries to [] before convening; the current Claude-only no-policy projection does not erase an
old on-disk chain merely because the persisted chain is empty.

3. Set these operational fields in the project-owned
.claude/skills/qe-court/config.json.
Preserve its $schema, descriptions, and other metadata:

{
  "prosecutors": [
    "devils-advocate",
    "brutal-honesty",
    "sherlock",
    "security-scanner",
    "mutation"
  ],
  "overturnDepth": 2,
  "emitScore": false,
  "routing": {
    "defense": { "provider": "claude-code", "model": "sonnet" },
    "prosecutor.devils-advocate": {
      "provider": "openrouter", "model": "deepseek/deepseek-v4-flash"
    },
    "prosecutor.brutal-honesty": { "provider": "claude-code", "model": "opus" },
    "prosecutor.sherlock": { "provider": "openrouter", "model": "z-ai/glm-5.2" },
    "prosecutor.security-scanner": {
      "provider": "openrouter", "model": "google/gemini-3.5-flash"
    },
    "prosecutor.mutation": {
      "provider": "openrouter", "model": "google/gemini-3.5-flash"
    },
    "jury": { "provider": "openrouter", "model": "openai/gpt-5.6-terra" },
    "deeperReviewer": { "provider": "openrouter", "model": "openai/gpt-5.6-sol" }
  },
  "options": {
    "blindFiling": true,
    "writerIsNeverJuror": true,
    "minDistinctVendors": 2,
    "requireDoeGatedScore": true,
    "signCourtRecord": true
  }
}

The candidate panel passes agentic-kit's current validateCourtConfig() with no violations.
The OpenRouter slugs were verified at the evidence cutoff:
DeepSeek V4 Flash for inexpensive adversarial breadth,
GLM 5.2 for deductive review,
Gemini 3.5 Flash for fast security/mutation evidence interpretation,
GPT-5.6 Terra for the jury, and
GPT-5.6 Sol only as the expensive overturn ceiling.

Do not use an anthropic/* OpenRouter model in the jury. The current validator maps the provider
name openrouter to one coarse vendor and does not inspect the model slug's underlying model
maker; an Anthropic-via-OpenRouter jury could therefore pass the structural check while violating
the substantive writer-versus-juror independence goal.

4. Keep provider attempts bounded. Agentic-qe's Claude Code provider disables Bash, edits,
web access, and subagents by default and has a 120-second request timeout
(source). Its OpenRouter provider uses bounded HTTP requests; make
the retry policy explicit in .agentic-qe/llm-config.json
(source):

{
  "providers": {
    "openrouter": {
      "enabled": true,
      "timeoutMs": 60000,
      "maxRetries": 1,
      "allowFallback": false
    }
  }
}

Agentic-kit's router projection preserves these provider-specific sibling fields. A failed or
timed-out jury/deeper seat must produce a skipped-seat note and REMAND; it must never fall back
to Claude and then grade Claude's defense.

5. Run commands outside the court, then review immutable evidence. Run builds, Cargo, tests,
security scanners, and mutation tools once through Agentic-QE or a supervised ak run --timeout
workflow. Give the resulting diff, logs, and reports to court seats as read-only evidence. The
court prompt must prohibit mcp__codex__codex, codex, nested MCP, builds, tests, and package
manager commands inside seats.

6. Verify before every court:

ak host status
aqe llm providers
aqe llm health
claude mcp get codex

The expected state is: Claude enabled and primary; Codex disabled; both claude-code and
openrouter healthy; qe-court panel valid; no project Codex MCP registration. If
claude mcp get codex still finds a project entry, agentic-kit did not own it. Inspect it first;
if it is the exact bridge being retired, remove it explicitly:

claude mcp remove codex --scope project

Current CLI boundary: agentic-kit has no existing command that assigns arbitrary qe-court
roles and models. It intentionally treats the court config as project-owned and validates it
read-only. The commands above establish the host/provider boundary; the JSON establishes the role
map. Do not invent or document a one-command ak court-profile surface unless a later ADR amends
the stable command contract.

4. Projects and responsibilities

Project or actor Role in the path Accountable action Target
pacphi/agentic-kit Provisions the bidirectional bridge, routes activities, and owns managed projections Guard the Claude → Codex bridge; add preflight, deadline, cleanup, status, docs, tests, and ADR updates Next patch release
openai/codex Runs codex mcp-server, code-mode turns, sandbox policy, and nested MCP calls Diagnose the nested tool wait; add fail-fast cancellation/deadline semantics and clarify config propagation Upstream schedule
proffesor-for-testing/agentic-qe Defines qe-court protocol/assets and has a bounded Codex provider path Repair asset packaging; add seat capability validation, prompt policy, and timeout; reconcile ADR-124 Next compatible release
ruvnet/ruflo Provides nested MCP memory and swarm capabilities Assist only if the direct server or approval path reproduces independently Conditional
stuinfla/ruvnet-brain Adds guidance/hooks around Codex sessions Assist only if a specific hook or injected instruction is shown causal Conditional
Anthropic Claude Code Hosts the project MCP client and background transport Optional client deadline/lifecycle improvement; no present root-cause assignment Follow-up
Court convener/operator Chooses seat profile and prompt capabilities Use inspection-only raw seats; route builds through supervised execution; capture timeout errors, not unbounded waits Immediate

5. Multi-step action plan

5.1 Phase 0: contain and communicate

What Where Owner When Deliverable
Document raw bridge limitations and safe seat prompts claude/dual-mode-reference.md, docs/TROUBLESHOOTING.md agentic-kit maintainer T+0, 2026-08-03–04 Inspection-only guidance with ak run handoff
Warn on an unguarded Codex projection src/commands/status.mjs, src/lib/mcp.mjs agentic-kit maintainer T+0–1 Actionable status finding
Adopt a temporary outer deadline in court operations Convener procedure and qe-court config notes Court convener Immediate Seat ends with timeout evidence within 120 seconds
Preserve and redact evidence Local rollout records; no public raw upload Incident lead Before issue filing Sanitized repro bundle

5.2 Phase 1: file focused upstream issues

Issue Owner When Required content Done when
Codex nested MCP/code-mode stall Incident lead in openai/codex T+0–1 Clean vs integrated control, exact 0.146.0 call shape, event boundary, deadline behavior, sanitized logs Public issue URL recorded here and linked to related reports
qe-court packaged asset is incomplete Incident lead in agentic-qe T+0–1 3.13.3/3.13.6 package-vs-source comparison, missing schema/import evidence, installer path Maintainer can reproduce from published artifact
qe-court lacks execution compatibility preflight Incident lead in agentic-qe T+0–1 Manual MCP bypass, sandbox/command mismatch, timeout requirement, suggested seat capabilities Requirement accepted or disposition documented

Do not combine these into one cross-project issue. Each maintainer should receive the smallest reproduction inside their ownership boundary. Use the templates in Appendix E.

5.3 Phase 2: implement the guarded bridge

Step Where Owner When QA gate
Add managed bridge configuration and validation Existing config/schema modules; no secrets agentic-kit implementer T+1 Invalid mode/timeout rejected at boundary
Add stdio proxy command around the real Codex server New focused module under src/lib/execution/ plus command wiring agentic-kit implementer T+1–2 Transparent initialize/list/call fixture passes
Add request preflight and developer instructions Proxy policy module agentic-kit implementer T+2 Read-only build request rejected; diff-only request forwarded
Add deadline, cancellation, and process-tree cleanup Proxy lifecycle module, reusing execution-runner patterns agentic-kit implementer T+2 Forced stall exits on time with no descendant left
Project guarded command instead of bare Codex src/lib/providers.mjs, .mcp.json ownership path agentic-kit implementer T+2 ak sync converges and preserves unrelated user entries
Report guarded/direct/drift state src/lib/mcp.mjs, status renderers agentic-kit implementer T+3 Status fixtures cover healthy, legacy, drift, unavailable
Spike scoped nested-MCP hook Managed Codex hook projection, isolated test home agentic-kit security reviewer T+3 Rule acts only on marked bridge sessions or remains opt-in

The hook spike is not on the critical path. Official Codex documentation says PreToolUse can deny MCP and other local function calls, including the nested code-mode path, but specialized paths may bypass hooks (Codex hooks). The outer proxy deadline therefore remains the mandatory enforcement layer.

5.4 Phase 3: add court-aware preflight and routing

What Where Owner When QA gate
Model seat capabilities: inspect, build, network, nested tools src/lib/qeCourt.mjs read-only awareness; upstream qe-court schema agentic-kit + agentic-qe maintainers T+3 Incompatible seat/prompt fails before dispatch
Route inspection seats to guarded MCP qe-court instructions and activity routing agentic-kit maintainer T+3 Diff-reading seat completes under read-only
Route build/test seats to supervised execution ak run templates/routes or agentic-qe ProviderManager agentic-kit + court convener T+3 Writable build seat is bounded and reports artifacts/errors
Repair self-contained referee installation agentic-qe asset build and installer agentic-qe maintainer Upstream Fresh install runs validator without source-tree imports
Reconcile design status agentic-qe ADR-124; agentic-kit ADRs as applicable Respective maintainers With implementation Status and Updated metadata match shipped behavior

5.5 Phase 4: prove, release, and monitor

  1. Run the matrix in Appendix B on macOS with Codex
    0.146.0 and the then-current stable Codex version.
  2. Run focused provider, MCP, status, qe-court, and execution-runner tests.
  3. Run pnpm run check, pnpm run lint:md, and internal/external link checks.
  4. Review the projected .mcp.json diff and prove unrelated user-managed MCP entries survive.
  5. Release in the next patch only after all mandatory criteria pass.
  6. During week 2, review issue responses and revise this plan's status, dates, and links.

6. Options considered

Option Benefit Cost or failure mode Disposition
Wait for Codex upstream; change nothing No local code Leaves indefinite, silent stalls in an agentic-kit-managed projection Rejected
Documentation/status + developer instructions only Ships immediately and preserves ownership User steering can bypass it; no wall-clock enforcement Phase 0 containment
Prompt-only “do not run Cargo” wording Immediate and already correlated with completion Does not address the confirmed nested MCP wait; user steering can override it Containment only
Per-call config to disable plugins/MCP Narrow in theory Tested overrides did not remove loaded integrations in Codex 0.146.0 child sessions Rejected until proven upstream
Isolated CODEX_HOME for court seats Clean control completed normally Auth/config portability, update, ownership, and user-expectation risks Diagnostic control; possible future profile
Change all seats to danger-full-access Avoids some sandbox failures Excess privilege and still no proof it prevents nested MCP stalls Rejected
Use workspace-write for Cargo Correct capability for build output Solves command compatibility, not the observed nested wait Recommended only for supervised build seats
Disable Ruflo/RuvNet plugins globally Removes integrated variables Broad collateral damage; direct Ruflo was healthy; violates external ownership Rejected
Codex PreToolUse hook only Can deny supported nested MCP calls Documented exceptions; scope and propagation must be proven Optional defense-in-depth
Guarded stdio proxy only Provides preflight, deadline, cleanup, and stable diagnostics Cannot observe every internal call; needs robust JSON-RPC proxying Mandatory base
Guarded proxy + scoped hook + supervised routing Bounds the turn, blocks known traps, preserves build capability elsewhere More implementation and test work Recommended
Route every seat through ak run/ProviderManager Existing timeout supervision May not preserve interactive court semantics for all seats Recommended for build/test seats
Remove the Claude → Codex bridge Eliminates this path Loses a documented ambidextrous capability Rejected
Export referee subpath or copy TypeScript Reuses canonical source Global installs cannot reliably import the subpath; consumers may lack a transpiler Rejected as sole packaging fix
Handwrite a second installed referee Simple artifact Duplicates policy and will drift Rejected
Generate installed JavaScript, then expose aqe court validate Self-contained short-term artifact and stable long-term API Requires release artifact tests and CLI design Recommended agentic-qe path

7. Acceptance and exit criteria

The patch is releasable only when all mandatory criteria pass:

  • A read-only request that demands Cargo/build/test output is rejected before Codex starts, with a
    remediation pointing to a supervised writable route.
  • A forced nested-memory stall is either blocked by a proven scoped hook or terminated by the outer
    deadline. It never remains indefinitely “working.”
  • A normal diff/grep-only inspection request completes through the guarded bridge.
  • A build-capable request completes or fails within the configured ak run/provider timeout.
  • Timeout termination removes the Codex child and descendants; no orphan session remains.
  • Guarded/direct mode and drift are visible in human and JSON status output.
  • ak sync is convergent and does not mutate user-owned plugin caches, Codex settings, or unrelated
    MCP registrations.
  • Diagnostics identify phase, elapsed time, policy decision, and child exit state without logging
    source, prompt text, credentials, or environment secrets by default.
  • Focused tests and the full project check pass on supported Node versions.
  • ADR-0016, ADR-0018, and ADR-0020 are reviewed; any behavior-changing decision gets an Updated
    entry and implementation evidence in the same patch.
  • Upstream issue links and dispositions are added to this living plan.

8. Risks, dependencies, and open questions

  • Exact Codex mechanism remains unresolved. The evidence locates the wait at a nested MCP
    promise, but does not yet distinguish Codex orchestration, elicitation, cancellation, or an
    interaction with plugin-provided machinery.
  • Hook scoping may be insufficient. A global nested-MCP denial would break legitimate Codex
    work. The default hook requires a reliable bridge-session marker and isolated-home proof.
  • JSON-RPC proxy correctness is security-sensitive. Preserve framing, backpressure, stderr,
    cancellation, request IDs, and shutdown semantics; reject malformed input at the boundary.
  • Timeout selection is policy, not truth. Start at 120 seconds for raw court seats, expose a
    bounded configuration, and use telemetry before increasing it.
  • Upstream version drift matters. Re-run controls against current Codex before implementation;
    do not assume 0.146.0 behavior is permanent.
  • Ownership must remain precise. Agentic-kit may replace the projection it owns, but must not
    adopt or rewrite user-owned Codex plugin state.
  • Decision required after the hook spike: enable a bridge-scoped deny by default, keep it opt-in,
    or omit it and rely on the proxy deadline plus routing.

Appendix A: incident background

A.1 Reported symptom

During phase 2 of a qe-court, three of four Codex-routed prosecutor calls produced no output for
more than 35 minutes and were killed manually. The hung prompts asked for Cargo commands under
sandbox: "read-only" and approval-policy: "never"; diff-reading prompts completed. The path was:

Claude Code → mcp__codex__codex → project .mcp.json → codex mcp-server 0.146.0 → Codex turn

The local Codex configuration also loaded Ruflo and RuvNet Brain integrations. Completed calls
showed the Brain guidance footer, which made plugin interaction a reasonable hypothesis but not
proof of fault.

A.2 Corrected forensic conclusion

Rollout inspection showed that all three stalled seats entered code mode and awaited a nested
mcp__ruflo__memory_search. No shell or Cargo call followed. The original “Cargo cannot write
target/ and Codex retries forever” mechanism is therefore disproved for this incident.

The strongest supported conclusion is:

Codex MCP sessions with the integrated configuration can stall indefinitely while a code-mode
turn awaits a nested MCP call; the exact allocation between Codex core and integration
interaction remains open.

A.3 Why the distinction matters

Changing read-only to workspace-write is correct for an intentional build, but it does not fix
the observed stall. Filing the incident as a Cargo sandbox bug would send upstream maintainers the
wrong reproduction. The action plan therefore bounds every raw seat while separately validating
command/sandbox compatibility.

Appendix B: experiments and fault tree

B.1 Experiment matrix

Case Integration state Prompt/action Sandbox Result Interpretation
Three incident seats Ruflo/Brain loaded Prosecutor prompts that later mentioned Cargo Read-only/never Stalled at nested memory_search; no shell event Confirms event boundary, not Cargo causality
Memory-only reproduction Ruflo/Brain loaded Invoke nested Ruflo memory search Read-only/never Exceeded 90-second outer deadline Reproduces class without Cargo
Isolated Codex home Plugins/MCP absent Equivalent analysis prompt Read-only/never Returned in about 9 seconds Integrated state is required for observed reproduction
Direct Ruflo calls Ruflo server directly memory_search N/A 31–61 ms Ruflo server is not independently slow
Cargo controls Plugin-free cargo test under read-only Read-only/never Exit 101 and final response in 11–16 seconds Sandbox denial fails fast in the control
Diff-only court seats Integrated Git/grep/reasoning only Read-only/never Returned in about 5–25 minutes Raw path can complete, but remains unbounded

Times are observed local measurements, not service-level guarantees.

B.2 Revised fault tree

  • H1 — Codex MCP/code-mode orchestration: still primary for upstream research. Discriminator:
    reproduce nested MCP waiting with the smallest non-Ruflo MCP server and clean plugin setup.
  • H2 — agentic-kit provisioning: owns lack of caller-side bounding and guardrails. It does not
    own Codex plugin lifecycle. Discriminator: guarded proxy prevents unbounded impact regardless of
    child cause.
  • H3 — qe-court installation/config: owns missing validation assets and absent seat capability
    contract. It did not execute through agentic-qe's provider timeout in this manual court.
  • Plugin-specific fault: unproven. Discriminator: enable Ruflo and Brain separately, then compare
    code-mode nested calls, hook traces, and approval events.

Appendix C: current architecture and ownership

C.1 Request path

Agentic-kit currently registers Codex in Claude Code as a project-scoped stdio MCP server. Codex then independently reads its home configuration and can register Ruflo as a nested MCP server. Claude Code's project scope is shared through .mcp.json, while user and plugin scopes have their own precedence rules (Claude Code MCP scopes).

C.2 Current agentic-kit seams

  • src/lib/providers.mjs: ensureCodexMcp() projects bare codex mcp-server and records
    agentic-kit ownership of that MCP entry (source).
  • src/lib/mcp.mjs: detects Claude → Codex and Codex → Ruflo registration state.
  • src/lib/qeCourt.mjs: validates read-only awareness and an existing qe-court config; it does not
    implement or dispatch the court protocol (source).
  • claude/dual-mode-reference.md: documents the bidirectional bridge and ak run as the canonical
    activity pipeline (source).

C.3 ADR constraints

  • ADR-0016 requires capability-driven adapters, precise ownership, and convergent
    managed projections. The wrapper may replace only the Codex MCP projection agentic-kit owns.
  • ADR-0018 makes ak run canonical for supervised host-worker execution and defines
    per-attempt timeout/cancellation behavior.
  • ADR-0020 establishes one stable GA surface per capability; the guard should extend
    the existing bridge and ak run, not add a competing public execution command.

Appendix D: proposed configuration and behavior

D.1 Managed configuration sketch

The exact schema should follow existing agentic-kit configuration conventions. The intended policy is equivalent to:

{
  "codexBridge": {
    "mode": "guarded",
    "timeoutMs": 120000,
    "readOnlyPolicy": "inspect-only",
    "nestedMcp": "deny-when-scoped"
  }
}

nestedMcp must remain deadline-only or opt-in if bridge-only hook scoping cannot be proven.

D.2 Guard decisions

Request Decision Message or route
Read-only + explicit build/test/package install Reject before child call Use ak run with a writable activity route
Read-only + edit/write instruction Reject before child call Select an authorized writable workflow
Read-only + diff/grep/read-only inspection Forward with inspection developer instructions Guarded Codex seat
Workspace-write requested through raw court bridge Reject or require explicit direct escape hatch Prefer ak run supervision
Nested MCP attempted in a proven marked bridge session Deny via scoped hook Return limitation to the model
Any forwarded request exceeds deadline Cancel, terminate tree, return structured timeout Include elapsed phase and remediation

Preflight is deliberately conservative and must not pretend natural-language classification is a security boundary. The outer deadline and sandbox remain enforcement layers.

D.3 Timeout and cleanup contract

  • Deadline is absolute per top-level codex request, not reset by progress events.
  • On expiry: send protocol cancellation if available, close stdin, send graceful termination, then
    force-kill the validated descendant process group after a short grace period.
  • Return one terminal MCP error with a stable agentic-kit error code.
  • Record timestamps, PID identities, exit/signal, and cleanup result; redact prompts and content.
  • Never target a broad or unresolved process set. Validate the spawned child/process group first.

Appendix E: issue filing packages

E.1 OpenAI Codex

Title: mcp-server turn can hang indefinitely awaiting nested MCP tool in code mode

Include Codex 0.146.0, macOS/architecture, stdio client, sandbox/approval values, exact final rollout
event, a tiny nested MCP server, clean/integrated controls, and external timeout result. Ask for a
per-turn deadline, cancellation propagation, fail-fast terminal response, and documented per-call
config behavior. Link related but non-identical reports
Codex #11816, Codex #18243, and
codex-plugin-cc #258. Explicitly state that Cargo failed fast in controls.

E.2 agentic-qe packaging

Title: qe-court installed asset is not self-contained: referee/schema omitted or source-bound

Compare the published 3.13.3 and later package revision footprint with the cited source implementations:
the referee, skills installer, and
asset preparation script. Provide a fresh-install reproduction and expected
self-contained validator behavior. Request an artifact test in release CI.

E.3 agentic-qe execution policy

Title: qe-court seats need sandbox capability preflight and bounded provider execution

Explain that the manual MCP path bypassed the bounded Codex provider.
Propose declared seat capabilities, sandbox-aware templates, a pre-dispatch compatibility error,
and a required timeout for every provider/manual adapter. Ask maintainers to reconcile shipped
scope with ADR-124's Proposed status.

Appendix F: evidence handling

The primary incident artifacts are local Codex rollout JSONL files, the emailibrium court record, the installed qe-court footprint, and a local session lesson. They may contain private prompts, paths, repository content, or machine metadata.

  • Keep originals local and immutable during issue preparation.
  • Publish a minimized reproduction in a disposable Rust repository or synthetic MCP server.
  • Replace usernames, absolute paths, session IDs, and unrelated MCP configuration.
  • Include only the events needed to establish request parameters, final completed event, elapsed
    time, cancellation, and process cleanup.
  • Label measurements as observations and causal claims as confirmed, disproved, or open.

Appendix G: public references

All references below were accessed on 2026-08-03. Source-code links are pinned where a revision was used in the investigation.

  1. OpenAI, Codex hooks documentation. Documents PreToolUse coverage, deny
    responses, and the warning that specialized paths can opt out.
  2. OpenAI, Use Codex with the Agents SDK. Documents codex mcp-server as a
    long-lived stdio server and shows caller-side session timeout configuration.
  3. OpenAI Codex, issue #11816. Related indefinite MCP/elicitation wait.
  4. OpenAI Codex, issue #18243. Related macOS MCP sandbox setup failure.
  5. OpenAI Codex Claude Code plugin, issue #258. Related nested MCP
    elicitation stall under read-only/never.
  6. Anthropic, Claude Code MCP documentation. Defines project-scoped .mcp.json
    stdio servers and scope precedence.
  7. OpenAI Codex 0.146.0, codex_tool_config.rs and
    release. Pinned incident-version tool configuration and release context.
  8. agentic-kit, repository, Codex projection,
    qe-court awareness, and dual-host reference.
  9. agentic-kit, ADR-0016, ADR-0018, and
    ADR-0020. Current ownership, execution, and stable-surface constraints.
  10. agentic-qe, ADR-124, referee,
    skills installer, Codex provider, and
    asset preparation. The revision comparison showed no
    relevant repair at the evidence cutoff.
  11. Ruflo, repository and MCP tools reference. Public project and
    memory-tool reference.
  12. RuvNet Brain, repository. Public integration project.
  13. OpenRouter model records for DeepSeek V4 Flash,
    GLM 5.2, Gemini 3.5 Flash,
    GPT-5.6 Terra, and GPT-5.6 Sol.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions