Skip to content

[PROJ-1433] Refresh live recsys metrics packet - #304

Merged
AndrewNordstrom merged 7 commits into
mainfrom
dev/PROJ-1433-recsys-live-metrics-packet
Jul 7, 2026
Merged

AndrewNordstrom merged 7 commits into
mainfrom
dev/PROJ-1433-recsys-live-metrics-packet

Conversation

@AndrewNordstrom

@AndrewNordstrom AndrewNordstrom commented Jul 7, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add a dated PROJ-1433 live metrics packet sourced from public production endpoints.
  • Refresh README and Corgi web-next demo/homepage figures from fake or stale values to the 2026-07-07 03:00 UTC production snapshot.
  • Replace the demo's fake epoch 47 / 312-vote fixture with epoch 2, 3,348 scored posts, 3,007 unique authors, 0 current-epoch votes, and an anonymized rank-1 production receipt.
  • Centralize the shared live snapshot values for web-next and 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.
  • Fix two pre-existing web-next TypeScript 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.
  • getFeedSkeleton with limit=100: returned 100 post URIs plus a cursor, recorded only as a served-page receipt.
  • Engagement-heavy counterfactual top-10 receipt: 4 posts moved up, 6 moved down, max rank change 13, average absolute rank change 4.1.

Validation

  • git diff --check
  • npm run docs:verify: 14 tracked docs / 29 markdown files scanned.
  • npx tsc --noEmit from web-next
  • npx vitest tests/web-next-demo-fixtures.test.ts --run: 1 file / 7 tests.
  • npm run verify with 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.
  • CodeRabbit CLI final committed review on 9e71720: 6 findings, all lower-severity (minor/trivial); 0 major/high-medium blockers remain.

Notes

  • Production receipts used public endpoints only: no admin export, database query, cookie, bearer token, or host mutation.
  • Sybil-resistance wording is intentionally caveated as simulation/mechanism evidence, not a live production proof.
  • Real source handles/URIs remain in the internal lab packet only; public site/demo copy uses anonymized receipt labels while preserving numeric proof.
  • The external workspace paper draft corgi-recsys2026-paper-draft.md was 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

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b685c3b9-ebfa-4888-9cae-aecf3e3b5038

📥 Commits

Reviewing files that changed from the base of the PR and between 4f9f60e and 8f091c0.

📒 Files selected for processing (4)
  • scripts/migrate.ts
  • tests/migrate-bootstrap.test.ts
  • tests/web-next-demo-fixtures.test.ts
  • tests/web-next-live-demo-data.test.ts

Walkthrough

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

Changes

Live metrics packet and anonymization

Layer / File(s) Summary
Live metrics packet documentation
README.md, docs/dev-journal.md, docs/lab/2026-07-07-recsys-live-metrics-packet.md
Adds the live production snapshot line, the dated lab packet, and the journal entry with receipts, claims, counterfactuals, simulation-derived claims, and copy guidance.
Live snapshot data module
web-next/lib/live-metrics-snapshot.ts
Defines typed live snapshot interfaces and immutable constants for metrics, rank-one explanation data, and ranked feed previews.
Client live demo data fetch
web-next/lib/live-demo-data.ts
Adds live demo request models, URL builders, normalization helpers, and staged fetch orchestration for feed skeleton, weights, stats, explanation, and hydrated posts.
Run-scoped stats and migration support
scripts/migrate.ts, src/db/migrations/024_post_scores_run_scope_index.sql, src/scoring/score-reader.ts, src/transparency/routes/feed-stats.ts
Adds non-transactional migration support and a run-scoped index, splits score-reader queries by runId presence, and changes feed-stats to combine base totals with per-component aggregates.
Demo page wiring to live data
web-next/app/demo/page.tsx, web-next/components/dashboard-preview.tsx, web-next/components/hero-section.tsx
Replaces mock demo content with live-or-snapshot data for stats, feed, topics, explanations, counterfactuals, and page copy.
UI typing updates
web-next/components/animated-section.tsx, web-next/components/ui/score-breakdown.tsx, web-next/components/ui/score-radar.tsx
Updates motion prop typing, makes score components readonly, and aligns tooltip typing with the accessed payload shape.
Regression tests
tests/migrate-bootstrap.test.ts, tests/score-reader-parity.test.ts, tests/transparency-run-scope.test.ts, tests/web-next-demo-fixtures.test.ts, tests/web-next-live-demo-data.test.ts
Adds tests for migration markers, score-reader query paths, run-scoped feed-stats SQL, live-demo helpers, and anonymization/consistency checks for public docs and fixtures.

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
Loading

Possibly related issues

  • PROJ-1433: These changes directly implement the live production metrics refresh, the anonymized public packet, and the web/demo refresh described in the issue.
  • PROJ-1440: The README/docs/web-next refresh aligns with the parent sprint’s metrics, paper/site, and reviewer-ready demo work.

Possibly related PRs

Suggested labels: documentation, javascript

AI agent prompts

  • Verify the public lab packet never reintroduces raw handles, DIDs, AT-URIs, or post text in future edits.
  • Add a focused test for fetchLiveDemoData partial-failure behavior if the feed skeleton succeeds but hydration fails.
  • Add a focused test for the feed_stats route when bridging or engagement component stats return null.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: refreshing the live recsys metrics packet.
Description check ✅ Passed The description is directly about the production snapshot refresh, anonymization, and related demo updates.
Linked Issues check ✅ Passed The PR updates the live metrics packet, README, and web-next demo with production-safe receipts and anonymized labels, matching PROJ-1433.
Out of Scope Changes check ✅ Passed The additional migration, scoring, and type-fix changes support the refreshed metrics flow and validation, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/PROJ-1433-recsys-live-metrics-packet
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch dev/PROJ-1433-recsys-live-metrics-packet

Warning

Review ran into problems

🔥 Problems

These MCP integrations need to be re-authenticated in the Integrations settings: Notion


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

AndrewNordstrom commented Jul 7, 2026 •

Copy link
Copy Markdown
Collaborator Author

PROJ-1433 final implementation receipts

Active review target: #304 on dev/PROJ-1433-recsys-live-metrics-packet at 9e7172076d4deda8800f29463a006e53e508b210.

Live production snapshot, collected 2026-07-07 03:00 UTC from public endpoints only:

  • epoch 2 active
  • 3,348 scored posts
  • 3,007 unique authors
  • 0 current-epoch votes
  • active weights: recency 0.25, engagement 0.20, bridging 0.10, source diversity 0.10, relevance 0.35
  • engagement-heavy top-10 counterfactual: 4 posts moved up, 6 down, max rank change 13, average absolute rank change 4.1

Validation receipts:

  • git diff --check: pass
  • npx tsc --noEmit from web-next: pass
  • npx vitest tests/web-next-demo-fixtures.test.ts --run: pass, 1 file / 7 tests
  • npm run docs:verify: pass, 14 tracked docs / 29 markdown files scanned
  • npm run verify with dummy non-production env and local loopback/IPC permission: pass, root build, 98 Vitest files / 885 tests, CLI build, MCP-local skip, SDK build, SDK fixture, web lint/build, and web-next build
  • GitHub checks after final push: pass for CodeQL/analyze, backend-verify, frontend-verify, docs-verify, report-scripts-verify, linear-policy, linear-state-sync, quality-gate, security-gate, secret-scan, CodeRabbit freshness/thread checks, Aikido thread check, dependabot automerge, and internal-tooling hygiene
  • PR review threads: 0

CodeRabbit receipt:

  • CLI committed review was rerun on final head 9e71720.
  • Final result: 6 findings, all lower severity (minor/trivial); 0 major/high-medium blockers remain.
  • GitHub CodeRabbit app status still says skipped because PR [PROJ-1433] Refresh live recsys metrics packet #304 is draft; the CLI review is the current review receipt.

External workspace paper draft corgi-recsys2026-paper-draft.md was refreshed locally with the same production numbers and final verification counts, but it lives outside the repo PR.

@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1433-recsys-live-metrics-packet branch 2 times, most recently from f1080e4 to 8ef8272 Compare July 7, 2026 04:04
@AndrewNordstrom
AndrewNordstrom force-pushed the dev/PROJ-1433-recsys-live-metrics-packet branch from 8ef8272 to 9e71720 Compare July 7, 2026 04:12
@AndrewNordstrom
AndrewNordstrom marked this pull request as ready for review July 7, 2026 05:40
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

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.

Copy link
Copy Markdown
Collaborator Author

PROJ-1433 public receipt-boundary closeout

Head: 578c468d7fa1ceff89fc64def07b12f796ca7937 ([PROJ-1433] Redact public metrics receipts).

What changed:

  • Redacted raw DIDs, AT-URIs, author handles, and post text from the public dated metrics packet while preserving numeric production receipts, endpoint provenance, timestamps, ranks, score components, and caveats.
  • Updated README wording to call the linked packet anonymized.
  • Corrected the dev journal line that previously implied raw identifiers lived only in an internal packet.
  • Extended tests/web-next-demo-fixtures.test.ts so public UI fixtures and the PROJ-1433 README/journal/packet sections reject raw or encoded DIDs, AT-URIs, Bluesky handles, and unredacted sensitive fields.

Verification:

  • git diff --check: pass.
  • npx vitest tests/web-next-demo-fixtures.test.ts --run: pass, 1 file / 11 tests.
  • npm run docs:verify: pass, 14 tracked docs / 29 markdown files.
  • npm run verify with dummy non-production env and local loopback/IPC permission: pass, 98 test files / 889 tests, CLI build, MCP-local skip, SDK build, SDK fixture, Vite lint/build, and Next static build.
  • CodeRabbit CLI uncommitted review after fixes: 3 trivial suggestions only; no major/high-medium blockers.
  • GitHub checks on 578c468: pass for CodeQL/analyze, backend-verify, frontend-verify, docs-verify, report-scripts-verify, linear-policy, linear-state-sync, quality-gate, security-gate, secret-scan, Aikido thread check, dependabot automerge, internal-tooling hygiene, and CodeRabbit thread check.

Current blocker:

  • After marking the PR ready for review, the GitHub CodeRabbit app and coderabbit-freshness failed with Usage spending cap reached.
  • I am not merging or deploying this PR while the required CodeRabbit app/freshness gate is failed. This is a vendor-capacity blocker, not an implementation/test failure.

@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

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.

@AndrewNordstrom

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation javascript Pull requests that update javascript code labels Jul 7, 2026

@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

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 difference is ever negative.

diff comes directly from LIVE_RANK_ONE_EXPLANATION.counterfactual.difference, whose type is number (not constrained to be non-negative). Currently it's 3, so the moved === "down" branch is never exercised, but on the next data refresh a post could plausibly rank worse under community governance (negative difference). In that case value: \${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

📥 Commits

Reviewing files that changed from the base of the PR and between da2450f and a7e6937.

📒 Files selected for processing (11)
  • README.md
  • docs/dev-journal.md
  • docs/lab/2026-07-07-recsys-live-metrics-packet.md
  • tests/web-next-demo-fixtures.test.ts
  • web-next/app/demo/page.tsx
  • web-next/components/animated-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/ui/score-breakdown.tsx
  • web-next/components/ui/score-radar.tsx
  • web-next/lib/live-metrics-snapshot.ts

Comment thread tests/web-next-demo-fixtures.test.ts
Comment thread web-next/components/dashboard-preview.tsx
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

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[bot]
coderabbitai Bot previously approved these changes Jul 7, 2026
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

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.

@AndrewNordstrom
AndrewNordstrom enabled auto-merge (squash) July 7, 2026 08:52
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

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.

@AndrewNordstrom

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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: 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 win

Duplicate 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 win

Align the partial index predicate with the run-scoped filters. WHERE component_details ? 'run_id' is not implied by the only run-scoped reads in src/scoring/score-reader.ts and src/transparency/routes/feed-stats.ts, which filter with component_details->>'run_id' = $N. Postgres will not match this partial index for those queries, so it won't prevent the large post_scores scans this migration is meant to avoid. Add the same component_details ? 'run_id' condition to those readers or drop the partial clause; add an EXPLAIN (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

📥 Commits

Reviewing files that changed from the base of the PR and between 0d688e9 and 4f9f60e.

📒 Files selected for processing (20)
  • README.md
  • docs/dev-journal.md
  • docs/lab/2026-07-07-recsys-live-metrics-packet.md
  • scripts/migrate.ts
  • src/db/migrations/024_post_scores_run_scope_index.sql
  • src/scoring/score-reader.ts
  • src/transparency/routes/feed-stats.ts
  • tests/migrate-bootstrap.test.ts
  • tests/score-reader-parity.test.ts
  • tests/transparency-run-scope.test.ts
  • tests/web-next-demo-fixtures.test.ts
  • tests/web-next-live-demo-data.test.ts
  • web-next/app/demo/page.tsx
  • web-next/components/animated-section.tsx
  • web-next/components/dashboard-preview.tsx
  • web-next/components/hero-section.tsx
  • web-next/components/ui/score-breakdown.tsx
  • web-next/components/ui/score-radar.tsx
  • web-next/lib/live-demo-data.ts
  • web-next/lib/live-metrics-snapshot.ts

Comment thread scripts/migrate.ts
Comment thread tests/migrate-bootstrap.test.ts
Comment thread tests/web-next-demo-fixtures.test.ts
Comment thread tests/web-next-live-demo-data.test.ts
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

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.

@AndrewNordstrom
AndrewNordstrom merged commit 35b66ef into main Jul 7, 2026
20 of 26 checks passed
@AndrewNordstrom
AndrewNordstrom deleted the dev/PROJ-1433-recsys-live-metrics-packet branch July 7, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant