Skip to content

feat(career): genre families — sub-genres inherit the family drill#951

Merged
byrongamatos merged 1 commit into
mainfrom
feat/career-genre-families
Jul 13, 2026
Merged

feat(career): genre families — sub-genres inherit the family drill#951
byrongamatos merged 1 commit into
mainfrom
feat/career-genre-families

Conversation

@byrongamatos

@byrongamatos byrongamatos commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

The enrichment fallback (#949) made the passport rack real — hundreds of MB sub-genres — but only the five exact umbrella keys carried Virtuoso drill requirements, so "death metal" (×439 on the real library) was songs-only while "metal" demanded Gallop Picking.

Genres now resolve to a family by keyword substring (MB's vocabulary is open — "metalcore" must hit metal without an exact alias), first-match-wins in list order ("blues rock" → blues), and inherit the family's requirement from the same genres map. Exact per-genre entries still win; per-instrument scoping unchanged (a keys passport never inherits a guitar drill); unmatched genres stay songs-only.

Shipped families: metal (djent/grindcore/thrash/doom), blues, jazz (bebop/swing/bossa), funk (disco), rock (punk/grunge/shoegaze). Pure data — retuning coverage is a passports.json edit.

Testing

Family inheritance (death metal, metalcore substring), list-order ambiguity (blues rock), outside-family songs-only, exact-beats-family, per-instrument isolation. 29 career tests green. Codex preflight clean (round 1).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added genre family support for career passports, including metal, blues, jazz, funk, and rock.
    • Passports can now inherit drill requirements from matching genre families when no exact genre requirement exists.
    • Exact genre-specific requirements continue to take precedence over family defaults.
    • Family-based drill requirements remain isolated by instrument.
  • Bug Fixes

    • Improved handling of multi-word and unmatched genres when determining required drills.

The enrichment fallback made the passport rack real (hundreds of MB
sub-genres) but only the five exact umbrella keys carried Virtuoso
drills. Genres now resolve to a family by keyword substring (MB's
vocabulary is open — 'metalcore' must hit metal without an alias),
first-match-wins in list order ('blues rock' → blues), and inherit the
family's requirement from the same genres map. Exact entries still win;
per-instrument scoping unchanged; unmatched genres stay songs-only.

Data: families for metal (incl. djent/grindcore/thrash/doom), blues,
jazz (bebop/swing/bossa), funk (disco), rock (punk/grunge/shoegaze).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Career passports now define genre families and inherit family-level drill requirements when no exact genre override exists. Exact genre entries remain preferred, while unmatched genres receive no family drills.

Changes

Career passport genre families

Layer / File(s) Summary
Family configuration
plugins/career/passports.json
Adds metal, blues, jazz, funk, and rock families with matching genre aliases.
Family requirement resolution and validation
plugins/career/routes.py, tests/plugins/career/test_passports.py
Adds substring-based family lookup and family fallback in _badge_requirement; tests cover precedence, family ordering, unmatched genres, badge state, and per-instrument isolation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the change and testing, but it misses the required template sections and checklist items. Add the What, feedpak surface, and Checklist sections with the required checkbox items and any issue link.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: genre-family inheritance for career passport drills.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/career-genre-families

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/plugins/career/test_passports.py (1)

232-236: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Exact-override assertion doesn't actually distinguish itself from family fallback.

genres_cfg["metal"] is both the exact entry for gkey "metal" and the fallback target when family resolution returns "metal", so this assertion would still pass even if the exact-match branch in _badge_requirement were removed. Consider a case where the exact override differs from the family default (e.g. monkeypatch a distinct override for a subgenre key) to truly exercise precedence.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/plugins/career/test_passports.py` around lines 232 - 236, Update the
exact-override test around _badge_requirement to use a subgenre whose exact
configuration is distinct from its family fallback, such as by monkeypatching a
separate override for the subgenre key. Assert that _passport returns the exact
override for that genre, so the test fails if exact-match precedence is removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/plugins/career/test_passports.py`:
- Around line 232-236: Update the exact-override test around _badge_requirement
to use a subgenre whose exact configuration is distinct from its family
fallback, such as by monkeypatching a separate override for the subgenre key.
Assert that _passport returns the exact override for that genre, so the test
fails if exact-match precedence is removed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f0a5948-34a5-42fc-9edd-2c2ac997560f

📥 Commits

Reviewing files that changed from the base of the PR and between 329cc86 and b6e7b3c.

📒 Files selected for processing (3)
  • plugins/career/passports.json
  • plugins/career/routes.py
  • tests/plugins/career/test_passports.py

@byrongamatos
byrongamatos merged commit 6cc0312 into main Jul 13, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant