Skip to content

fix(recyclarr): restore guide SQP-1 scores and match profiles by trash_id - #1491

Merged
Aviator-Coding merged 4 commits into
mainfrom
fm/homeops-recyclarr-quality-profile-fix
Aug 29, 2026
Merged

fix(recyclarr): restore guide SQP-1 scores and match profiles by trash_id#1491
Aviator-Coding merged 4 commits into
mainfrom
fm/homeops-recyclarr-quality-profile-fix

Conversation

@Aviator-Coding

@Aviator-Coding Aviator-Coding commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Intent

Fix Radarr's movie quality profiles so it can grab releases again. 240 of 1077 movies sit in the [SQP] SQP-1 (2160p) Radarr quality profile, which our recyclarr.yml configures with min_format_score: 2000 - double the TRaSH guide's own value of 1000. This gives the profile no scoring path to acceptance for anything below a 2160p WEB/UHD-Bluray release with HDR, so Radarr's decision engine rejects every release that exists for those movies (measured: 0 accepted releases across 5 sampled movies at threshold 2000, vs 2-13 accepted at the guide's 1000). Radarr, Prowlarr, and SABnzbd are otherwise healthy; this is purely a quality-profile config defect.

The captain decided on the full guide-aligned fix, not a one-line patch. All four parts, all in scope:

  1. Delete the min_format_score: 2000 override so the guide's own 1000 applies.
  2. Change every assign_scores_to entry in recyclarr.yml from matching by profile name to matching by trash_id (5128baeb2b081b72126bc8482b2a86a0 for SQP-1 2160p). This mirrors the reference repo (joryirving/home-ops) and is immune to guide renames - exactly the class of silent breakage that caused this outage: a 2026-04-09 guide rename orphaned every custom-format score onto a 2-movie profile instead of the 240-movie one actually in use, so a real fix (PR fix(radarr): deprioritize parse-risky releases, alert on stuck import queue #1369) landed with zero effect for over four months.
  3. Add the guide's [SQP] SQP-1 (1080p) profile (trash_id 0896c29d74de619df168d23b98104b22) and move catalogue, pre-2010, and documentary titles onto it - the structural answer for movies that will never get a UHD release. This supersedes the hand-made "[SQP] SQP-1 (2160p) < Year 2000" profile (id 41), which recyclarr does not manage.
  4. Retire the orphaned "SQP-1 (2160p)" profile (id 7, 2 movies) after moving its movies, so this class of defect cannot recur.

Both trash_ids were independently verified against the live TRaSH-Guides GitHub source (not just trusted from the brief) before use.

Moving movies between profiles is inherently a Radarr-side action, not a config change (recyclarr only creates/scores profiles - it never assigns a movie to one). This was done deliberately, live, against the cluster, using a reproducible, documented rule: a movie moves to the 1080p profile if year < 2010 OR its genres include "Documentary"; everything else stays on 2160p. This moved 262 movies total: 157 from the 240-movie 2160p profile by that rule, all 103 from the retired hand-made <2000 profile (id 41, wholly superseded), and both of the orphaned profile 7's movies (Scream 1996, Hackers 1995 - also pre-2010, so the same rule applies). 3 Radarr Collections (Die Hard, Jurassic Park, WarGames) referenced orphan profile 7 as their default and were repointed to profile 8 before it could be deleted. Profiles 7 and 41 are now deleted from Radarr.

The live cluster fix was verified end-to-end before committing: suspended the Flux Kustomization for downloads/recyclarr, applied the locally-built kustomize output (kubectl apply -n downloads, matching this repo's documented pre-merge live-testing pattern), triggered a manual sync job, confirmed via Radarr's interactive-search API that Million Dollar Baby (movieId 726) went from 0/163 to 10/163 accepted releases and The Lego Movie (movieId 810) went from 0/291 to 2/291 accepted releases - matching the outage report's own counterfactual numbers exactly. Flux was then resumed per the documented pattern (this reverts the live ConfigMap back to unmerged main, so the recyclarr.yml fix must merge before the next @daily CronJob run, roughly 04:00 America/New_York the next day, or the min_format_score threshold reverts in the live cluster - the movie/collection/profile reassignments themselves are durable Radarr database state and are not affected by that revert).

Explicitly out of scope for this change, per the captain: do not trigger a Radarr backlog/missing-movie search (approved separately, gated on this merging - tracked as a separate task homeops-radarr-backlog-search); do not touch Plex settings or Tdarr transcoding (separate faults, owned by other workers); do not change indexers, download clients, or storage layout; do not fix anything by hand-editing Radarr's UI (the daily recyclarr CronJob would silently revert any UI-only fix within 24h) - the config-level fix belongs in recyclarr.yml only.

Docs were updated (docs/media-stack.md, AGENTS.md) to record the trash_id-matching root cause and the reproducible movie-classification rule, since profile membership is Radarr database state invisible to GitOps and this exact class of silent drift is what caused the original 4-month outage.

Live Verification Evidence (against the real cluster, pre-merge)

The Test step's warning below is accurate about its own sandbox (no kubeconfig there) but the acceptance proof this PR claims was already captured directly against the live cluster before this PR was opened, using this repo's documented suspend-Flux / apply-locally-built-config / manual-sync / resume-Flux pre-merge testing pattern:

Movie movieId Releases returned Accepted before fix Accepted after fix
Million Dollar Baby (2004) 726 163 0 10
The Lego Movie (2014) 810 291 0 2

These numbers match the original outage report's own counterfactual measurement exactly (0 accepted at min_format_score: 2000, 10 and 2 accepted at the guide's 1000), confirmed live via Radarr's own GET /api/v3/release?movieId=<id> decision-engine output, not inferred.

Also verified live and durable in Radarr's database (independent of this PR's merge state):

  • 262 movies reassigned via PUT /api/v3/movie/editor - 157 from the 2160p profile (year < 2010 or genre Documentary), 103 from the retired hand-made < Year 2000 profile (id 41), 2 from the orphaned profile (id 7).
  • 3 Radarr Collections (Die Hard, Jurassic Park, WarGames) that referenced orphan profile 7 repointed to profile 8.
  • Orphan profiles 7 and 41 confirmed deleted (DELETE /api/v3/qualityprofile/{id} returned 200 for both, after clearing the referencing collections).

What is still open, and who owns it: because Flux was resumed after this live test (per the documented pattern), the live ConfigMap now reflects unmerged main again - the min_format_score / trash_id fix only takes effect in the cluster once this PR merges and the recyclarr CronJob (@daily, next run ~04:00 America/New_York) syncs it, or a manual sync job is triggered post-merge. The movie/collection/profile reassignments above are Radarr database state and are unaffected by that. Firstmate re-checks the live grab path after merge, once recyclarr has synced, before the separately-tracked backlog search (homeops-radarr-backlog-search) is triggered.

What Changed

  • Updated recyclarr.yml to drop the Radarr min_format_score: 2000 override (guide default 1000), add the TRaSH [SQP] SQP-1 (1080p) profile, and retarget every assign_scores_to entry (Radarr and Sonarr) from profile name to stable trash_id values.
  • Documented the rename/orphan root cause, dual SQP-1 profile layout, and the one-off Radarr movie classification rule (year < 2010 or Documentary → 1080p) in docs/media-stack.md and AGENTS.md.
  • Added scripts/ci/recyclarr-quality-profile-test.py (and README inventory entry) to pin guide min scores, both SQP-1 trash_ids, trash_id-only scoring targets, and the kustomize-built ConfigMap semantics.

Risk Assessment

✅ Low: Bounded recyclarr config and docs change that closes the documented grab outage (guide min_format_score, trash_id matching, 1080p profile) with the prior Sonarr name-match gap fixed and no remaining source contradictions to intent.

Testing

Added and ran a semantic recyclarr regression test that parses the source config and the kustomize-built ConfigMap Flux mounts, confirms both SQP-1 profiles by live TRaSH trash_ids with guide minFormatScore 1000 and zero overrides, requires trash_id-only assign_scores_to, and shows the pre-fix blob still fails those invariants; live Radarr interactive-search re-proof was not possible here without cluster credentials.

Evidence: recyclarr-quality-profile-test.py full pass + evidence JSON

[PASS] source recyclarr.yml satisfies SQP-1 fix invariants [PASS] kustomize ConfigMap satisfies SQP-1 fix invariants [PASS] pre-fix config fails the same invariants (regression) pre_fix: min_format_score_overrides=[2000], name_matched_assign_count=6; fixed: both SQP trash_ids, min_format_score_overrides=[], guide minFormatScore=1000

[PASS] source recyclarr.yml satisfies SQP-1 fix invariants
[PASS] kustomize ConfigMap satisfies SQP-1 fix invariants
[PASS] pre-fix config fails the same invariants (regression)
--- evidence ---
{
  "from_configmap": {
    "guide_profiles": {
      "0896c29d74de619df168d23b98104b22": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (1080p)"
      },
      "5128baeb2b081b72126bc8482b2a86a0": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (2160p)"
      }
    },
    "min_format_score_overrides": [],
    "radarr_assign_scores_trash_ids": [
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "radarr_quality_profile_trash_ids": [
      "0896c29d74de619df168d23b98104b22",
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "threshold_counterfactual": {
      "accepted_at_guide_1000": true,
      "rejected_at_override_2000": true,
      "sample_custom_format_score": 1500
    }
  },
  "from_file": {
    "guide_profiles": {
      "0896c29d74de619df168d23b98104b22": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (1080p)"
      },
      "5128baeb2b081b72126bc8482b2a86a0": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (2160p)"
      }
    },
    "min_format_score_overrides": [],
    "radarr_assign_scores_trash_ids": [
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "radarr_quality_profile_trash_ids": [
      "0896c29d74de619df168d23b98104b22",
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "threshold_counterfactual": {
      "accepted_at_guide_1000": true,
      "rejected_at_override_2000": true,
      "sample_custom_format_score": 1500
    }
  },
  "pre_fix": {
    "min_format_score_overrides": [
      2000
    ],
    "name_matched_assign_count": 6,
    "quality_profile_trash_ids": [
      "5128baeb2b081b72126bc8482b2a86a0"
    ]
  }
}

all checks passed
Evidence: Semantic evidence (file vs ConfigMap vs pre-fix)
{
  "from_configmap": {
    "guide_profiles": {
      "0896c29d74de619df168d23b98104b22": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (1080p)"
      },
      "5128baeb2b081b72126bc8482b2a86a0": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (2160p)"
      }
    },
    "min_format_score_overrides": [],
    "radarr_assign_scores_trash_ids": [
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "radarr_quality_profile_trash_ids": [
      "0896c29d74de619df168d23b98104b22",
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "threshold_counterfactual": {
      "accepted_at_guide_1000": true,
      "rejected_at_override_2000": true,
      "sample_custom_format_score": 1500
    }
  },
  "from_file": {
    "guide_profiles": {
      "0896c29d74de619df168d23b98104b22": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (1080p)"
      },
      "5128baeb2b081b72126bc8482b2a86a0": {
        "cutoffFormatScore": 10000,
        "minFormatScore": 1000,
        "name": "[SQP] SQP-1 (2160p)"
      }
    },
    "min_format_score_overrides": [],
    "radarr_assign_scores_trash_ids": [
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "radarr_quality_profile_trash_ids": [
      "0896c29d74de619df168d23b98104b22",
      "5128baeb2b081b72126bc8482b2a86a0"
    ],
    "threshold_counterfactual": {
      "accepted_at_guide_1000": true,
      "rejected_at_override_2000": true,
      "sample_custom_format_score": 1500
    }
  },
  "pre_fix": {
    "min_format_score_overrides": [
      2000
    ],
    "name_matched_assign_count": 6,
    "quality_profile_trash_ids": [
      "5128baeb2b081b72126bc8482b2a86a0"
    ]
  }
}
Evidence: Kustomize ConfigMap Radarr profiles and assign_scores_to targets

configmap recyclarr-9925979k9k declares trash_ids 5128baeb… (2160p) and 0896c29d… (1080p); all Radarr/Sonarr assign_scores_to use trash_id only; no min_format_score key

{
  "configmap_name": "recyclarr-9925979k9k",
  "radarr_quality_profiles": [
    {
      "trash_id": "5128baeb2b081b72126bc8482b2a86a0",
      "reset_unmatched_scores": {
        "enabled": true
      }
    },
    {
      "trash_id": "0896c29d74de619df168d23b98104b22",
      "reset_unmatched_scores": {
        "enabled": true
      }
    }
  ],
  "radarr_assign_scores_to_targets": [
    {
      "trash_id": "5128baeb2b081b72126bc8482b2a86a0"
    },
    {
      "trash_id": "5128baeb2b081b72126bc8482b2a86a0"
    },
    {
      "trash_id": "5128baeb2b081b72126bc8482b2a86a0"
    },
    {
      "trash_id": "5128baeb2b081b72126bc8482b2a86a0"
    },
    {
      "trash_id": "5128baeb2b081b72126bc8482b2a86a0"
    },
    {
      "trash_id": "5128baeb2b081b72126bc8482b2a86a0"
    }
  ],
  "sonarr_assign_scores_to_targets": [
    {
      "trash_id": "d1498e7d189fbe6c7110ceaabb7473e6"
    },
    {
      "trash_id": "72dae194fc92bf828f32cde7744e51a1"
    },
    {
      "trash_id": "d1498e7d189fbe6c7110ceaabb7473e6"
    },
    {
      "trash_id": "72dae194fc92bf828f32cde7744e51a1"
    },
    {
      "trash_id": "d1498e7d189fbe6c7110ceaabb7473e6"
    },
    {
      "trash_id": "72dae194fc92bf828f32cde7744e51a1"
    },
    {
      "trash_id": "d1498e7d189fbe6c7110ceaabb7473e6"
    }
  ]
}
Evidence: TRaSH-Guides SQP-1 profile summary (live fetch)

[SQP] SQP-1 (1080p) trash_id=0896c29d74de619df168d23b98104b22 minFormatScore=1000; [SQP] SQP-1 (2160p) trash_id=5128baeb2b081b72126bc8482b2a86a0 minFormatScore=1000

[
  {
    "file": "trash-sqp-1-1080p.json",
    "trash_id": "0896c29d74de619df168d23b98104b22",
    "name": "[SQP] SQP-1 (1080p)",
    "minFormatScore": 1000,
    "cutoffFormatScore": 10000
  },
  {
    "file": "trash-sqp-1-2160p.json",
    "trash_id": "5128baeb2b081b72126bc8482b2a86a0",
    "name": "[SQP] SQP-1 (2160p)",
    "minFormatScore": 1000,
    "cutoffFormatScore": 10000
  }
]
Evidence: Raw TRaSH sqp-1-2160p.json
{
  "trash_id": "5128baeb2b081b72126bc8482b2a86a0",
  "name": "[SQP] SQP-1 (2160p)",
  "trash_score_set": "sqp-1-2160p",
  "trash_description": "This Special Quality Profile is an advanced Quality Profile designed for a specific use case. Before using this Quality Profile please join the <a href=\"https://trash-guides.info/discord\" target=\"_blank\">TRaSH-Guide Discord</a> for more information. Open the #access-to-sqp channel and accept the three simple rules. Any questions related to the SQP should only be asked in the dedicated SQP support channels.",
  "group": 98,
  "upgradeAllowed": true,
  "cutoff": "Bluray-2160p",
  "minFormatScore": 1000,
  "cutoffFormatScore": 10000,
  "minUpgradeFormatScore": 1,
  "language": "Original",
  "items": [
    { "name": "Bluray-2160p", "allowed": true },
    {
      "name": "WEB 2160p",
      "allowed": true,
      "items": ["WEBRip-2160p", "WEBDL-2160p"]
    },
    {
      "name": "Bluray|WEB-1080p",
      "allowed": true,
      "items": ["Bluray-1080p", "WEBDL-1080p", "WEBRip-1080p", "WEBDL-720p", "WEBRip-720p"]
    },
    { "name": "Bluray-720p", "allowed": true },
    { "name": "Raw-HD", "allowed": false },
    { "name": "BR-DISK", "allowed": false },
    { "name": "Remux-2160p", "allowed": false },
    { "name": "HDTV-2160p", "allowed": false },
    { "name": "Remux-1080p", "allowed": false },
    { "name": "HDTV-1080p", "allowed": false },
    { "name": "HDTV-720p", "allowed": false },
    { "name": "Bluray-576p", "allowed": false },
    { "name": "Bluray-480p", "allowed": false },
    {
      "name": "WEB 480p",
      "allowed": false,
      "items": ["WEBRip-480p", "WEBDL-480p"]
    },
    { "name": "DVD-R", "allowed": false },
    { "name": "DVD", "allowed": false },
    { "name": "SDTV", "allowed": false },
    { "name": "DVDSCR", "allowed": false },
    { "name": "REGIONAL", "allowed": false },
    { "name": "TELECINE", "allowed": false },
    { "name": "TELESYNC", "allowed": false },
    { "name": "CAM", "allowed": false },
    { "name": "WORKPRINT", "allowed": false },
    { "name": "Unknown", "allowed": false }
  ],
  "formatItems": {
    "TrueHD ATMOS": "496f355514737f7d83bf7aa4d24f8169",
    "DTS X": "2f22d89048b01681dde8afe203bf2e95",
    "ATMOS (undefined)": "417804f7f2c4308c1f4c5d380d4c4475",
    "DD+ ATMOS": "1af239278386be2919e1bcee0bde047e",
    "TrueHD": "3cafb66171b47f226146a0770576870f",
    "DTS-HD MA": "dcf3ec6938fa32445f590a4da84256cd",
    "FLAC": "a570d4a0e56a2874b64e5bfa55202a1b",
    "PCM": "e7c2fcae07cbada050a0af3357491d7b",
    "DTS-HD HRA": "8e109e50e0a0b83a5098b056e13bf6db",
    "DD+": "185f1dd7264c4562b9022d963ac37424",
    "DTS-ES": "f9f847ac70a0af62ea4a08280b859636",
    "DTS": "1c1a4c5e823891c75bc50380a6866f73",
    "AAC": "240770601cc226190c367ef59aba7463",
    "DD": "c2998bd0d90ed5621d8df281e839436e",
    "DV (w/o HDR fallback)": "923b6abef9b17f937fab56cfcf89e1f1",
    "BHDStudio": "5153ec7413d9dae44e24275589b5e944",
    "hallowed": "7a0d1ad358fee9f5b074af3ef3f9d9ef",
    "WEB Tier 01": "c20f169ef63c5f40c2def54abaf4438e",
    "WEB Tier 02": "403816d65392c79236dcb6dd591aeda4",
    "WEB Tier 03": "af94e0fe497124d1f9ce732069ec8c3b",
    "HD Bluray Tier 01": "ed27ebfef2f323e964fb1f61391bcb35",
    "HD Bluray Tier 02": "c20c8647f2746a1f4c4262b0fbbeeeae",
    "HD Bluray Tier 03": "5608c71bcebba0a5e666223bae8c9227",
    "UHD Bluray Tier 01": "4d74ac4c4db0b64bff6ce0cffef99bf0",
    "UHD Bluray Tier 02": "a58f517a70193f8e578056642178419d",
    "UHD Bluray Tier 03": "e71939fae578037e7aed3ee219bbe7c1",
    "Repack/Proper": "e7718d7a3ce595f289bfee26adc178f5",
    "Repack2": "ae43b294509409a6a13919dedd4764c4",
    "Repack3": "5caaaa1c08c1742aa4342d8c4cc463f2",
    "BR-DISK": "ed38b889b31be83fda192888e2286d83",
    "LQ": "90a6f9a284dff5103f6346090e6280c8",
    "LQ (Release Title)": "e204b80c87be9497a8a6eaff48f72905",
    "x265 (no HDR/DV)": "839bea857ed2c0a8e084f3cbdbd65ecb",
    "3D": "b8cd450cbfa689c0259a01d9e29ba3d6",
    "AV1": "cae4ca30163749b891686f95532519bd",
    "1080p": "820b09bb9acbfde9c35c71e0e565dad8",
    "720p": "b2be17d608fc88818940cd1833b0b24c"
  }
}
Evidence: Raw TRaSH sqp-1-1080p.json
{
  "trash_id": "0896c29d74de619df168d23b98104b22",
  "name": "[SQP] SQP-1 (1080p)",
  "trash_score_set": "sqp-1-1080p",
  "trash_description": "This Special Quality Profile is an advanced Quality Profile designed for a specific use case. Before using this Quality Profile please join the <a href=\"https://trash-guides.info/discord\" target=\"_blank\">TRaSH-Guide Discord</a> for more information. Open the #access-to-sqp channel and accept the three simple rules. Any questions related to the SQP should only be asked in the dedicated SQP support channels.",
  "group": 98,
  "upgradeAllowed": true,
  "cutoff": "Bluray|WEB-1080p",
  "minFormatScore": 1000,
  "cutoffFormatScore": 10000,
  "minUpgradeFormatScore": 1,
  "language": "Original",
  "items": [
    {
      "name": "Bluray|WEB-1080p",
      "allowed": true,
      "items": ["Bluray-1080p", "WEBRip-1080p", "WEBDL-1080p", "WEBRip-720p", "WEBDL-720p"]
    },
    { "name": "Bluray-720p", "allowed": true },
    { "name": "Raw-HD", "allowed": false },
    { "name": "BR-DISK", "allowed": false },
    { "name": "Remux-2160p", "allowed": false },
    { "name": "Bluray-2160p", "allowed": false },
    {
      "name": "WEB 2160p",
      "allowed": false,
      "items": ["WEBRip-2160p", "WEBDL-2160p"]
    },
    { "name": "HDTV-2160p", "allowed": false },
    { "name": "Remux-1080p", "allowed": false },
    { "name": "HDTV-1080p", "allowed": false },
    { "name": "HDTV-720p", "allowed": false },
    { "name": "Bluray-576p", "allowed": false },
    { "name": "Bluray-480p", "allowed": false },
    {
      "name": "WEB 480p",
      "allowed": false,
      "items": ["WEBRip-480p", "WEBDL-480p"]
    },
    { "name": "DVD-R", "allowed": false },
    { "name": "DVD", "allowed": false },
    { "name": "SDTV", "allowed": false },
    { "name": "DVDSCR", "allowed": false },
    { "name": "REGIONAL", "allowed": false },
    { "name": "TELECINE", "allowed": false },
    { "name": "TELESYNC", "allowed": false },
    { "name": "CAM", "allowed": false },
    { "name": "WORKPRINT", "allowed": false },
    { "name": "Unknown", "allowed": false }
  ],
  "formatItems": {
    "TrueHD ATMOS": "496f355514737f7d83bf7aa4d24f8169",
    "DTS X": "2f22d89048b01681dde8afe203bf2e95",
    "ATMOS (undefined)": "417804f7f2c4308c1f4c5d380d4c4475",
    "DD+ ATMOS": "1af239278386be2919e1bcee0bde047e",
    "TrueHD": "3cafb66171b47f226146a0770576870f",
    "DTS-HD MA": "dcf3ec6938fa32445f590a4da84256cd",
    "FLAC": "a570d4a0e56a2874b64e5bfa55202a1b",
    "PCM": "e7c2fcae07cbada050a0af3357491d7b",
    "DTS-HD HRA": "8e109e50e0a0b83a5098b056e13bf6db",
    "DD+": "185f1dd7264c4562b9022d963ac37424",
    "DTS-ES": "f9f847ac70a0af62ea4a08280b859636",
    "DTS": "1c1a4c5e823891c75bc50380a6866f73",
    "AAC": "240770601cc226190c367ef59aba7463",
    "DD": "c2998bd0d90ed5621d8df281e839436e",
    "BHDStudio": "5153ec7413d9dae44e24275589b5e944",
    "hallowed": "7a0d1ad358fee9f5b074af3ef3f9d9ef",
    "WEB Tier 01": "c20f169ef63c5f40c2def54abaf4438e",
    "WEB Tier 02": "403816d65392c79236dcb6dd591aeda4",
    "WEB Tier 03": "af94e0fe497124d1f9ce732069ec8c3b",
    "HD Bluray Tier 01": "ed27ebfef2f323e964fb1f61391bcb35",
    "HD Bluray Tier 02": "c20c8647f2746a1f4c4262b0fbbeeeae",
    "HD Bluray Tier 03": "5608c71bcebba0a5e666223bae8c9227",
    "Repack/Proper": "e7718d7a3ce595f289bfee26adc178f5",
    "Repack2": "ae43b294509409a6a13919dedd4764c4",
    "Repack3": "5caaaa1c08c1742aa4342d8c4cc463f2",
    "BR-DISK": "ed38b889b31be83fda192888e2286d83",
    "LQ": "90a6f9a284dff5103f6346090e6280c8",
    "LQ (Release Title)": "e204b80c87be9497a8a6eaff48f72905",
    "x265 (HD)": "dc98083864ea246d05a42df0d05f81cc",
    "3D": "b8cd450cbfa689c0259a01d9e29ba3d6",
    "AV1": "cae4ca30163749b891686f95532519bd",
    "1080p": "820b09bb9acbfde9c35c71e0e565dad8",
    "720p": "b2be17d608fc88818940cd1833b0b24c"
  }
}
- Outcome: ⚠️ 1 warning across 1 run (3m23s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ kubernetes/apps/base/downloads/recyclarr/app/config/recyclarr.yml:27 - The durable invariant this change documents (AGENTS.md + docs/media-stack.md: assign_scores_to must match by trash_id, never by profile name) is only enforced on the Radarr section. Sonarr still has six assign_scores_to entries matching WEB-1080p / WEB-2160p by name (lines 27, 42-43, 51-52, 71-72), while those profiles already have trash_ids on the quality_profiles block (72dae194… / d1498e7d…). A TRaSH rename of either WEB profile would silently orphan Sonarr CF scores the same way SQP-1 did. Either convert those Sonarr entries to trash_id (mirrors joryirving/home-ops and the new AGENTS rule), or narrow AGENTS/docs to say the rule applies to Radarr SQP-1 only so the written invariant matches the file.

🔧 Fix: Match Sonarr scores by trash_id
✅ Re-checked - no issues remain.

⚠️ **Test** - 1 warning
  • ⚠️ This sandbox has no kubeconfig/cluster access, so the end-user acceptance proof (Radarr interactive-search accepted-release counts for Million Dollar Baby / The Lego Movie, and the durable movie/collection/profile reassignments) could not be re-run here. GitOps halves of the fix are fully proven: guide-aligned minFormatScore 1000 with no override, both SQP-1 trash_ids present, trash_id-only assign_scores_to, kustomize ConfigMap parity, and pre-fix blob fails the same invariants. Live grab-path re-verification still depends on merge + the next recyclarr CronJob (or a manual job) against the cluster.
  • python3 scripts/ci/recyclarr-quality-profile-test.py (source YAML + kustomize ConfigMap invariants + pre-fix regression)
  • kustomize build kubernetes/apps/base/downloads/recyclarr/app → parse ConfigMap recyclarr.yml quality_profiles/assign_scores_to
  • Fetched TRaSH-Guides sqp-1-2160p.json / sqp-1-1080p.json and asserted trash_id + minFormatScore: 1000
  • Compared base blob cb3529b9:.../recyclarr.yml (min_format_score 2000, name-matched assigns, no 1080p profile) against fixed config
  • Checked for live Radarr API access via kubeconfig (unavailable in this worktree)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

min_format_score: 2000 (double the TRaSH guide's 1000) made the [SQP]
SQP-1 (2160p) profile reject every release for its 240 movies - the
decision engine had no scoring path above ~1275 for anything below
2160p WEB/UHD-Bluray with HDR. Removing the override restores the
guide default.

assign_scores_to entries matched the profile by name (SQP-1 (2160p)),
which orphaned onto profile id 7 when the 2026-04-09 rewrite switched
the quality_profiles entry to match by trash_id and created a new
profile (id 8) under the guide's full bracketed name. Every
custom-format tuning since (including PR #1369's Language/MULTi
scores) landed on the 2-movie orphan instead of the 240-movie profile
actually in use. Matching by trash_id is immune to this class of
rename.

Also adds the guide's [SQP] SQP-1 (1080p) profile (trash_id
0896c29d74de619df168d23b98104b22), the structural fix for titles that
will never get a UHD release - many of the 240 stuck movies are
catalogue, pre-2010, or documentary titles that simply don't exist in
2160p. This supersedes the hand-made "[SQP] SQP-1 (2160p) < Year 2000"
profile, which recyclarr doesn't manage.
Records the min_format_score/trash_id root cause and the reproducible
movie-reassignment rule (year < 2010 or Documentary genre -> 1080p
profile) used for the one-off Radarr API classification pass, since
profile membership is Radarr database state that GitOps cannot see.
@mortyops

mortyops Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor
--- ConfigMap downloads/recyclarr-9925979k9k
+++ ConfigMap downloads/recyclarr-9925979k9k
@@ -1 +1,162 @@
+apiVersion: v1
+data:
+  recyclarr.yml: |
+    ---
+    # yaml-language-server: $schema=https://schemas.recyclarr.dev/v8/config-schema.json
+    sonarr:
+      sonarr_main:
+        base_url: http://sonarr.downloads.svc.cluster.local:8989
+        api_key: !env_var SONARR_API_KEY
 
+        delete_old_custom_formats: true
+
+        quality_definition:
+          type: series
+
+        quality_profiles:
+          - trash_id: 72dae194fc92bf828f32cde7744e51a1 # WEB-1080p
+            reset_unmatched_scores:
+              enabled: true
+          - trash_id: d1498e7d189fbe6c7110ceaabb7473e6 # WEB-2160p
+            reset_unmatched_scores:
+              enabled: true
+
+        custom_formats:
+          # HDR Formats (WEB-2160p only)
+          - trash_ids:
+              # Comment out the next line if you and all of your users' setups are fully DV compatible
+              - 9b27ab6498ec0f31a3353992e19434ca # DV (WEBDL)
+            assign_scores_to:
+              - trash_id: d1498e7d189fbe6c7110ceaabb7473e6 # WEB-2160p
+
+          # Unwanted
+          - trash_ids:
+              - 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
+              - 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
+              - e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
+              - 06d66ab109d4d2eddb2794d21526d140 # Retags
+              - 1b3994c551cbb92a2c781af061f4ab44 # Scene
+              - 15a05bc7c1a36e2b57fd628f8f3e15a6 # AV1
+              - 85c61753df5da1fb2aab6f2a47c8b789 # BR-DISK
+              - 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
+              - e2315f990da2e2e0c9b11b485e36a947 # LQ (Release Title)
+              - 47435ece6b99a0b477caf360e79ba0bb # x265 (HD)
+            assign_scores_to:
+              - trash_id: 72dae194fc92bf828f32cde7744e51a1 # WEB-1080p
+              - trash_id: d1498e7d189fbe6c7110ceaabb7473e6 # WEB-2160p
+
+          # Miscellaneous
+          - trash_ids:
+              - ec8fa7296b64e8cd390a1600981f3923 # Repack/Proper
+              - eb3d5cc0a2be0db205fb823640db6a3c # Repack2
+              - 44e7c4de10ae50265753082e5dc76047 # Repack3
+            assign_scores_to:
+              - trash_id: 72dae194fc92bf828f32cde7744e51a1 # WEB-1080p
+              - trash_id: d1498e7d189fbe6c7110ceaabb7473e6 # WEB-2160p
+
+          # Streaming Services
+          - trash_ids:
+              - d660701077794679fd59e8bdf4ce3a29 # AMZN
+              - f67c9ca88f463a48346062e8ad07713f # ATVP
+              - 36b72f59f4ea20aad9316f475f2d9fbb # DCU
+              - 89358767a60cc28783ab36f5fd3e5cb0 # DSNP
+              - 7a235133c87f7da4c8ccccbe915e60aa # HBO
+              - a880d6abc21e7c16884f3ae393f84179 # HMAX
+              - f6cce30f1733d5c8194222a7507f2e49 # HULU
+              - 0ac24a2a68a9700bcb7eee4e573a6227 # iT
+              - 81d1fbf600e2540cee87f3a23f9d3c1c # MAX
+              - d34870697c9db575f17700212167be23 # NF
+              - 1656adc6d7bb2c8cca6acfb6592db421 # PCOK
+              - c67a75ae4a1715f2bb4d492c17f80112 # PMTP
+              - ae58039e1319178e6be73f5f551e1afd # SHO
+              - 1efe8da11bfd74fbbcd4d8117ddb9213 # STAN
+            assign_scores_to:
+              - trash_id: 72dae194fc92bf828f32cde7744e51a1 # WEB-1080p
+              - trash_id: d1498e7d189fbe6c7110ceaabb7473e6 # WEB-2160p
+
+    radarr:
+      radarr_main:
+        base_url: http://radarr.downloads.svc.cluster.local:7878
+        api_key: !env_var RADARR_API_KEY
+
+        delete_old_custom_formats: true
+
+        quality_definition:
+          type: sqp-streaming
+
+        quality_profiles:
+          - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
+            reset_unmatched_scores:
+              enabled: true
+          - trash_id: 0896c29d74de619df168d23b98104b22 # [SQP] SQP-1 (1080p)
+            reset_unmatched_scores:
+              enabled: true
+
+        custom_formats:
+          # Trusted Groups
+          - trash_ids:
+              - 7a0d1ad358fee9f5b074af3ef3f9d9ef # hallowed
+            assign_scores_to:
+              - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
+
+          # Unwanted
+          - trash_ids:
+              - b6832f586342ef70d9c128d40c07b872 # Bad Dual Groups
+              - ae9b7c9ebde1f3bd336a8cbd1ec4c5e5 # No-RlsGroup
+              - 7357cf5161efbf8c4d5d0c30b4815ee2 # Obfuscated
+              - 5c44f52a8714fdd79bb4d98e2673be1f # Retags
+              - f537cf427b64c38c8e36298f657e4828 # Scene
+              - cae4ca30163749b891686f95532519bd # AV1
+              - ed38b889b31be83fda192888e2286d83 # BR-DISK
+              - 90a6f9a284dff5103f6346090e6280c8 # LQ
+              - e204b80c87be9497a8a6eaff48f72905 # LQ (Release Title)
+              - dc98083c8c6b34cc9ab94e6c4a45b18c # x265 (HD)
+              - b8cd450cbfa689c0259a01d9e29ba3d6 # 3D
+            assign_scores_to:
+              - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
+
+          # Miscellaneous
+          - trash_ids:
+              - e7718d7a3ce595f289bfee26adc178f5 # Repack/Proper
+              - ae43b294509409a6a13919dedd49c257 # Repack2
+              - 5caaaa1c08c1742aa4342571f427e5c5 # Repack3
+            assign_scores_to:
+              - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
+
+          # Movie Versions
+          - trash_ids:
+              - eca37840c13c6ef2dd0754c2a6a89554 # Criterion Collection
+              - 0f12c086e289cf966fa5948eac571f44 # Hybrid
+              - 570bc9ebecd92723d2d21500f4be314c # Remaster
+              - eecf3a857724171f968a66cb5719e152 # IMAX
+              - 9d27d9d2181838f76dee150882bdc58c # IMAX Enhanced
+            assign_scores_to:
+              - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
+
+          # Language / naming risk - deprioritize (not block) releases whose title format is more
+          # likely to defeat Radarr's import parser and trigger the "matched movie by ID, Manual
+          # Import required" stuck-queue state. Scores are intentionally small (well under
+          # min_format_score) so a foreign-audio or MULTi release is still grabbed when it's the
+          # best/only match - this only nudges Radarr toward a cleaner-named English release when
+          # more than one candidate is available.
+          - trash_ids:
+              - 0dc8aec3bd1c47cd6c40c46ecd27e846 # Language: Not English
+            score: -25
+            assign_scores_to:
+              - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
+          - trash_ids:
+              - 4b900e171accbfb172729b63323ea8ca # MULTi
+            score: -25
+            assign_scores_to:
+              - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
+kind: ConfigMap
+metadata:
+  annotations:
+    kustomize.toolkit.fluxcd.io/substitute: disabled
+  labels:
+    app.kubernetes.io/name: recyclarr
+    kustomize.toolkit.fluxcd.io/name: recyclarr
+    kustomize.toolkit.fluxcd.io/namespace: downloads
+  name: recyclarr-9925979k9k
+  namespace: downloads
+

--- ConfigMap downloads/recyclarr-m2dt5hb278
+++ ConfigMap downloads/recyclarr-m2dt5hb278
@@ -1,160 +1 @@
-apiVersion: v1
-data:
-  recyclarr.yml: |
-    ---
-    # yaml-language-server: $schema=https://schemas.recyclarr.dev/v8/config-schema.json
-    sonarr:
-      sonarr_main:
-        base_url: http://sonarr.downloads.svc.cluster.local:8989
-        api_key: !env_var SONARR_API_KEY
 
-        delete_old_custom_formats: true
-
-        quality_definition:
-          type: series
-
-        quality_profiles:
-          - trash_id: 72dae194fc92bf828f32cde7744e51a1 # WEB-1080p
-            reset_unmatched_scores:
-              enabled: true
-          - trash_id: d1498e7d189fbe6c7110ceaabb7473e6 # WEB-2160p
-            reset_unmatched_scores:
-              enabled: true
-
-        custom_formats:
-          # HDR Formats (WEB-2160p only)
-          - trash_ids:
-              # Comment out the next line if you and all of your users' setups are fully DV compatible
-              - 9b27ab6498ec0f31a3353992e19434ca # DV (WEBDL)
-            assign_scores_to:
-              - name: WEB-2160p
-
-          # Unwanted
-          - trash_ids:
-              - 32b367365729d530ca1c124a0b180c64 # Bad Dual Groups
-              - 82d40da2bc6923f41e14394075dd4b03 # No-RlsGroup
-              - e1a997ddb54e3ecbfe06341ad323c458 # Obfuscated
-              - 06d66ab109d4d2eddb2794d21526d140 # Retags
-              - 1b3994c551cbb92a2c781af061f4ab44 # Scene
-              - 15a05bc7c1a36e2b57fd628f8f3e15a6 # AV1
-              - 85c61753df5da1fb2aab6f2a47c8b789 # BR-DISK
-              - 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
-              - e2315f990da2e2e0c9b11b485e36a947 # LQ (Release Title)
-              - 47435ece6b99a0b477caf360e79ba0bb # x265 (HD)
-            assign_scores_to:
-              - name: WEB-1080p
-              - name: WEB-2160p
-
-          # Miscellaneous
-          - trash_ids:
-              - ec8fa7296b64e8cd390a1600981f3923 # Repack/Proper
-              - eb3d5cc0a2be0db205fb823640db6a3c # Repack2
-              - 44e7c4de10ae50265753082e5dc76047 # Repack3
-            assign_scores_to:
-              - name: WEB-1080p
-              - name: WEB-2160p
-
-          # Streaming Services
-          - trash_ids:
-              - d660701077794679fd59e8bdf4ce3a29 # AMZN
-              - f67c9ca88f463a48346062e8ad07713f # ATVP
-              - 36b72f59f4ea20aad9316f475f2d9fbb # DCU
-              - 89358767a60cc28783ab36f5fd3e5cb0 # DSNP
-              - 7a235133c87f7da4c8ccccbe915e60aa # HBO
-              - a880d6abc21e7c16884f3ae393f84179 # HMAX
-              - f6cce30f1733d5c8194222a7507f2e49 # HULU
-              - 0ac24a2a68a9700bcb7eee4e573a6227 # iT
-              - 81d1fbf600e2540cee87f3a23f9d3c1c # MAX
-              - d34870697c9db575f17700212167be23 # NF
-              - 1656adc6d7bb2c8cca6acfb6592db421 # PCOK
-              - c67a75ae4a1715f2bb4d492c17f80112 # PMTP
-              - ae58039e1319178e6be73f5f551e1afd # SHO
-              - 1efe8da11bfd74fbbcd4d8117ddb9213 # STAN
-            assign_scores_to:
-              - name: WEB-1080p
-              - name: WEB-2160p
-
-    radarr:
-      radarr_main:
-        base_url: http://radarr.downloads.svc.cluster.local:7878
-        api_key: !env_var RADARR_API_KEY
-
-        delete_old_custom_formats: true
-
-        quality_definition:
-          type: sqp-streaming
-
-        quality_profiles:
-          - trash_id: 5128baeb2b081b72126bc8482b2a86a0 # [SQP] SQP-1 (2160p)
-            reset_unmatched_scores:
-              enabled: true
-            min_format_score: 2000
-
-        custom_formats:
-          # Trusted Groups
-          - trash_ids:
-              - 7a0d1ad358fee9f5b074af3ef3f9d9ef # hallowed
-            assign_scores_to:
-              - name: SQP-1 (2160p)
-
-          # Unwanted
-          - trash_ids:
-              - b6832f586342ef70d9c128d40c07b872 # Bad Dual Groups
-              - ae9b7c9ebde1f3bd336a8cbd1ec4c5e5 # No-RlsGroup
-              - 7357cf5161efbf8c4d5d0c30b4815ee2 # Obfuscated
-              - 5c44f52a8714fdd79bb4d98e2673be1f # Retags
-              - f537cf427b64c38c8e36298f657e4828 # Scene
-              - cae4ca30163749b891686f95532519bd # AV1
-              - ed38b889b31be83fda192888e2286d83 # BR-DISK
-              - 90a6f9a284dff5103f6346090e6280c8 # LQ
-              - e204b80c87be9497a8a6eaff48f72905 # LQ (Release Title)
-              - dc98083c8c6b34cc9ab94e6c4a45b18c # x265 (HD)
-              - b8cd450cbfa689c0259a01d9e29ba3d6 # 3D
-            assign_scores_to:
-              - name: SQP-1 (2160p)
-
-          # Miscellaneous
-          - trash_ids:
-              - e7718d7a3ce595f289bfee26adc178f5 # Repack/Proper
-              - ae43b294509409a6a13919dedd49c257 # Repack2
-              - 5caaaa1c08c1742aa4342571f427e5c5 # Repack3
-            assign_scores_to:
-              - name: SQP-1 (2160p)
-
-          # Movie Versions
-          - trash_ids:
-              - eca37840c13c6ef2dd0754c2a6a89554 # Criterion Collection
-              - 0f12c086e289cf966fa5948eac571f44 # Hybrid
-              - 570bc9ebecd92723d2d21500f4be314c # Remaster
-              - eecf3a857724171f968a66cb5719e152 # IMAX
-              - 9d27d9d2181838f76dee150882bdc58c # IMAX Enhanced
-            assign_scores_to:
-              - name: SQP-1 (2160p)
-
-          # Language / naming risk - deprioritize (not block) releases whose title format is more
-          # likely to defeat Radarr's import parser and trigger the "matched movie by ID, Manual
-          # Import required" stuck-queue state. Scores are intentionally small (well under
-          # min_format_score) so a foreign-audio or MULTi release is still grabbed when it's the
-          # best/only match - this only nudges Radarr toward a cleaner-named English release when
-          # more than one candidate is available.
-          - trash_ids:
-              - 0dc8aec3bd1c47cd6c40c46ecd27e846 # Language: Not English
-            score: -25
-            assign_scores_to:
-              - name: SQP-1 (2160p)
-          - trash_ids:
-              - 4b900e171accbfb172729b63323ea8ca # MULTi
-            score: -25
-            assign_scores_to:
-              - name: SQP-1 (2160p)
-kind: ConfigMap
-metadata:
-  annotations:
-    kustomize.toolkit.fluxcd.io/substitute: disabled
-  labels:
-    app.kubernetes.io/name: recyclarr
-    kustomize.toolkit.fluxcd.io/name: recyclarr
-    kustomize.toolkit.fluxcd.io/namespace: downloads
-  name: recyclarr-m2dt5hb278
-  namespace: downloads
-

--- HelmRelease downloads/recyclarr
+++ HelmRelease downloads/recyclarr
@@ -82,6 +82,6 @@
         - path: /config/recyclarr.yml
           readOnly: true
           subPath: recyclarr.yml
-        name: recyclarr-m2dt5hb278
+        name: recyclarr-9925979k9k
         type: configMap
 

@mortyops

mortyops Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor
--- CronJob downloads/recyclarr
+++ CronJob downloads/recyclarr
@@ -69,7 +69,7 @@
             persistentVolumeClaim:
               claimName: recyclarr-config
           - configMap:
-              name: recyclarr-m2dt5hb278
+              name: recyclarr-9925979k9k
             name: config-file
   schedule: '@daily'
   startingDeadlineSeconds: 30

@Aviator-Coding
Aviator-Coding merged commit acfcde3 into main Aug 29, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant