As of v0.3.0 (c73dc6c).
Summary
The client render-request frame is decoded with hard-coded positional indices (fields[28], non_empty_string(&fields[11]), ...) in src/worker/protocol.rs, and the same field order is duplicated by hand in the zsh adapter as one long interpolated string (src/shell/init.zsh:148). expect_render_field_count additionally accepts both 28 and 29 fields to stay compatible with the pre-PATH layout.
The protocol is versioned and well tested (round-trip, torn frames, UTF-8 boundaries), so this is not a correctness bug today — but every new field requires manually keeping three places in sync (encode array, decode indices, zsh frame string), which is easy to get wrong silently.
Proposed fix
Options, roughly in order of increasing change:
- Field index constants/enum: define a single
enum RenderField { Generation = 1, Cwd = 2, ... Path = 28 } used by both encode_client_record and decode_client_record, with a unit test asserting the count matches expect_render_field_count. The zsh side stays positional but gains a documented table to sync against.
- Generated zsh frame: derive the zsh
frame= line (or at least a checked field-order comment in init.zsh) from the same table via zsh_init.rs, so Rust is the single source of truth.
- Key-value fields: switch to
key=value pairs and drop positional coupling entirely (bigger protocol bump).
Option 1 (+2 if cheap) seems like the right cost/benefit for now.
🤖 Generated with Claude Code — Claude Fable 5
As of v0.3.0 (c73dc6c).
Summary
The client render-request frame is decoded with hard-coded positional indices (
fields[28],non_empty_string(&fields[11]), ...) insrc/worker/protocol.rs, and the same field order is duplicated by hand in the zsh adapter as one long interpolated string (src/shell/init.zsh:148).expect_render_field_countadditionally accepts both 28 and 29 fields to stay compatible with the pre-PATHlayout.The protocol is versioned and well tested (round-trip, torn frames, UTF-8 boundaries), so this is not a correctness bug today — but every new field requires manually keeping three places in sync (encode array, decode indices, zsh frame string), which is easy to get wrong silently.
Proposed fix
Options, roughly in order of increasing change:
enum RenderField { Generation = 1, Cwd = 2, ... Path = 28 }used by bothencode_client_recordanddecode_client_record, with a unit test asserting the count matchesexpect_render_field_count. The zsh side stays positional but gains a documented table to sync against.frame=line (or at least a checked field-order comment ininit.zsh) from the same table viazsh_init.rs, so Rust is the single source of truth.key=valuepairs and drop positional coupling entirely (bigger protocol bump).Option 1 (+2 if cheap) seems like the right cost/benefit for now.
🤖 Generated with Claude Code — Claude Fable 5