Performance & code-quality pass 2026-07-12: 84 verified findings, lint 63 to 0, nothing deferred - #237
Conversation
…indings, track plan 73 confirmed findings across 9 review dimensions plus an exhaustive triage of all 63 lint warnings; every finding adversarially verified (2 skeptics for high severity). Implementation plan: 11 parallel disjoint-ownership tracks + 2 sequential cross-cutting tracks, nothing deferred. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hase 0/1.5 Two plan reviewers (ownership/coupling, sequencing/risk). Accepted: app-dialog to CSS track, finding 9/15 dedup, ma-earth split across T7 + phase 1.5 with PDS fallback, phase-0 shared helpers, lint gate restated (<=2 warnings, 0 unused-disable), 5 new tests, T7/T9 commit splits, 7 file-list corrections. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
postIndexer: single rich-result wrapper ({ok,status,data,errors}) for the
hand-rolled POST /api/indexer blocks; never throws on HTTP errors so each
call site keeps its exact throw/fail-soft/warn semantics when migrated.
deriveIdentity: canonical displayName/handle/initials/href/avatar
derivation with record-level overrides, replacing ~20 drifting copies.
Phase 0 of docs/perf-quality-2026-07-12/plan.md; call-site migration
follows in later tracks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
HomeFeedRow/EndorsementGroupRow/HomeFeedBody memoized (element-wise group comparator per review); grouped-endorsement expansion windows 50 accounts per click instead of mounting up to ~1000; row/sentence/preview layer moved verbatim to home-feed-rows.tsx (CertPreview re-exported for tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…chunks Re-enable autoPauseRedraw with a repaintEpoch bumped on image preload and theme flips (paintNode/linkColor deps); force config no longer re-applies and reheats on container resize; NetworkActorsByDids chunks fetch via Promise.all; AllEndorsements loader switched to the cacheable indexer GET contract (op/badgeType/first/after). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, router staleTimes; metadata fixes Profile route loads SettingsPanel/ProfileEndorsements/ProfileFollowers/ ProfileLists via next/dynamic (OrgSettings likewise inside settings-panel); landing network stats server-fetched in the ISR render via network-counts-server.ts (fail-soft, 5s timeout) with the client hook as null-field fallback; experimental.staleTimes.dynamic=30; double-Certified title suffixes fixed (workspace/explore/endorsement-graph); dead /about sitemap entry removed; /apps converted to a server component with an SsoAppLink island; /home and /project/new gain titles. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r bodies at boundaries coerceClaimActivityValue normalizes malformed PDS records before render in use-activity and use-project-items; sessionStorage active-org restore is shape-validated; /api/auth/login non-JSON error bodies no longer surface raw SyntaxError to the sign-in form. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… CGS resolution, collapse hyperboard waterfall createCachedDidResource factory (module cache + stale window + abort-safe fetch + refetch) adopted by use-followers/use-following; in-flight coalescers added to use-received-endorsements, use-endorsements, fetchDisplayProfile/fetchBoardForActivity; use-endorsement-lists moves from permanent force-refetch to a versioned cache bus; use-cgs-memberships resolves groups through the batched DID resolver; useHyperboard fetches displayProfiles per-identity instead of behind a global barrier; rewritten fetchers ride postIndexer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ing components; drop dead draft plumbing useContextUpdates gains a 30s shared cache + in-flight dedupe (invalidated from UpdateForm saves), halving duplicate fetches on activity/project detail; useRouteRkey derives during render instead of a post-mount effect (kills a guaranteed second render of the 2300-line component); trailing component cluster moved to cert-detail-parts.tsx; contributorKey/ contributionRoleText deduped into lib/atproto/contributor-display.ts; never-read swap-draft writes removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…stable callbacks; split below-fold + modals EndorsementSubjectRow (on deriveIdentity, info+isLoading props) replaces three drifted row copies; ProfileEndorsements calls useGivenEndorsements once and derives the endorsed-set from it; row onToggle handlers are useCallback-stable so list memos hold; below-fold views split to profile-endorsement-views.tsx and the three list modals to their own module. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…loaders/filters/results ExploreSearchField owns keystroke state + 350ms debounce (was re-rendering the full results tree per keypress, twice over via the copy-pasted block in the All view); All-view blocks fetch 2x block size instead of 4x50 for 5 rendered items (funding keeps the full window for the client-side Confirmed-by filter); use-explore.ts loader layer split to use-explore-loaders.ts; quality filters and results area extracted; explore.tsx 2131 -> ~1480 lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…modules OPERATIONS/validation moved to operations.ts + variables.ts (pure module split); new GET handler for an explicit CACHEABLE_OPS allowlist (five zero-variable counts s-maxage=300 swr=86400; AllEndorsements pages s-maxage=60 swr=600; no cache headers on upstream errors); CollectionsByUris batch op added for the Ma Earth loader; allowlist + cache-header tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ound-trips in xrpc proxy Foreign-repo/blob GETs no longer restore the caller's OAuth session (hottest read path did a full token restore per request); immutable CID-addressed blobs get s-maxage (foreign) and private max-age (own-repo); rate-limit INCR and session lookup run concurrently; lazy-restore regression tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…he headers Group-registration limit check now fails closed on CGS errors and stops walking member lists once the limit is provably unreachable; direct CGS fetches carry abort timeouts; public group profile/metadata GETs get short private cache headers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
54x set-state-in-effect + 2x exhaustive-deps + 6x no-img-element triaged per docs/perf-quality-2026-07-12/findings.md: fetch-reset effects now compare previous keys inline, prop-mirrors derive during render, event work moved to handlers, mounted/matchMedia flags ride useSyncExternalStore; 20 sites where the pattern is deliberately correct carry justified eslint-disable comments. Repo lint output: 63 warnings -> 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
use-display-profile / use-pending-awards-count / use-user-activities (zero production importers) removed with their test files; dead exports dropped from account-email, app-passwords, urls, activity-uri; parseLocationCoords de-exported; stale doc references fixed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…iewport shrink Onboarding modal remounts per open via key so draft seeding is initialization instead of a set-state-in-effect (also stops the bsky-graph sync mounting on every page while closed); tour context exposes a clamped stepIndex and clamps back() so a mid-tour resize across 800px cannot strand the step index past the shorter steps array; covered by new tour-context tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…contain long lists All literal z-index rules mapped onto the --z-* scale (stacking table in findings.md; new --z-local-raise + --z-skip-nav tokens); error focus ring and status colors tokenized (dark mode now legible); --shadow-modal token replaces three literal copies; 2px radius literals -> var(--radius); ~640 lines of orphaned CSS removed (live compound-selector partners preserved); content-visibility + contain-intrinsic-size on home-feed and explore lists; app-dialog latest-ref writes moved into an effect (react-hooks/refs errors surfaced when the stale disable directive was removed). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…back fetchIndexerProjectsByUris batches the curated-URI set through the new CollectionsByUris proxy op (50-URI chunks, postIndexer, ok flag instead of throws); the Ma Earth loader tries the batch, restores curator order, and falls back to the untouched per-URI PDS path on error or empty-but-expected results — shippable whether or not the deployed magic-indexer supports the uri-in filter yet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…b, surface HTTP errors
19 remaining hand-rolled POST /api/indexer blocks migrated onto postIndexer
with per-site semantics preserved; fetchCount rides the cacheable GET
variant (dev mock-fetch-provider taught the GET form); indexer.ts split
into indexer-{funding,closure,counts,collections}.ts behind a re-export
barrel (1558 -> 597 lines, 30+ importers unchanged);
fetchIndexerActivities/ByUris now throw on HTTP !ok instead of rendering
an empty feed, keeping warn+fail-soft only for 200-with-GraphQL-errors.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Image helpers replace 50+ duplicated sites 16 more identity-fallback sites ride deriveIdentity (record-level overrides via the options bag; unresolved DIDs now uniformly truncated instead of raw 40-char strings or 'Anonymous'); rkeyFromUri joins parseAtUri in lib/urls (4 private extractRkey, 2 private parseAtUri, 16 inline split-pop sites removed); formatTimePeriod shared across the four date-range copies; slot-aware projectTitle/projectImage in collection.ts fix the confirmed home-rail thumbnail precedence drift while keeping banner-first hero slots; 14 new unit tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…taleness; round-2 cleanups Object.hasOwn guards on the indexer op lookups (prototype keys die at the first gate, pinned by tests); shared indexer plumbing moved to a leaf indexer-client.ts so the domain split is acyclic; ExploreSearchField debounce reads latest onCommit/search via effect-synced refs (could previously revert a URL change made mid-window); repaintEpoch bumps coalesced to one per frame; explore content-visibility scoped to the list variants where containment can apply; CertPreview compat re-export dropped; stale operations.ts comment pointers, suppression justifications, and zero-consumer exports cleaned up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
…cross-repo follow-ups Live probing of the prod indexer showed the three recorded magic-indexer follow-ups need no upstream work: uri-in filtering already works (real-URI probe returns the node), avatar is already in the lexicon-built schema (the nulls mirror the PDS records, verified for 30), and authorLabels validates on the same connection. The genuine gap was app-side: Projects/UserProjects/ ProjectsContainingCert never selected avatar — now they do, so projectImage's avatar-first thumb precedence reaches indexer-fed surfaces. Evidence in docs/perf-quality-2026-07-12/followups-probe.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Full performance & code-quality pass over
staging, executed per the self-authored mission indocs/perf-quality-2026-07-12/prompt.md.What this is
A 10-dimension multi-agent review of the whole codebase (every finding adversarially verified — 73 confirmed, 1 refuted, recorded in
findings.md) followed by implementation of every confirmed finding, nothing deferred, in 15 disjoint-ownership tracks (plan.md, decisions inreview-round-1.md). A post-implementation review round (3 lenses, skeptic-verified) produced 11 accepted fixes, recorded inreview-round-2.md.Results
npx tsc --noEmitnpm run typecheck:testnpm run lintnpm testnpm run buildHighlights by area
Render performance — home-feed rows/body memoized (element-wise group comparator) with grouped-endorsement expansion windowed at 50; explore search keystrokes isolated from the results tree (was reconciling every row per keypress, twice via a copy-pasted debounce);
content-visibility+contain-intrinsic-sizeon home/explore lists; endorsement force-graph no longer runs a permanent rAF repaint loop and no longer reheats on container resize; activity-detail loses a guaranteed double render (route rkey derived during render).Data fetching — single-flight caches/coalescers for received-endorsements (3 identical cold scans → 1), followers, following, given-endorsements, displayProfile/board; shared
createCachedDidResourcefactory; hyperboard displayProfile double-barrier collapsed to per-identity chains; CGS memberships ride the batched DID resolver; Ma Earth curated projects batch through a newCollectionsByUrisindexer op with an automatic per-URI PDS fallback (safe if the deployed indexer lacksuri:{in}support).Server/API — cacheable
GET /api/indexerfor an allowlisted set of public ops (countss-maxage=300 swr=86400, AllEndorsements pagess-maxage=60 swr=600; errors never cached); xrpc proxy no longer restores the full OAuth session for foreign-repo/blob reads (hottest path), immutable blobs get cache headers, rate-limit + session Upstash round-trips parallelized; group-registration limit check fails closed and stops walking member lists early; CGS fetches carry abort timeouts.Next.js architecture — profile route no longer statically bundles the settings surface + all tab panels (dynamic imports); landing network stats server-fetched in the ISR render (was 5 proxied GraphQL round-trips per anonymous visitor);
staleTimes.dynamic=30;/appsconverted to a server component; title/sitemap/metadata fixes.Code quality —
explore.tsx2131→1480,1830,activity-detail.tsx2307→use-explore.tssplit (loader layer),lib/atproto/indexer.ts1558→597 + 4 domain modules behind a re-export barrel,api/indexer/route.tssplit (operations/variables); ~640 lines dead CSS, 3 dead hooks, 9 dead exports removed; shared helpers replace 50+ drifted copies (postIndexer×20 sites,deriveIdentity×20,rkeyFromUri×22,formatTimePeriod×4, slot-awareprojectImage/projectTitle×8 — fixing a confirmed home-rail thumbnail precedence drift).Lint — all 63 warnings triaged and resolved: 40 fixed properly (derive-during-render, compare-prev-key, event-handler moves,
useSyncExternalStore, key-remount), 20 carry one-line justified suppressions, plus the onboarding-modal latent bug and the tour-context resize clamp (both with new tests). Removing one stale disable directive surfaced 3 pre-existingreact-hooks/refserrors inapp-dialog.tsx— fixed with the effect-based latest-ref pattern.Intentional behavior changes (reviewed, small)
avatar ?? image ?? banner(the documented canonical order) for projects carrying an avatar; hero/banner slots stay banner-first.fetchIndexerActivitiessurfaces HTTP errors to callers' error paths instead of rendering an empty feed.Test plan (staging preview)
staleTimesfrom next.config.ts)Cross-repo follow-ups: dissolved. Live probing of the prod indexer (
followups-probe.md) showed the three recorded magic-indexer follow-ups need no upstream work —uri:{in}already works,avataris already in the schema (the nulls mirror the PDS records), andauthorLabelsvalidates on the same connection. The one genuine gap was app-side and is fixed in this branch (all collection ops now selectavatar). Remaining open questions for @holke: whether the Ma Earth curated list should respect the org-quality filter (product call, currently "ignored by design"), and the explore gallery card's banner-first design question.🤖 Generated with Claude Code