Skip to content

fix(omp): drop omp's inline suggestion from the draft the send guard verifies - #128

Merged
AltanS merged 1 commit into
AltanS:mainfrom
enieuwy:fix/omp-inline-suggestion
Aug 24, 2026
Merged

fix(omp): drop omp's inline suggestion from the draft the send guard verifies#128
AltanS merged 1 commit into
AltanS:mainfrom
enieuwy:fix/omp-inline-suggestion

Conversation

@enieuwy

@enieuwy enieuwy commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

What breaks today

On an omp pane, a reply can stall with "Message didn't reach the input box" while the message really
is sitting in the box. Every retry types it again and stalls again.

omp paints an inline completion suggestion after the operator's text, inside the composer, in its own
foreground colour. It is not in the input buffer, and no Backspace deletes it. It is on the row the
send guard reads back. Live capture (omp v17.2.12), after typing leftover draft here:

\x1b[38;2;190;149;255m╰─ \x1b[0mleftover draft here\x1b[0m\x1b[38;2;111;115;119m's\x1b[0m … ─╯
                                                        ^^ omp's ghost, in its muted colour

The chain:

  1. harness/omp/chrome.tsextractInputDraft returns leftover draft here's.
  2. reply-action.tsdraftCarriesSend requires the visible draft to be contained in what was
    typed. 's is not, so the claim fails.
  3. The guard withholds the submit key and reports the stall. The bridge did nothing wrong. The
    adapter answered a screen question wrongly.

This fires on ordinary prose, on anything omp offers a completion for. On this host it hit most
sends.

The fix

composerGhost (harness/omp/markers.ts) claims the trailing run of coloured segments that follows
unstyled text on the composer's bottom border, the row the caret is on. extractInputDraft subtracts
that run before it returns the draft.

The rule is relative, like the rest of this adapter:

  • No colour literal and no threshold. The operator's own text is what the terminal echoed, so it is
    unstyled. omp's suggestion is the styled tail after it. Themes and truecolor palettes stay free to
    change.
  • It claims nothing on a row that has no unstyled text of its own. A fully-coloured row is ambiguous,
    because it could be a themed draft.
  • It claims nothing on a row that is not a composer bottom border. A wrongly-claimed ghost would
    shorten the draft the guard checks, which is the unsafe direction.

This also fixes the stranded-draft chip and "Take over". Both used to copy the suggestion into the
phone composer as if the operator had typed it.

Evidence

  • Reproduced on a live sandbox omp pane (2026-08-23) driving pane.send_text and pane.read
    directly. Before the patch, draftCarriesSend → false on two separate ghost captures. After it,
    true.
  • New fixture omp--draft-ghost-suggestion.txt, derived from omp--draft-single.txt. The SGR run and
    six ghost cells were spliced in and six padding cells taken out. The row still measures 189 display
    cells and keeps its 28 rows, its LF endings and every other byte. It is registered in the corpus
    lists and the fixture README, and the census sentences that count captures were updated with it.
  • New tests: five composerGhost cases in omp/markers.test.ts, the fixture's draft in
    omp/chrome.test.ts, and an end-to-end sendGuardedReply case in reply-action.test.ts on an omp
    pane whose composer shows a suggestion. Both new behavioural assertions fail without the patch. I
    checked that by reverting the strip.
  • End-to-end on the deployed build: the phrase that used to stall now shows "Sent ✓" in the web UI,
    and omp starts working on it.
  • web: harness and reply suites pass, tsc clean. Root bun run test: 688 pass.

Notes for the maintainer

No version bump and no CHANGELOG entry, per CLAUDE.md's fork rule. A line for the release, if you
want one:

  • Every reply to an omp pane could stall with "Message didn't reach the input box" — omp paints an
    inline completion suggestion after your text, and the send guard read it back as part of the draft

…verifies

omp paints an inline completion after the operator's text, inside the
composer, in its own foreground colour. It is not in the input buffer,
but extractInputDraft returned it, and draftCarriesSend requires the
visible draft to be CONTAINED in what was typed — so every send omp
suggested for stalled with "Message didn't reach the input box" while
the message really was sitting in the box, and each retry re-suggested
and re-stalled.

composerGhost (omp/markers.ts) claims the trailing run of COLOURED
segments that follows unstyled text on the bottom border — the row the
caret is on. The rule is relative: no colour literal, nothing measured,
and nothing claimed on a row with no unstyled text of its own, because a
wrongly-claimed ghost would shorten the draft the guard checks.

Evidence: live sandbox omp pane, 2026-08-23. The fixture
omp--draft-ghost-suggestion.txt is derived from omp--draft-single.txt,
width-preserving.

(cherry picked from commit a6dcdcf8fbe7a5d6e82c6e98760c58ae4d3c0d2c)
AltanS added a commit that referenced this pull request Aug 24, 2026
fix(omp): drop omp's inline suggestion from the draft the send guard verifies
@AltanS
AltanS merged commit 86527a7 into AltanS:main Aug 24, 2026
1 check passed
@AltanS

AltanS commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Merged — thank you, this is a model diagnosis. The relative no-colour-literal rule and both fail-closed refusals are exactly right, and the containment failure chain in the description made review trivial. I rebased onto today's codex/grok adapter merges on our side (one comment-paragraph conflict) — your fixture now also runs foreign against those two corpora automatically. Gates after the rebase: root 687, web 3429, typechecks clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants