Blocker Message Flows
Transcript Blocker Actions
A blocker prompt became a chat message with keyboard and mouse controls.
0 milestones 3 tasks 8 agents
2 plan 3 execute 3 review
99k peak context
98k median execute
37m 4s total 11m 20s per task
2m 53s plan 20m 34s execute 9m 10s review
43 edits 262 commands
codex harness
This run moved blocker prompts out of modal-style chat chrome and into the assistant transcript. The result is a blocked run that appears where the operator is already reading, keeps the blocker body in the same markdown path as assistant replies, and answers through inline controls rather than copied prompt text in the composer.
The work was divided into text semantics first, then keyboard ownership, then mouse routing. That shape let each sprint depend on a visible contract from the previous one: a rendered blocker message, a guarded focus cursor, and finally frame-local click targets that must still match the live prompt before they do anything.
How this walkthrough is structured
Feature
What did the run build and ship?
The current TUI still routes pending blockers into chat messages with markdown bodies, guarded action focus, composer handoff, and stale-safe button footprints.
Build
How did Gantry structure the work?
The cut built the blocker as transcript content first, then made the inline row keyboard-owned and mouse-clickable without recorded recovery or replanning.
Milestone 1
Inline Blocker Message Actions
The current tree still treats a blocker as assistant-pane transcript state rather than as a frontmost modal. The message stores the original prompt identity with its body, choices, and buttons, then the renderer turns it into a run-blocked entry with markdown content and inline controls. The same state also keeps pending action focus and per-frame button coordinates for the later input paths.
This milestone carried the whole user-facing blocker flow as one slab: transcript rendering, focus, keyboard action, mouse action, composer behavior, and label semantics. Its brief states the end state broadly enough to anchor the run, while the sprint files below split the work into surfaces a fresh worker could hold. The recorded facts show no recovery or replan at this boundary, so the full slab stayed coherent as its pieces accumulated.
Conversational Blocker Message
Blockers are now stored as routed chat messages with a run-blocked speaker line, a title, a markdown-rendered body, and button data. The renderer still omits the old prompt identifier and action heading, and resolved blocker history drops live controls while retaining the fact that choices existed. The visible Gantry handoff label is still phrased as asking the Gantry Assistant, while the composer remains empty on blocker arrival until that handoff path is invoked.
This sprint established what a blocker should read like before any input behavior depended on it. The brief kept the worker on visual and text semantics: speaker identity, markdown-preserving body rendering, inline buttons, no internal prompt banner, no redundant action label, no automatic composer seed, and a clearer Gantry Agent label. Its gate and review stayed green, which fits a foundation sprint whose main risk was preserving the old prompt contract while changing where the prompt appeared.
Keyboard Inline Blocker Actions
The TUI now keeps an inline blocker focus cursor with an owner that distinguishes the action row from the composer. Arrival restores the assistant pane and gives ordinary keys to the row; arrow keys wrap through actions, activation uses the focused action, shortcuts dispatch only while the row owns keys, and Esc still follows the stop path. Moving into the composer preserves the focused action as a return target, and blurring the composer gives blocker keys back to the row while keeping the draft intact.
This sprint made the inline row a real keyboard target after the first sprint made it visible. Its contract bound focus to the current prompt identity, action index, and owner, which let the worker add movement, activation, shortcuts, and Tab cycling without reopening the transcript-rendering work. The run record shows the sprint passed through gate and review without repair, so the keyboard boundary held as a state-machine change rather than a broader chat rewrite.
Mouse Inline Blocker Actions
Rendered inline blocker buttons now publish visible footprints, and mouse routing checks those footprints before composer focus, selection, or ordinary transcript handling can claim the same press. A click focuses the exact button and activates it through the same guarded prompt-choice path used by keyboard input. Footprints from resolved, replaced, hidden, or overlaid blockers are inert because the router revalidates the stored prompt and action against current pending state.
This sprint consumed the keyboard focus contract and added click routing around it. The brief was precise about safety: every drawn button had to publish a frame-local footprint carrying prompt identity and action token, and mouse handling had to reject stale or overlaid targets. The facts show the gate ran again after review, making this the one place where the boundary was rechecked under extra scrutiny rather than merely accepted at first pass.