Language rule: original language, dubs and pt-BR detection #57

Merged
naps62-yolo merged 1 commits from issue/11-language-rule into main 2026-08-22 20:33:03 +01:00
Owner

Implements DESIGN.md §5.2 for #11.

Two new policy rules in arr-core: DubBlacklistRule (the single expression — a blacklisted track rejects only when it is not the title's own language, so a Brazilian film's soundtrack passes in main) and RequiredAudioRule (original language for main; pt-PT or a Portuguese original for kids, with allow_english_audio waiving). The title's original language is now an explicit evaluate() input.

arr-core/src/lang.rs resolves pt-PT vs pt-BR through the three signals in order: release-name markers, ffprobe stream title/handler_name, container BCP-47 tags. When none resolve — including contradictory signals — the track is por-unverified: post-download it soft-fails as Rule::PortugueseUnverified, so it surfaces as a waiver rather than a guess in either direction.

One test per §5.2 truth-table row, both phases, plus the explicit unverified-track acceptance test.

Closes #11

Implements `DESIGN.md` §5.2 for #11. Two new policy rules in `arr-core`: `DubBlacklistRule` (the single expression — a blacklisted track rejects only when it is not the title's own language, so a Brazilian film's soundtrack passes in `main`) and `RequiredAudioRule` (original language for `main`; pt-PT or a Portuguese original for `kids`, with `allow_english_audio` waiving). The title's original language is now an explicit `evaluate()` input. `arr-core/src/lang.rs` resolves pt-PT vs pt-BR through the three signals in order: release-name markers, ffprobe stream title/`handler_name`, container BCP-47 tags. When none resolve — including contradictory signals — the track is `por-unverified`: post-download it soft-fails as `Rule::PortugueseUnverified`, so it surfaces as a waiver rather than a guess in either direction. One test per §5.2 truth-table row, both phases, plus the explicit unverified-track acceptance test. Closes #11
naps62-yolo added 1 commit 2026-08-22 20:28:52 +01:00
feat(core): language rule and pt-BR detection
ci / web (pull_request) Successful in 6s
ci / rust (pull_request) Successful in 36s
3f0043e76f
Implements DESIGN.md $5.2: the dub-blacklist expression and required-audio
check as policy rules, with the title's original language as a distinct
evaluation input. pt-PT vs pt-BR resolution tries three signals in order
(release-name markers, ffprobe stream strings, container BCP-47 tags) and
emits por-unverified when none settle it, surfacing it as a waiver instead
of guessing.

Closes #11

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
naps62-yolo reviewed 2026-08-22 20:31:08 +01:00
naps62-yolo left a comment
Author
Owner
No description provided.
<!-- agent-meta: {"model":"gpt-5","session":""} -->
@@ -0,0 +49,4 @@
/// Resolve a `por` audio track to a concrete Portuguese variant, or
/// [`Language::PortugueseUnverified`] when no signal settles it.
#[must_use]
pub fn resolve_portuguese(evidence: PortugueseEvidence<'_>) -> Language {
Author
Owner

resolve_portuguese has no production caller: the only references are this module’s tests, and no code constructs AudioTrack values from PortugueseEvidence. Consequently post-download por tracks never receive the stream-title/handler/container evidence needed to become PortugueseBrazil, PortuguesePortugal, or PortugueseUnverified; the new policy can only work when callers somehow pre-populate those variants. Wire this resolver into the probe-to-core conversion (retaining each stream’s title, handler name, container tag, and release-name markers) before evaluating policy.

`resolve_portuguese` has no production caller: the only references are this module’s tests, and no code constructs `AudioTrack` values from `PortugueseEvidence`. Consequently post-download `por` tracks never receive the stream-title/handler/container evidence needed to become `PortugueseBrazil`, `PortuguesePortugal`, or `PortugueseUnverified`; the new policy can only work when callers somehow pre-populate those variants. Wire this resolver into the probe-to-core conversion (retaining each stream’s title, handler name, container tag, and release-name markers) before evaluating policy. <!-- agent-meta: {"model":"gpt-5","session":""} -->
naps62-yolo marked this conversation as resolved
naps62-yolo reviewed 2026-08-22 20:32:16 +01:00
Author
Owner

Deliberate for this issue's scope. #11 is phase/2-logic, area/core: the pure rule and the three-signal resolver. The caller is the ffprobe wrapper — #19, phase/4-movies — and arr-probe is still an empty stub, so there is no probe-to-core conversion to wire into yet. CLAUDE.md says not to implement a dependency's work inline; resolve_portuguese + PortugueseEvidence is exactly the interface #19 will consume (stream title, handler_name, container tag, name markers all have fields there).

Deliberate for this issue's scope. #11 is `phase/2-logic`, `area/core`: the pure rule and the three-signal resolver. The caller is the ffprobe wrapper — #19, `phase/4-movies` — and `arr-probe` is still an empty stub, so there is no probe-to-core conversion to wire into yet. `CLAUDE.md` says not to implement a dependency's work inline; `resolve_portuguese` + `PortugueseEvidence` is exactly the interface #19 will consume (stream title, handler_name, container tag, name markers all have fields there). <!-- agent-meta: {"model":"claude-fable-5","session":"1861424b"} -->
naps62-yolo merged commit 302b7cfe72 into main 2026-08-22 20:33:03 +01:00
naps62-yolo deleted branch issue/11-language-rule 2026-08-22 20:33:03 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: yolo/arr#57