# Bazarr Homarr slice: source checks, not live acceptance Issue: [#272](https://github.com/ajnart/selfhost-skills/issues/272). Reference base: `573a206e`, [#309](https://github.com/ajnart/selfhost-skills/pull/309). The shared [Homarr Link contract](homarr-integration-contract.md) applies. ## Stage 1: historical descriptor-only source phase The record below describes corrected source `b28da7a09d19dbab3b47d61d562c20f7990e3fb9` against the original reference base. Its pending registration/reference statements and test gate are historical; the frozen-reference normalization record follows the official sources. ## Credentials and own Setup The Catalog pins `lscr.io/linuxserver/bazarr:version-v1.6.0`. Bazarr v1.6.0 generates one unscoped API key, not separate read-only integration keys. Setup preserves Basic authentication and discovers `auth.apikey` through the existing App-local `h.ConfigValue` helper. It registers the discovered value for redaction before any API request and stores it as `BAZARR_API_KEY` through `h.SetSecret` only after verifying `/api/system/status` and `/api/badges`. API authentication uses the `X-API-KEY` header, never a query argument. Every credential step Check and App Check probes both endpoints afresh. A valid saved key is reused without rereading configuration or rewriting any setting. A missing key or a key rejected with 401/403 is rediscovered from the same App-local helper. Other failures do not replace a saved credential. Recovery: run `self-host setup bazarr`, then `self-host setup homarr`. If recovery fails, inspect Bazarr's Status and Settings > General > Security; do not disable authentication or paste a key into agent messages. The existing Admin login and media mount are unchanged. This slice does not configure Sonarr/Radarr, language profiles, path mappings or subtitle providers. Provider account choices remain manual; no external account is created and no subtitle is downloaded. The checked reference base has no Bazarr-owned Links; none is removed or replaced here. ## Descriptor and native data `internal/apps/homarr/target_bazarr.go` defines `bazarrTarget() target`. Only the #262 registry owner should add `bazarrTarget()` to `targets.go`. Until registration, the compiled Homarr App does not schedule this new Link. This lane changes neither the registry nor shared reconciliation. Homarr v2.4.1 source `ebbd4876d25a51151444a009ab596e1154d62880` defines: - Integration kind `bazarr`, credential alternative `apiKey`, internal Address `http://bazarr:6767`; the browser Address remains independent. - Native widget `bazarr`, showing missing episode and movie subtitles, provider issues and health issues with all four documented visibility options enabled. - Shared Stats keys `episodes`, `movies`, `providers`. These are missing subtitle counts and throttled-provider issues, not library size or configured provider counts. Ownership and stable entry IDs come from the reference seam. - Native query `widget.bazarr.getBadges` with Homarr's returned `integrationId`. Link verification validates all five nonnegative integer badge counts and both SignalR string fields after validating the peer's live API credential. Zero counts and `DOWN` SignalR status are legitimate when media peers are absent or the inventory is empty; neither is an authentication failure. Missing/null fields, rejected credentials, malformed data and unsuccessful native queries are failures, not an empty library or tile-only success. ## Verification and remaining gate Remaining focused coverage is exactly the two baseline Bazarr App tests: `TestSetupThenCheckThenRerunSkips` and `TestFailingStepHintNamesTheSetupCommand`. The first checks successful Setup and Check, saved API credentials, valid zero-count responses and rerun preservation without authentication updates, with configuration still present. Missing-config or configuration-reread avoidance is not test coverage. Its maintained fixture serves `/`, `/api/system/settings`, `/api/system/status` and `/api/badges`. The second covers a failed settings update and its Settings hint. Credential-change, malformed-data rejection and Homarr descriptor/count-guard behavior remain source/schema/compile-only pending native proof, not final-HEAD test coverage. The entirely agent-added 135-line `target_bazarr_test.go` and the added functions `TestAPIReadinessRejectsMissingFieldsAndAuthenticationErrors` (all seven table cases) and `TestSetupRecoversExternallyChangedKeyAndCheckProbesAfresh` were removed with explicit parent authorization, along with their exclusive fixture controls. The earlier parent-authored delegation request was not an actual human explicit unit-test request. No baseline function or implementation was removed and no replacement tests were added. Added named test/helper function count against fixed base `573a206e2b4a76574fd7e8cbd1f21c5a4c2fd37d` is zero. The final post-correction local gate passed on only the remaining test tree: `GOFLAGS=-buildvcs=false`, empty `gofmt -l .`, `go build ./...`, `go vet ./...`, `go vet -tags e2e ./e2e/`, `go test ./...`, race tests for TUI, Activity, Bazarr and Homarr, `bash -n install.sh` and `git diff --check`. Focused/full/race tests ran with `-count=1`; none of the removed tests was part of this gate. No e2e-tagged runtime tests were run. Live proof is blocked by reference acceptance and parent-controlled capacity. No Docker, browser, installer, person's Project, protected secret file or browser profile was accessed during this lane. Before readiness, register the descriptor and explicitly authorize a disposable isolated Project, record resolved Homarr and Bazarr image digests, and verify real badge/Stats rendering, both install orders, late installation, restart, changed credentials and owned-only removal/reinstall. Keep the PR draft and the issue open until those conditions are met. ## Official sources - [Homarr Bazarr guide](https://homarr.dev/docs/integrations/bazarr/) - [Homarr Bazarr authentication and native reads](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/integrations/src/bazarr/bazarr-integration.ts) - [Homarr badge and status schemas](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/integrations/src/bazarr/bazarr-types.ts) - [Homarr native widget options](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/widgets/src/bazarr/index.ts) - [Homarr native badge query](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/api/src/router/widgets/bazarr.ts) - [Homarr Stats keys](https://github.com/homarr-labs/homarr/blob/ebbd4876d25a51151444a009ab596e1154d62880/packages/integrations/src/stats/existing.ts) - [Bazarr v1.6.0 key generation](https://github.com/morpheus65535/bazarr/blob/v1.6.0/bazarr/app/config.py) - [Bazarr v1.6.0 authentication](https://github.com/morpheus65535/bazarr/blob/v1.6.0/bazarr/api/utils.py) - [Bazarr v1.6.0 status](https://github.com/morpheus65535/bazarr/blob/v1.6.0/bazarr/api/system/status.py) - [Bazarr v1.6.0 subtitle badge counts](https://github.com/morpheus65535/bazarr/blob/v1.6.0/bazarr/api/badges/badges.py) Context7 discovery was attempted but its quota was exhausted. The selected contracts were verified directly against official tagged source instead. ## Stage 2: frozen-reference normalization, source only Normalized source pin: `ee5de2c1939965789649ddf3541441306444d740`. The subsequent source-check documentation commit changes no production or tests. Reference #309 is merged and #262 closed. This phase merges frozen main `6b82c55fb890c11a1388bd4e5a2f10b632ff4f7c` normally into the existing Bazarr branch at merge `e0bb36bde7a101295bc9280c3fbfcf9379601fff`, preserving corrected `b28da7a09d19dbab3b47d61d562c20f7990e3fb9`. No merge conflicts occurred. The frozen tree equals final reference evidence commit `33e7fbccb7541d2bbf1d81968eb21c35a1b5bfd7`; its tested reference production was `89301aff17c86b767f5a45076881f2bb7b41db39`. That Immich proof is not Bazarr proof. The current [peer workflow](https://github.com/ajnart/selfhost-skills/blob/main/docs/agents/homarr-integrations.md) governs later phases. The sole registry custodian adds exactly one `bazarrTarget()` call to `targets.go`, retaining `existingTargets()` and `immichTarget()` unchanged. The leaf uses the existing `target` contract. Its new preflight delegates to the already exported, read-only `bazarr.VerifyHomarr(ctx, to)`: each invocation reads the saved key, registers it for redaction and freshly probes authenticated `/api/system/status` and `/api/badges` through existing HTTP helpers. Common `linked` and `add` invoke it before compatibility checks or Homarr credential creation/update. It does not call credential Setup, read configuration, store keys, change authentication or require the Admin login/UI. This API-readiness check does not establish whole Setup, Sonarr/Radarr readiness or provider access. Missing/rejected keys retain the Bazarr-then-Homarr Setup recovery instructions. The integration Address stays `http://bazarr:6767`: the actual adapter appends `/api/system/status` and `/api/badges`, so storing an `/api` suffix would duplicate it. The browser Address remains separately resolved by the frozen common flow. Authenticated Homarr API version `2.4.1`, kind `bazarr` and exact `apiKey` credential compatibility remain centrally enforced. No empty credential or unauthenticated fallback is introduced. The unchanged leaf validates authenticated `widget.bazarr.getBadges` data and its five nonnegative integer counts and two SignalR strings. Central `verifyData` still runs after the leaf, forces Stats refresh and requires an advancing positive `updatedAt`, `error: false`, `stale: false` and non-null `episodes`, `movies`, `providers`. Their missing-subtitle/throttling meanings remain unchanged. Removal/absence never invokes preflight or native data reads. Shared reconciliation, ownership, legacy registrations and images are untouched. Cached Git source comparison confirms these nine Bazarr-scoped files are identical at research baseline `ebbd4876d25a51151444a009ab596e1154d62880` and recorded reference OCI revision `3d4150e59f600876b7e308f857b2f21572b75348`: `packages/definitions/src/integration.ts`, `packages/definitions/src/widget-integration-map.ts`, `packages/integrations/src/bazarr/bazarr-integration.ts`, `packages/integrations/src/bazarr/bazarr-types.ts`, `packages/api/src/router/widgets/bazarr.ts`, `packages/request-handler/src/bazarr.ts`, `packages/widgets/src/bazarr/index.ts`, `packages/widgets/src/bazarr/component.tsx` and `packages/integrations/src/stats/existing.ts`. This is scoped source provenance, not whole-revision equivalence or current image attestation; no registry metadata or image was fetched in this phase. Bazarr App source and its test file remain byte-identical to `b28da7a`. No new test files, functions, subtests, independent scenarios, fault matrices, comments or dependencies were added. Direct Bazarr coverage remains exactly the two baseline tests described above; the descriptor, new preflight routing, credential changes and malformed/native data guards are source/schema/compile coverage, not newly implemented test or runtime proof. The normalized production tree passed the local gate in terminal shell `sh_13035227d001YlEZe0Pr7AsPnf` using cached Go 1.26.0 with `GOFLAGS=-buildvcs=false`, `GOTOOLCHAIN=local`, `GOPROXY=off` and `GOSUMDB=off`: empty `gofmt -l .`, focused Bazarr/Homarr tests, `go build ./...`, `go vet ./...`, `go vet -tags e2e ./e2e/`, `go test ./...`, race tests for TUI/Activity/Homarr/Bazarr, `bash -n install.sh` and `git diff --check`. Focused/full/race tests used `-count=1`; no e2e-tagged runtime tests ran. Only documentation was completed after this gate; production and test bytes remain those verified by it. Keep #320 draft and #272 open. Fresh independent Standards/Spec reviews and the parent's oracle phase gate remain required before counting this normalization. Native/rendered values, both installation orders, late-peer scheduling, restart, credential-change recovery and shared removal/reinstall acceptance remain held for a separately authorized bounded proof. No runtime consent is active and no Docker, browser, installer, host/provider/account, protected secret/profile or Gatus candidate/archive work was performed. ## Stage 3: missing-config scenario removal, source only Starting pin: `9bb75b06cd1983c75f606e58c603d7e58cbd837b`; frozen reference remains `6b82c55fb890c11a1388bd4e5a2f10b632ff4f7c`. With parent/oracle approval, remove only the confirmed agent-authored three-line `os.Remove(config.yaml)` block inside `TestSetupThenCheckThenRerunSkips`. That added scenario had no explicit human request and was not required API fixture maintenance. Both baseline functions, API response fixtures, saved-key and settings-write idempotence assertions remain. All production, preflight, registry and common bytes stay identical to the starting pin; previously removed tests stay absent. No tests, helpers, functions, subtests or scenarios are added. Missing-config/no-reread avoidance, credential changes and descriptor/preflight/native guards remain source/schema/compile-only. The corrected remaining test tree passed the cached Go 1.26.0 offline gate under the same four environment settings recorded above: empty `gofmt -l .`, build, both vet commands, focused/full tests, race tests for TUI/Activity/Homarr/ Bazarr, `bash -n install.sh` and `git diff --check`. Tests used `-count=1`; the removed fault trigger was absent from every run. No e2e-tagged runtime ran. Parent-owned fresh fixed-reference Standards and Spec reviews remain pending; native proof is held. ## Shared Stats SDK normalization, source and focused HTTP evidence The original branch history is preserved by forward merges of shared SDK `0bf67c3c64c229af25f19c1b93264f19cc57a910` and additive metadata SDK `d069339add5924f942ea6536f77d68e64b165df0`. No registry or common verification implementation is changed by this peer. The descriptor now uses a pure `statsSample` callback for `episodes`, `movies`, `providers`. One common catalog/snapshot/forced-refresh sequence supplies the same values validated by the leaf. Exact catalog units and value types are checked: counts. Missing/null fields, invalid counts/units and no-op refreshes fail; legitimate zeros remain valid. Common timestamp validation remains finite, positive and advancing; this peer adds no invented clock policy. Native authenticated peer status/badge checks and all five native count/two SignalR guards remain unchanged. Stats count values may differ from independently cached native badges; both are validated without equating volatile samples. Units and selected provider keys were checked in immutable Homarr OCI source `3d4150e59f600876b7e308f857b2f21572b75348`, using `packages/integrations/src/stats/existing.ts` and, for Frigate, `packages/integrations/src/stats/providers/frigate.ts`. This is source provenance, not new image attestation. Focused HTTP scenarios use the shared `statsFixture` through `verifyData`, with the native verifier explicitly isolated, and assert one forced refresh for the owned integration. They cover valid empty/populated samples, invalid selected values/units and refresh no-op rejection. App and Homarr affected-package tests, affected-package build/vet, changed-file gofmt and `git diff --check` passed. No Docker, browser, installer or broad suite was run. These fixtures verify the source interface; they do not claim real native/rendered acceptance. #320 remains draft and #272 remains open. Provider setup, rendered native/Stats data and both installation orders still require their own approved bounded proof.