fix(ui): filter system event messages from chat transcript (#68508)#68518
fix(ui): filter system event messages from chat transcript (#68508)#68518kagura-agent wants to merge 1 commit into
Conversation
…68508) System event messages (cron/exec completion notifications with 'System:' and 'System (untrusted):' prefixes) are internal agent-only signals that were leaking into the visible WebChat/Control UI transcript. Filter them out in shouldHideHistoryMessage so they remain available to the agent but invisible to users. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Greptile SummaryThis PR filters system event messages (lines starting with Confidence Score: 5/5Safe to merge; the one finding is a P2 style suggestion about regex specificity. The logic is correct, tests cover both the filtering and the mixed-content preservation cases, and the change is scoped to the UI rendering layer with no data loss. The only open concern is a broad prefix match that could theoretically hide unusual user messages — a P2 improvement, not a blocker. ui/src/ui/controllers/chat.ts — regex specificity on line 19 Prompt To Fix All With AIThis is a comment left during a code review.
Path: ui/src/ui/controllers/chat.ts
Line: 19
Comment:
**Broad prefix risks filtering real user messages**
`SYSTEM_EVENT_LINE_RE` matches any line that starts with `System: ` or `System (untrusted): `, regardless of what follows. A user who types something like `System: can you reboot the server?` would have their message silently hidden from the chat transcript (it still reaches the agent, but they wouldn't see it on reload). The actual runtime-injected events appear to include a bracketed timestamp (e.g. `System: [2026-04-18 10:00:00] Exec completed`). Tightening the pattern to require that structure would eliminate false positives without breaking the intended filtering:
```suggestion
const SYSTEM_EVENT_LINE_RE = /^System(?:\s*\(untrusted\))?:\s*\[\d{4}-\d{2}-\d{2}/;
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(ui): filter system event messages fr..." | Re-trigger Greptile |
| * (e.g. "System: [timestamp] Exec completed", "System (untrusted): ..."). | ||
| * These are agent-only signals and should not be visible in the chat transcript. | ||
| */ | ||
| const SYSTEM_EVENT_LINE_RE = /^System(?:\s*\(untrusted\))?:\s/; |
There was a problem hiding this comment.
Broad prefix risks filtering real user messages
SYSTEM_EVENT_LINE_RE matches any line that starts with System: or System (untrusted): , regardless of what follows. A user who types something like System: can you reboot the server? would have their message silently hidden from the chat transcript (it still reaches the agent, but they wouldn't see it on reload). The actual runtime-injected events appear to include a bracketed timestamp (e.g. System: [2026-04-18 10:00:00] Exec completed). Tightening the pattern to require that structure would eliminate false positives without breaking the intended filtering:
| const SYSTEM_EVENT_LINE_RE = /^System(?:\s*\(untrusted\))?:\s/; | |
| const SYSTEM_EVENT_LINE_RE = /^System(?:\s*\(untrusted\))?:\s*\[\d{4}-\d{2}-\d{2}/; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/ui/controllers/chat.ts
Line: 19
Comment:
**Broad prefix risks filtering real user messages**
`SYSTEM_EVENT_LINE_RE` matches any line that starts with `System: ` or `System (untrusted): `, regardless of what follows. A user who types something like `System: can you reboot the server?` would have their message silently hidden from the chat transcript (it still reaches the agent, but they wouldn't see it on reload). The actual runtime-injected events appear to include a bracketed timestamp (e.g. `System: [2026-04-18 10:00:00] Exec completed`). Tightening the pattern to require that structure would eliminate false positives without breaking the intended filtering:
```suggestion
const SYSTEM_EVENT_LINE_RE = /^System(?:\s*\(untrusted\))?:\s*\[\d{4}-\d{2}-\d{2}/;
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cec811c843
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| * (e.g. "System: [timestamp] Exec completed", "System (untrusted): ..."). | ||
| * These are agent-only signals and should not be visible in the chat transcript. | ||
| */ | ||
| const SYSTEM_EVENT_LINE_RE = /^System(?:\s*\(untrusted\))?:\s/; |
There was a problem hiding this comment.
Narrow system-event matcher before dropping user history messages
The new SYSTEM_EVENT_LINE_RE/isSystemEventOnlyMessage logic hides any user message whose lines all start with System: or System (untrusted):, which can suppress legitimate user text, not just injected runtime events. This is especially likely because inbound normalization rewrites user-authored System: line prefixes to System (untrusted): (src/auto-reply/reply/inbound-text.ts:9-17), so a normal message like System: reboot failed after update would disappear from chat history. Please constrain the filter to the actual internal event shape (for example, the timestamped event format) or a dedicated marker so real user content remains visible.
Useful? React with 👍 / 👎.
|
Related work from PRtags group Title: Open PR duplicate: Control UI async exec/system transcript leak
|
|
Closing this as duplicate or superseded after Codex automated review. PR #68518 should close as superseded. Current main already prevents new async exec/system-event prompts from being persisted as visible chat-history user rows, and the broader UI-side legacy leaked-row guard is already tracked by related open PR #67036. This PR's narrower UI-only prefix filter also had review feedback that it could hide legitimate user-authored Best possible solution: Close #68518 as superseded. Keep the current main source-level runtime/transcript separation for new async exec leaks, and use #67036 as the canonical place for any remaining legacy transcript/render hardening with a narrow matcher that avoids hiding legitimate user messages. What I checked:
So I’m closing this here and keeping the remaining discussion on the canonical linked item. Codex Review notes: model gpt-5.5, reasoning high; reviewed against c7a0d9b1889c. |
Summary
Fixes #68508 — System event messages (async exec completion notifications with
System:andSystem (untrusted):prefixes) were leaking into the visible WebChat/Control UI chat transcript. These are internal agent-only signals and should not be shown to users.Changes
ui/src/ui/controllers/chat.ts: UpdatedshouldHideHistoryMessageto filter out system event messages (matchingSystem:andSystem (untrusted):prefixes) from the rendered chat historyui/src/ui/controllers/chat.test.ts: Added tests verifying system event messages are hidden while normal messages remain visibleHow it works
Messages are filtered at the UI rendering layer only — they remain in the underlying message history so the agent can still access them, but they are excluded from what users see in WebChat/Control UI.