telemetry-facade-patternlisted
Install: claude install-skill wei18/apple-dev-skills
# Telemetry Facade Pattern
## When to invoke
- Starting a new project and designing the logger / tracker / metrics interface.
- About to introduce OSLog and any tracking / analytics at the same time.
- Wanting to preserve flexibility for "swap the tracking provider later".
- User asks "should Logger and Tracking be separate", "how should the event interface look".
## Default decisions
### A single `Telemetry` target
- Create one `Telemetry` target inside the SwiftPM Package.
- It contains:
- `TelemetryEvent` value type (enum / struct, `Sendable`)
- `TelemetrySink` protocol
- The main facade — default to a `Telemetry` **actor**. Sink stateful subscriptions (e.g. `MetricKitSink` holding `MXMetricManagerSubscriber` reference identity) require an actor for clean lifecycle management. A `Sendable` struct facade is acceptable only when every sink is fully synchronous and stateless. The facade fans out to multiple sinks.
- Default sinks (see below)
### Call sites describe only "what happened"
```swift
telemetry.observe(.puzzleCompleted(id: puzzleId, durationMs: 12_345))
```
- The call site **doesn't know** who will consume the event.
- Swapping providers / adding sinks only requires replacing a sink; call sites change nothing.
### Default sink set
| Sink | Receives | Purpose |
|---|---|---|
| `OSLogSink` | All events | Human-readable debug messages |
| `TrackingSink` (default `NoOpTrackingSink`) | Business events | v1 has no third-party tracking but the protocol is