# Per-Integration Gap Audit: `transmission` > Part of Milestone #2 — Contribution Strategy & Design Document. > Audit method, status legend, and effort sizing are defined in > [`docs/03-quality-scale-audit-rubric.md`](../03-quality-scale-audit-rubric.md). > All findings are a **point-in-time snapshot** from the Milestone #1 analysis and must be > re-verified against `home-assistant/core` `dev` immediately before implementation > (items needing re-verification are marked 🔍). ## 1. Snapshot | Field | Value | |---|---| | Domain | `transmission` | | Category | Downloader / BitTorrent client | | IoT class | `local_polling` | | Backing library | `transmission-rpc` (PyPI, actively maintained) | | Platforms | `sensor`, `switch` | | Custom services | `add_torrent`, `remove_torrent`, `start_torrent`, `stop_torrent` | | Declared `quality_scale` | none (unrated / legacy) | | Code owners | Listed in `CODEOWNERS` — confirm current owners before opening issues 🔍 | | Popularity band (M1 dataset) | High (top-150 by analytics installs among device/service integrations) | | Issue-volume band (M1 dataset) | Medium — recurring themes: session/auth errors after server restart, sensor unavailability, service call ergonomics | **Why selected:** strong install base, unrated quality scale, a credential-bearing local service (so reauth/diagnostics gaps are user-visible), and a contained surface area (two platforms + four services) that fits our PR sizing conventions. ## 2. Architecture summary The integration polls a Transmission daemon over its RPC API using `transmission-rpc`, with a `DataUpdateCoordinator` owning the client and refresh cycle. Sensors expose session/torrent statistics (download/upload speed, status, torrent counts); switches control turtle mode and start/stop-all. Services manipulate torrents by ID/URL and are registered at integration level. Authentication is username/password against the daemon's RPC endpoint. ## 3. Gap audit | # | Dimension | Status | Evidence / notes | |---|---|---|---| | D1 | Config flow completeness | 🟡 Partial | Config flow present with host/port/credentials and an options flow (scan interval, limits). No `reconfigure` step for host/port changes; no discovery (acceptable — daemon is not discoverable; mark N/A for discovery sub-item). Duplicate-entry prevention via host/port match — verify it uses a stable unique ID rather than data comparison 🔍 | | D2 | Reauth & credentials | 🟡 Partial 🔍 | A reauth flow has existed in some form; verify that (a) auth failures during *runtime* (not just setup) raise `ConfigEntryAuthFailed` from the coordinator, and (b) the reauth step covers username **and** password and aborts correctly on mismatched entry. M1 issue triage shows users still hitting "setup retry loop" after credential rotation, which suggests runtime auth errors are mapped to `ConfigEntryNotReady` somewhere. | | D3 | Runtime data & typing | 🟡 Partial | Coordinator stored via legacy `hass.data[DOMAIN]` pattern at snapshot time 🔍; migrate to `ConfigEntry.runtime_data` with a typed alias (`TransmissionConfigEntry`). Module not in `.strict-typing`; annotations mostly present but not strict-clean. | | D4 | Update strategy | ✅ Met | `DataUpdateCoordinator` in place; polling interval user-configurable through options. Confirm `PARALLEL_UPDATES` is set appropriately on entity platforms (0 for coordinator-driven read-only platforms) 🔍 | | D5 | Diagnostics & repairs | ❌ Gap | No `diagnostics.py`. High value here: session stats, daemon version, and coordinator state with credentials/host redacted. No repair issues; none obviously needed. | | D6 | Entity naming & device registry | 🟡 Partial 🔍 | Entities grouped under one device per entry. Verify `_attr_has_entity_name = True` plus `translation_key`-based names across both platforms; M1 sampling indicated sensor names still composed with the entry title prefix in at least one platform. | | D7 | Error handling & availability | 🟡 Partial | `ConfigEntryNotReady` raised on connect failure at setup. Gaps: exceptions raised from service handlers are not translation-backed (`HomeAssistantError` with raw strings); torrent-not-found in `remove_torrent`/`start_torrent` should raise `ServiceValidationError` with a translation key. | | D8 | Test coverage | 🟡 Partial | Config-flow tests exist (including error paths). Platform coverage thin: no snapshot tests for sensors/switches, no service-call tests, no coordinator failure-path tests (auth-failed → reauth started). | | D9 | Documentation & strings | 🟡 Partial | `strings.json` lacks `data_description` for config/option fields; service descriptions exist in `services.yaml` but field descriptions should be re-checked against current schema 🔍. Docs page (`home-assistant.io`) lacks a troubleshooting section for auth/session errors — the single most common issue theme. | | D10 | Quality-scale declaration | ❌ Gap | No `quality_scale` in manifest, no `quality_scale.yaml`. After Bronze items land, declare Bronze and file the checklist with honest `todo`/`exempt` entries. | ## 4. Detailed findings ### D2 — Reauth (highest-impact gap) M1 issue clustering shows the dominant user pain is the daemon restarting with rotated or newly enabled credentials, after which the entry loops in setup-retry instead of prompting reauth. The fix is to map `transmission-rpc` authentication errors (`TransmissionAuthError` or equivalent — confirm exact exception class against the pinned library version 🔍) to `ConfigEntryAuthFailed` inside `_async_update_data`, and ensure the reauth flow pre-fills username and re-validates before `async_update_reload_and_abort`. ### D5 — Diagnostics Proposed payload: redacted entry data/options (`CONF_HOST`, `CONF_USERNAME`, `CONF_PASSWORD` via `async_redact_data`), daemon RPC version, session statistics dict, torrent count by status (not torrent names — they can be sensitive), and last coordinator success/exception. This directly shortens the triage loop on the medium-volume issue tracker. ### D8 — Tests Target: 100% of `config_flow.py` (Bronze requirement), snapshot tests for all entities using a fixture-driven mock of `transmission-rpc`, service tests covering success + `ServiceValidationError` paths, and a coordinator test asserting reauth flow creation on auth failure. ## 5. Work items | ID | Title | Dimensions | Effort | Depends on | |---|---|---|---|---| | TRA-01 | Migrate to `ConfigEntry.runtime_data` with typed entry alias | D3 | S | — | | TRA-02 | Runtime auth-failure → `ConfigEntryAuthFailed`; harden reauth flow + tests | D2, D8 | M | TRA-01 | | TRA-03 | Add `diagnostics.py` with redaction + tests | D5 | S | TRA-01 | | TRA-04 | `has_entity_name` / `translation_key` migration for sensors & switches (with registry-safe naming, no unique_id changes) | D6 | M | — | | TRA-05 | Translation-backed exceptions in services; `ServiceValidationError` for user errors | D7, D9 | S | — | | TRA-06 | Snapshot tests for sensor/switch platforms + service tests | D8 | M | TRA-04 | | TRA-07 | `data_description` strings; docs troubleshooting section (separate `home-assistant.io` PR) | D9 | S | — | | TRA-08 | Declare `quality_scale: bronze` + `quality_scale.yaml` checklist | D10 | S | TRA-02, TRA-03, TRA-06 | Target tier after this program: **Bronze declared, Silver-track** (Silver requires the reauth + parallel-updates + entity-unavailable items, all covered above; remaining Silver gate is doc completeness, tracked in TRA-07). ## 6. Risks & coordination notes - Service schemas are user-visible automation surface — no breaking changes to service fields; only additive validation and error-message improvements. - Entity-naming migration must not alter unique IDs or entity IDs of existing installs; follow the friendly-name-only migration pattern and call it out explicitly in the PR description for the code owners. - `transmission-rpc` major-version behavior (exception class names, session field names) must be confirmed against the version pinned in `manifest.json` at implementation time 🔍.