- LiveDSAskClient: S3-owned concrete DSAskClient (GET /search/ask -> decode AIFabric.AskResponse),
the piece S2's plan assigned to S3 for the real RemoteDSProvider
- AppAIComposition.realRouter(): makeDefaultRouter(client: LiveDSAskClient) — the one-call swap from
mock to the real S2 fabric; app default stays mockRouter (offline scaffold)
- DSError.from made public (used cross-module by the bridge)
swift build + swift test green (71). Sources/AI untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>