fix: route interactive diagnostics away from TUI output - #1185
Merged
SamSaffron merged 3 commits intoSep 27, 2026
Merged
Conversation
sam-saffron-jarvis
marked this pull request as ready for review
September 27, 2026 16:50
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to merged #1183: keep application diagnostics off renderer-owned stdout/stderr in chat and the interactive skills, MCP, sessions and theme views. The scoped
runtimeoutputsink writes application diagnostics to restricted$XDG_DATA_HOME/term-llm/diagnostics/tui.log(or the usual home data fallback); actionable session warnings still use the chat footer. It does not replace global descriptors or default loggers, and ordinary CLI, service, renderer, explicit terminal hand-off and auth-login output remain unchanged.Additional follow-up at
894ac0bcaddresses the completedclaude-bin:opus-highreview (verdict REQUEST CHANGES):runtimeoutput.Error/Infowith their original severity and fields. A scoped Go AST guard detects future directslog,log.Print*, stdout/stderr writes in interactive worker packages and selected chat-reachable command files; named exceptions are documented for guarded authentication, CLI-only output, and unrecoverable forced exit. It intentionally does not flag source string fixtures or renderer/auth output wholesale.term-llm auth login grok; missing and expired credential paths have regression coverage.runtimeoutput.Printfwrites raw formatted bytes rather than slog-escaped messages. Debug sections and analogous provider CLI/request blocks now write atomically, preserving readable multiline output. User-facing debugging docs distinguish this file from sessiondebug-logJSONL and warn that raw requests/tool results can contain sensitive data; existing debug flags still gate that output. No automatic rotation/retention is introduced; inspect and rotate/delete the file as needed. No new size/time thresholds or flags were added.chat --auto-sendwith redirected stdin; reload/terminal-host gating remains separate.skills validate --allincludes malformed discovered manifests while keeping first-valid precedence (a shadowed invalid duplicate does not replace a valid skill). During explicit handover/reload there is no active UI, so ordinary stderr is expected. A same-user attacker who can replace the diagnostic file betweenLstatandOpenFileremains an accepted TOCTOU boundary for now; the directory is private (0700) in the normal case. No platform-specific no-follow implementation or descriptor-wide redirect was introduced.Verification
At follow-up head
894ac0bc:make build,go build ./...,go vet ./...,make complexity,git diff --check: passed.go test ./...using temporary HOME/XDG and preserved GOMODCACHE: passed after follow-up changes.go test -race ./internal/runtimeoutput ./internal/llm ./internal/termhost ./cmd -run 'Test(InteractiveWorkersDoNotBypassDiagnosticSink|InteractiveDiagnosticsOpenFailureWarnsBeforeUIAndDiscards|ChildProgressStaysOutOfFooter|GrokPreflightCannotPromptInsideTUI|AuthPromptsRefuseActiveTUI|DebugSectionsRemainRawAndAtomicInInteractiveDiagnostics|BestEffortDiscardOnOpenFailure|RawDebugBlocksAndStructuredLevels|OldDiscardCloserCannotReleaseNewUI|LifecycleDiagnosticUsesActiveSinkInsteadOfTerminal|LifecycleDebugReportsSafeRateLimitedErrorClasses|ChatSessionWarningsAcrossSwitchDetachAndClose|ChatOutputOwnershipIndependentOfInput)' -count=5: passed. A lifecycle test's close-vs-second-state race was observed in one full suite run; the test now accepts the extra safe cancellation class on shutdown, and isolated full suite plus focused repeated/race tests pass.cmdrun failed tests depending on the host's extra skills; isolated HOME/XDG passed. Prior PR verification included a real PTYconfig themerun and CLI validation of valid/invalid skill manifests; no new PTY test was run for this follow-up.Review status
Ready for review. The completed
claude-bin:opus-highreview requested changes; the follow-up addresses B1–B3 and M1–M3 with the explicit accepted limits above. Parent integration checks verified the routing/auth/startup changes, clean worktree, matching PR head, passing six CI checks and mergeability. There was no second model review or fresh Opus sign-off on the fix commit; do not interpret addressed findings as an Opus approval. No deployment performed.