feat(boxen): C M6 #805 -- input_decoder cutover (replaces tb2 input layer)#821
Open
jsavin wants to merge 2 commits into
Open
feat(boxen): C M6 #805 -- input_decoder cutover (replaces tb2 input layer)#821jsavin wants to merge 2 commits into
jsavin wants to merge 2 commits into
Conversation
Replace termbox2's input layer with the custom input_decoder built in M1-M5. The decoder now owns the TTY fd read loop end-to-end: escape-sequence parsing, modifier param decoding, mouse, bracketed paste, Kitty protocol, double-click synthesis. backend_tb2.c changes: - include input_decoder.h; add static input_decoder_t *g_decoder - tb2_init creates the decoder after tb_init; obtains TTY fd via tb_get_fds with /dev/tty fallback (risk R1) - tb2_shutdown destroys the decoder BEFORE tb_shutdown so any decoder writes land while raw mode is still active - tb2_poll_event forwards directly to input_decoder_poll; no translation - Removed translate_key, translate_mod, translate_mouse, and the g_tb2_last_press double-click state struct -- all subsumed by the decoder - Kept translate_attr and translate_color (rendering-side; unaffected) - DOES NOT call tb_set_input_mode(TB_INPUT_MOUSE). Mouse starts disabled per plan section 5.1; M7 /mouse toggle wires the enable input_decoder.c changes: - Add the real read(2) + select(2) path in input_decoder_poll. When tty_fd >= 0, block up to timeout_ms on select(2), then drain the pipe with non-blocking reads (collapses multi-byte escape sequences that arrive as one OS burst into one parse cycle). Test seam (tty_fd == -1) preserved -- inject_bytes path unchanged - Split poll body into dec_drain_buffer + orchestrator so the same parser loop runs both before and after the TTY fill - EINTR/EAGAIN handled correctly; EOF on the TTY surfaces as BOXEN_ERR_IO so the REPL can shut down rather than spin Test results at HEAD: - PTY-replay: 138/138 passed (no regression from M5 baseline) - Unit suite: 964/964 passed - Integration: 2186/2207 (21 pre-existing failures match develop) Closes #814 Closes #805
Gate review (PR #821 P1, concurrency reviewer): the M6 cutover comments in backend_tb2.c and input_decoder.c mis-stated the GIL contract, saying the decoder runs with the GIL held during select(2). Actual behavior (boxen_repl.c:2147-2152, mirroring debugger_tui_main per ADR-014): the REPL drops the GIL via pthread_mutex_unlock BEFORE calling boxen_poll_event, so the decoder's blocking select(2) runs with the GIL NOT held. The single-owner invariant from input_decoder.h still holds (the REPL thread is the only caller). Comment-only fix. No behavioral change. PTY-replay 138/138 still green; unit suite still 964/964 green.
Owner
Author
/gate Report (post-fix)Original gate verdict: PASS WITH NOTES (1 P1, 3 P2). The P1 Reviewer breakdown (gate ran in this sub-agent context without Agent Tests
Reviewers
P0 -- Blocking(none) P1 -- Important (addressed in commit 48112cb)
P2 -- Deferred
Verdict (post-fix): PASSAll P0/P1 resolved. P2s are tracked above for triage. Manual smoke Stats
|
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.
Summary
Phase C input decoder M6 -- THE CUTOVER. Replaces termbox2's input
layer in
backend_tb2.cwith the custominput_decoderbuilt inM1-M5. This is the milestone that actually fixes issue #805 in
production -- all prior milestones built and tested the decoder in
isolation against the inject-bytes test seam.
What changes
frontier-cli/boxen/backend_tb2.c(cutover):#include "input_decoder.h"andstatic input_decoder_t *g_decoder = NULL;tb2_initcreates the decoder aftertb_init(), obtaining the TTY fd viatb_get_fds()with a/dev/ttyfallback per risk R1tb2_shutdowndestroys the decoder BEFOREtb_shutdown()so any decoder writes (mouse-disable on destroy in a future milestone) land while raw mode is still activetb2_poll_eventforwards directly toinput_decoder_poll-- no translation layer; the decoder emitsboxen_event_tdirectlytranslate_key,translate_mod,translate_mouse, and theg_tb2_last_pressdouble-click state struct. All subsumed by the decoder.translate_attrandtranslate_color(rendering-side; untouched)tb_set_input_mode(TB_INPUT_MOUSE). Mouse starts disabled per plan section 5.1; M7/mousetoggle will wire the on-demand enable.frontier-cli/boxen/input_decoder.c(real read loop):read(2)+select(2)path ininput_decoder_poll. Whentty_fd >= 0, block up totimeout_msonselect(2), then drain the pipe with non-blocking reads (collapses multi-byte escape sequences that arrive as one OS burst into one parse cycle, per plan section 4.4)dec_drain_buffer+ orchestrator so the same parser loop runs both before and after the TTY fillEINTR/EAGAINhandled correctly; EOF on the TTY surfaces asBOXEN_ERR_IOso the REPL can shut down rather than spintty_fd == -1) preserved --inject_bytespath unchanged; all 138 M1-M5 PTY-replay tests pass without modificationMerge gate (per plan section 7 + 9 + risk R4)
PTY-replay test run at HEAD:
Test results at HEAD
tests/input_decoder_tests)./tools/run_headless_tests.sh)cd tests && make test-integration)The 21 integration failures match the develop baseline (pre-existing in
html.*,tcp.*,startup-- unrelated to input handling).Manual smoke status
The /auto runner cannot drive Terminal.app from inside the agent context. The plan section 6.4 manual smoke checklist remains for orchestrator (human-supervised) verification before merge:
b/f)The PR #808 disaster occurred because tmux-only testing missed real Terminal.app behavior. This checklist MUST be exercised in Terminal.app (not tmux) before merge.
Risk disposition
tb_get_fdsavailability): vendored termbox2 exports it. Fallback to/dev/ttyis wired but should not fire on the supported platforms./mouse onlands.References
planning/phase_c/INPUT_DECODER_PLAN.mdsections 2.3, 5, 7 (M6 spec), 8.R1/R3/R4, 9Closes #814
Closes #805