Skip to content

docs(rfd): Add RFD 096 for terminal output sanitization - #856

Merged
JeanMertz merged 3 commits into
mainfrom
terminal-output-sanitization
Jul 8, 2026
Merged

docs(rfd): Add RFD 096 for terminal output sanitization#856
JeanMertz merged 3 commits into
mainfrom
terminal-output-sanitization

Conversation

@JeanMertz

Copy link
Copy Markdown
Collaborator

Propose sanitizing untrusted content (echoed user messages, streamed LLM output, tool results) before it reaches the terminal. Currently, raw escape sequences in that content execute on the user's terminal instead of being displayed, as happened when a pasted script log corrupted a user's display and, since messages are stored verbatim, recurred on every replay.

The design allowlists benign SGR styling (colors, bold) while dropping cursor, erase, scroll, DEC-mode, and OSC sequences from content, via a new jp_term::sanitize::Sanitizer built on the same vte::Parser foundation as the existing AnsiStripper. A style.sanitize config knob (strip/visualize/off) controls the behavior, defaulting to strip. OSC embedding (window titles, hyperlinks) is hardened independently by escaping control characters in spliced strings, since conversation titles are LLM-generated and can otherwise terminate an OSC sequence early.

Stored conversation data and LLM input remain untouched; this is a display-only concern scoped to the render pipeline.

Propose sanitizing untrusted content (echoed user messages, streamed
LLM output, tool results) before it reaches the terminal. Currently,
raw escape sequences in that content execute on the user's terminal
instead of being displayed, as happened when a pasted `script` log
corrupted a user's display and, since messages are stored verbatim,
recurred on every replay.

The design allowlists benign SGR styling (colors, bold) while
dropping cursor, erase, scroll, DEC-mode, and OSC sequences from
content, via a new `jp_term::sanitize::Sanitizer` built on the same
`vte::Parser` foundation as the existing `AnsiStripper`. A
`style.sanitize` config knob (`strip`/`visualize`/`off`) controls the
behavior, defaulting to `strip`. OSC embedding (window titles,
hyperlinks) is hardened independently by escaping control characters
in spliced strings, since conversation titles are LLM-generated and
can otherwise terminate an OSC sequence early.

Stored conversation data and LLM input remain untouched; this is a
display-only concern scoped to the render pipeline.

Signed-off-by: Jean Mertz <git@jeanmertz.com>
@JeanMertz
JeanMertz force-pushed the terminal-output-sanitization branch from dc32b2b to 7831efa Compare July 8, 2026 13:50
JeanMertz added 2 commits July 8, 2026 15:52
Signed-off-by: Jean Mertz <git@jeanmertz.com>
Signed-off-by: Jean Mertz <git@jeanmertz.com>
@JeanMertz
JeanMertz merged commit 0c2cbd8 into main Jul 8, 2026
15 checks passed
@JeanMertz
JeanMertz deleted the terminal-output-sanitization branch July 8, 2026 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant