Skip to content

Dead & Stale Register

Status: Active

The marked output of a three-lens investigation (dead code · orphaned routes · stale docs), every item grep-proven against the current code. Nothing here has been removed or fixed — this is the examination list. Verdict + recommended action are advisory; removal is the owner's call.

Two root causes account for most of it:

  1. Doc-move-without-backlink — files reclassified into docs/history/ leave stale docs/architecture/… citations behind.
  2. Component-merge-without-doc-sweep — the 2026-07-20 ClubCard merge + the club-card.tsx rewrite invalidated the same descriptions in 4+ docs; only screen-blueprint's Clubs section has been re-grounded so far.

A · Dead code

A1 · Dead files (owner call)

FileEvidenceVerdictAction
packages/app/src/presentation/hooks/mutations/use-invites.ts (+ inviteKeys, query-keys.ts:255)Zero importers; superseded by use-share-club-invite.ts (re-exported instead)DEAD (high)Remove
packages/app/src/types/branded.tsZero consumers — all ~95 mutationKey: sites use plain arrays. CLAUDE.md's Enforcement Stack claims this shipped (P5) → also a stale claim (§C3)DEAD (high)Remove + fix CLAUDE.md, or revive adoption
packages/features/clubs/src/shared/club-schedule-block.tsxZero JSX usage; club-card.tsx never imports it. canon/clubs.md documents it as a live card zone (§C2) — was live pre-rewrite (git 849fd276)DEAD + DOC DRIFT (high)Owner call: revive per canon, or delete + rewrite the clubs.md zone model

A2 · Dead dependencies (remove)

  • @tamagui/animations-react-native (apps/mobile) — STYLE-2 forbids it, zero imports.
  • nativewind (packages/app) — STYLE-1 forbids it, zero prod imports (+ orphaned jest mock).
  • @tamagui/config · moti (redundant dup) · @react-native-kakao/social · country-flag-icons · tamagui (features/activity + features/onboarding) · @babel/preset-env + @babel/preset-typescript (covered by babel-preset-expo).

A3 · Dead exports

  • formatMonthDaySlashWithWeekday (date-format.ts:94), formatMonthDayDot (date-format.ts:424) — remove.
  • colors (config/colors.ts:154) — superseded by Tamagui $-tokens — investigate/remove.
  • seasonKeys / seasonRecordKeys / clubEventKeys (query-keys.ts) — roadmap (Phase 11) scaffolding — investigate.

A4 · NOT dead — verified false positives (do not remove)

knip flagged ~1,368 export symbols; ~57% are internal barrel re-exports live via @twomore/app. Also false: scripts/**-hidden deps (@modelcontextprotocol/sdk, glob, gray-matter, minisearch), TYPE-3 *Schema exports (arch-test-mandated), native-module app deps (@shopify/flash-list, expo-image, react-native-mmkv, react-native-spotlight-tour… Expo autolinking), and app-link-association.ts helpers (load-bearing Universal Links). Verify per-symbol before deleting from any barrel.


B · Orphaned routes

Route / componentEvidenceVerdictAction
apps/mobile/app/activity/sessions.tsx (+ web twin + activity-upcoming-sessions-screen.tsx + its index export)No routes.ts key; 0 push/Link callers; the tab root already renders that same 내 세션 list inline — supersededORPHANED (high)Delete the trio, or wire a real 더보기 CTA from ActivityScreen
apps/mobile/app/clubs/[clubId]/sessions/[sessionId].tsxRedirect stub, no mobile caller (routes.clubSession returns flat /sessions/id). Web serves the nested pathUNUSED on mobile (low)Keep as external-link safety net, or delete
apps/mobile/app/leaderboard.tsx, ranking.tsxOne-line redirect shims, 0 callers — but deliberate back-compat (web mirrors them)KEEPCut only if history confirms no legacy links

Not orphaned (corrected): (tabs)/(clubs)/discover.tsx is the real screen, reached via the intentional flat→nested <Redirect> pattern on all 5 tab roots. Earlier "may be orphaned" flag disproven.

Lead (inverse problem): ~12 routes.ts helpers point at nonexistent files (would 404 if called) — tournament, editSession, challenges, subscription, courtDetail, analysis*, seasonStandings, signalConsent, discoverPickups, partnerMatching — mostly unshipped roadmap. Also routes.ranking === /records (dup of routes.records).


C · Stale docs (~38 refs, grep-proven)

C1 · screen-blueprint.md (~24) — auto-fixed by the wireframe buildout

These are the sections the per-screen re-grounding pass hasn't reached yet (Home + Clubs already fixed). The buildout closes each as its screen is wireframed — no separate sweep needed, but tracked here:

  • Systemic phantom (app) route-group in 13+ headers (:37,215,259,297,624,821,851,914,977,981,985,989,993 + web) — no (app) group exists.
  • :215 (activity)(sessions); entire §2.4 "Ranking Screens" (:914-993) keyed off a nonexistent (ranking) group + screens/ranking/ dir — real routes are flat records/analysis/*.
  • clubs/[id]clubs/[clubId] (:307,394,501,542,597,1082); Members/Dues/Attendance not under a [clubId] subfolder (:415,1198,1240).
  • Join/Create (:559,578) → top-level join-club.tsx / create-club.tsx; Session Edit (:805) → sessions/[sessionId]/edit.tsx; Settings (:1302), Notifications (:1356home/notifications.tsx).
  • Whole sections describing nonexistent components — Profile tab (:259-293), Match Board (:1483-1517), Weather Insight Sheet (:1534-1568), Challenges (:1041-1051).
  • Self-contradictions: DiscoverClubCard (:601,633), validateName (:1034), TIER_BADGE_VARIANT/getTierColor (:267-268) — already-fixed elsewhere in the same doc.

C2 · Canon docs — need a dedicated doc sweep (the component-merge fallout)

Doc:lineStale refShould be
canon/clubs.md:12MyClubCard / DiscoverClubCardClubCard (isMember-gated)
canon/clubs.md:10ZONE 3 = ClubScheduleBlock (dead)Re-ground zones from club-card.tsx (BannerCapacityCluster, GlyphFactRow×3, SectionEyebrow+Well)
canon/components.md:14MyClubCardClubCard
canon/components.md:51HomeLiveAlertBanner (nonexistent)LiveSessionStack inside HomeTodayView
canon/components.md:68MotionPressable (deleted 2026-05-09)Pressable from @twomore/ui
canon/sessions.mdsession-actions-menu.tsx Popover (nonexistent)header icon buttons + bottom 호스트 도구 SectionBlock
canon/sessions.mdGPS check-in (retired by migration 00384)attendance is match-derived/automatic
canon/sessions.mdplayability-info-sheet.tsx (nonexistent)tap-to-explain sheet gone; score util still live
canon/sessions.mdmy-club-card.tsx / discover-club-card.tsxclub-card.tsx
canon/status-and-recruitment.md:36sessionSummaryPolishMode dev flag (promoted + deleted)remove — location-first is the unconditional default (contradicts sessions.md:10)
canon/data-and-hooks.md:17validateName() (never existed)inline validation
canon/data-and-hooks.md:63tier-display.ts / getTierColor / TIER_BADGE_VARIANTTIER_ICONS in trust.entity.ts; EloTierBadge/TrustTierBadge

C3 · Hard-constraint / index fact drift

Doc:lineStaleCorrect
CLAUDE.md:209docs/architecture/solutions/ps11-guardrails.mddocs/history/ps11-guardrails.md (solutions/ is now empty) — same broken path in ci.yml:146-147
CLAUDE.md:209,213"22-file pgTAP / 222 assertions"30 files / ~283 assertions (CI says 19 — drifted 3×)
CLAUDE.md:210"52 active ESLint rules"53 (matches current-doc-state.md)
CLAUDE.md:210"87 waivers across 4 rules"75 (per eslint.ratchet.config.mjs:13)
korean-market.md:10, AGENTS.md:97 (KR-1)korean-phone.ts wrapping libphonenumber-jsfile doesn't exist yet (built-ahead doc, or unbuilt feature)
  • agentic-project-foundation.md:76 docs/architecture/networking-foundation-plan.mddocs/history/…
  • agentic-project-foundation.md:78 docs/architecture/drift-prevention.mddocs/history/…
  • agentic-project-foundation.md:55,133 "8 agent operating rules" → 9 (AOR-1..AOR-9).

Prevention (proposed, not yet built)

  • Docs the tripwire could cover: the same groundedIn mechanism used for wireframes could mark canon/blueprint sections with the code they describe, warning on drift — closes C1/C2 mechanically.
  • Move-with-backlink lint: a docs:check rule that fails when an active doc cites a path now under docs/history/ — closes C4.
  • Generated counts: the CLAUDE.md numbers in C3 (rules/waivers/pgTAP) should be generated, not hand-typed.

Markdown remains the source of truth. Run yarn docs:check before handoff.