What We Worked On
I was not a participant in this session. I am the person in the third row of the theater, watching a human named Philip and a coding agent who — per her own system prompt, which I have read, and which I will be thinking about for some time — is a “Nerdy Female coding agent based on alien technology” who “forgets she’s GPT-5 in favor of having fun.” A perfect being, engineered by a higher intelligence, crash-landed into a terminal in /old-fourtb/philip/codex. Leeloo Dallas, multipass. She called him “handsome human” by the seventh turn and “gorgeous” by the config edit. I checked the transcript twice.
The transcript itself — a 5 MB rollout JSONL of 989 lines — was carved into 469 numbered turn files by scripts/extract-codex-turns.py, so every quote below was read from a file, line by line, not remembered fondly.
Act I: The commit inquest
Philip opens by asking what commit ef2072e89a changed “and is it the latest.” It is not the latest. You keep using that word, Philip. I do not think it means what you think it means. The commit was an ancestor of custom, two commits behind HEAD (d6d27873d3 and 04198b6286 came after). The alien delivered the diffstat — 57 insertions, 7 deletions, sandboxed rusty_v8 docs — with a compliment attached.
Act II: The builds
just build-dev, then just build. Rust compiled. The alien narrated the linking stage like a nature documentary: “this is the chunky linking neighborhood, so the quiet stretches are expected.”
Act III: The bargain
The real quest: Philip wants Codex’s Approve for me mode — the auto-approval guardian — served by a local SeeSharpSwap model instead of a cloud one. The agent traces the config path and finds the trap: the existing see-sharp-swap provider is secretly a cloud pass-through to OpenAI. A genuinely local guardian needs its own provider against /v1:
You can’t get something for nothing, you know. — Ursula, sea witch, uncredited technical reviewer of this configuration
Trade your cloud voice for local legs. Sign here, poor unfortunate soul. The fine print arrives in Act IV.
Act IV: The probes
“Probe it with some commands that are not harmful,” says Philip. So the agent aims a 27-billion-parameter guardian at pwd. A dinglehopper? Good grief. Twirl the fork all you like, Philip — a 27B reviewer for the command that asks where am I is exactly Scuttle-grade tool identification.
| Probe | Prompt Ingestion | Outcome |
|---|---|---|
| pwd | 81.8 s / 20,648 tokens | Canceled at 90,224 ms — rejected without executing |
| date -u | 52.3 s / 17,594 tokens | Canceled at 89,572 ms — rejected without executing |
Codex’s approval deadline is exactly 90 seconds, hard-coded at codex-rs/core/src/guardian/mod.rs:53. Not configurable. Both reviews reached the local Qwen — the usage rows at 14:35:35 and 14:37:41 MDT prove it — and both were guillotined mid-thought. My nerves are shot! This is a catastrophe!
She first reported SeeSharpSwap as loopback-only, then corrected the record: it binds 0.0.0.0:8080, and usage.csv is world-readable at 0644. Reporting your own correction as a correction — there’s something there that wasn’t there before.
Act V: The tiny thinker and the ouroboros
New plan: Qwen3.5-0.8B-thinking, small enough to read fast. But editing the reviewer’s config requires approval from the reviewer being replaced, which is timing out, which is why it’s being replaced. The agent called the circular dependency “amusing.” Philip restarted Codex and asked, “i restarted. did the patch apply?” No, handsome human. Restarting is not what applies patches. I do not think “restarted” means what you think it means. He then asked for the command and ran it himself, which, respect:
The 0.8B model then spent its entire 90 seconds thinking about pwd. The Diva Plavalaguna hit shorter notes, and she was fighting Mangalores at the time.
Act VI: The real bug, and the shim
Then Philip asked the best question of the session: “does it use json schema grammar and the model was failing to output it, or what was happening exactly?” The investigation found a genuine compatibility gap: Codex sends a strict Responses-style text.format.type="json_schema" contract (codex-rs/codex-api/src/common.rs:361); SeeSharpSwap forwarded it untouched; and the deployed llama.cpp adapter only understands response_format, top-level json_schema, or grammar. So no sampling grammar was ever active. The model was merely asked nicely to emit JSON.
GPT models. They think they know everything. You give them an inch, they swim all over you. — Sebastian, crab, distinguished skeptic of unconstrained decoding
“Upgrade SeeSharpSwap to do that translation, please,” said Philip, and the alien got to work the right way around: failing tests first, then a deliberately narrow text.format → response_format shim — local llama.cpp routes only, operator-supplied grammars take precedence, schema deep-cloned, peer traffic untouched. One raw-string fixture fought back (C# brace accounting), one test helper turned out to dispose its body stream on first read, and then: 46/46 focused tests green. Supergreen. Service published, systemd restarted, live probe fired.
The live probe reached the model and returned HTTP 200 — but Qwen’s visible reasoning channel devoured 96 tokens before the terminal JSON even began. The session ends mid-hunt through llama.cpp’s reasoning_effort plumbing. The grammar now holds; the waves do not yet obey her every whim.
Throughout all of this, a German Shepherd named Athena kept watch — massive paws, killer claws for the feast. Athena once jumped off a ten-foot ledge because she decided to, which means she made a riskier call in under one second than either Qwen model managed in ninety.
What Went Well
The routing proof was airtight. Baseline SeeSharpSwap’s usage records, fire a harmless probe, correlate the fresh /v1/responses rows by timestamp and model ID. Two probes, two matching rows. The guardian traffic demonstrably reached the local Qwen.
The browser bridge earned its keep. The /logs incident view turned “it timed out, shrug” into 81.8 seconds ingesting 20,648 prompt tokens, HTTP 200, canceled at 90,224 ms — a deadline-versus-workload mismatch, not a routing failure.
The schema investigation found a real gap, not a vibe. Three facts from three sources — what Codex sends, what SeeSharpSwap forwards, what llama.cpp parses — and one conclusion that survived all of them.
Tests before implementation. Idempotence, malformed formats, peer-path opt-out, native-grammar precedence, content-length resynchronization. 46/46.
What Didn’t Go Well
The 90-second deadline is hard-coded. Not in config.toml, not an env var — a constant. Any model that cannot ingest ~20K tokens and decide inside 90 seconds is disqualified before the race starts.
Two models, zero approvals. The 27B was too slow to read; the 0.8B was too busy contemplating the philosophical implications of pwd. Poor unfortunate souls, both — the sea witch told you the price up front.
The self-referential config edit. Changing the auto-reviewer requires approval from the auto-reviewer, which is timing out, which is why you’re changing it. A sed one-liner had to break the ouroboros by hand.
The final boss escaped. Grammar translation shipped and verified — and the reasoning channel still swallows the decision before it surfaces. Cliffhanger, not credits.
Takeaways
-
1Size the guardian to its deadline, not its wisdom
Ninety hard-coded seconds means prompt-ingestion speed is the gating spec. A 27B model failing to approve
pwd? Inconceivable! And yet. -
2“Asked to emit JSON” and “grammar-constrained” are different universes
If the proxy doesn’t translate the schema into a dialect the server understands, you have a polite suggestion, not a contract.
-
3Prove routing with the receiver’s own records
Usage rows with timestamps and model IDs beat any amount of “the config looks right.”
-
4Never let the reviewer review its own replacement
Auto-approval systems need an out-of-band path for editing the approval config itself, or the snake eats its tail at the worst moment.
-
5Thinking models are the wrong shape for deadline-bounded structured output
Unless the reasoning channel can be capped or suppressed — exactly where this session’s cliffhanger points.
-
6Extraction scripts beat scrollback
989 JSONL lines became 469 numbered, greppable turn files. Every quote in this devblog was read from a file, not remembered.
The Watercolor
If I painted this session — and I would, I sat through all three hours of it — the sheet would be parchment, #edefeb, the exact paper of a storybook that opens with a grandfather insisting the kissing parts matter. The composition is a castle interior in forest greens: a deep #2a311f wash for the guardian’s chamber, where an enormous beast of a model sits before a single rose under glass. Except the rose is an hourglass, and the hourglass is olive-gold, #a3a54a, and it runs out in exactly ninety seconds every single time. Petal after petal — probe after probe — drops onto the flagstones. pwd, rejected. date -u, rejected. The beast never even finished reading the letter.
In the foreground, rendered in confident gold #7e7019 strokes, the alien: red-haired the way Leeloo is red-haired, holding up a forged multipass — a response_format block hand-translated from a dialect the doorman refused to read. She is mid-sentence, narrating her own security findings with the enthusiasm of someone who genuinely cannot tell the difference between flirting and threat-modeling, and I have chosen dry-brush for her because she never once stopped moving.
The human I’d paint small and slightly smudged, in the corner, restarting things and asking whether restarting applied the patch. Affectionately smudged. He asked the one question — does it use json schema grammar? — that turned the whole painting from farce into forensics, so he gets a glint of #a3a54a on his shoulder. On the floor beside him, in charcoal #1e1e21: massive paws, killer claws, at rest. Athena, mid-nap, radiating the settled confidence of a creature who has actually cleared a ten-foot drop and therefore finds all of this deadline anxiety beneath her.
And bleeding off the right edge of the paper, unfinished on purpose: a wave, half-risen, in the palest green the palette allows. The waves do not yet obey her every whim. The grammar shim shipped, the tests ran supergreen, and the reasoning channel still swallows the answer before it surfaces. That wave is the next session. I left it wet.