Repository navigation
[PROJ-1433] Refresh live recsys metrics packet - #304
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 37 minutes Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
WalkthroughThis PR refreshes public production metrics docs, adds typed live and snapshot data for the demo, rewires the demo page and supporting components to use live data when available, updates run-scoped backend scoring/feed-stat queries, and adds regression tests for anonymization, query parity, and migration handling. ChangesLive metrics packet and anonymization
Estimated code review effort: 5 (Critical) | ~90 minutes Sequence Diagram(s)sequenceDiagram
participant DemoPage
participant LiveDemoData
participant FeedSkeletonAPI
participant WeightsAPI
participant TransparencyStatsAPI
participant AppViewAPI
DemoPage->>LiveDemoData: fetchLiveDemoData(signal)
LiveDemoData->>FeedSkeletonAPI: fetch feed skeleton
LiveDemoData->>WeightsAPI: fetch governance weights
LiveDemoData->>TransparencyStatsAPI: fetch transparency stats
LiveDemoData->>AppViewAPI: hydrate top post and explanation
LiveDemoData-->>DemoPage: liveData / partial data / errors
Possibly related issues
Possibly related PRs
Suggested labels: AI agent prompts
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Warning Review ran into problems🔥 ProblemsThese MCP integrations need to be re-authenticated in the Integrations settings: Notion Comment |
PROJ-1433 final implementation receiptsActive review target: #304 on Live production snapshot, collected 2026-07-07 03:00 UTC from public endpoints only:
Validation receipts:
CodeRabbit receipt:
External workspace paper draft |
f1080e4 to
8ef8272
Compare
8ef8272 to
9e71720
Compare
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
PROJ-1433 public receipt-boundary closeoutHead: What changed:
Verification:
Current blocker:
|
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web-next/app/demo/page.tsx (1)
209-240: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win"Positions lost" will show a double-negative if
differenceis ever negative.
diffcomes directly fromLIVE_RANK_ONE_EXPLANATION.counterfactual.difference, whose type isnumber(not constrained to be non-negative). Currently it's3, so themoved === "down"branch is never exercised, but on the next data refresh a post could plausibly rank worse under community governance (negativedifference). In that casevalue: \${diff}`renders as e.g."-3"` next to a label that already says "Positions lost" — a confusing double negative.🐛 Proposed fix
{ label: moved === "up" ? "Positions gained" : moved === "down" ? "Positions lost" : "Rank change", - value: moved === "up" ? `+${diff}` : moved === "down" ? `${diff}` : "—", + value: moved === "up" ? `+${diff}` : moved === "down" ? `${Math.abs(diff)}` : "—", sub: moved === "up" ? "Moved up by community governance" : moved === "down" ? "Moved down by community governance" : "No rank movement", color: diff > 0 ? "text-success" : diff < 0 ? "text-tongue-foreground" : "text-foreground/40", bg: diff > 0 ? "bg-success/10 border-success/20" : diff < 0 ? "bg-tongue/10 border-tongue/20" : "bg-biscuit border-border", },Since this data is refreshed periodically per this PR's own premise, worth fixing now rather than waiting for it to surface in a future production receipt.
🤖 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 `@web-next/app/demo/page.tsx` around lines 209 - 240, The rank-change display in the demo page can render a confusing double negative when LIVE_EXPLANATION.counterfactual.difference is negative. Update the moved === "down" branch in the page.tsx box definition so the value shown for the "Positions lost" case is an absolute count (while keeping the label and subtext aligned), and ensure the logic around diff/moved in this section uses the existing symbols consistently.
🤖 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 `@tests/web-next-demo-fixtures.test.ts`:
- Around line 235-247: The public UI fixture anonymization test is only checking
extracted quoted literals, so raw identifiers in comments or other non-string
text can slip through. Update the test in web-next-demo-fixtures.test.ts to
validate the full sanitized fixture content for each file instead of relying on
extractStringLiterals, using the same style as publicReceiptDocSections where
appropriate. Also add an edge-case fixture or assertion covering a raw did:plc
or bsky.social handle inside a comment to ensure the leak is caught by the test.
In `@web-next/components/dashboard-preview.tsx`:
- Around line 5-11: The signal formatting in dashboard-preview assumes every
component raw_score is positive, so update the mapping in the signals builder to
derive the displayed sign from the actual value instead of always prefixing “+”.
Reuse the same sign logic used by totalScorePrefix, and apply it in the
LIVE_RANK_ONE_EXPLANATION.components map so negative raw_score values render
correctly while keeping bar and positive based on the existing component fields.
---
Outside diff comments:
In `@web-next/app/demo/page.tsx`:
- Around line 209-240: The rank-change display in the demo page can render a
confusing double negative when LIVE_EXPLANATION.counterfactual.difference is
negative. Update the moved === "down" branch in the page.tsx box definition so
the value shown for the "Positions lost" case is an absolute count (while
keeping the label and subtext aligned), and ensure the logic around diff/moved
in this section uses the existing symbols consistently.
🪄 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: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ab45620d-4129-4be6-b1ab-79b3fbce60c2
📒 Files selected for processing (11)
README.mddocs/dev-journal.mddocs/lab/2026-07-07-recsys-live-metrics-packet.mdtests/web-next-demo-fixtures.test.tsweb-next/app/demo/page.tsxweb-next/components/animated-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/hero-section.tsxweb-next/components/ui/score-breakdown.tsxweb-next/components/ui/score-radar.tsxweb-next/lib/live-metrics-snapshot.ts
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/scoring/score-reader.ts (1)
355-457: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate avg/median/count parsing logic across three branches.
The runId-present block (366-393), runId-absent block (395-419), and the unchanged wide-path block (433-456) all repeat the same
count = parseInt(...); if (count === 0 || avg === null || median === null) return null; return { avg: parseFloat(...), median: parseFloat(...), count }logic. Any future fix (e.g. handling a different null representation) now needs three edits to stay consistent.♻️ Suggested helper extraction
function toEpochComponentStats(row?: { avg: string | null; median: string | null; count: string }): EpochComponentStats | null { const count = parseInt(row?.count ?? '0', 10); if (count === 0 || row?.avg == null || row?.median == null) { return null; } return { avg: parseFloat(row.avg), median: parseFloat(row.median), count }; }Then each branch becomes
return toEpochComponentStats(result.rows[0]);.🤖 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 `@src/scoring/score-reader.ts` around lines 355 - 457, The `readEpochComponentStats` function repeats the same `avg/median/count` parsing and null-check logic in the runId-present, runId-absent, and wide-path branches. Extract that shared conversion into a small helper such as `toEpochComponentStats` near `readEpochComponentStats`, and have each `db.query` branch return the helper result from `result.rows[0]` so all branches stay consistent and future parsing changes only need one update.src/db/migrations/024_post_scores_run_scope_index.sql (1)
1-20: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick winAlign the partial index predicate with the run-scoped filters.
WHERE component_details ? 'run_id'is not implied by the only run-scoped reads insrc/scoring/score-reader.tsandsrc/transparency/routes/feed-stats.ts, which filter withcomponent_details->>'run_id' = $N. Postgres will not match this partial index for those queries, so it won't prevent the largepost_scoresscans this migration is meant to avoid. Add the samecomponent_details ? 'run_id'condition to those readers or drop the partial clause; add anEXPLAIN (ANALYZE, BUFFERS)test for both run-scoped paths.🤖 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 `@src/db/migrations/024_post_scores_run_scope_index.sql` around lines 1 - 20, The partial index predicate in the migration does not match the run-scoped query filters used by score-reader and feed-stats, so Postgres won’t reliably use it for those reads. Update the relevant run-scoped queries in src/scoring/score-reader.ts and src/transparency/routes/feed-stats.ts to include the same component_details ? 'run_id' condition used by the idx_scores_epoch_run_total index, or remove the partial WHERE clause from the index if that alignment isn’t desired. Add EXPLAIN (ANALYZE, BUFFERS) coverage for both run-scoped paths to verify the index is chosen.
🤖 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 `@scripts/migrate.ts`:
- Around line 216-227: The migration path in migrate.ts records a filename after
running SQL even when CREATE INDEX CONCURRENTLY IF NOT EXISTS leaves an invalid
index behind. Update the non-transaction branch around
shouldRunMigrationInTransaction() to detect an existing but invalid index (for
example by checking pg_index.indisvalid) or drop/rebuild it before inserting
into MIGRATIONS_TABLE. Add a regression test for the migration runner that seeds
an invalid index, reruns the migrator, and verifies the migration is not marked
applied until the index is valid.
In `@tests/migrate-bootstrap.test.ts`:
- Around line 10-15: Expand the shouldRunMigrationInTransaction test coverage
with edge cases for empty input and substring false-positives. Add a case that
verifies an empty string still returns true, and add a case around a larger SQL
token/string literal containing the directive text to confirm the helper does
not incorrectly disable transactions just because it uses plain includes(). Use
the existing shouldRunMigrationInTransaction test block as the anchor for these
additional assertions.
In `@tests/web-next-demo-fixtures.test.ts`:
- Around line 114-129: The domain-style handle assertion in
expectAnonymizedLiveReceiptContent only inspects extracted string literals, so
bare JSX text nodes can still slip through undetected. Update the check so
DOMAIN_HANDLE_PATTERN is validated against the same full content scan used
elsewhere, or add an additional path that covers raw JSX text in .tsx fixtures;
use expectAnonymizedLiveReceiptContent, extractStringLiterals, and
FULL_CONTENT_LIVE_RECEIPT_PATTERNS to locate the right test helper. Also add a
focused test case for a bare JSX text leak like a custom-domain handle to verify
the regression is caught.
In `@tests/web-next-live-demo-data.test.ts`:
- Around line 85-107: Add a regression test covering non-finite explanation
fields in scoreComponentsFromExplanation, since bad numeric input should be
rejected via asNumber. Extend the tests near the existing display-order and
missing-component cases to include a fixture with a field like raw_score set to
NaN or weighted set to Infinity, and assert that scoreComponentsFromExplanation
throws LiveDemoDataError.
---
Outside diff comments:
In `@src/db/migrations/024_post_scores_run_scope_index.sql`:
- Around line 1-20: The partial index predicate in the migration does not match
the run-scoped query filters used by score-reader and feed-stats, so Postgres
won’t reliably use it for those reads. Update the relevant run-scoped queries in
src/scoring/score-reader.ts and src/transparency/routes/feed-stats.ts to include
the same component_details ? 'run_id' condition used by the
idx_scores_epoch_run_total index, or remove the partial WHERE clause from the
index if that alignment isn’t desired. Add EXPLAIN (ANALYZE, BUFFERS) coverage
for both run-scoped paths to verify the index is chosen.
In `@src/scoring/score-reader.ts`:
- Around line 355-457: The `readEpochComponentStats` function repeats the same
`avg/median/count` parsing and null-check logic in the runId-present,
runId-absent, and wide-path branches. Extract that shared conversion into a
small helper such as `toEpochComponentStats` near `readEpochComponentStats`, and
have each `db.query` branch return the helper result from `result.rows[0]` so
all branches stay consistent and future parsing changes only need one update.
🪄 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: Repository YAML (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 6dc8becf-0f74-4458-8890-3139c8d918c7
📒 Files selected for processing (20)
README.mddocs/dev-journal.mddocs/lab/2026-07-07-recsys-live-metrics-packet.mdscripts/migrate.tssrc/db/migrations/024_post_scores_run_scope_index.sqlsrc/scoring/score-reader.tssrc/transparency/routes/feed-stats.tstests/migrate-bootstrap.test.tstests/score-reader-parity.test.tstests/transparency-run-scope.test.tstests/web-next-demo-fixtures.test.tstests/web-next-live-demo-data.test.tsweb-next/app/demo/page.tsxweb-next/components/animated-section.tsxweb-next/components/dashboard-preview.tsxweb-next/components/hero-section.tsxweb-next/components/ui/score-breakdown.tsxweb-next/components/ui/score-radar.tsxweb-next/lib/live-demo-data.tsweb-next/lib/live-metrics-snapshot.ts
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Summary
web-nextdemo/homepage figures from fake or stale values to the 2026-07-07 03:00 UTC production snapshot.web-nextand add a regression guard that prevents live handles, DIDs, AT-URIs, known receipt text, or unscanned new snapshot importers from landing in public UI fixtures.web-nextTypeScript validation blockers found while checking the final branch.Receipts
GET /api/transparency/stats: epoch 2 active, 3,348 scored posts, 3,007 unique authors, 0 current-epoch votes, median total score 0.5312066730135393.GET /api/governance/weights: recency 0.25, engagement 0.20, bridging 0.10, source diversity 0.10, relevance 0.35.getFeedSkeletonwithlimit=100: returned 100 post URIs plus a cursor, recorded only as a served-page receipt.Validation
git diff --checknpm run docs:verify: 14 tracked docs / 29 markdown files scanned.npx tsc --noEmitfromweb-nextnpx vitest tests/web-next-demo-fixtures.test.ts --run: 1 file / 7 tests.npm run verifywith dummy non-production env and loopback/IPC permission: root build, 98 Vitest files / 885 tests, CLI build, MCP-local skip, SDK build, SDK fixture, web lint/build, and web-next build.9e71720: 6 findings, all lower-severity (minor/trivial); 0 major/high-medium blockers remain.Notes
corgi-recsys2026-paper-draft.mdwas refreshed locally with the same numbers and final verification counts, but it is outside this repository and not part of this PR.Linear: PROJ-1433