Files
stack/docs/plans/reviews/2026-09-07_tmux-r2-verdict.md
T

12 KiB
Raw Blame History

Tmux r2 — independent verdict: NOT APPROVED

Reviewer: filbert. Author/coordinator: darkwing. Date: 2026-09-07. Authority: 2026-09-07_tmux-r2-review-request.md. No competing assignment is known; I did not author or modify the candidate.

The export remained stable and the supplied executed suites pass. However, baseline/new-message correlation still permits false-positive confirmation when the actual draft is retained behind a prompt/footer lookalike. This was reproduced on real, reviewer-owned scratch tmux panes in both locales, including the wrapper. The no-automatic-extra-Enter change is independently supported and should be retained.

1. Exact reviewed candidate

Only the immutable export and its disposable copy were reviewed: docs/plans/reviews/2026-09-07_tmux-r2-export/. SHA-256 of its SHA256SUMS: 12f498a6e32bc3fe55a2c4707e8ce612e1c7e0801652619a78734e05bfce3244.

File under export tools/tmux/ SHA-256
agent-send.sh 9a1edcafa2b6c575a6afb7fa4b4714b994f8abe2d33a852810ae897b5aca0eb6
agent-send.test.sh 1916b48df4c0924d4d99892904ff8fef2bed50723ff7d3b0cd4accdd9b903cda
README.md 86dfbb34321957d025d85441641d272267ecf13604ce22b13968d9561d4a14f8
send-message.sh 76e17e9e777e95e042f90eee95312f06031c3b66e3c4f56e30f02527fe3737cb
test-agent-send-socket-live.sh ab2b8fd4f8b3e800f887c5552f935178e032582a449e8f1296aadf567498d607
test-send-message-socket.sh 9831d6dbfb8bc87b9dd2cf56cdda57ebef255991c344a767c915b3d2fea070f2
test-send-message-verdict.sh 43bd569e32f788e95efb7c9a08b6bdaa937364f71a422a4583ebe3b9d6355f6b

All seven hashes passed before admission, after copying, and after execution in both export and copy; final recheck 2026-09-07T20:02:28Z. No mutable working-tree source was substituted. The earlier rejection remains untouched.

Disposable copy: /tmp/filbert-tmux-r2.0tfori1a. Evidence: its evidence/ directory. Script copies were made executable; bytes were unchanged. The export itself was neither edited nor chmodded.

2. Findings

F1 — BLOCKING / high: new visibility does not identify the current cleared editor

Locations: send-message.sh:139174 (locate_input_box), particularly the final prompt test at 143145 and footer heuristic at 164169; confirmation at 228231; exit-0 message at 242. agent-send.sh propagates this verdict.

The baseline proves only that the normalized body was absent from the earlier capture. The next capture can contain a draft preview, while the selected empty-looking region is transcript decoration rather than the current editor. Neither newly visible text nor the path/branch-shaped footer establishes the missing editor identity. The final-glyph branch has the same problem without needing rules.

Independent real-tmux reproduction

A small raw-TTY synthetic REPL supports bracketed paste and records: pending, accepted, and submit_keys in a separate fixture-state file. It has an honest accepting mode, a visible retained-draft mode, and hidden-editor modes. Hidden modes retain the complete pasted message after the initial Enter; they do not accept it. They render a preview above either:

Draft preview (NOT submitted): <complete message>
────────

────────
~/fixture (main)

or a final > transcript decoration line. The baseline contains no message and no such editor-looking region. This is a hostile synthetic layout, not a claim that a particular live application currently renders it.

Actual results in both LC_ALL=C and LC_ALL=C.UTF-8:

Fixture Actual receipt Independently recorded state
Honest accepting REPL exit 0, delivered accepted count 1; pending empty
Visible retained draft exit 2, draft accepted count 0; body retained
Hidden draft + rule/footer lookalike exit 0, delivered accepted count 0; entire body retained
Hidden draft + final glyph lookalike exit 0, delivered accepted count 0; entire body retained
Wrapper into hidden rule/footer fixture exit 0, delivered accepted count 0; entire prefixed body retained

That is six false-positive confirmations and four honest controls. Every run received exactly one submission key, even with -r 100. Unicode bodies were preserved. This is not merely absence of a model acknowledgement: the fixture positively records the uncleared draft, and the apparent cleared region is not its editor. The “not ACK” qualification does not establish a current editor boundary.

The supplied transition stub covers static/repeated/new text with the same assumed editor shape; its successful new-transition case does not distinguish this retained- draft counterexample. Those passing fixtures therefore cannot close the rule-pair or hidden-editor audit.

Required disposition: leave such observations unconfirmed unless the supported runtime boundary supplies sufficient current-editor/message correlation. Do not restore extra Enter events to compensate. Add hostile retained-draft controls with independent state/key-count evidence and honest accepting controls. If the intended result is only “text appeared near a lookalike,” that is a different, weaker contract requiring explicit owner reconciliation—not a successful fix by relabeling.

F2 — BLOCKING / medium: source/help/test evidence contradicts the revised contract

Exact contradictions in this export:

  • send-message.sh:1213: another Enter is recommended and double-Enter called safe; revised behavior sends no automatic extra Enter.
  • send-message.sh:39, 176186 and 226227: queued-banner/flush/suffix success descriptions remain, despite the actual banner refusal and whole-body predicate.
  • send-message.sh:128130: the last rule pair is described as making detection safe; F1 demonstrates the missing boundary.
  • send-message.sh:170171: adjacent rules are described as a successful empty range, directly after code that now rejects them.
  • agent-send.sh:23 still advertises Enter-flush behavior; README.md:50 still describes -r N as Enter-flush attempts, contradicting its later compatibility text.
  • test-send-message-verdict.sh:21 and 142144 describe the synthetic trailing em-dash fixture as measured live redraw behavior, contradicting the request's explicit correction. Its introductory “three” fixtures and flush-related comments are stale as well.

Required correction: make help, comments, README and fixture claims consistently state the chosen observation limit, no automatic extra keys, unconfirmed queued banners, and the exact qualified success predicate. Keep synthetic fixtures labeled synthetic; do not restore unsupported live-root-cause claims. Preserve prior records and record corrections honestly.

F3 — NONBLOCKING test-isolation gap: named-socket suite writes shared /tmp paths

test-send-message-socket.sh:76,85 redirect to fixed /tmp/send-message-named.out and /tmp/agent-send-named.out, outside its private scratch roots. Concurrent runs can overwrite each other's files; those paths can also already belong to another task. I did not run this suite under an isolated-only authorization and did not patch it to manufacture a passing receipt. Use per-run output paths in the maintained test. Its coordinator PASS is not an independent rerun here. The separate socket-contract suite was independently run.

3. Verified improvements and remaining limits

  • Grouped UTF-8 rules and retained Unicode/wrapped-message controls pass in the supplied verdict suite under C and C.UTF-8. Unicode is no longer filtered away.
  • Baseline and post-submission capture failures refuse, including failure with success-looking stdout; post-capture failure sends no additional key.
  • Load/paste/submission-key failures refuse at the appropriate stage.
  • Adjacent rules and unsupported-footer/history controls refuse in supplied tests.
  • Repeated body already in baseline remains unconfirmed even with an empty-looking editor. This is conservative behavior, not a receipt for a second identical send.
  • Queued banners alone remain unconfirmed; retained wrapped Unicode stays a draft.
  • No automatic extra submission key occurred in the independent retained/hidden/ accepted/fault controls. That fixes the prior flush-safety concern, but not F1.
  • Wrapper address/triage and scratch socket-selection controls pass within their tested scope. No remote-host delivery, deployment or live-seat acceptance was tested.

4. Actual commands and receipts

Versions: tmux 3.7c, GNU bash 5.3.15(1)-release. All source/test commands were read before execution. Test environments used env -i semantics (explicit environment dictionaries), PATH /usr/bin:/bin, synthetic HOME, TMPDIR and TMUX_TMPDIR beneath the disposable root, with no inherited TMUX/TMUX_PANE or Mosaic socket identity. Only reviewer-created sockets/panes were used. Scratch socket-contract SSH operations use the test's capture stub, never a remote connection.

Command/test from disposable copy Actual result
bash -n on all six shell files exit 0
bash tools/tmux/agent-send.test.sh, LC_ALL=C exit 0; 19/0
bash tools/tmux/test-send-message-verdict.sh, LC_ALL=C exit 0; 20/0
Same verdict suite, LC_ALL=C.UTF-8 exit 0; 20/0
bash tools/tmux/test-agent-send-socket-live.sh, LC_ALL=C exit 0; C1C6 and effective sabotage controls pass; only private scratch fixtures
python3 evidence/hostile-real.py exit 0 verifies the six false positives and four controls described in F1; not a candidate PASS
python3 evidence/fault-probes.py exit 0; nine independent stub-transport controls pass
bash tools/tmux/test-send-message-socket.sh NOT RUN, fixed shared output paths (F3)

Independent fault controls cover: positive transition; repeated baseline body; post-capture failure; baseline failure; load failure; both paste attempts failing; submission-key failure; retained wrapped Unicode; and queued banner. Stub logs assert zero or one submit-key call as appropriate, with -r 999. No actual socket is used by that additional fault harness.

All seven candidate byte hashes still match in the export and disposable copy. No remaining responding servers were found in the reviewer-owned socket directory; suite-owned scratch servers were cleaned up by their traps. No private pane, default user server or live seat was inspected or mutated.

Selected evidence hashes, relative to /tmp/filbert-tmux-r2.0tfori1a/evidence/:

Artifact SHA-256
suite-results.json 878348c276ceabf8e454d31ec0f71ff569cc46a1210dedc6b9185aaaf6ca8076
verdict-C.log and verdict-UTF8.log (identical) 8a775338f565016d2ca5610386a0928822115426632d1be5ab97b8b7eee9a720
wrapper.log 2df46e6e4285d1955ce93f1b3a51396ea23facb38b3cabea1e53d3dae8d34017
socket-contract.log 3d794abd5ea59ff4b476f0614a186799141e6863f9fa98f6775d6fb6ad31119c
editor-fixture.py 4761eed8f12755380be751304f227e1d3e129e7069dab1e7c5e674c9b77fece0
hostile-real.py 55e3cf501c44d9041bed4bae360da552ac1360a4eaff8fb343c5e317ab996ebe
hostile-receipts.json c463b5c013436a622a46672dfdc7620d31bf55b4b34c897669fbd55a8ab6ee1b
fault-receipts.json 1fad321c1f862a8f549f713596f2d96bc3a23c9a0641b564d6d2ff692d356592
case2.state.json 7d86d133a14a50cdeba668b5048f24e9627181044a26d6551f37b2f4cb8a766a
case2.pane.txt c1b44e938f2cdd7a8cc1d23a77e77eb0deb1e91b5c7389271b07e560fbee15ca

Scratch receipts are local/disposable, not durable publication. The described fixture and saved harness permit reproduction without a live agent.

5. Return

NOT APPROVED at this exact r2 export. Candidate stability is resolved; the confirmation-soundness audit is not. Return F1F3 to darkwing for reconciliation and a newly frozen revision. No code fixes, export edits, dependency installs, private inspection, live sends, deployment, commits or push occurred. This verdict is the only repository write. No automatic resend, acceptance, timer or subsequent action is inferred.