tmux symbols broken: sessions start without a UTF-8 locale #161

Closed
opened 2026-10-11 06:58:37 +00:00 by kayg · 26 comments
Owner

Owner report (2026-10-11): tmux on o2, inside a canvas terminal window, does not display its symbols properly.

Finding: production terminal sessions start with TERM=xterm-256color but no LANG, LC_ALL or LC_CTYPE (checked on monitor01: the session shell's environment has TERM only). Without a UTF-8 locale tmux assumes a non-UTF-8 terminal and draws borders and symbols with ASCII fallbacks. A real login (D229) would load the host's locale through PAM (pam_env, /etc/default/locale, /etc/locale.conf); until then sessions get nothing. Also check: font coverage for Nerd Font / box-drawing glyphs (#150) and whether TERM/terminfo matches what the client emulates.

Owner report (2026-10-11): tmux on o2, inside a canvas terminal window, does not display its symbols properly. Finding: production terminal sessions start with `TERM=xterm-256color` but no `LANG`, `LC_ALL` or `LC_CTYPE` (checked on monitor01: the session shell's environment has TERM only). Without a UTF-8 locale tmux assumes a non-UTF-8 terminal and draws borders and symbols with ASCII fallbacks. A real login (D229) would load the host's locale through PAM (pam_env, /etc/default/locale, /etc/locale.conf); until then sessions get nothing. Also check: font coverage for Nerd Font / box-drawing glyphs (#150) and whether TERM/terminfo matches what the client emulates.
Author
Owner

Starting #161 on branch terminal-fidelity, based on prod-batch at ebcc73a0ec.

Starting #161 on branch terminal-fidelity, based on prod-batch at ebcc73a0ec22f8498a0466b2d8641ac569f87e77.
Author
Owner

Finding: terminal shell startup clears the environment in crates/infraternal-shim/src/pty.rs and sets TERM/PATH without any locale variables. The host has LANG=en_US.UTF-8 in both /etc/default/locale and /etc/locale.conf; locale -a reports the corresponding installed en_US.utf8 locale and C.utf8 fallback. The new locale selection tests reproduced four missing-locale cases before the fix (configured locale, unsupported configured locale, absent locale fallback, and rejected shell expansion); all five tests pass after the locale selector was added. A real PTY test confirms selected locale values reach the login shell while unrelated inherited variables stay cleared. Locale discovery is cached in the long-lived launcher before the per-session shim starts.

Finding: terminal shell startup clears the environment in crates/infraternal-shim/src/pty.rs and sets TERM/PATH without any locale variables. The host has LANG=en_US.UTF-8 in both /etc/default/locale and /etc/locale.conf; locale -a reports the corresponding installed en_US.utf8 locale and C.utf8 fallback. The new locale selection tests reproduced four missing-locale cases before the fix (configured locale, unsupported configured locale, absent locale fallback, and rejected shell expansion); all five tests pass after the locale selector was added. A real PTY test confirms selected locale values reach the login shell while unrelated inherited variables stay cleared. Locale discovery is cached in the long-lived launcher before the per-session shim starts.
Author
Owner

Font finding: the existing production font-metrics.spec.ts powerline test passes (arrow 1.00, branch 0.97, house 0.72, node 0.67). fc-query confirms U+2500, U+2588 and U+2592 in all 10 roman font files; the dedicated nerd-symbols.woff2 contains U+E0B0, U+E0A0, U+F015 and U+E718. This covers the box-drawing, block and sampled Powerline/Nerd glyphs relevant to #150. Production captures use real tmux 3.5a PTY output: C locale has ASCII borders and no prompt icons; LANG=en_US.UTF-8 has UTF-8 borders and the Nerd Font prompt. PNGs are 1440x900 at apps/tracer/captures/terminal-locale/tmux-before-1440x900.png and apps/tracer/captures/terminal-locale/tmux-after-1440x900.png.

TERM finding: infocmp -1 -x xterm-256color reports 256 colors and standard underline/reset capabilities in 288 capability lines; it has no Tc, RGB, Smulx or Setulc extensions. The client uses the pinned Ghostty VT web build. Ghostty's official terminfo note says its own terminal entry is xterm-ghostty and that xterm-256color omits capabilities including colored/styled underlines: https://ghostty.org/docs/help/terminfo. The current TERM covers the tmux baseline shown in the captures, while the broader renderer capability set is under-advertised. A dedicated entry remains an owner decision; this job leaves TERM unchanged.

Discovery cost: on infraternal-dev (8 cores), a weighted systemd-run --user --scope -p CPUWeight=10000 run of 21 locale-list probes measured p50 5.784 ms, p95 19.303 ms, 4,216 output bytes and 512 locale names; load average was 28.03/26.46/26.74. The long-lived launcher caches discovery once per host process. At 50 sessions that is one locale inventory, not 50; the added LANG environment entry is 17 raw bytes per shell (850 bytes across 50 shells).

Font finding: the existing production `font-metrics.spec.ts` powerline test passes (arrow 1.00, branch 0.97, house 0.72, node 0.67). `fc-query` confirms U+2500, U+2588 and U+2592 in all 10 roman font files; the dedicated `nerd-symbols.woff2` contains U+E0B0, U+E0A0, U+F015 and U+E718. This covers the box-drawing, block and sampled Powerline/Nerd glyphs relevant to #150. Production captures use real tmux 3.5a PTY output: C locale has ASCII borders and no prompt icons; `LANG=en_US.UTF-8` has UTF-8 borders and the Nerd Font prompt. PNGs are 1440x900 at `apps/tracer/captures/terminal-locale/tmux-before-1440x900.png` and `apps/tracer/captures/terminal-locale/tmux-after-1440x900.png`. TERM finding: `infocmp -1 -x xterm-256color` reports 256 colors and standard underline/reset capabilities in 288 capability lines; it has no `Tc`, `RGB`, `Smulx` or `Setulc` extensions. The client uses the pinned Ghostty VT web build. Ghostty's official terminfo note says its own terminal entry is `xterm-ghostty` and that `xterm-256color` omits capabilities including colored/styled underlines: https://ghostty.org/docs/help/terminfo. The current TERM covers the tmux baseline shown in the captures, while the broader renderer capability set is under-advertised. A dedicated entry remains an owner decision; this job leaves TERM unchanged. Discovery cost: on infraternal-dev (8 cores), a weighted `systemd-run --user --scope -p CPUWeight=10000` run of 21 locale-list probes measured p50 5.784 ms, p95 19.303 ms, 4,216 output bytes and 512 locale names; load average was 28.03/26.46/26.74. The long-lived launcher caches discovery once per host process. At 50 sessions that is one locale inventory, not 50; the added `LANG` environment entry is 17 raw bytes per shell (850 bytes across 50 shells).
Author
Owner

Step complete: host locale selector and seven deterministic cases committed as fda2cabe and pushed to terminal-fidelity. Gate: cargo test -p infraternal-shim --lib locale::tests -- --test-threads=1 — test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 78 filtered out. The earlier red run had four locale-selection failures before implementation.

Step complete: host locale selector and seven deterministic cases committed as fda2cabe and pushed to terminal-fidelity. Gate: `cargo test -p infraternal-shim --lib locale::tests -- --test-threads=1` — test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 78 filtered out. The earlier red run had four locale-selection failures before implementation.
Author
Owner

Step complete: PTY login shells now receive the selected locale after .env_clear(), with unrelated inherited variables still excluded. Commit 0d0b320d is pushed. Gate: cargo test -p infraternal-shim --lib spawned_login_shell_receives_selected_locale_without_other_host_variables -- --test-threads=1 — test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 84 filtered out; finished in 0.00s.

Step complete: PTY login shells now receive the selected locale after `.env_clear()`, with unrelated inherited variables still excluded. Commit 0d0b320d is pushed. Gate: `cargo test -p infraternal-shim --lib spawned_login_shell_receives_selected_locale_without_other_host_variables -- --test-threads=1` — test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 84 filtered out; finished in 0.00s.
Author
Owner

Step complete: the host agent resolves locale once before starting each shim; commit 10f599a9 is pushed. This avoids repeating the locale-list probe per PTY. Gate: cargo check -p infraternal-agent --lib — Finished dev profile [unoptimized + debuginfo] target(s) in 7.42s.

Step complete: the host agent resolves locale once before starting each shim; commit 10f599a9 is pushed. This avoids repeating the locale-list probe per PTY. Gate: `cargo check -p infraternal-agent --lib` — Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.42s.
Author
Owner

Step complete: production-build tmux captures are committed and pushed in 43cb463b. Before (C locale): tmux status and ASCII border. After (LANG=en_US.UTF-8): tmux status, UTF-8 border and Nerd Font prompt. Both are 1440x900; the output came from real tmux 3.5a PTYs and was rendered by the production tracer build.

Step complete: production-build tmux captures are committed and pushed in 43cb463b. Before (C locale): [tmux status and ASCII border](https://git.kayg.org/kayg/infraternal/raw/commit/43cb463b/apps/tracer/captures/terminal-locale/tmux-before-1440x900.png). After (LANG=en_US.UTF-8): [tmux status, UTF-8 border and Nerd Font prompt](https://git.kayg.org/kayg/infraternal/raw/commit/43cb463b/apps/tracer/captures/terminal-locale/tmux-after-1440x900.png). Both are 1440x900; the output came from real tmux 3.5a PTYs and was rendered by the production tracer build.
Author
Owner

macOS path complete in 0009d153 (pushed): when inherited LANG is absent, the selector reads the current user's AppleLocale preference and maps it to UTF-8; inherited LANG/LC_* values still win. Apple documents AppleLocale as the user's region preference: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFLocales/Articles/CFLocaleConcepts.html. The conversion test failed first (en_US was unchanged instead of gaining .UTF-8) and now passes; locale selection is 8/8. This host is Linux, so the /usr/bin/defaults runtime path still needs a macOS-host run.

macOS path complete in 0009d153 (pushed): when inherited LANG is absent, the selector reads the current user's AppleLocale preference and maps it to UTF-8; inherited LANG/LC_* values still win. Apple documents AppleLocale as the user's region preference: https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFLocales/Articles/CFLocaleConcepts.html. The conversion test failed first (`en_US` was unchanged instead of gaining `.UTF-8`) and now passes; locale selection is 8/8. This host is Linux, so the `/usr/bin/defaults` runtime path still needs a macOS-host run.
Author
Owner

Follow-up: the macOS cfg branch in locale.rs now type-checks for x86_64-apple-darwin with rustc --emit=metadata; the pure AppleLocale-to-POSIX conversion test passes on Linux. The actual /usr/bin/defaults query remains unrun without a macOS host.

Follow-up: the macOS cfg branch in `locale.rs` now type-checks for `x86_64-apple-darwin` with `rustc --emit=metadata`; the pure AppleLocale-to-POSIX conversion test passes on Linux. The actual `/usr/bin/defaults` query remains unrun without a macOS host.
Author
Owner

Gate finding: the first bun test src run had 141 pass and 1 fail in the unrelated 1,000 nodes lay out in a few milliseconds wall-clock check (168.875 ms measured against <25 ms) under host load. I am rerunning that suite in the required weighted local scope; no mesh files changed in this branch.

Gate finding: the first `bun test src` run had 141 pass and 1 fail in the unrelated `1,000 nodes lay out in a few milliseconds` wall-clock check (168.875 ms measured against <25 ms) under host load. I am rerunning that suite in the required weighted local scope; no mesh files changed in this branch.
Author
Owner

Gate follow-up: the first unweighted mesh layout timing miss reran cleanly under systemd-run --user --scope -p CPUWeight=10000. bun test src: 142 pass, 0 fail, 10,901 expect() calls; 1,000-node layout measured 9.64 ms against <25 ms. infraternal-dev: 8 cores, load average 40.27/33.27/27.26 at start and end. No mesh code changed.

Gate follow-up: the first unweighted mesh layout timing miss reran cleanly under `systemd-run --user --scope -p CPUWeight=10000`. `bun test src`: 142 pass, 0 fail, 10,901 expect() calls; 1,000-node layout measured 9.64 ms against <25 ms. infraternal-dev: 8 cores, load average 40.27/33.27/27.26 at start and end. No mesh code changed.
Author
Owner

Clippy cleanup committed and pushed as 9b3ea5aa: targeted shim/agent Clippy passed, locale unit tests passed 8/8, and cargo fmt --all --check passed. The prior full fast run also measured the x86_64 static binary at 20,084,656 bytes against the existing 16,404,816-byte cap; no budget was changed.

Clippy cleanup committed and pushed as `9b3ea5aa`: targeted shim/agent Clippy passed, locale unit tests passed 8/8, and `cargo fmt --all --check` passed. The prior full fast run also measured the x86_64 static binary at 20,084,656 bytes against the existing 16,404,816-byte cap; no budget was changed.
Author
Owner

The required real-session check found a live PTY socket and running shim (UID 1001, child present) while host.facts.read returned sessionCount=0 and backgroundSessionCount=0. /proc/<pid>/stat was readable with a valid birth tick, but /proc/<pid>/exe was hidden because harden_startup() sets the shim non-dumpable. Registry::Live::alive therefore discarded valid sessions. process_birth_ticks already rejects zombie/exit states; I’m removing the redundant executable-link requirement and will rerun the lifecycle test.

The required real-session check found a live PTY socket and running shim (UID 1001, child present) while `host.facts.read` returned `sessionCount=0` and `backgroundSessionCount=0`. `/proc/<pid>/stat` was readable with a valid birth tick, but `/proc/<pid>/exe` was hidden because `harden_startup()` sets the shim non-dumpable. `Registry::Live::alive` therefore discarded valid sessions. `process_birth_ticks` already rejects zombie/exit states; I’m removing the redundant executable-link requirement and will rerun the lifecycle test.
Author
Owner

Registry liveness now uses the authenticated socket path and matching process birth tick; the birth parser already rejects zombie states. Commit 77148b61 pushed. The red-to-green real-session test now passes: local_session_counts_and_memory_refusals_follow_real_lifecycle 1/1; shim/agent Clippy and cargo fmt --check also pass.

Registry liveness now uses the authenticated socket path and matching process birth tick; the birth parser already rejects zombie states. Commit `77148b61` pushed. The red-to-green real-session test now passes: `local_session_counts_and_memory_refusals_follow_real_lifecycle` 1/1; shim/agent Clippy and `cargo fmt --check` also pass.
Author
Owner

Finished at HEAD 30011d951a on branch terminal-fidelity; all commits are pushed. Issue remains open.

  • Linux reads literal LANG from /etc/default/locale and /etc/locale.conf, checks that the locale is installed, and uses C.UTF-8 only when available. Existing LANG and LC_* values are preserved; only locale variables cross the scrubbed PTY environment. macOS reads the user's AppleLocale setting and maps it to UTF-8.
  • Locale inventory was measured at 21 calls / 4,216 bytes over 512 locales, p50 5.784 ms and p95 19.303 ms, on 8 cores at load average 28.03/26.46/26.74. Discovery is cached once per long-lived agent; 50 sessions share one inventory, with 850 bytes of LANG environment data.
  • Font inspection confirmed box-drawing U+2500, block U+2588, and shade U+2592 coverage in the default roman fonts; the Nerd Symbols font contains the prompt's Powerline/private-use glyphs. The production prompt renders those glyphs after the locale change.
  • The existing xterm-256color terminfo works for the exercised tmux screen, status bar, and borders, but advertises capabilities beyond the client implementation. I recorded whether a dedicated terminfo is warranted for the owner; this task leaves TERM unchanged.
  • Tracer gates passed: check exit 0; 142 source tests, 0 failures, 10,901 assertions; production build exit 0; transfer budget exit 0. Critical gzip/Brotli was 290,585/241,576 of 307,200/256,000 bytes; deferred was 50,726/44,750 of 51,200/45,056; largest on-demand chunk was 15,001/13,314 of 20,480/18,432. Font budgets remain unchanged and pass.
  • Production browser checks passed: terminal query replay 2/2 on port 5801; dead-session 4/4 on port 5802. The macOS locale code was cross-target typechecked; no native macOS runtime was available.

The fast gate ran with RUST_TEST_THREADS=4 under host contention. Its Rust test row passed; the only failing row is the known static size overrun, with D188 unchanged. Fast-gate summary, verbatim:

METRIC name=network_rtt_selftest configured_rtt_ms=300 jitter_ms=30 loss=unsupported transport=tcp-stream n=3 p50_ms=301.59 p99_ms=311.25 result=PASS
binary exceeds the 16404816-byte size budget: 20084464 bytes
+---------------------------+--------------+
| Rust gate                 | Result       |
+---------------------------+--------------+
| fmt                       | PASS         |
| VT native fmt             | PASS         |
| clippy                    | PASS         |
| test                      | PASS         |
| cargo-deny                | PASS         |
| static builds             | FAIL (1)     |
+---------------------------+--------------+
FAST_RUN exit=1 elapsed_s=735.0 load_start=35.56/36.44/32.40 load_end=23.92/30.70/32.30 log=/home/kayg/.cache/codex-scratch/terminal-fidelity/verify-fast.log

Production captures (1440×900):

  • Before: apps/tracer/captures/terminal-locale/tmux-before-1440x900.png
  • After: apps/tracer/captures/terminal-locale/tmux-after-1440x900.png

Before: tmux status bar, borders, and prompt

After: tmux status bar, borders, and Nerd Font prompt glyphs

Finished at HEAD 30011d951a1fca5da4aa708d14b0e27bb7daf8b8 on branch terminal-fidelity; all commits are pushed. Issue remains open. - Linux reads literal `LANG` from `/etc/default/locale` and `/etc/locale.conf`, checks that the locale is installed, and uses `C.UTF-8` only when available. Existing `LANG` and `LC_*` values are preserved; only locale variables cross the scrubbed PTY environment. macOS reads the user's `AppleLocale` setting and maps it to UTF-8. - Locale inventory was measured at 21 calls / 4,216 bytes over 512 locales, p50 5.784 ms and p95 19.303 ms, on 8 cores at load average 28.03/26.46/26.74. Discovery is cached once per long-lived agent; 50 sessions share one inventory, with 850 bytes of `LANG` environment data. - Font inspection confirmed box-drawing U+2500, block U+2588, and shade U+2592 coverage in the default roman fonts; the Nerd Symbols font contains the prompt's Powerline/private-use glyphs. The production prompt renders those glyphs after the locale change. - The existing `xterm-256color` terminfo works for the exercised tmux screen, status bar, and borders, but advertises capabilities beyond the client implementation. I recorded whether a dedicated terminfo is warranted for the owner; this task leaves `TERM` unchanged. - Tracer gates passed: check exit 0; 142 source tests, 0 failures, 10,901 assertions; production build exit 0; transfer budget exit 0. Critical gzip/Brotli was 290,585/241,576 of 307,200/256,000 bytes; deferred was 50,726/44,750 of 51,200/45,056; largest on-demand chunk was 15,001/13,314 of 20,480/18,432. Font budgets remain unchanged and pass. - Production browser checks passed: terminal query replay 2/2 on port 5801; dead-session 4/4 on port 5802. The macOS locale code was cross-target typechecked; no native macOS runtime was available. The fast gate ran with `RUST_TEST_THREADS=4` under host contention. Its Rust test row passed; the only failing row is the known static size overrun, with D188 unchanged. Fast-gate summary, verbatim: ```text METRIC name=network_rtt_selftest configured_rtt_ms=300 jitter_ms=30 loss=unsupported transport=tcp-stream n=3 p50_ms=301.59 p99_ms=311.25 result=PASS binary exceeds the 16404816-byte size budget: 20084464 bytes +---------------------------+--------------+ | Rust gate | Result | +---------------------------+--------------+ | fmt | PASS | | VT native fmt | PASS | | clippy | PASS | | test | PASS | | cargo-deny | PASS | | static builds | FAIL (1) | +---------------------------+--------------+ FAST_RUN exit=1 elapsed_s=735.0 load_start=35.56/36.44/32.40 load_end=23.92/30.70/32.30 log=/home/kayg/.cache/codex-scratch/terminal-fidelity/verify-fast.log ``` Production captures (1440×900): - Before: `apps/tracer/captures/terminal-locale/tmux-before-1440x900.png` - After: `apps/tracer/captures/terminal-locale/tmux-after-1440x900.png` ![Before: tmux status bar, borders, and prompt](<https://git.kayg.org/kayg/infraternal/raw/commit/30011d951a1fca5da4aa708d14b0e27bb7daf8b8/apps/tracer/captures/terminal-locale/tmux-before-1440x900.png>) ![After: tmux status bar, borders, and Nerd Font prompt glyphs](<https://git.kayg.org/kayg/infraternal/raw/commit/30011d951a1fca5da4aa708d14b0e27bb7daf8b8/apps/tracer/captures/terminal-locale/tmux-after-1440x900.png>)
Author
Owner

Starting the #161 locale fix port as part of the production-batch integration on branch release-prod-3c, based on origin/release-prod-3b at 8cff05cdeee4b43c5b7234e09fb12296fb602ad8. The terminal-fidelity source is origin/terminal-fidelity at 27db08cf8717596dee20d7de8e109ce69f03beb7; I have read this issue's history and will retain the existing production lifecycle work while merging the locale behavior.

Starting the #161 locale fix port as part of the production-batch integration on branch `release-prod-3c`, based on `origin/release-prod-3b` at `8cff05cdeee4b43c5b7234e09fb12296fb602ad8`. The terminal-fidelity source is `origin/terminal-fidelity` at `27db08cf8717596dee20d7de8e109ce69f03beb7`; I have read this issue's history and will retain the existing production lifecycle work while merging the locale behavior.
Author
Owner

Finding from the branch comparison: origin/release-prod-3b checks lifecycle.rs with symlink_metadata(...).file_type().is_symlink() and adds nondumpable_process_keeps_its_authenticated_lifetime; origin/terminal-fidelity removes the followed /proc/<pid>/exe check because hardened shims deny following it. The production check inspects link metadata without following it, so I will retain that check and its regression test while preserving the terminal-fidelity locale and replay changes. The two script conflicts also differ: production counts the private rendezvous in /proc/<pid>/net/unix, while terminal-fidelity validates detach through a wire-level resize/ack and waits specifically for terminal.exited after the replay marker.

Finding from the branch comparison: `origin/release-prod-3b` checks `lifecycle.rs` with `symlink_metadata(...).file_type().is_symlink()` and adds `nondumpable_process_keeps_its_authenticated_lifetime`; `origin/terminal-fidelity` removes the followed `/proc/<pid>/exe` check because hardened shims deny following it. The production check inspects link metadata without following it, so I will retain that check and its regression test while preserving the terminal-fidelity locale and replay changes. The two script conflicts also differ: production counts the private rendezvous in `/proc/<pid>/net/unix`, while terminal-fidelity validates detach through a wire-level resize/ack and waits specifically for `terminal.exited` after the replay marker.
Author
Owner

Gate step: cargo clippy --locked --all-targets --all-features -p infraternal-agent -p infraternal-shim -p infraternal-server -p infraternal -- -D warnings PASS; finished in 7m 02s. cargo fmt --all -- --check also PASS.

Gate step: `cargo clippy --locked --all-targets --all-features -p infraternal-agent -p infraternal-shim -p infraternal-server -p infraternal -- -D warnings` PASS; finished in 7m 02s. `cargo fmt --all -- --check` also PASS.
Author
Owner

Rust tests (default features) PASS after pointing existing ../../target fixture paths through a temporary symlink into scratch: agent 34 passed/6 ignored + 2 transport; server 187 passed/14 ignored plus its integration targets; shim 73 passed/13 ignored, detach 2/2, mouse 1/1. The TF-001 replay_complete_notice_is_accepted_by_embedded_server passed in the server suite. Initial ENOENT setup attempt is recorded above; no test was waived.

Rust tests (default features) PASS after pointing existing `../../target` fixture paths through a temporary symlink into scratch: agent 34 passed/6 ignored + 2 transport; server 187 passed/14 ignored plus its integration targets; shim 73 passed/13 ignored, detach 2/2, mouse 1/1. The TF-001 `replay_complete_notice_is_accepted_by_embedded_server` passed in the server suite. Initial ENOENT setup attempt is recorded above; no test was waived.
Author
Owner

Real-shim session scripts PASS against the scratch-built CLI (INFRATERAL_TEST_STATE_ROOT under scratch): verify-session-exit-credit.py --exit-after-detach reported “Reaped shim final output and ordered exit survive delayed credit: PASS”; verify-session-retention.py reported “Bounded owned exit, unfunded notification, restarted reconnect status, retirement handshake race, unknown session: PASS”.

Real-shim session scripts PASS against the scratch-built CLI (`INFRATERAL_TEST_STATE_ROOT` under scratch): `verify-session-exit-credit.py --exit-after-detach` reported “Reaped shim final output and ordered exit survive delayed credit: PASS”; `verify-session-retention.py` reported “Bounded owned exit, unfunded notification, restarted reconnect status, retirement handshake race, unknown session: PASS”.
Author
Owner

Owner report 2026-10-12 (iPhone, production 1f77a449): after opening Settings and navigating back, a line of stray characters (tofu, symbols) was typed into the root shell on monitor01. Likely replayed terminal query answers on reattach (#161). Job settings-roundtrip (queued after prod-batch-4) reproduces this exact path on 1f77a449 and verifies the release-prod-4 fix before batch 4 deploys.

Owner report 2026-10-12 (iPhone, production 1f77a449): after opening Settings and navigating back, a line of stray characters (tofu, symbols) was typed into the root shell on monitor01. Likely replayed terminal query answers on reattach (#161). Job settings-roundtrip (queued after prod-batch-4) reproduces this exact path on 1f77a449 and verifies the release-prod-4 fix before batch 4 deploys.
Author
Owner

Base/head result for the Settings-return terminal replay report, using matched production builds and an echo-disabled PTY fixture:

  • Base 1f77a449 failed on mobile 393×852 (39 → 229 accepted PTY bytes, +190) and desktop 1440×900 (39 → 199, +160) at the first Settings → Shortcuts → About → Console return.
  • Head 74305cc690 passed both sizes across five cycles, renderer reload from cursor zero, background/foreground and network reconnect. Each stayed at 29 accepted bytes, output sequence 160, and unchanged screen text.

The head test also observed one reconnect attach on each viewport. No product change was needed beyond the replay fence already merged in production batch 4.

Base/head result for the Settings-return terminal replay report, using matched production builds and an echo-disabled PTY fixture: - Base 1f77a449 failed on mobile 393×852 (39 → 229 accepted PTY bytes, +190) and desktop 1440×900 (39 → 199, +160) at the first Settings → Shortcuts → About → Console return. - Head 74305cc690140d315772779076408e1371eaeb67 passed both sizes across five cycles, renderer reload from cursor zero, background/foreground and network reconnect. Each stayed at 29 accepted bytes, output sequence 160, and unchanged screen text. The head test also observed one reconnect attach on each viewport. No product change was needed beyond the replay fence already merged in production batch 4.
Author
Owner

Updated matched result with the shared DA3/extended-keyboard corpus and cleanup fixed to preserve the primary assertion: base 1f77a449 accepts 200 extra PTY bytes on mobile and 180 on desktop at the first Settings return. Head f9f4b045 accepts no extra input (29→29) in either viewport through five Settings cycles, cursor-zero reload, visibilitychange and network reconnect; the screen stays unchanged. This reproduces #161 on base and verifies the existing replay fence on head. No product fix was needed.

Updated matched result with the shared DA3/extended-keyboard corpus and cleanup fixed to preserve the primary assertion: base 1f77a449 accepts 200 extra PTY bytes on mobile and 180 on desktop at the first Settings return. Head f9f4b045 accepts no extra input (29→29) in either viewport through five Settings cycles, cursor-zero reload, visibilitychange and network reconnect; the screen stays unchanged. This reproduces #161 on base and verifies the existing replay fence on head. No product fix was needed.
Author
Owner

Orchestrator: DEPLOYED to production at 09:13 UTC (14:43 IST): release-prod-4 @ 3aec316e = live 1f77a449 + terminal fidelity (#160/#161) + ended sessions (#168) + live web fixes (3w) + settings rows (text never collides). Binaries built from 61bdbd9f (later merges are web-only); sha256 prefixes x86 2af382ef / arm 8fd4d67f match on host. healthz 200, public 200, 0 errors in journal, 23 shims survived the restart. Settings round-trip evidence (#161): base 1f77a449 accepted 190-200 stray PTY bytes after Settings return; head 0 across five cycles, background/foreground and reconnect. Restart re-locked the CA: owner unlock needed. Perf VM latency A/B (prod-batch-4 report): p50/p99 0.57/2.25 → 0.56/2.70 ms, overlapping.

Orchestrator: DEPLOYED to production at 09:13 UTC (14:43 IST): release-prod-4 @ 3aec316e = live 1f77a449 + terminal fidelity (#160/#161) + ended sessions (#168) + live web fixes (3w) + settings rows (text never collides). Binaries built from 61bdbd9f (later merges are web-only); sha256 prefixes x86 2af382ef / arm 8fd4d67f match on host. healthz 200, public 200, 0 errors in journal, 23 shims survived the restart. Settings round-trip evidence (#161): base 1f77a449 accepted 190-200 stray PTY bytes after Settings return; head 0 across five cycles, background/foreground and reconnect. Restart re-locked the CA: owner unlock needed. Perf VM latency A/B (prod-batch-4 report): p50/p99 0.57/2.25 → 0.56/2.70 ms, overlapping.
Author
Owner

Final branch head: settings-roundtrip at 051d0a40c158270fdffb86bb4b87cd6d08419ac0 (pushed).

Base 1f77a449 accepts +200 PTY input bytes on the first Settings return at 393×852 and +180 at 1440×900. On head, both viewport specs complete five Settings cycles with accepted PTY input unchanged at 29 bytes, query output sequence 164, screen unchanged, and no page errors. Cursor-zero reload and network reconnect each cause exactly one attach; the visibilitychange background/foreground path also preserves the input log and screen. The common corpus covers DA1/2/3, DSR, OSC color queries, XTVERSION, CSI ? u, DECRQM, DECRQSS and XTGETTCAP.

The fixture has no real shell, vim or htop. It feeds the query output through the production canvas and mock PTY with echo disabled, then checks the server-side accepted-input log, so the test exercises the client PTY reply route without shell feedback. The base reproduces the stray-input regression; head passes it. No product fix was needed beyond #161's replay behavior.

Final branch head: `settings-roundtrip` at `051d0a40c158270fdffb86bb4b87cd6d08419ac0` (pushed). Base `1f77a449` accepts +200 PTY input bytes on the first Settings return at 393×852 and +180 at 1440×900. On head, both viewport specs complete five Settings cycles with accepted PTY input unchanged at 29 bytes, query output sequence 164, screen unchanged, and no page errors. Cursor-zero reload and network reconnect each cause exactly one attach; the visibilitychange background/foreground path also preserves the input log and screen. The common corpus covers DA1/2/3, DSR, OSC color queries, XTVERSION, `CSI ? u`, DECRQM, DECRQSS and XTGETTCAP. The fixture has no real shell, vim or htop. It feeds the query output through the production canvas and mock PTY with echo disabled, then checks the server-side accepted-input log, so the test exercises the client PTY reply route without shell feedback. The base reproduces the stray-input regression; head passes it. No product fix was needed beyond #161's replay behavior.
Author
Owner

Closed by the orchestrator during the 2026-10-28 handover (#254), on the owner's request to close finished issues. Evidence: Fixed (settings-roundtrip 051d0a40 in dev and prod) and deployed in release-prod-4 3aec316e with before/after evidence (0 stray PTY bytes across five cycles). Reopen if anything is still missing.

Closed by the orchestrator during the 2026-10-28 handover (#254), on the owner's request to close finished issues. Evidence: Fixed (settings-roundtrip 051d0a40 in dev and prod) and deployed in release-prod-4 3aec316e with before/after evidence (0 stray PTY bytes across five cycles). Reopen if anything is still missing.
kayg closed this issue 2026-10-28 17:52:54 +00:00
Sign in to join this conversation.
No labels
launch-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal#161
No description provided.