9.6 KiB
Codex final verification (RV8, 2026-10-12)
Parity remains partial: 9 verified gap groups remain. Audited e47009e21e8cba1f931e18a9b14efa037202f519 read-only; no files changed.
“Resolved” means the reported defect is fixed, not that the entire module has parity.
| Review item | Status | Current-code verification |
|---|---|---|
| RV7 #1: Windows environment-key casing | Resolved | Uses Zig’s per-unit mapping. All 2,544 table entries match. env.rs:18 |
| #2: Windows locale initialization | Resolved | Windows now runs the locale fallback chain, including environment updates. locale.rs:69 |
| #3: Bash rcfile bytes | Resolved | Decodes before inserting GHOSTTY_BASH_RCFILE. shell_integration.rs:268 |
#4: Configured TERM |
Resolved | Both platforms decode before exporting. exec.rs:805, exec_windows.rs:639 |
#5: GTK inherited LANG |
Resolved | Saved as OsString using var_os, then restored without UTF-8 conversion. application.rs:402 |
| #6: Windows Kitty paths | Partial | Lone surrogates work; the new decoder rejects another representation Zig accepts. Finding 3 below. |
| #7: Windows malformed-byte handling | Partial | Launch rejects byte FF, but conversion contracts still differ. Findings 1–2. |
| #8: C clipboard completion / binding actions | Resolved | Clipboard remains bytes; action input enters the reversible encoding. embedded.rs:1946, embedded.rs:1990 |
| #9: Text/CSI/ESC binding output | Resolved | Decodes payload bytes; CSI/ESC length limit applies after decoding. binding.rs:723 |
| Z9: C key-event text limitation | Resolved | Byte slices now reach the encoder, including through VT C API. key_event.rs:35 |
| Z9/Z10: Invalid preedit limitation | Resolved | Clears prior preedit, marks dirty, then returns an error, matching Zig. surface/mod.rs:1694 |
| Z9: Invalid clipboard replacement strings | Partial | Replacement conversion masks missing input validation. Finding 6. |
| Z9: Flatpak / new-window D-Bus limits | Partial | UTF-8 transport limitations are shared; Rust additionally changes conversion/wire behavior. Finding 9. |
The sweep found these concrete remaining gaps:
-
Windows filesystem paths still replace malformed bytes.
EncodedOs::to_path()reaches the lossy Windows decoder. A config pathname containingFFcan therefore open the corresponding U+FFFD pathname instead of failing. Config loading and renderer assets use this route. osbytes.rs:95, file_load.rs:162. Zig’s Windows path conversion returnsBadPathName. Threaded.zig:6652 -
Windows process launch accepts surrogate bytes Zig rejects. Rust accepts
ED A0 80throughtry_to_wide; inherited environment values also pass directly through UTF-16. Zig’sCommanduses strict UTF-8, not WTF-8, for application, cwd, command line and environment. command_windows.rs:138, windows_args.rs:20, Command.zig:261, Command.zig:487 -
The new strict decoder over-rejects Windows Kitty path input.
ED A0 BD ED B8 80decodes to a surrogate pair, then re-encodes asF0 9F 98 80; the equality check rejects it. Zig explicitly permits paired surrogate encodings in its WTF-8 validation. This is a Z9 decoder regression relative to Zig’s accepted inputs. osbytes.rs:192, graphics_image.rs:38, unicode.zig:1630 -
A literal U+FDD0 Unicode key trigger is rejected. Config input doubles that character, but trigger parsing counts encoded characters directly and sees two. Zig accepts the original single codepoint. binding/mod.rs:617, Binding.zig:1730
-
selection-word-charsparses encoding artifacts as delimiters. Raw byteFFbecomes delimiter codepoints U+FDD0 and U+00FF instead of producingInvalidValue. types_a.rs:639, string.rs:147, Config.zig:6143 -
clipboard-codepoint-mapaccepts invalid UTF-8 replacements. The parser incorrectly assumes its encoded&strproves the original bytes valid. A replacement containingFFis accepted and later becomes U+FFFD; Zig rejects the configuration value. types_a.rs:922, clipboard.rs:421, Config.zig:8212 -
Font styles and codepoint-map family names remain encoded during lookup. Unlike
font-family, these consumers never decode. A literal U+FDD0 therefore becomes two characters in the Fontconfig/CoreText lookup name. shared_grid_set.rs:505, types_a.rs:875, discovery.rs:40. Zig retains the original names. SharedGridSet.zig:604, Config.zig:7940 -
C title actions still lose bytes.
set_surface_title:orset_tab_title:followed byFFbecomes U+FFFD before the embedder callback. Configured titles have the same conversion. Zig forwards the original bytes. binding.rs:938, surface/mod.rs:610, Surface.zig:5486 -
D-Bus string handling differs beyond the shared UTF-8 restriction. New-window sends and expects the internal encoding. An ordinary GTK action argument containing literal U+FDD0 followed by
écan consequently decode into different bytes; Zig treats it as ordinary text. new_window.rs:38, application.rs:1141, application.zig:1717. Flatpak additionally replaces invalid bytes itself; a local GLib probe of Zig’s construction produced[Invalid UTF-8]for the whole invalid value instead. flatpak.rs:152, flatpak.zig:349
The inspected non-test stub markers matched upstream limitations or implementations elsewhere. The literal C/WASM export-name sweep found no unmatched names; that does not establish behavioral parity.
| Verdict count | Result |
|---|---|
| Nine RV7 rows resolved / partial | 7 / 2 |
| Z9 key-text / preedit limitations resolved | 2 / 2 |
| Remaining verified gap groups | 9 |
| Additional wholly unimplemented features verified | 0 |
| Literal C/WASM export names checked / unmatched | 159 / 0 |
| Selected existing-binary tests passed / failed | 121 / 0 |
Native verification remains separate: no macOS/Windows hardware execution, WASM host execution, or fresh rebuild was performed. The platform gaps above are source-verified; passing existing binaries cannot certify exhaustive parity across all of ghostty/src.