Files
james.maes 6ea2852af1 feat(devoverlay,logging): live log stream — every swift-log line into the overlay
Slice 3 of dev-overlay-end-to-end. Adds a fourth DevOverlay tab that
tails every log record from every Jarvis subsystem in real time —
agent, voice, vision, memory, MCP, bus, replay, system — without
polling files or relying on Console.app.

How it works:

1. `LogBroadcaster` (new) — process-wide actor with a 500-line ring
   buffer + subscriber set. Borrowed shape from
   OrchestratorEventBroadcaster so the project's three broadcasters
   share a mental model. New subscribers replay the buffer in order,
   then go live.

2. `BroadcastLogHandler` (new) — swift-log LogHandler conformance.
   Formats each log call into a `LogLine` and schedules an unstructured
   `Task { await LogBroadcaster.shared.publish(...) }` so the logging
   caller never blocks on actor isolation. Synchronous handler contract
   preserved; ordering is best-effort under heavy load.

3. `LoggingBootstrap.make(label:)` now returns
   `MultiplexLogHandler([file, os, broadcast])` — the new handler is
   purely additive. File rotation + os.Logger streaming unchanged.

4. `DevOverlayLogsView` (new) — fourth tab in the overlay. Subscribes
   to `LogBroadcaster.shared` on appear, caps at 1000 lines, renders
   monospaced. Per-channel filter (Menu w/ checkboxes), per-level
   filter (debug → critical), substring search, Pause/Resume button
   (Cmd+P), auto-scroll-to-bottom while not paused. Color-coded by
   level (warn=orange, error/critical=red).

Tests:
- 5 new LogBroadcasterTests covering publish/cap/replay/live/handler.
- swift test --package-path packages/Logging → 22/22 pass.
- swift test --package-path packages/DevOverlay → 14/14 pass.
- bash scripts/check-app-builds.sh → PASS.
- 18/18 boundary gates green.

Redaction note: file handler still routes through Redact.apply for
disk writes; the broadcaster sees raw messages because the DevOverlay
is a developer-only in-process surface. If this ever becomes
user-facing, route through Redact before publishing.
2026-05-12 14:27:57 -05:00
..

Logging

Library product JarvisLogging. Channel taxonomy + swift-log bootstrap + file rotation + the Redact helper.

Key public types

Type Purpose
JarvisLogChannel Channel enum — agent, tools, ui, system, plus subsystem-specific
LoggingBootstrap Wires swift-log to OSLogHandler (default) + FileLogHandler (rotation)
OSLogHandler os_log backend
FileLogHandler NDJSON rotating file backend
FileRotatingWriter Size + time-based rotation
Redact Mask helper for secrets in logger.debug strings
LogPaths ~/Library/Application Support/Jarvis/logs/ resolver
DateProvider Test seam for deterministic timestamps

Depends on

External only: swift-log.

Used by

Every package and App/. This is the leaf logging dependency for the whole project.

Key invariants / contracts

  • Bootstrap is idempotent. Calling LoggingBootstrap.bootstrap() twice is a no-op.
  • Channels match the taxonomy in CLAUDE.md. Don't invent ad-hoc subsystems — extend the enum.
  • Redact is the only sanitizer for log strings that may contain secrets / PII / transcript text.
  • T-06-05-03: never log voice transcript text. Enforced by code review + reading every Voice/Memory logger.debug site.
  • File rotation: size cap + age cap. Old logs get rolled to .gz siblings, then pruned.

Tests

XCTest. Round-trip log emission, rotation triggers, redact patterns.

Notable files

  • Sources/JarvisLogging/JarvisLogChannel.swift — channel enum
  • Sources/JarvisLogging/LoggingBootstrap.swift — entry point
  • Sources/JarvisLogging/Redact.swift — sanitizer
  • Sources/JarvisLogging/FileRotatingWriter.swift — rotation