Phase 1 REVIEW.md IN-02: `OSLogHandler.log` interpolated message text
as `\(message, privacy: .public)`. That override defeats os.Logger's
default `%{private}@` masking for interpolated values — a caller who
logs `logger.info("saving key \(userInput)")` produces a redacted line
in the file log (via `Redact.apply` in `FileLogHandler`) but a
plaintext line in `os.Logger`. The docstring already flagged the
discipline risk; the cure (caller redacts first) is on the honor
system with no enforcement.
packages/Logging/Sources/JarvisLogging/OSLogHandler.swift
- Drop the `.public` override. Interpolate as
`\(message, privacy: .private(mask: .hash))` so untrusted interpolated
values are hashed in Console.app captures by default.
- Keep `osLevel` via the `logger.log(level:)` API so severity signal
is preserved in Console.app filters (level isn't embedded in the
message body).
All 14 logging tests still pass — there's no explicit capture of the
os.Logger stream in-test, so the privacy override change is behaviour-
compatible at the test layer. Observable in Console.app only.
- JarvisLogChannel: four cases (agent, tools, ui, system)
- JarvisLogHandlerFactory.bootstrap wires MultiplexLogHandler that
fans out to FileLogHandler + OSLogHandler (D-17)
- FileLogHandler applies Redact.apply once (S-4 single call site)
- OSLogHandler does NOT redact (os.Logger handles %{private}@ at
system layer; callers redact untrusted input before logging)
- Redact covers exactly 5 patterns: sk-ant-, Authorization:Bearer,
sk- (OpenAI), AKIA, ghp_ (D-20, OBS-06); Anthropic branch ordered
before OpenAI so sk-ant- consumes the full prefix
- FileRotatingWriter: lazy midnight rotation via TestDateProvider-
injectable DateProvider; serial DispatchQueue; retain-7 GC on
rotate (D-18)
- LogPaths.channelDirectory = ~/Library/Logs/Jarvis/
- Swift 6 strict: ISO8601DateFormatter.jarvisShared uses
nonisolated(unsafe) since the formatter is documented thread-safe
after configuration but not Sendable-annotated by Apple
- OSLogHandler uses fully-qualified Logging.Logger to disambiguate
from os.Logger (both imported)
- Tests: 13/13 pass (7 Redact + 2 FileLogHandler rotate/retain +
4 bootstrap/factory/channels)
- Deletes Plan 01 placeholders
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>