As of v0.3.0 (c73dc6c).
Summary
Segment text is sanitized (strip_control_chars in SegmentContent::new / SegmentPart::new, src/segments/mod.rs:121,150), and duration.prefix / loading placeholders flow through those constructors — but layout.separator does not. lower_side (src/render/mod.rs:192) only applies % escaping to the separator before joining it into the prompt string.
A config containing
[layout]
separator = "�" # or any string containing \x1e / \x00
injects the protocol's RECORD_SEPARATOR / FIELD_SEPARATOR bytes into the WorkerRecord::Prompt payload, tearing frames on the zsh side: fields shift, the generation check misparses, and the session degrades to the fallback prompt with no diagnostic pointing at the config.
Proposed fix
Two complementary layers:
- Sanitize at the render boundary: strip control characters from the separator in
lower_side (or when reading LayoutConfig::separator()), matching the existing segment-text policy.
- Warn at check time: emit a
ConfigWarning for control characters in layout.separator (and any future free-string config values that reach the prompt output) so nova check explains the problem instead of the prompt silently breaking.
Self-inflicted configuration, but the failure mode (silent fallback prompt) is disproportionate to the mistake, and the fix closes the last unsanitized path from config to protocol output.
🤖 Generated with Claude Code — Claude Fable 5
As of v0.3.0 (c73dc6c).
Summary
Segment text is sanitized (
strip_control_charsinSegmentContent::new/SegmentPart::new, src/segments/mod.rs:121,150), andduration.prefix/loadingplaceholders flow through those constructors — butlayout.separatordoes not.lower_side(src/render/mod.rs:192) only applies%escaping to the separator before joining it into the prompt string.A config containing
injects the protocol's RECORD_SEPARATOR / FIELD_SEPARATOR bytes into the
WorkerRecord::Promptpayload, tearing frames on the zsh side: fields shift, the generation check misparses, and the session degrades to the fallback prompt with no diagnostic pointing at the config.Proposed fix
Two complementary layers:
lower_side(or when readingLayoutConfig::separator()), matching the existing segment-text policy.ConfigWarningfor control characters inlayout.separator(and any future free-string config values that reach the prompt output) sonova checkexplains the problem instead of the prompt silently breaking.Self-inflicted configuration, but the failure mode (silent fallback prompt) is disproportionate to the mistake, and the fix closes the last unsanitized path from config to protocol output.
🤖 Generated with Claude Code — Claude Fable 5