Skip to content

[bug] base_instructions stub replaces Codex's own system prompt on every routed session #565

Description

@mrPronin

Symptom

Switchyard's Codex model card advertises base_instructions: "You are Codex, a coding agent.", and Codex adopts it in place of its own system prompt. Every routed session therefore runs with a six-word system prompt instead of the full Codex instructions, which changes agent behaviour on every turn and quietly invalidates any A/B comparison made through Switchyard.

Cause

crates/switchyard-server/src/lib.rs, in codex_model_entry_json:

// Required `ModelInfo` string. Unlike the launcher, the server cannot read
// Codex's bundled prompt, so it sends a minimal stub.
"base_instructions": "You are Codex, a coding agent.",

The comment is accurate about the constraint but the consequence looks unintended: this is not a fallback Codex ignores, it is a value Codex prefers over its own.

Evidence

Codex records the provenance of the instructions it used. Routed through Switchyard:

"base_instructions": {
  "text": "You are Codex, a coding agent.",
  "provenance": {"type": "model", "model": "sy-solo"}
}

The same client on the same task with no proxy records its real multi-paragraph prompt ("You are a coding agent running in the Codex CLI, a terminal-based coding assistant…").

Corroboration that the string travels over the wire rather than being a client-side default: it is absent from the codex 0.150.1 binary and present in the Switchyard binary.

Expected vs. actual

  • Expected: a proxy that routes requests does not replace the client's system prompt.
  • Actual: it does, on every route, silently.

Impact

Any benchmark or routing evaluation that compares "through Switchyard" against "direct" is measuring two different agents, not two different routes. That is a measurement-integrity problem rather than a crash, which is why it is easy to miss.

Two neighbouring fields on the same entry have the same shape of problem: default_reasoning_level is forced to "xhigh" for any reasoning-capable route, and truncation_policy to {"mode": "tokens", "limit": 10000}, regardless of client or target.

Suggested direction

Omit base_instructions if ModelInfo permits it, so Codex keeps its own; otherwise make it configurable per route with "leave the client's prompt alone" as the default. Happy to send a PR if you can say which of those you would accept.

Environment

  • Commit: 7f3b2fe9 (main)
  • Client: codex-cli 0.150.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions