fix(privacy): stop persisting dictated content to the disk log - #403
fix(privacy): stop persisting dictated content to the disk log#403postoso wants to merge 2 commits into
Conversation
DebugLogger.log() writes every line to a persistent plaintext file (~/Library/Logs/Fluid/Fluid.log) unconditionally: FileLogger.append runs before the `guard loggingEnabled` check, so the EnableDebugLogs toggle only gates the in-memory UI panel, not the disk file. As a result, multiple log call sites persisted the user's dictated transcript, spoken prompts/instructions, selected text, and the AI-processed result to disk in plaintext on release builds. Redact user content at every leak site, logging metadata (lengths, byte counts, model/provider names, status, response field names) instead of the content itself, while keeping diagnostics useful: - LLMClient: redact the cURL request body, the request-body debug log, the full streaming delta (now logs field names only), the streamed content chunk, and the non-streaming HTTP-error body. - LLMClient: LLMError.httpError.errorDescription no longer embeds the raw provider error body, which callers persist via error.localizedDescription; expose status code and body size only. - AIProvider / FunctionCallingProvider: redact request body, response body, error bodies, and tool-call arguments. - ASRService: redact the final transcript, post-processed transcript, streaming partial, and boosted-term logs. - AppleSpeechAnalyzerProvider / AppleSpeechProvider: redact recognized-speech logs. - ContentView / RewriteModeService: the prompt-trace sinks (logDictationPromptTrace, logPromptTrace) persist only a redacted metadata line; the full trace remains available on the console behind the explicit FLUID_PROMPT_TRACE=1 env var. - TypingService: drop the typed-text content previews; the adjacent length logs are retained.
c89b16d to
5a9753f
Compare
Greptile SummaryThis PR prevents dictated, selected, prompted, and AI-generated content from being persisted in the plaintext diagnostic log while retaining metadata useful for debugging.
|
|
Closing this out. On reflection the scattered shape here isn't something a narrower version fixes: the content gets interpolated at ~20 call sites, so any correct fix touches at least as many files as this PR, and the version with a real regression test comes out larger. Rather than leave a stale diff adding to the queue, I'm withdrawing. Happy to revisit if logging privacy gets picked up on the roadmap. |
DebugLoggerpersists every log line to~/Library/Logs/Fluid/Fluid.logunconditionally:FileLogger.appendruns before theloggingEnabledguard, so the "Enable debug logs" toggle only gates the in-memory UI panel, not the disk file. As a result, on release builds the dictated transcript, spoken prompts/instructions, selected text, and LLM request/response bodies were written to that log in plaintext. The dictation prompt-trace path was also on by default, so it logged the transcript + prompt + AI answer on every AI-enhanced dictation.This redacts user content to metadata only (lengths, byte counts, model/provider names, status, response field names) at every affected site, keeping diagnostics useful. Full prompt traces are still available on the console behind
FLUID_PROMPT_TRACE=1, but are never persisted to disk.Scope
28 logging sites across 9 files (
LLMClient,AIProvider,FunctionCallingProvider,ASRService, the two Apple speech providers,ContentView,RewriteModeService,TypingService). IncludesLLMError.httpError's description, which embedded the raw provider error body and escaped to the log via downstreamerror.localizedDescriptioncalls.Testing