Skip to content

refactor: extract visual-evidence from ClinicalDashboard monolith (move-only) - #240

Merged
BigSimmo merged 1 commit into
mainfrom
claude/clinical-dashboard-decomp
Jul 3, 2026
Merged

refactor: extract visual-evidence from ClinicalDashboard monolith (move-only)#240
BigSimmo merged 1 commit into
mainfrom
claude/clinical-dashboard-decomp

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

What

Continues the move-only decomposition of ClinicalDashboard.tsx (AuthPanel #202; answer-content + evidence-panels #211; output-panel #214). Extracts the visual-evidence family (compactClinicalTableCaption, visualEvidenceHeader, VisualEvidenceStrip, InlineTableCard, supportDotClass, supportLabel, claimRowsForEvidencePanel, EvidenceClaimsList, EvidenceGapsPanel, MobileEvidenceSheetContent, MobileEvidenceTabPanel, UnifiedEvidenceDrawerContent) into clinical-dashboard/visual-evidence.tsx (contiguous block, 712 lines). Monolith 5953 → 5241 lines.

Cleanest of the series — no runtime cycle

The only monolith dependency is type AnswerFeedbackType, which is erased at compile time. The module imports one-way from evidence-panels / answer-content / other siblings; the monolith imports InlineTableCard + MobileEvidenceSheetContent back (the surfaces the main component renders). VisualEvidenceStrip / MobileEvidenceTabPanel are internal to the block; UnifiedEvidenceDrawerContent is pre-existing dead code, moved along.

Move fidelity

  • Block cut verbatim — the original range diffs empty against the new module body.
  • data-testid / aria-label sha1 checksum over ClinicalDashboard.tsx + clinical-dashboard/*.tsx is byte-identical to main.
  • Stripped 22 now-orphaned monolith imports; two pre-existing dead imports left untouched.

Pinned guard

rendered-text-formatting.test.ts: added visual-evidence.tsx to the scanned corpus (the item.tableTextSnippet / item.title / item.caption render surfaces moved here; verified it trips none of the raw-render negative regexes). No AST pin lives in this module, so clinical-dashboard-merge-artifacts.test.ts is unchanged.

Gates

typecheck; lint 0 errors; pinned vitest 12/12; testid/aria checksum identical; format:check; verify:cheap 980/980.

Deferred

1 module left: document-results.tsx (WhyThisMatchedPanel, RelatedDocumentsPanel, StagedAnswerResultSurface). Hand-off in docs/process-hardening.md Phase 3.

Note

Done on a dedicated branch off main (not the shared claude/* branch) to avoid the squash-ancestry churn from earlier PRs.

🤖 Generated with Claude Code

…onolith
Move-only extraction of the visual-evidence family (compactClinicalTableCaption,
visualEvidenceHeader, VisualEvidenceStrip, InlineTableCard, supportDotClass,
supportLabel, claimRowsForEvidencePanel, EvidenceClaimsList, EvidenceGapsPanel,
MobileEvidenceSheetContent, MobileEvidenceTabPanel, UnifiedEvidenceDrawerContent)
into clinical-dashboard/visual-evidence.tsx. Contiguous block 547-1259 moved
verbatim — it diffs empty against the new module body, and the
data-testid/aria-label sha1 checksum over ClinicalDashboard.tsx +
clinical-dashboard/*.tsx is byte-identical to main. Monolith 5953 -> 5241 lines.
Cleanest module of the series: NO runtime cycle. The only monolith dependency is
`type AnswerFeedbackType`, which is erased at compile time; the module imports
one-way from evidence-panels / answer-content / other siblings, and the monolith
imports InlineTableCard + MobileEvidenceSheetContent back (the surfaces the main
component still renders). VisualEvidenceStrip/MobileEvidenceTabPanel are internal
to the block; UnifiedEvidenceDrawerContent is pre-existing dead code, moved along.
Added visual-evidence.tsx to the rendered-text-formatting corpus (the
item.tableTextSnippet / item.title / item.caption render surfaces moved here;
verified the module trips none of the raw-render negative regexes). Stripped 22
now-orphaned monolith imports; two pre-existing dead imports left untouched.
Done on a dedicated worktree/branch (claude/clinical-dashboard-decomp off main)
instead of the shared claude branch, to avoid squash-ancestry churn.
Gates: typecheck, lint (0 errors), pinned vitest 12/12, testid/aria checksum
identical, format:check, verify:cheap 980/980.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BigSimmo
BigSimmo enabled auto-merge (squash) July 3, 2026 10:12
@BigSimmo
BigSimmo merged commit be64aa7 into mainJul 3, 2026
4 checks passed
@BigSimmo
BigSimmo deleted the claude/clinical-dashboard-decomp branch July 3, 2026 12:52
BigSimmo pushed a commit that referenced this pull request Aug 5, 2026
cursorBot pushed a commit that referenced this pull request Aug 5, 2026
* fix(gates): catch lint and type errors before push, not in CI
Two open PRs burned full CI cycles this week on defects a single local
command would have caught: #1606 on a react-hooks/set-state-in-effect lint
error, #1618 on a TS2339 for `mode.devOnly` (a union member that lacks the
property, where app-modes.ts already exports the correct `"devOnly" in mode`
guard). Neither lint nor typecheck was in the pre-push path.
Typecheck could not simply be added, because it was already unusable
(outstanding-issues #210). tsconfig.json's `include` carries
`.next/types/**/*.ts` and `.next/dev/types/**/*.ts` — gitignored build
artifacts — so deleting a page leaves the stale generated validator importing
a removed module. Reproduced rather than inferred: a planted
`.next/dev/types/validator.ts` referencing a removed mockup page yields
`error TS2307: Cannot find module .../mockups/deleted-mockup-route/page.js`,
base config exit 2, source-only config exit 0. Full source typecheck is clean
(71s cold, 8.8s warm). Red locally and green in CI is how the gate got
abandoned, which is how the real type error then reached CI.
- tsconfig.typecheck.json + `typecheck:source`: identical compiler options,
minus the `.next` globs, with a separate tsbuildinfo so the two incremental
caches cannot invalidate each other. Route-signature validation is not lost;
`next build` still covers it in CI.
- guard-push.mjs gains a fourth guard running eslint over the pushed files and
this typecheck. Verified to reproduce both defects above with CI-identical
messages. Scoped to the lint roots and to pushes that touch TS, skips loudly
when node_modules is absent rather than pushing people to
GUARD_PUSH_DISABLE=1, and overridable with SKIP_STATIC_GUARD=1.
Also corrects a doc claim that made #1580 surprising: "mockups are exempt"
was being read as blanket. Mockups are exempt from the wiring and reachability
gates and nothing else — they are still typechecked, and their client chunks
still count toward check:bundle-budget, which totals every built chunk rather
than the initial production bundle. That the budget's scope contradicts
ledger #13's "not an initial production bundle" position is a real unmade
decision, now recorded as #237 rather than papered over.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T97Kqdj9Xh1Cubv5ms3KVy
* docs(issues): capture the phone Category soft-menu fix salvaged from PR #1606#1606 is closed, but it carried the one fix nothing else in the queue provides:
MobileResultFilterControl's native <select> paints a harsh system-blue highlight
on phones, and #1615 keeps that native select (its change is the iOS 16px
anti-zoom rule). So the fix does not survive #1615 landing.
Records it as #238 with the two defects the redo must not repeat: the unresolved
keyboard trap on disabled options, and the set-state-in-effect lint error that
PR #1620's new pre-push guard would now catch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T97Kqdj9Xh1Cubv5ms3KVy
* issues: capture #239 stale Cloud acceptance pin on PR #1617, #240 remote-container browser gate drift
* Tighten guard coordinator test
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
* fix(gates): shared source-typecheck lease and safer static pre-push
Treat typecheck:source:internal as a shared read-only coordinator lease with
a distinct per-worktree buildinfo file, drop the pinned in-repo cache path,
and harden staticGuard: acquire a short exclusive lease (fail-open when busy),
use a private eslint cache, escalate lint on eslint policy changes, fail closed
when the push tip is not HEAD, cover eslint-rules, and add Vitest coverage.
Align hook/docs wording with the fourth guard and point CLAUDE.md at #252.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
* fix(gates): keep tsBuildInfoFile when run-heavy has no npm_execpath
Pre-push invokes run-heavy via plain node, so the npm_execpath spawn path
was skipped and the fallback dropped effectiveForwarded — undoing the
per-worktree buildinfo injection. Also warn when staticGuard passes on a
dirty working tree.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
* docs: refresh scripts-index for lint:changed:internal
Keep docs:check-inventory green after adding the pre-push eslint wrapper
script to package.json.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
* fix(gates): address Devin findings on static pre-push guard
- Treat "Database focused-test capacity is full" as coordinator busy so
shared typecheck slot exhaustion fails open instead of faking a type error.
- Skip source typecheck when every changed .ts path is excluded by
tsconfig.typecheck.json (edge functions, archive, scratch, worktrees).
- Restore check-github-shell-access.mjs (and its Role notes) in the scripts index.
* chore(ledger): record PR #1620 babysit
* fix(gates): emit structured heavy-run admission-busy signal
Prefer exit 75 + DATABASE_HEAVY_RUN_ADMISSION_BUSY over prose matching so
tsc/eslint output that quotes busy strings cannot false-pass the static guard.
* fix(gates): tip-check only when static work runs; isolate typecheck cache
Addresses follow-up Devin on PR #1620:
- Reorder staticGuard so tip-vs-HEAD fails closed only when lint/typecheck
will actually read the working tree; ignore tag refs in the tip check.
- Pin a distinct tsBuildInfoFile on tsconfig.typecheck.json so direct tsc
does not collide with the base config cache (run-heavy still overrides).
* fix(gates): keep lint failures when typecheck admission is busy
Addresses Devin on PR #1620 — a prior eslint failure must still block the
push if the follow-up source typecheck cannot get a coordinator slot.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@BigSimmo