chore(#262): delete the dead routes' leftovers; add a reachability guard that can only shrink - #266
Merged
Merged
Conversation
…ard that can only shrink 24 source files were reachable from no `app/` route. That is not dead weight, it is a trap for issue authors: the file compiles, its tests pass, and nothing renders it. It has already cost two issues — #236 was written entirely against `BlueprintsSection`, and the plan half of #245 against `LivePlanBoard`, both orphaned by 54c13fb (2026-07-25) when the Planner tab's segment strip was removed and the components were left on disk. The #245 work was implemented before anyone noticed and had to be stripped back out of PR #259. **The guard is the point of this change.** `src/lib/reachability.test.ts` walks the import graph from every `app/` route and fails on any source file it cannot reach. It runs in the normal suite — no CI wiring, and it fails locally before a push. The rule mirrors `PENDING_DOMAINS` in the payload harness: the `ORPHANS` list may only SHRINK. • unreachable and not listed → fail (you just orphaned something) • listed but now reachable → fail (delete the stale entry) • listed with no issue number → fail (debt must be explained) Both failure modes were verified by deliberately breaking them, not assumed: a scratch file with no importer fails the first assertion, and a bogus entry for a live file fails the second. A guard that cannot fail is worth nothing. It also self-checks the walker (>100 files reachable, and `graph/index.ts` resolvable through its barrel), because the first version of this analysis was WRONG in a plausible way — it built directory-index paths with `base + '/index.ts'`, whose mixed separators match nothing on Windows, so every barrel looked orphaned. That canary would have caught it. **Deleted** — no importers, no routes, nothing to decide: - `components/fleet/CoordInboxCard.tsx`, `components/fleet/WorkerCard.tsx` — the (fleet) route no longer exists - `screens/GraphDemoScreen.tsx` — demo screen with no route; the stale reference to it in `graph/index.ts`'s header is corrected **Declared, not deleted** — every remaining orphan is blocked on a decision that is not this issue's to make, which is exactly why they were left: - planner reshape casualties (`LivePlanBoard`, `plannerBoard`, `BlueprintsSection`, `blueprintsPage`, and five superseded planner tabs) — removing the selectors means deciding whether `plan` and `blueprints` stay in `STORE_DOMAINS`. Resolve #236 and the #245 re-scope first, then delete them together with their domains. - repo-client leftovers (`github/*`, `diff.ts`, `syntax.ts`, `githubCache`, `githubPulse`, `planner/seed`) and the task-system UI (`TaskSheet`, `IssueLinkSheet`, `TopPill`) — note `lib/tasks.ts` and `session.tsx` ARE live (SessionProvider is mounted in `app/_layout.tsx`), so the state layer survives while its UI does not. Needs a product call on whether the IDE surface returns. **Annotated, not debt:** `pages/orgPage.ts` is deliberately ahead of its consumer — built by #235 for #233's Teams segment. It cannot rot unnoticed (`org` is in the harness `DECODERS` and `orgPage.test.ts` covers the parsing), and the file now says so. Gates: `npx tsc --noEmit` clean; 537 tests pass. Refs #262 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAPZC6xEyCrH9qSKUKLQdy
📦 Preview build readyArtifact: Built from commit c6b3358 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #262.
24 source files were reachable from no
app/route. That is not dead weight — it is a trap for issue authors: the file compiles, its tests pass, and nothing renders it.It has already cost two issues.
54c13fb(2026-07-25) rewroteapp/(tabs)/plan.tsxand removed the segment strip that was the only mount point for the Blueprints and Live-plan mirrors, leaving the components on disk. #236 was then written entirely againstBlueprintsSection; the plan half of #245 was written againstLivePlanBoard, implemented, and had to be stripped back out of PR #259 before merge.The guard is the point of this change
src/lib/reachability.test.tswalks the import graph from everyapp/route and fails on any source file it cannot reach. It runs in the normal suite — no CI wiring, and it fails locally before a push.The rule mirrors
PENDING_DOMAINSin the payload harness:ORPHANSmay only SHRINK.Both failure modes were verified by deliberately breaking them, not assumed. A scratch file with no importer fails the first assertion; a bogus entry for a live file fails the second. A guard that cannot fail is worth nothing.
It also self-checks the walker — asserts >100 files reachable and that
graph/index.tsresolves through its barrel. That canary exists because the first version of this analysis was wrong in a plausible way: it built directory-index paths withbase + '/index.ts', whose mixed separators match nothing on Windows, so every barrel looked orphaned. The only reason I caught it was a demonstrably-live component contradicting the output.Deleted — no importers, no routes, nothing to decide
components/fleet/CoordInboxCard.tsx,components/fleet/WorkerCard.tsx— the(fleet)route no longer existsscreens/GraphDemoScreen.tsx— demo screen with no routeAlso corrected the stale reference to
GraphDemoScreeningraph/index.ts's header, which claimed the shell mounts it.Verified before deleting: no reachable importer, and none of their dependencies (
GraphCanvas,orgAdapter,sampleData, …) become orphaned as a result.Declared, not deleted
Every remaining orphan is blocked on a decision that is not this issue's to make — which is exactly why they were left rather than quietly removed:
Planner reshape casualties (
LivePlanBoard,plannerBoard,BlueprintsSection,blueprintsPage, and five superseded planner tabs) — deleting the selectors means deciding whetherplanandblueprintsstay inSTORE_DOMAINS. Resolve blueprints domain: soundKit/h/origin/updatedAt unread; only the ACTIVE team crosses the wire #236 and the skills + plan domains: in sync; lesson timestamps dropped, StageStatus 'ahead' has no colour #245 re-scope first, then remove them together with their domains.Repo-client leftovers (
github/*,diff.ts,syntax.ts,githubCache,githubPulse,planner/seed) and the task-system UI (TaskSheet,IssueLinkSheet,TopPill).Worth knowing:
lib/tasks.tsandsession.tsxARE live —SessionProvideris mounted inapp/_layout.tsxandapp/repo.tsxusesuseSession. So the task system's state layer survives while its UI does not. That is a product call on whether the IDE surface returns, not a cleanup call.Annotated, not debt
pages/orgPage.tsis deliberately ahead of its consumer — built by #235 for #233's Teams segment, which will renderorg.orgs. It cannot rot unnoticed (orgsits in the harnessDECODERS, andorgPage.test.tscovers the parsing), and the file now says so rather than leaving the next auditor to guess.Gate
npx tsc --noEmitclean.🤖 Generated with Claude Code
https://claude.ai/code/session_01RAPZC6xEyCrH9qSKUKLQdy