#!/usr/bin/env python3 """The D-20260831-03(c) holdout rule, as a pure function over (identifier, tier, track). Kept in its own module so the freeze script and the dry-run share ONE implementation — a split rule that exists twice is a split rule that will disagree with itself. """ from __future__ import annotations RULE_VERBATIM = ( "D-20260831-03(c) — ~20% held out, STRATIFIED BY ITEM (an item's tracks are all-in " "or all-out; no EP straddles): eligible-for-holdout = items with <=8 tracks (the " "mega-items hardware-techno, onmp215a, unfound88, shinji-wakasa-dawn, " "braids-flurish-perish are never held out). Group eligible items by tier " "(CC0/BY/BY-SA); within each tier sort by identifier case-insensitively; walk taking " "every 3rd item (index%3==0) until that tier's held-out track count reaches ~20% of " "the tier's post-exclusion tracks; if short after the walk, a second pass at " "index%3==1. Deterministic, no seed." ) MAX_ELIGIBLE_TRACKS = 8 HOLDOUT_FRACTION = 0.20 TIER_ORDER = ("CC0", "BY", "BY-SA") def split_tier(items: dict[str, list], tier_tracks: int) -> dict: """Apply the rule inside one tier. `items` maps identifier -> its track rows.""" target = HOLDOUT_FRACTION * tier_tracks eligible = sorted((i for i, rows in items.items() if len(rows) <= MAX_ELIGIBLE_TRACKS), key=str.lower) ineligible = sorted((i for i, rows in items.items() if len(rows) > MAX_ELIGIBLE_TRACKS), key=str.lower) held: list[str] = [] held_tracks = 0 walks = [] for remainder in (0, 1): walk = [ident for idx, ident in enumerate(eligible) if idx % 3 == remainder] taken = [] for ident in walk: if held_tracks >= target: break held.append(ident) taken.append(ident) held_tracks += len(items[ident]) walks.append({ "pass": f"index%3=={remainder}", "candidates": walk, "taken": taken, "held_tracks_after": held_tracks, "target_reached": held_tracks >= target, }) if held_tracks >= target: break return { "tier_items_post_exclusion": len(items), "tier_tracks_post_exclusion": tier_tracks, "target_tracks_20pct": round(target, 2), "eligible_items": eligible, "eligible_item_order_note": "sorted by identifier, case-insensitively (str.lower)", "ineligible_items_gt8_tracks": ineligible, "walks": walks, "held_items": held, "held_tracks": held_tracks, "held_pct_of_tier": round(100.0 * held_tracks / tier_tracks, 2) if tier_tracks else 0.0, } def split_corpus(rows: list[dict]) -> dict: """Apply the rule across every tier. Rows need `identifier`, `tier`, `work_key`.""" by_tier: dict[str, dict[str, list]] = {} for row in rows: by_tier.setdefault(row["tier"], {}).setdefault(row["identifier"], []).append(row) tiers = {} for tier in TIER_ORDER: if tier not in by_tier: continue items = by_tier[tier] tiers[tier] = split_tier(items, sum(len(v) for v in items.values())) held_items = {i for t in tiers.values() for i in t["held_items"]} return { "rule_verbatim": RULE_VERBATIM, "tiers": tiers, "held_item_set": sorted(held_items), "held_tracks_total": sum(t["held_tracks"] for t in tiers.values()), "tracks_total_post_exclusion": len(rows), }