Files
ghostty-rs/docs/rewrite/notes/review-rv7-codex.md
T

9.2 KiB
Raw Blame History

Codex final verification (RV7, 2026-10-12)

Parity remains partial: 9 concrete gap groups remain. Verified commit 350330838598e01a3090932afc7101df64511d7b, read-only. No files changed.

“Resolved” below means the reported defect is fixed, not that the entire module has complete parity. Abbreviated Rust paths are relative to crates/ghostty-<crate>/src/.

RV5 row carried into RV6 Status Current-code verification
Surface.zig Resolved Screen-file copy/paste retain path bytes; open targets decode explicitly. core/surface/binding.rs:630, os/open.rs:33
renderer/shadertoy.zig Resolved Array reconstruction preserves padded uniforms and whole-array reads. renderer/shadertoy.rs:265
cli/args.zig Resolved OS argument encoding preserves lone surrogates and literal U+FDD0. os/osbytes.rs:74, os/args.rs:66
config/Config.zig Resolved Template substitution uses decoded bytes; filesystem operations use decoded paths. config/config.rs:3961
apprt/gtk/class/surface.zig Resolved Confirmation decodes only explicitly encoded byte pastes. apprt-gtk/class/surface.rs:2684
os/resourcesdir.zig Resolved Windows resource exports and TERMINFO use native OS paths. termio/exec_windows.rs:620
config/path.zig Resolved Custom-shader paths decode before loading. renderer/generic.rs:248
cli/list_themes.zig Resolved File hyperlinks percent-encode decoded pathname bytes. cli/list_themes.rs:74
lib/allocator.zig Resolved OSC color requests use parser auxiliary storage; X11 lookup does not allocate. vt/osc/parsers/color.rs:87, vt/color.rs:640
terminal/c/osc.zig Resolved Auxiliary storage and growth use the caller allocator; refusal invalidates the command. vt-capi/osc.rs:82
crash/sentry.zig Resolved Suspension guard resumes threads before reply; receive failure returns false; SIGABRT subcode reaches the minidump. crash/mach_handler.rs:352, :476, :513
tripwire.zig Resolved CopyMap injection and owned-allocation cleanup are present. terminal/screen.rs:2619
build/GhosttyLibVt.zig Resolved Build script supplies versioned SONAME/install name. vt-capi/build.rs:23
Previous sweep finding Status Current boundary
GUI Open Config Resolved config/edit.rs:24
Background image Resolved renderer/generic.rs:863
Crash directory Resolved crash/dir.rs:24
SSH cache directory Resolved cli/ssh_cache/disk_cache.rs:62
Executable directory / child PATH Resolved termio/exec.rs:1193, termio/exec_windows.rs:871
Fontconfig filenames Resolved font/deferred_face.rs:75
Relative links / OSC8 Resolved core/surface/mouse.rs:406, :1620
Kitty temporary directory Resolved terminal/kitty/graphics_image.rs:568
macOS .hushlogin Resolved termio/exec.rs:1443
Benchmark C arguments Resolved lib/benchmark.rs:65
Six additional RV6 findings Status Current-code result
Default SHELL Resolved var_os plus explicit encoding. config/config.rs:4628
macOS executable-search PATH Resolved Candidates are constructed from raw bytes. termio/command.rs:301
Windows config environment overrides Resolved Both keys and values decode before insertion. termio/exec_windows.rs:588
Windows environment-key comparison Partial Surrogate collisions fixed; Windows casing semantics remain incorrect. Gap 1 below.
+show-config round-trip Resolved Formatted output decodes before stdout. cli/show_config.rs:85
Non-Apple C API locale initialization Partial Unix fallback chain implemented; Windows remains a no-op. Gap 2 below.

The remaining verified gaps are:

  1. Windows environment-key comparison still differs from Windows/Zig. char::to_uppercase() followed by rejecting multi-character mappings is not Windows’ per-unit uppercase mapping. For example, U+1F80 and U+1F88 compare equal under Windows/Zig’s table but remain different here. Conversely, modern Unicode mappings can merge keys Windows keeps distinct. This affects lookup and overrides. env.rs:18, Windows/Zig mapping:133.

  2. Windows C API locale initialization remains unimplemented. ghostty_init → init_lib → ensure_locale reaches the cfg(not(unix)) function returning None. Zig calls its locale initialization and fallback chain, including Windows environment-update implementations. locale.rs:24, Zig global.zig:164, Zig locale.zig:32.

  3. Bash --rcfile / --init-file paths lose their decoded identity. The intercepted argument remains config-encoded when inserted into GHOSTTY_BASH_RCFILE. A pathname containing byte FF therefore becomes literal escape characters in the environment, so integration sources the wrong pathname. shell_integration.rs:266. Zig inserts the original bytes at shell_integration.zig:387.

  4. Configured TERM is exported without decoding on Unix and Windows. With resources available, both implementations insert cfg.term directly. Non-UTF-8 config bytes and literal U+FDD0 consequently reach the child incorrectly. exec.rs:804, exec_windows.rs:627. Zig preserves the value’s bytes at Exec.zig:639.

  5. GTK discards non-UTF-8 inherited LANG. std::env::var("LANG").ok() treats it as absent; surface environment construction then removes LANG. This remains observable when, for example, LC_ALL=C lets locale initialization succeed despite a non-UTF-8 LANG. application.rs:401, surface.rs:1444. Zig saves the original bytes at application.zig:270.

  6. Windows Kitty file paths reject valid WTF-8 lone surrogates. The non-Unix OsStrExt::from_bytes substitutes an empty pathname whenever from_utf8 fails. Both canonicalization and subsequent file opening use it. graphics_image.rs:24, graphics_image.rs:140. Zig passes the original pathname to realpath at graphics_image.zig:89.

  7. Malformed Windows byte sequences are silently replaced instead of rejected. wtf8_to_wide maps malformed input such as byte FF to U+FFFD, and process creation uses that result. Zig’s process-launch conversions are fallible: malformed input fails instead of selecting a replacement-character executable/path or changing arguments. osbytes.rs:163, command_windows.rs:134, Zig Command.zig:261.

  8. Embedded C API clipboard and binding-action input remain lossy. Clipboard completion and ghostty_surface_binding_action replace invalid UTF-8. For example, clipboard byte FF, or action bytes text: followed by FF, become U+FFFD instead of the original byte. embedded.rs:1938, embedded.rs:1979. Zig passes byte slices at embedded.zig:1973 and embedded.zig:1995.

  9. Config-loaded text/CSI/ESC bindings leak the reversible encoding into PTY output. The file reader encodes raw bytes, but these action handlers write the resulting strings without decoding. A literal U+FDD0 in a text: binding is doubled; byte FF becomes the UTF-8 escape representation. cli_args.rs:811, binding.rs:725, binding.rs:739. Zig’s parser copies unescaped bytes directly at string.zig:17.

Other inspected stub markers matched upstream limitations, stale comments, or implementations elsewhere. The literal export-name comparison found no missing active Zig C/WASM exports; app_new and app_free are commented out upstream.

Verdict count Result
Original rows resolved / partial 13 / 0
Previous sweep findings resolved / partial 10 / 0
Six additional RV6 findings resolved / partial 4 / 2
Newly verified gap groups 7
Total remaining verified gap groups 9
Selected existing-binary tests passed / failed 58 / 0

No rebuild or native macOS/Windows/WASM execution was performed. The platform findings are source-verified; passing existing-binary tests do not establish exhaustive parity.