Skip to content

Add tiered steward review workflow#949

Open
JoaquinBN wants to merge 8 commits into
devfrom
JoaquinBN/steward-review-layers
Open

Add tiered steward review workflow#949
JoaquinBN wants to merge 8 commits into
devfrom
JoaquinBN/steward-review-layers

Conversation

@JoaquinBN

@JoaquinBN JoaquinBN commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add reviewer, top-level, and apex steward tiers with effective superuser elevation
  • gate tier-1 access to AI-reviewed, appealed, resubmitted, assigned, or already-proposed submissions
  • convert tier-1 accepts at configured final-point thresholds into auditable human proposals
  • add escalated queue filtering, tier-aware shortcuts, and escalation feedback in the steward portal
  • extend AI review handling so appeals remain pending for human reconsideration

Review safeguards

  • preserve milestone links while changed-type proposals await approval, including grandfathered links to projects that are no longer highlighted
  • allow downward and unchanged accepted-point corrections while blocking upward threshold-level changes by tier-1 reviewers
  • clear stale escalation markers after admin state changes
  • keep public user profiles from exposing steward tier or superuser elevation
  • use the last successfully applied queue query for client-side row updates
  • avoid database writes from tier-1 visibility checks and skip unused deterministic gate evaluation for appeals

Validation

  • 1,241 backend tests passed
  • 88 migration-enabled hierarchy and lifecycle tests passed
  • 49 focused steward queue, card, and search tests passed
  • Django system check passed
  • migration drift check reported no changes
  • production frontend build succeeded

The repository-wide frontend test command still reports existing failures in unrelated Profile, Dashboard, route metadata, and AuthButton mock suites; all steward-related frontend tests pass.

Deployment note

Migration 0084_enable_builder_review_hierarchy enables AI gating for every builder-category contribution type. Confirm external AI coverage for each builder type before deployment, or selectively disable requires_ai_review in admin for uncovered types.

Summary by CodeRabbit

  • New Features
    • Rolled out tiered steward hierarchy with builder submissions gated by AI review and optional escalation thresholds.
    • Added escalation tracking and queue/search support, including is:escalated / not:escalated, new escalation-aware UI labels, and steward/user fields (steward_tier, escalated_at).
    • Updated reviewer rewards/points logic to account for escalation and decision changes, with new decision-reward granting behavior.
  • Bug Fixes
    • AI review listings and processing now include appealed submissions by default (and can be filtered explicitly).
  • Documentation
    • Updated review-pipeline and search/queue documentation to reflect the new AI + human escalation flow.
  • Tests
    • Expanded backend and frontend coverage for escalation, appeals, permissions/visibility, and queue/search interactions.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a three-tier steward hierarchy with AI-gated visibility, threshold-based escalation, appeal-aware AI processing, escalation lifecycle tracking, backend filters, reward adjustments, and tier-aware frontend queues and review controls.

Changes

Review hierarchy

Layer / File(s) Summary
Hierarchy contracts and permissions
backend/contributions/models.py, backend/contributions/migrations/*, backend/stewards/*, backend/contributions/permissions.py, backend/users/serializers.py
Adds steward tiers, AI-review configuration, escalation timestamps, transition events, tier-aware permissions, serializer fields, migrations, admin exposure, and fixture updates.
AI review and appeal handling
backend/contributions/ai_review/views.py, backend/contributions/management/commands/review_submissions.py, backend/contributions/tests/test_ai_review_auth.py, backend/contributions/tests/test_review_submissions.py
Appealed submissions are included in AI review flows, marked gate_reviewed, and skipped by deterministic rejection logic while remaining available for human review.
Escalation orchestration and rewards
backend/contributions/views.py, backend/contributions/reviewer_rewards.py, backend/contributions/tests/test_escalation.py, backend/contributions/tests/test_reviewer_rewards.py
Implements threshold-based proposal escalation, tier-gated visibility, lifecycle cleanup, proposal persistence, milestone handling, decision rewards, and point-adjusted reviewer rewards.
Steward queue and escalation UI
frontend/src/components/*, frontend/src/routes/StewardSubmissions.svelte, frontend/src/lib/*, frontend/src/tests/*
Adds escalated search filters, tier-gated queue shortcuts, escalation-aware review cards, questioned-escalation revision controls, and queue removal after actions change filter membership.
Review workflow documentation
CHANGELOG.md, backend/*CLAUDE.md, backend/submissions_review.md, frontend/CLAUDE.md
Documents the multi-stage AI/steward workflow, appeal visibility, escalation behavior, steward tiers, rewards, and frontend queue conventions.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: introducing a tiered steward review workflow.
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 JoaquinBN/steward-review-layers

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.

@JoaquinBN
JoaquinBN marked this pull request as ready for review July 23, 2026 08:11

@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.

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@backend/contributions/migrations/0084_enable_builder_review_hierarchy.py`:
- Around line 4-17: The migration functions enable_builder_review_hierarchy and
disable_builder_review_hierarchy should not be responsible for enforcing Builder
defaults on existing rows. Move the requires_ai_review and
escalation_threshold_points defaults into the ContributionType
creation/configuration path for Builder-category types, preserving them for
types created later. Make disable_builder_review_hierarchy non-destructive so
rollback does not overwrite later per-type configuration, and align the
implementation with the documented Builder-category default behavior.

In `@frontend/src/routes/StewardSubmissions.svelte`:
- Around line 441-445: Extract the repeated response handling in
handleToggleInteresting, handleContributionTypeUpdate, and handlePropose into a
shared helper that checks matchesActiveQueueFlags, removes mismatched
submissions via removeSubmissionFromPage, and otherwise performs the existing
in-place update. Reuse this helper from handleReview while preserving its
additional stateFilter condition.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3812a0d0-f67b-452e-a8c4-32d3dcfc8082

📥 Commits

Reviewing files that changed from the base of the PR and between 404740a and 3870039.

📒 Files selected for processing (32)
  • CHANGELOG.md
  • backend/CLAUDE.md
  • backend/contributions/admin.py
  • backend/contributions/ai_review/views.py
  • backend/contributions/management/commands/review_submissions.py
  • backend/contributions/migrations/0083_review_hierarchy_fields.py
  • backend/contributions/migrations/0084_enable_builder_review_hierarchy.py
  • backend/contributions/models.py
  • backend/contributions/permissions.py
  • backend/contributions/serializers.py
  • backend/contributions/tests/test_ai_review_auth.py
  • backend/contributions/tests/test_escalation.py
  • backend/contributions/tests/test_review_submissions.py
  • backend/contributions/tests/test_state_transitions.py
  • backend/contributions/tests/test_steward_submission_search.py
  • backend/contributions/tests/test_tier_permissions.py
  • backend/contributions/views.py
  • backend/stewards/admin.py
  • backend/stewards/migrations/0013_steward_tier.py
  • backend/stewards/models.py
  • backend/submissions_review.md
  • backend/users/serializers.py
  • frontend/CLAUDE.md
  • frontend/src/components/StewardSearchBar.svelte
  • frontend/src/components/StewardSubmissionCard.svelte
  • frontend/src/lib/searchParser.js
  • frontend/src/lib/searchToParams.js
  • frontend/src/routes/StewardSubmissions.svelte
  • frontend/src/tests/StewardSearchBar.test.js
  • frontend/src/tests/StewardSubmissionCard.test.js
  • frontend/src/tests/StewardSubmissions.test.js
  • frontend/src/tests/searchParser.test.js
💤 Files with no reviewable changes (1)
  • backend/contributions/ai_review/views.py

Comment on lines +4 to +17
def enable_builder_review_hierarchy(apps, schema_editor):
ContributionType = apps.get_model('contributions', 'ContributionType')
ContributionType.objects.filter(category__slug='builder').update(
requires_ai_review=True,
escalation_threshold_points=400,
)


def disable_builder_review_hierarchy(apps, schema_editor):
ContributionType = apps.get_model('contributions', 'ContributionType')
ContributionType.objects.filter(category__slug='builder').update(
requires_ai_review=False,
escalation_threshold_points=None,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Do not make Builder hierarchy configuration a one-time data migration.

Line 6 configures only existing rows; Builder types created later retain False/None and bypass the intended AI gate and escalation. Line 14 also erases any later per-type configuration during rollback. Enforce the Builder default in the creation/configuration path and use a non-destructive reverse migration.

This conflicts with the documented Builder-category default behavior in backend/CLAUDE.md.

🧰 Tools
🪛 Ruff (0.15.21)

[warning] 4-4: Unused function argument: schema_editor

(ARG001)


[warning] 12-12: Unused function argument: schema_editor

(ARG001)

🤖 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 `@backend/contributions/migrations/0084_enable_builder_review_hierarchy.py`
around lines 4 - 17, The migration functions enable_builder_review_hierarchy and
disable_builder_review_hierarchy should not be responsible for enforcing Builder
defaults on existing rows. Move the requires_ai_review and
escalation_threshold_points defaults into the ContributionType
creation/configuration path for Builder-category types, preserving them for
types created later. Make disable_builder_review_hierarchy non-destructive so
rollback does not overwrite later per-type configuration, and align the
implementation with the documented Builder-category default behavior.

Comment thread frontend/src/routes/StewardSubmissions.svelte Outdated
@JoaquinBN
JoaquinBN force-pushed the JoaquinBN/steward-review-layers branch from 3870039 to 5b58433 Compare July 23, 2026 08:57

@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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/components/StewardSubmissionCard.svelte (1)

628-643: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Use the submission-date multiplier for escalation previews.

getFinalPoints() uses the active multiplier map, but escalation is defined against the multiplier effective on the submission’s contribution date. A multiplier change can make the tier-1 UI incorrectly present an acceptance as final or escalated. Pass a server-calculated escalation result or a per-submission effective multiplier to this card.

🤖 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 `@frontend/src/components/StewardSubmissionCard.svelte` around lines 628 - 643,
Update the escalation preview flow around getFinalPoints() and
acceptWillEscalate() to use the multiplier effective on the submission’s
contribution date, not the current active multipliers map. Prefer consuming a
server-calculated escalation result; otherwise provide and apply a
per-submission effective multiplier when calculating final points, while
preserving the existing threshold and tier checks.
🤖 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.

Inline comments:
In `@backend/contributions/management/commands/review_submissions.py`:
- Around line 332-341: Move the submission appeal handling around the
`has_appeal` branch ahead of the global `if not templates: return` preflight, so
appealed submissions are counted, logged, and passed to `_mark_gate_reviewed`
during non-dry runs even when no templates are available. Keep
template-dependent rejection processing after this appeal path.

In `@backend/contributions/models.py`:
- Around line 84-96: Replace the __init__-kwargs-based tracking of
_explicit_review_fields_on_create with logic that identifies Admin-assigned
builder review values after form data is applied but before
ContributionType.save() mutates defaults. Update the related save/default logic
to preserve explicit False/None and excluded-field behavior, and remove reliance
on explicit_review_fields captured in __init__.

In `@backend/contributions/views.py`:
- Around line 2518-2526: Update the GlobalLeaderboardMultiplier.DoesNotExist
branch in the escalation check around effective_steward_tier and
escalation_threshold_points so a missing date-specific multiplier cannot bypass
escalation; conservatively require escalation or use a multiplier of 1 for the
threshold comparison, while preserving existing behavior when a multiplier is
found.

---

Outside diff comments:
In `@frontend/src/components/StewardSubmissionCard.svelte`:
- Around line 628-643: Update the escalation preview flow around
getFinalPoints() and acceptWillEscalate() to use the multiplier effective on the
submission’s contribution date, not the current active multipliers map. Prefer
consuming a server-calculated escalation result; otherwise provide and apply a
per-submission effective multiplier when calculating final points, while
preserving the existing threshold and tier checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: af2508d8-a2bc-4bc0-a94a-7071cf5d4930

📥 Commits

Reviewing files that changed from the base of the PR and between 3870039 and 6ef2526.

📒 Files selected for processing (36)
  • CHANGELOG.md
  • backend/CLAUDE.md
  • backend/contributions/admin.py
  • backend/contributions/ai_review/views.py
  • backend/contributions/management/commands/review_submissions.py
  • backend/contributions/migrations/0083_review_hierarchy_fields.py
  • backend/contributions/migrations/0084_enable_builder_review_hierarchy.py
  • backend/contributions/models.py
  • backend/contributions/permissions.py
  • backend/contributions/serializers.py
  • backend/contributions/tests/test_ai_review_auth.py
  • backend/contributions/tests/test_calibration_data.py
  • backend/contributions/tests/test_escalation.py
  • backend/contributions/tests/test_project_milestone_rubric.py
  • backend/contributions/tests/test_projects_and_milestones.py
  • backend/contributions/tests/test_review_submissions.py
  • backend/contributions/tests/test_reviewer_rewards.py
  • backend/contributions/tests/test_state_transitions.py
  • backend/contributions/tests/test_steward_submission_search.py
  • backend/contributions/tests/test_tier_permissions.py
  • backend/contributions/views.py
  • backend/stewards/admin.py
  • backend/stewards/migrations/0013_steward_tier.py
  • backend/stewards/models.py
  • backend/submissions_review.md
  • backend/users/serializers.py
  • frontend/CLAUDE.md
  • frontend/src/components/StewardSearchBar.svelte
  • frontend/src/components/StewardSubmissionCard.svelte
  • frontend/src/lib/searchParser.js
  • frontend/src/lib/searchToParams.js
  • frontend/src/routes/StewardSubmissions.svelte
  • frontend/src/tests/StewardSearchBar.test.js
  • frontend/src/tests/StewardSubmissionCard.test.js
  • frontend/src/tests/StewardSubmissions.test.js
  • frontend/src/tests/searchParser.test.js
💤 Files with no reviewable changes (1)
  • backend/contributions/ai_review/views.py

Comment thread backend/contributions/management/commands/review_submissions.py Outdated
Comment thread backend/contributions/models.py Outdated
Comment thread backend/contributions/views.py Outdated
Comment on lines +2518 to +2526
threshold = contribution_type.escalation_threshold_points
if effective_steward_tier(request.user) < 2 and threshold is not None:
try:
_, multiplier = GlobalLeaderboardMultiplier.get_active_for_type(
contribution_type,
at_date=submission.contribution_date,
)
except GlobalLeaderboardMultiplier.DoesNotExist:
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find how frozen_global_points is computed on Contribution creation to compare
# with the escalation final_points formula, and whether missing multiplier is handled.
ast-grep outline backend/leaderboard/models.py --items all --match 'Contribution|GlobalLeaderboardMultiplier' 2>/dev/null
rg -nP -C3 '\bfrozen_global_points\b|multiplier_at_creation' backend/contributions/models.py backend/leaderboard/models.py

Repository: genlayer-foundation/points

Length of output: 18794


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== views outline around escalation =="
ast-grep outline backend/contributions/views.py --match 'escalation|final_points|final_review' 2>/dev/null | sed -n '1,220p' || true

echo
echo "== relevant views lines 2460-2550 =="
cat -n backend/contributions/views.py | sed -n '2460,2550p'

echo
echo "== relevant models lines 440-486 =="
cat -n backend/contributions/models.py | sed -n '440,486p'

echo
echo "== GlobalLeaderboardMultiplier methods =="
cat -n backend/leaderboard/models.py | sed -n '292,345p'

echo
echo "== search escalation_threshold_points usages =="
rg -n -C3 'escalation_threshold_points|final_points|FinalPoints|GlobalLeaderboardMultiplier\.get_active_for_type' backend

Repository: genlayer-foundation/points

Length of output: 50382


Conservatively gate escalation when the date-specific multiplier is unavailable.

A missing GlobalLeaderboardMultiplier falls through pass, so a tier‑1 steward can accept an award that is normally above escalation_threshold_points without creating the tiered-approval proposal. Escalation is an authorization control; handle the missing multiplier conservatively, e.g. by requiring escalation or using multiplier 1 for the threshold comparison.

🤖 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 `@backend/contributions/views.py` around lines 2518 - 2526, Update the
GlobalLeaderboardMultiplier.DoesNotExist branch in the escalation check around
effective_steward_tier and escalation_threshold_points so a missing
date-specific multiplier cannot bypass escalation; conservatively require
escalation or use a multiplier of 1 for the threshold comparison, while
preserving existing behavior when a multiplier is found.

Source: Path instructions

Threshold-enabled review decisions now grant deduplicated rewards to tier-one stewards, while escalated standard and rubric proposals share the existing accuracy-based economy. Proposal rewards scale down for point disagreements, and decision notes keep direct and proposer rewards separate.

## Claude Implementation Notes
- backend/contributions/reviewer_rewards.py: Add proportional point slashing, shared reward grants, and deduplicated decision rewards.
- backend/contributions/views.py: Record every escalation proposal and integrate proposal and direct-decision rewards.
- backend/contributions/tests/test_escalation.py: Cover escalation outcomes, exclusions, deduplication, and combined rewards.
- backend/contributions/tests/test_reviewer_rewards.py: Cover reward math, point adjustments, and persisted reward metadata.
- backend/submissions_review.md: Document the expanded reviewer economy.
- backend/CLAUDE.md: Record reward rules and deduplication behavior.

@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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@backend/contributions/reviewer_rewards.py`:
- Around line 46-54: Update the proportional-scaling condition in the reviewer
reward calculation to recognize proposed_points == 0 as provided, while avoiding
division by zero by handling the zero-proposal case explicitly. Preserve the
existing scaling behavior for nonzero proposed_points and final_points values,
and add a regression test alongside test_points_proportional_slash covering
proposed_points=0 with a nonzero final_points.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2480f171-272a-457a-b3df-43c7dfcdeba1

📥 Commits

Reviewing files that changed from the base of the PR and between f415151 and e561a74.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • backend/CLAUDE.md
  • backend/contributions/reviewer_rewards.py
  • backend/contributions/tests/test_escalation.py
  • backend/contributions/tests/test_reviewer_rewards.py
  • backend/contributions/views.py
  • backend/submissions_review.md

Comment thread backend/contributions/reviewer_rewards.py
Reviewer reward scaling now treats zero as a provided point proposal without dividing by zero. Matching zero-point decisions retain the computed reward, while nonzero final awards reduce it to zero.

## Claude Implementation Notes
- backend/contributions/reviewer_rewards.py: Handle zero-point proposals explicitly during proportional scaling.
- backend/contributions/tests/test_reviewer_rewards.py: Add regression coverage for zero-to-nonzero point changes.

@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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/contributions/reviewer_rewards.py (1)

130-150: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make decision-reward deduplication atomic.

The duplicate check runs before _grant_reward_contribution() acquires its lock. Concurrent requests can both observe no existing contribution and create duplicate rewards for the same user, submission, and action. Move the check under the same select_for_update() transaction, or enforce a database-level idempotency constraint and handle conflicts.

🤖 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 `@backend/contributions/reviewer_rewards.py` around lines 130 - 150, Make
deduplication in the decision-reward flow atomic by moving the existing
contribution lookup for user, contribution_type, and notes into the same
select_for_update() transaction used by _grant_reward_contribution, or enforce
and handle an equivalent database idempotency constraint. Preserve the existing
'duplicate' return behavior while preventing concurrent requests from creating
multiple rewards for the same user, submission, and action.
🤖 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.

Inline comments:
In `@backend/contributions/tests/test_reviewer_rewards.py`:
- Around line 485-492: Add a second assertion alongside the existing
compute_reviewer_reward exact-match test, using proposed_points=0 and
final_points=0, and verify that it returns the base reward. Keep the current
nonzero-final assertion unchanged.

---

Outside diff comments:
In `@backend/contributions/reviewer_rewards.py`:
- Around line 130-150: Make deduplication in the decision-reward flow atomic by
moving the existing contribution lookup for user, contribution_type, and notes
into the same select_for_update() transaction used by
_grant_reward_contribution, or enforce and handle an equivalent database
idempotency constraint. Preserve the existing 'duplicate' return behavior while
preventing concurrent requests from creating multiple rewards for the same user,
submission, and action.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e2c04260-6ba0-412e-9513-84cef8e12cff

📥 Commits

Reviewing files that changed from the base of the PR and between e561a74 and 2e33b1a.

📒 Files selected for processing (2)
  • backend/contributions/reviewer_rewards.py
  • backend/contributions/tests/test_reviewer_rewards.py

Comment on lines +485 to +492
self.assertEqual(
compute_reviewer_reward(
**exact_match,
proposed_points=0,
final_points=10,
),
0,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for zero-point exact matches.

The implementation intentionally preserves the computed reward when both proposed_points and final_points are 0, but this test only covers the nonzero-final case. Add an assertion for proposed_points=0, final_points=0 expecting the base reward.

🤖 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 `@backend/contributions/tests/test_reviewer_rewards.py` around lines 485 - 492,
Add a second assertion alongside the existing compute_reviewer_reward
exact-match test, using proposed_points=0 and final_points=0, and verify that it
returns the base reward. Keep the current nonzero-final assertion unchanged.

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