Every so often you watch an AI coding session and think: that’s it, that’s the workflow we built all of this for.
This afternoon we had one of those runs, and because zcoderd logs everything, we can replay it move by move. The model was Tencent’s Hy3 (via Novita), driven through Zaguán Blade with zcoderd orchestrating. The task: a dropdown menu on our changelog page was getting clipped by its parent card. Twelve minutes later there was a three-part CSS patch, a verified root-cause explanation, and a total bill of about a quarter of a credit.
No flailing. No grepping the world. No “let me read this 2,300-line file five times.” Just the right tool, at the right moment, every single turn — 17 tool calls from first read to final answer.
Let’s walk through it.
The setup
The bug report, roughly: the release download menu on zblade.dev’s changelog page gets cut off at the card’s edge instead of floating above the content below it. A classic front-end mystery — the kind where most people (and most models) immediately start throwing z-index: 9999 at everything.
Blade had ReleaseDownload.astro open in the editor. The session warmed up, zcoderd sniffed the request, classified it as a debugging task, and composed the prompt accordingly. Then the run began.
Phase one: understand before you touch
Here’s the actual tool trace from the zcoderd logs, in order:
read_file→ReleaseDownload.astro— read the component with the misbehaving menusymbol_search→ “ReleaseDownload usage” in*.astro— who actually uses this component?symbol_search→ “release-download overflow hidden card” — hunt for the clipping culpritread_file→changelog.astro— the one consumer the index pointed atsymbol_search→ “version-card overflow hidden global css” in*.cssget_editor_state— sync with what the developer is looking atsymbol_search→ “container layout max-width overflow” inglobal.cssread_file_range→global.css, lines 80–100 — twenty lines. Not the whole file. Twenty lines.
That last call is the Symbols Index doing exactly what it’s for. The index — Blade’s tree-sitter-powered map of every symbol in the workspace — told the model where the container layout rules lived, so instead of ingesting the whole stylesheet it asked for a 20-line window and got its answer.
The same pattern shows up in step 2. changelog.astro is a big file — when the model read it in full, the result came in at 126 KB and 2,350 lines. But it only had to do that once, and it only knew which file to read because symbol_search resolved “who uses ReleaseDownload” instantly instead of the model guessing at paths or asking for a directory listing.
By the end of phase one, the model had the whole causal chain: the menu is position: absolute; z-index: 50 (fine), but it lives inside .version-card, which declares overflow: hidden — and overflow: hidden clips descendant geometry no matter how high the z-index goes. It had also worked out why the overflow: hidden was there in the first place: to make the ::before accent stripes on .version-latest and .version-development follow the card’s rounded corners.
That second part matters. Finding the culprit line is easy. Understanding what breaks if you delete it is the difference between a fix and a regression.
The gate: zcoderd as the adult in the room
Here’s where the orchestration gets interesting. Look at what tools the model had at this point in the session, straight from the logs:
tool_count=16 tool_names=[... symbol_search symbol_resolve symbol_outline
symbol_references read_file read_file_range ...] has_apply_patch=false
No edit tools. zcoderd runs an understanding gate: at the start of a debugging session the model gets read-and-search tools only, and zcoderd records evidence as the model works — every read_file logged as code_read, every symbol_search as symbol_lookup. Editing capability isn’t granted until the model has demonstrably done its homework.
At 17:36:51 the model, confident in its diagnosis, tried to call apply_patch anyway. The log line is beautiful:
level=INFO msg="blocked hidden tool call" tool_name=apply_patch
zcoderd refused it — the tool wasn’t in the offered set, so the call never reached the editor. And here’s the part that made this run top-of-class: the model didn’t sulk, retry, or hallucinate a different way to write the file. It did the correct thing — it called tool_search with “edit an existing file apply patch”. zcoderd checked the accumulated evidence (three code reads, multiple symbol lookups — homework done), and the very next request went out with:
tool_count=18 ... apply_patch ... edit_impact find_files has_apply_patch=true
The edit tools unlocked because they were earned. Four seconds of protocol, and the session moved from investigation to surgery.
Phase two: the patch
One apply_patch call, three coordinated edits to changelog.astro:
- Remove
overflow: hiddenfrom.version-card— the actual fix. The menu can now escape the card. - Replace the
.version-latest::beforestripe withborder-left: 3px solid var(--color-accent). - Replace the
.version-development::beforestripe withborder-left: 3px solid var(--color-warn).
Edits 2 and 3 are the ones a lazier run would have missed. The ::before pseudo-elements were the whole reason the overflow: hidden existed — delete the overflow and the accent stripes would poke out past the rounded corners. Swapping them to border-left preserves the visual identically (borders follow border-radius for free) while removing the need for clipping entirely. The component itself needed zero changes.
That’s not pattern-matching a Stack Overflow answer. That’s understanding the dependency between two CSS decisions and unwinding both sides of it in one atomic patch.
Phase three: verify like you mean it
After the patch landed, the model didn’t declare victory. It issued six more read_file_range calls — targeted windows into changelog.astro’s style section (lines 1775–1812, 1810–1895, 1905–1982, 1980–2075, 2135–2205, 1006–1055), walking the stylesheet to confirm the edits applied cleanly, that no orphaned ::before blocks remained, and that no other ancestor in the chain (.container, .version-header, .version-actions) carried its own overflow: hidden that would re-clip the menu.
Range reads again — six checks for the price of a few hundred lines instead of six full-file reads. Then the final answer, which is worth quoting because it’s exactly the report you’d want from a senior engineer:
The clipping was not a z-index issue. The menu is already
position: absolute; z-index: 50, so it paints on top correctly. The problem is that it’s a descendant of.version-card, which hadoverflow: hidden— that clips the geometry of any descendant regardless of z-index. […] Theoverflow: hiddenwas only there to round the accent bars. I moved those::beforebars to aborder-left(which follows the card’sborder-radius), preserving the visual with no clipping side effects.
It even flagged its own limitation — “I did not run a browser build — if you want, I can start the dev server to confirm visually.” Honest about what was verified and what wasn’t.
What zcoderd was doing the whole time
The model gets the spotlight, but half of why this run went so well is what the orchestrator did around it:
- Runtime mode inference. zcoderd read the request, classified it as debugging-oriented, and composed a debug-mode prompt — no user configuration needed.
- The understanding gate. Edit tools stayed locked until evidence of real code reading and symbol work accumulated. The one premature
apply_patchwas blocked cold, and the recovery path (tool_search) was right there. - Tool-result artifacts. When that 126 KB full-file read came back — 2,350 lines, over the 2,000-line context threshold — zcoderd stored the full result as a retrievable artifact instead of letting it bloat every subsequent request.
- Context compression and cache alignment. Fourteen upstream requests, growing from 12 K to 84 K prompt tokens. By the final request, 83,984 of 84,391 input tokens were provider-cache hits — 99.5% cached, only 407 fresh tokens billed at full weight. Time-to-first-token on warm requests hovered around 3.5 seconds even with an 84 K-token context.
- Accounting. Every request metered through Zaguán CoreX with per-request debits. The whole session — a million cumulative prompt tokens across the conversation’s turns — cost 0.28 credits.
The takeaway
There’s a lot of talk about which model is “best at coding.” This session is a reminder that the harness matters as much as the model. Hy3 did excellent work here — genuinely sharp root-cause analysis and a fix with taste. But it did that work inside a system that:
- gave it a Symbols Index so “where is this used?” and “where does this style live?” are one cheap call instead of an expedition,
- offered range reads so knowing a location translates directly into reading 20 lines instead of 2,000,
- gated editing behind demonstrated understanding, so the patch came after the diagnosis rather than instead of it, and
- kept the context lean and the cache warm so turn fifteen was as snappy as turn one.
Search the index → read the range → understand the dependency → patch once → verify with more range reads. Seventeen tool calls, twelve minutes, one clipped dropdown menu set free.
That’s the workflow. When it clicks, it’s a genuine pleasure to watch — even in log files.
