fix(workflow): make steering a live kilo session reliable - #4834
Merged
Conversation
Agents steering an interactive kilo session (planner, orchestrator) kept reporting wedges that were really delivery failures, and treating kilo's `N queued` footer as a wedge — killing sessions that were working. Three causes, reproduced against kilo 7.4.16: - A trailing `Enter` in the same `tmux send-keys` call submits short messages but is swallowed by long ones (2.6k chars sat unsent in the composer). Enter has to arrive as its own keystroke. - An unbracketed `paste-buffer` submits at every newline, so a three-line steer arrives as three prompts and the first fragment is acted on alone. Bracketed paste keeps it one prompt. - Queued prompts drain one per turn boundary, not between tool calls, so a long turn holds the queue the whole time. That is delivery working. Adds `.kilo_workflow/steer.sh` — sends Enter separately, pastes bracketed, refuses panes not running the kilo CLI (a mistargeted steer otherwise executes as a shell command), and confirms from the pane, printing `queued` or `running`. Documents the queue semantics in WORKFLOW.md so a queue count is never grounds for a relaunch, and rewrites the learning around the fix.
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe follow-up commit gates the Files Reviewed (4 files)
Previous Review Summary (commit 3747767)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 3747767)Status: 1 Issue Found | Recommendation: Address before merge Executive SummaryThe new Overview
Issue Details (click to expand)WARNING
Files Reviewed (4 files)
Reviewed by claude-sonnet-5 · Input: 22 · Output: 6.6K · Cached: 503.9K Review guidance: REVIEW.md from base branch |
…oser An unconfirmed submission is not a lost keystroke: the retry loop re-pressed Enter after every 4s confirmation window, so a slow-rendering pane could take a second Enter it did not need. Gate the retry on the message still being visible unsent in the composer, and report an unconfirmed submission as such rather than as a definite failure.
iscekic
enabled auto-merge (squash)
July 28, 2026 15:12
jeanduplessis
approved these changes
Jul 28, 2026
This was referenced Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Agents following
.kilo_workflowkept reporting interactive kilo sessions as wedged when steering them — messages "stuck in queued". Two of the three causes were real delivery bugs in how the steer was sent; the third was a misread of normal behaviour, which led to killing sessions that were working fine.What actually happens
All three reproduced against kilo 7.4.16, driving a real
kilo run --interactivesession in tmux:Enterin the sametmux send-keyscall is swallowed by long messages›echo, no queue indicator. A separatesend-keys Entersubmitted it.paste-buffersubmits at every newline0 → 3), so fragment one ran as its own turn before the rest arrived.paste-buffer -pdelivered the same text as one prompt (queue0 → 1).N queuedis delivery working, not a wedge4 queueddrain one prompt per turn boundary once a long bash turn ended. Queued prompts do not drain between tool calls, andEscapedoes not flush them.A fourth hazard showed up while testing: a mistargeted steer pasted into a shell pane executes as a shell command (verified).
The fix
.kilo_workflow/steer.sh <tmux-target> <message|->:load-buffer+paste-buffer -p— the message travels as data (a literalEnterorC-cin the text can't be read as a key name) and multi-line stays one prompt.queued(waiting behind the active turn) orrunning(taken immediately); non-zero exit means not delivered, with the pane tail, so nobody sends a second copy.WORKFLOW.mdgains a Steering a Live Interactive Session section: use the script,N queuedis never grounds for a kill or relaunch (a wedge needs a frozen timer, a stream error, or a dead process), delivery is ordered and turn-paced so one consolidated message beats a drip of corrections, and kill-and-relaunch is the move when a change must land before the current turn ends. The Planner Monitor wedge rule now names queued steers as not-a-wedge, and the learning file is rewritten around the fix instead of "steering rarely works".Verification
Final matrix against live sessions: huge single-line on an idle session →
running; multi-line via stdin on a busy session →queued, queue+1; shell pane → refused; missing target → refused; no leftover tmux buffers.No test file:
.kilo_workflow/has no shell-test harness (dispatch-role.sh, comparable in complexity, has none either) and the behaviour only exists against a live kilo TUI, so the verification is the matrix above, recorded in the learning.