Skip to content

fix(rank): single shared H2H ceremony driver — no more forked placement loops - #70

Merged
BIBOYANG425 merged 1 commit into
mainfrom
fix/agent-rank-h2h-parity
Jul 13, 2026
Merged

fix(rank): single shared H2H ceremony driver — no more forked placement loops#70
BIBOYANG425 merged 1 commit into
mainfrom
fix/agent-rank-h2h-parity

Conversation

@BIBOYANG425

@BIBOYANG425 BIBOYANG425 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

The /agent-rank card and the main web flow each carried a byte-for-byte private copy of the head-to-head placement driver (sessionRef/comparison/undo/proceed logic) around the shared RankingSession engine. Identical today, guaranteed to drift tomorrow. Extracted one shared driver (hooks/useRankingCeremony.ts: pure core + thin React binding); AddMediaModal and RankingFlowModal both consume it.

  • 5 seeded-tier fixed-choice parity scenarios assert identical comparison trace + final placement for main-flow vs agent-flow drivers
  • structural guards: neither modal instantiates RankingSession directly; AgentRankPage drives the shared modal
  • write path untouched (upsert + set_tier_order + stub + event)

Tests 699 → 716 green; vite build green.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Standardized head-to-head ranking across media and agent ranking flows.
    • Added consistent comparison logging and session tracking.
    • Added protection against duplicate submissions during comparisons.
    • Added undo support for returning to the previous comparison state.
  • Bug Fixes

    • Improved consistency of ranking results across different ranking flows.
  • Tests

    • Added coverage for placement, comparisons, undo behavior, logging, and ranking parity.

…arity)

The /agent-rank ceremony and the main webapp movie flow ran the same
RankingSession engine but through two hand-copied drivers: AddMediaModal
(main movie flow) and RankingFlowModal (book flow + /agent-rank) each kept
a byte-for-byte clone of the placement loop (sessionRef, isProcessingRef,
currentComparison, sessionId, proceedFromNotes/handleCompareChoice/handleUndo).
Two copies of the head-to-head binary-search loop is a fork waiting to
drift — the /agent-rank "wrong comparisons, not the full loop" defect.

Extract the driver into a single shared module (hooks/useRankingCeremony):
a pure, React-free CeremonyDriver (createCeremonyDriver) owns the
RankingSession lifecycle + comparison-log emission, and useRankingCeremony
mirrors it into component state. Both modals now consume it, so the agent
flow and the main flow drive ONE engine through ONE driver.

Behavior of the main flow is preserved (699 baseline green, unchanged); the
write path is untouched (still the standard contract path under the
agent-rank token client). Adds driver unit tests (comparison selection, the
loop, re-entrancy guard, undo, logging) and a parity test proving a seeded
tier + fixed choice sequence places identically for the main-flow and
agent-flow drivers, plus structural guards that neither modal news its own
RankingSession.

Tests: 699 → 716 (17 new). vite build green.

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

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
movie-list Ready Ready Preview, Comment Jul 13, 2026 7:28am
movie-list-mvp Ready Ready Preview, Comment Jul 13, 2026 7:28am

@supabase

supabase Bot commented Jul 13, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project emulyralduiitxuigboj because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

A shared useRankingCeremony hook and driver now centralize head-to-head ranking, logging, undo, and placement behavior. AddMediaModal and RankingFlowModal use the shared flow, with tests covering selection behavior, logging, parity, and wiring.

Changes

Ranking Ceremony Flow

Layer / File(s) Summary
Ceremony driver and contracts
hooks/useRankingCeremony.ts
Adds ceremony result types, driver interfaces, comparison logging, placement progression, re-entrancy protection, and undo handling.
React ceremony binding
hooks/useRankingCeremony.ts
Exposes the driver through React state with lifecycle reset and begin, choose, and undo operations.
Ranking modal integration
components/media/AddMediaModal.tsx, components/media/RankingFlowModal.tsx
Migrates modal initialization, comparison choices, placement, and undo behavior from direct RankingSession management to useRankingCeremony.
Selection and flow parity validation
hooks/__tests__/useRankingCeremony.test.ts, services/__tests__/agentRankCeremonyParity.test.ts
Tests selection, logging, undo, deterministic placement, agent/main-flow parity, and shared-hook wiring.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RankingModal
  participant useRankingCeremony
  participant CeremonyDriver
  participant RankingSession
  RankingModal->>useRankingCeremony: begin(selectedItem, selectedTier)
  useRankingCeremony->>CeremonyDriver: begin(item, tier)
  CeremonyDriver->>RankingSession: start or place
  RankingSession-->>CeremonyDriver: comparison or rank
  CeremonyDriver-->>useRankingCeremony: CeremonyStep
  useRankingCeremony-->>RankingModal: compare or placed
  RankingModal->>useRankingCeremony: choose(choice)
  useRankingCeremony->>CeremonyDriver: choose(choice)
  CeremonyDriver->>RankingSession: advance comparison
  RankingSession-->>RankingModal: next comparison or rank
Loading

Possibly related PRs

  • BIBOYANG425/Movie_List#21: Introduced the earlier ranking orchestration in RankingFlowModal, which this PR replaces with the shared ceremony hook.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: extracting a shared head-to-head ceremony driver to replace forked placement logic.
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 fix/agent-rank-h2h-parity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
services/__tests__/agentRankCeremonyParity.test.ts (1)

74-98: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Parity assertion is largely tautological.

Both mainFlow and agentFlow run the same createCeremonyDriver directly and differ only by the withLogging flag; since logging is a read-only side channel, identical trace/rank is almost guaranteed by construction. This validates that logging doesn't perturb placement (useful), but it does not exercise the actual AddMediaModal/RankingFlowModal wiring — the "no fork" guarantee actually rests on the structural regex tests below. Consider clarifying the intent, or drive placement through the real modal hooks if you want true wiring parity.

🤖 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 `@services/__tests__/agentRankCeremonyParity.test.ts` around lines 74 - 98,
Clarify the ceremony parity test around runCeremony to state that it verifies
logging does not alter placement, rather than claiming to validate modal wiring.
Keep the trace and rank comparisons, and adjust the test description or comments
to distinguish this behavioral check from the separate structural regex
coverage.
hooks/useRankingCeremony.ts (1)

162-178: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Keep onCompare current in useRankingCeremony

ensure()/reset() freeze the first options object, but callers pass onCompare straight through from a render-scoped handler. If the modal rerenders before a compare completes, the driver can keep calling an outdated callback. Thread options through a ref or rebuild the driver when onCompare changes.

🤖 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 `@hooks/useRankingCeremony.ts` around lines 162 - 178, The ensure and reset
callbacks in useRankingCeremony capture the initial options object, leaving the
ceremony driver with a stale onCompare handler after rerenders. Keep the current
onCompare available to the driver by storing the latest options or onCompare in
a ref and using it when creating or invoking the driver, or recreate the driver
when onCompare changes while preserving existing session/reset behavior.
🤖 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 `@hooks/useRankingCeremony.ts`:
- Around line 162-178: The ensure and reset callbacks in useRankingCeremony
capture the initial options object, leaving the ceremony driver with a stale
onCompare handler after rerenders. Keep the current onCompare available to the
driver by storing the latest options or onCompare in a ref and using it when
creating or invoking the driver, or recreate the driver when onCompare changes
while preserving existing session/reset behavior.

In `@services/__tests__/agentRankCeremonyParity.test.ts`:
- Around line 74-98: Clarify the ceremony parity test around runCeremony to
state that it verifies logging does not alter placement, rather than claiming to
validate modal wiring. Keep the trace and rank comparisons, and adjust the test
description or comments to distinguish this behavioral check from the separate
structural regex coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fa8d011a-94c7-4075-9859-ee5ad6e05113

📥 Commits

Reviewing files that changed from the base of the PR and between 7aabaf9 and eef3bc3.

📒 Files selected for processing (5)
  • components/media/AddMediaModal.tsx
  • components/media/RankingFlowModal.tsx
  • hooks/__tests__/useRankingCeremony.test.ts
  • hooks/useRankingCeremony.ts
  • services/__tests__/agentRankCeremonyParity.test.ts

@BIBOYANG425
BIBOYANG425 merged commit b142669 into main Jul 13, 2026
6 checks passed
@BIBOYANG425
BIBOYANG425 deleted the fix/agent-rank-h2h-parity branch July 13, 2026 07:34
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