Skip to content

feat: land the recommendation-proof campaign (GOAL.md + scorer + corpus + UI badge) - #114

Merged
slittycode merged 3 commits into
mainfrom
chore/land-goal-and-recommendation-campaign
May 27, 2026
Merged

feat: land the recommendation-proof campaign (GOAL.md + scorer + corpus + UI badge)#114
slittycode merged 3 commits into
mainfrom
chore/land-goal-and-recommendation-campaign

Conversation

@slittycode

Copy link
Copy Markdown
Owner

Lands ASA's recommendation-proof campaign — the four-sub-goal effort
to turn recommendation quality from a manual ear-test into a
measurable, repeatable score, grounded in Live 12 projects with known
device settings. Brings the work that was sitting uncommitted on the
local `worktree-goal-doc` branch into `main`.

What lands

`GOAL.md` (commit 1) — the north-star spec. Sits below `PURPOSE.md`
(the why) and above `BACKLOG.md` (candidate features). Four sequenced
sub-goals: (1) ground-truth corpus + fixture format, (2) the scorer,
(3) iterate + Gemini verdict, (4) proof in product. Authority order
documented at the top.

Backend (commit 2): the scorer + answer-key corpus.

  • `recommendation_evaluation.py` — source-agnostic scorer
    implementing the role/parameter/direction-band rubric, with device
    equivalence classes (Compressor ↔ Glue Compressor earns credit),
    per-unit value tolerance bands, a chain-of-custody penalty that
    ports `phase2Validator.ts` semantics, and a `measurableIntent`
    equivalence credit so equivalent measurement routes earn partial
    score.
  • `scripts/evaluate_recommendations.py` — CLI runner
    (`--source {baseline,gemini,deterministic}`, `--self-test`,
    `--report`, `--json`, `--verification-artifact`).
  • `scripts/emit_deterministic_recs.ts` — Node 23+ TS bridge that
    wraps `apps/ui/src/data/abletonDevices.ts` so the free path can be
    scored without a Python re-port.
  • 5 catalog-valid spec fixtures (house, techno, melodic techno, dnb,
    acid), each with a manifest, a Phase 1 fingerprint, a per-track
    README, and a tiny proxy melody MIDI. Rendered audio is gitignored
    (renders are the owner's half — see `NEEDS.md`).
  • `NEEDS.md` — living campaign status doc and render-gated queue.
  • `RECOMMENDATION_VERDICT.md` — provisional Gemini-vs-deterministic
    verdict on synthetic-proxy renders (Gemini 0.227 vs deterministic
    0.000; deterministic loses on chain-of-custody despite competitive
    raw coverage).
  • 29 new tests; full backend suite 792 OK.

Frontend (commit 3): per-recommendation verification badge.

  • `RecommendationVerificationBadge` mounted on both the mix-chain
    cards and the patch cards in `AnalysisResults.tsx`.
  • Built on the shared `ui/` Pill primitive; honors invariant fix: chunk Demucs inference and stop boot-time memory spikes #4 by
    rendering nothing when corpus support is `NONE`.
  • 8 new tests; full UI suite 671 passed.

`CLAUDE.md` — synced to reference the new harness module, the
deterministic-source bridge, and the UI badge stack.

Honest caveats

  1. The corpus is on synthetic-proxy renders. The five fixtures were
    scored against numpy approximations of the specs, not Ableton
    renders, under an earlier "continue without input" directive. The
    known-settings axes (role recall, value accuracy) are provisional
    until the owner dials the specs in Live 12 and renders them
    (48 kHz / 24-bit FLAC; checklist in
    `apps/backend/tests/fixtures/recommendation_tracks/README.md`).
  2. Port drift to verify. `recommendation_evaluation.py`'s chain-of-
    custody penalty ports `phase2Validator.ts` semantics as of commit
    `0eac1ee5`. Main's validator has drifted (~131 lines changed) — re-
    verify port parity before any sub-goal 3 prompt iteration that
    depends on the custody penalty.
  3. Badge stays invisible until renders land. The generated artifact
    in `src/data/recommendationVerification.ts` is all-`NONE` pre-
    render. Wiring is proven by a unit test that injects a populated
    artifact; visible content waits on renders.
  4. `evaluate_recommendations.py` deterministic-source caveat. The
    bridge consumes an `AudioFeatures` object. Turning a real Phase 1
    fingerprint into `AudioFeatures` should reuse the app's
    `analyzer.ts` projection rather than re-deriving — only then is the
    deterministic score a real verdict input.

Verification

  • `cd apps/backend && ./venv/bin/python -m unittest discover -s tests`
    Ran 792 tests in 73.241s, OK (skipped=1).
  • `cd apps/ui && npm run lint` → clean (tsc).
  • `cd apps/ui && npm run test:unit` → 671 passed across 51 files.
  • `cd apps/ui && npm run build` → built in 1.53s.
  • Smoke (`npm run test:smoke`) skipped — needs the live stack.

After merge

Worth a follow-up decision: clean up the local `worktree-goal-doc`
branch and its worktree at `.claude/worktrees/goal-doc/` once this
lands, or leave them for reference until the real renders happen?

🤖 Generated with Claude Code

slittycode and others added 3 commits May 27, 2026 22:23
Brings the north-star campaign spec from the local 'worktree-goal-doc'
branch onto main so ASA has its current extended-effort objective
recorded in the canonical doc set. Sits below PURPOSE.md (the why) and
above BACKLOG.md (candidate features), per the authority order.

The doc is forward-looking — sub-goal sections describe what the work
*looks like*, not what's already on main. Implementation lives on the
'worktree-goal-doc' branch (scorer, fixtures, deterministic-source
bridge, UI verification badge) and is owner-render-gated; landing the
implementation is a separate decision the trailing 'Implementation
status' section flags. Verified every reference in GOAL.md resolves on
main before writing (audit file, prompt paths, sibling eval scripts,
fixture dirs, UI primitives).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lands the backend half of the recommendation-proof campaign (GOAL.md
sub-goals 1+2): a research-only scorer that grades Phase 2
recommendations against known Live 12 device settings, plus a corpus of
five catalog-valid spec fixtures (house, techno, melodic techno, dnb,
acid) and supporting status docs.

What's in:

- recommendation_evaluation.py — source-agnostic scorer implementing the
  role/parameter/direction-band rubric from GOAL.md. Per-domain
  breakdown over the seven production domains, device equivalence
  classes (Compressor ↔ Glue Compressor earns credit), per-unit value
  tolerance bands, and a chain-of-custody penalty that ports
  phase2Validator.ts semantics. Includes a measurableIntent equivalence
  credit so equivalent measurement routes earn partial score.
- scripts/evaluate_recommendations.py — CLI runner with
  --source {baseline,gemini,deterministic}, --self-test, --report,
  --json, --verification-artifact. Mirrors the existing eval-harness
  pattern; off the product path; deletable without affecting product.
- scripts/emit_deterministic_recs.ts — Node 23+ native TS bridge that
  wraps the product's abletonDevices.ts and emits the scorer's
  normalized rec shape. Single source of truth for the free path; no
  Python re-port.
- tests/test_recommendation_evaluation.py — 29 tests; full backend
  suite 792 OK.
- tests/fixtures/recommendation_tracks/ — five owner-plausible
  electronic-genre spec fixtures + a _TEMPLATE + corpus README +
  authoring checklist. Each fixture has a catalog-valid deviceSpec, a
  measurableIntent fingerprint, and a per-track README. Audio is
  gitignored (renders are the owner's half — see NEEDS.md); a tiny
  audio_melody.mid per fixture is the proxy melodic source.
- NEEDS.md — living campaign status doc + render-gated queue.
- RECOMMENDATION_VERDICT.md — provisional Gemini-vs-deterministic
  verdict on synthetic-proxy renders (Gemini 0.227 vs deterministic
  0.000; deterministic loses on chain-of-custody despite competitive
  raw coverage). Awaits real Ableton renders to become authoritative.

Known follow-up the next agent should not skip: the
recommendation_evaluation.py port of phase2Validator.ts semantics is
current as of 0eac1ee; main's validator has drifted (~131 lines
changed since). Re-verify port parity before any sub-goal 3 prompt
iteration that depends on the custody penalty.

Verified: cd apps/backend && ./venv/bin/python -m unittest discover -s
tests — Ran 792 tests in 73.241s, OK (skipped=1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lands the frontend half of the recommendation-proof campaign (GOAL.md
sub-goal 4): a confidence/verification badge that maps each Phase 2
recommendation card to a corpus support band, mounted on both the
mix-chain and patch recommendation cards in AnalysisResults.tsx.

Built on the shared ui/ Pill primitive — no one-off styled box. Honors
invariant #4 by rendering nothing when corpus support is NONE
(graceful pre-render degradation; the band only surfaces once the
backend scorer has scored real fixtures and regenerated the data
artifact).

What's in:

- src/components/RecommendationVerificationBadge.tsx — the badge.
- src/services/recommendationVerification.ts — domain inference
  (mirrors the backend scorer's infer_domain) + lookup against the
  generated artifact; node-testable.
- src/data/recommendationVerification.ts — typed artifact (all-NONE
  pre-render; regenerated from
  apps/backend/scripts/evaluate_recommendations.py
  --verification-artifact, per its header comment).
- tests/services/recommendationVerification.test.ts — 8 tests verifying
  the lookup path, the domain inference, and that an injected populated
  artifact surfaces the HIGH band (proves the wiring; the pre-render
  all-NONE state is the current honest content).
- AnalysisResults.tsx — RecommendationVerificationBadge mounted on both
  the mix-chain card header and the patch card header, beside the
  existing category pill.

Verified:
- cd apps/ui && npm run lint — clean (tsc).
- npm run test:unit — 671 passed across 51 files.
- npm run build — built in 1.53s; AnalysisResults bundle 256.77 kB.
- Smoke skipped (needs live stack).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@slittycode slittycode left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Verdict: APPROVE

Summary

Lands the recommendation-proof campaign: a research/eval harness (recommendation_evaluation.py, 1 206 lines) that scores Phase 2 recs against known-settings fixtures, a CLI runner, a Node 23+ TS bridge for the deterministic path, 5 genre fixture specs, 29 backend tests, a per-recommendation UI badge (8 frontend tests), and the GOAL.md north-star doc. The harness is strictly eval — it is not imported by analyze.py, server.py, or any server module; deleting it leaves the product exactly as it was. Phase boundary is clean throughout. The PR description is unusually honest about the caveats; the code matches.

Tests: Cannot locally verify (no venv or node_modules in this review environment). PR reports 792 OK backend / 671 passed frontend. Test quality is high — the suite exercises scoring semantics meaningfully (direction-scoring, equivalence credit, custody-penalty ordering invariant, determinism), not coverage padding.

Findings

Should fix

recommendationVerification.ts data vs. PR claim (apps/ui/src/data/recommendationVerification.ts): The PR description says "badge stays invisible until renders land." That's only true for the four NONE domains. bass (LOW / "Lightly checked") and master (MED / "Corpus-checked") will render today because those bands came from the synthetic-proxy scoring. The data file's own ⚠️ comment says these values are from synthetic proxies, so it's not hidden — but "Lightly checked" on a domain scored against numpy approximations, not Ableton renders, is easy to misread as real corpus evidence. Either ship the all-NONE pre-render artifact as the initial state and regenerate after real renders land, or ensure the tooltip copy makes the synthetic-proxy provenance explicit (the current tooltip only says Corpus support: 5 fixture(s) with no proxy caveat).

Worth considering

Keyword ordering divergence (recommendation_evaluation.py line ~626 vs recommendationVerification.ts line ~14): Python lists hathi-hathihat; TypeScript lists hi-hathihathat. The TS comment says it mirrors Python ordering — it doesn't. No functional difference (all three map to groove), but the comment is wrong and the divergence will bite if someone adds a keyword near hat that maps to a different domain and only updates one side.

Custody port drift: Already documented in the PR. Flagging it's the one thing that could make sub-goal 3 produce a misleading penalty score if run before the port is re-verified against the current phase2Validator.ts. The NEEDS.md note is sufficient; no action needed for this merge.

Test results

Cannot run locally (no venv, no node_modules). Reading the test code directly: ScoringTests.test_full_coverage_uncited_must_not_outscore_lower_coverage_cited is the most important gate (GOAL.md 2.d), and it's exercised correctly. AuthoredFixtureCatalogTests.test_example_fixtures_are_catalog_valid verifies all 7 domains are covered by the 5 committed fixtures — confirmed by inspection (all 5 manifests specify all 7 domains). CorpusVerificationTests.test_support_drives_confidence_band correctly validates the two-factor confidence logic. Frontend tests cover domain inference, graceful degradation, and the populated-artifact path.

Phase boundary check

Clean. recommendation_evaluation.py appears only in tests/, scripts/, and doc files — zero imports from analyze.py, server.py, or any router. The frontend badge reads a static pre-generated artifact, not live Phase 1 data; AnalysisResults.tsx passes only trackContext and category to the badge — both come from Phase 2 rec objects, not Phase 1 measurements. No Phase 1 fields are re-derived or overridden anywhere in this diff.


Generated by Claude Code

@slittycode
slittycode merged commit 348498d into main May 27, 2026
4 checks passed
@slittycode
slittycode deleted the chore/land-goal-and-recommendation-campaign branch May 27, 2026 14:08
slittycode added a commit that referenced this pull request May 28, 2026
The recommendation-proof campaign was authored on the `worktree-goal-doc`
branch and landed via PR #114 (commit 348498d), but the status sections in
GOAL.md and apps/backend/NEEDS.md still described the pre-merge state.

- GOAL.md "Implementation status": rewrite to reflect that the scorer,
  fixtures, deterministic-source bridge, UI badge, and verdict write-up
  are on main, and the remaining work is the owner-gated Live 12 renders.
- NEEDS.md: drop the now-merged "RETROACTIVE #5" branch-convergence item
  and reframe the "Branch convergence needed for 3.2" section as
  audit-context (the audit branch and Tier-1/2 fixes are on main via
  5610ca5/ade2ae5; the campaign sits on top of them).
- NEEDS.md provisional finding: replace "coordinate with branch
  convergence below" with a pointer to the NEEDS-WIRING dead-code finding,
  since the branch-convergence prerequisite no longer exists.

https://claude.ai/code/session_01Kh5q91wQoF8EF2BD41RMWN

Co-authored-by: Claude <noreply@anthropic.com>
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