Skip to content

fix(ui): guard intelligence chart widths against zero baselines#3

Merged
t41372 merged 1 commit into
feat/opus-intelligence-frontendfrom
codex/conduct-in-depth-code-review-for-antigravity
Apr 17, 2026
Merged

fix(ui): guard intelligence chart widths against zero baselines#3
t41372 merged 1 commit into
feat/opus-intelligence-frontendfrom
codex/conduct-in-depth-code-review-for-antigravity

Conversation

@t41372
Copy link
Copy Markdown
Owner

@t41372 t41372 commented Apr 17, 2026

Motivation

  • Prevent runtime rendering instability where chart width/scaling computations produce NaN% when the dataset baseline is zero (empty or all-zero early-profile states), causing visual glitches in the Core Intelligence UI.

Description

  • Add safe minimum denominators using Math.max(..., 1) in EngineRankingPanel, ConceptCloudPanel, and SearchEffectivenessSection in src/pages/intelligence/index.tsx so divisions never use zero; compute maxReformulations once to avoid repeated zero-unsafe calculations.

Testing

  • Ran bun run build which executed tsc and vite build and completed successfully.
  • Ran bunx eslint src/pages/intelligence/index.tsx which returned clean results for the changed file.
  • Ran the repo bun run check pipeline; the change did not introduce new errors, but bun run check still reports existing, unrelated React hooks lint violations elsewhere in the repo (pre-existing and outside this change's scope).

Codex Task

@t41372 t41372 changed the base branch from main to feat/opus-intelligence-frontend April 17, 2026 05:17
@t41372 t41372 merged commit c07ea6d into feat/opus-intelligence-frontend Apr 17, 2026
@t41372 t41372 deleted the codex/conduct-in-depth-code-review-for-antigravity branch April 22, 2026 05:24
t41372 added a commit that referenced this pull request May 21, 2026
Why: bun run check was failing at the 100% coverage gate (lines 96.63%,
fns 94.38%) because (a) src/components/heatmap/year-heatmap.tsx had no
remaining callers after the dashboard fake-data removal in c9a6189 —
handoff §4.1 #3 anticipated this — and (b) nineteen files under
src/components/ui/ (badge / button / command / dialog / dropdown-menu /
input / label / popover / radio-group / scroll-area / select /
separator / sheet / skeleton / slider / switch / tabs / textarea /
tooltip) were unreferenced shadcn primitives sitting in the tree from
an earlier phase, never imported by the active paper surface and never
caught because the full coverage gate had not run end-to-end on a
Linux box yet. AGENTS.md is explicit: zero-coverage active-runtime
files are deleted, not excluded. Per user instruction (this turn) we
remove them rather than smuggle them past the gate via exclusions.

What:
- git rm 20 files: year-heatmap.tsx + every file under
  src/components/ui/. Both src/components/heatmap/ and src/components/
  ui/ become empty and git collapses them. No imports anywhere in
  src/**/*.{ts,tsx} reference any of the deleted symbols (verified by
  grep before deletion); inside-ui button.tsx had a single import from
  the also-deleted ui/dialog.tsx, both fall together.
- vitest.config.ts: add three paper-shell re-export barrels to the
  coverage exclude list — src/components/cards/index.ts,
  src/components/explorer-paper/index.ts, src/components/shell/index.ts.
  These are pure `export {X} from './x'` files with no runtime
  semantics, matching the existing precedent for
  src/components/intelligence/workbench/index.ts and
  src/components/review/index.ts (both already excluded). The exclude
  list stays alphabetized.

How: ran the full bun run check; the 100% coverage threshold reported
the 20 zero-coverage files as the dominant gap. Confirmed
zero-import status via
`grep -rn "import.*from ['\"]@/components/ui/<name>['\"]" src/**`
before each deletion. fmt / typecheck / test:unit will be re-validated
by the next bun run check.

Caveats:
- No production behaviour change. The deleted shadcn primitives were
  unreachable; the paper components use their own primitives under
  src/components/primitives/ (skeleton.tsx etc. distinct from
  ui/skeleton.tsx).
- If future work brings back any of these primitives, restore them
  fresh via the shadcn CLI rather than reviving the orphans —
  upstream has moved.

Context: WORK-V03-PAPER-REDESIGN-A — Phase 0 dev-machine close-out.
t41372 added a commit that referenced this pull request May 22, 2026
… i18n

Why
- Codex review flagged three Blocking/High issues against feat/v0.3-redesign-2:
  (1) the ⌘K palette in shell.tsx sent `{ search, limit, offset }` to
      query_history and tried to read `response.rows`, but the real
      contract is `{ q, page, cursor, ... }` returning `items`. Result:
      palette searches were silently empty on desktop, and the existing
      tests had been mocking the wrong shape.
  (2) Paper UI still leaked raw English copy (char/chars counter, "Remove
      tag {tag}" aria, "Calendar" dialog label, "now"/"first" year-rail
      footers, dashboard greetings). i18n is a shipping contract, not
      polish.
  (3) Theme was held twice — once by the shell as a private useState,
      once by Settings → Appearance via applyPaperPreferences. Toggling
      one didn't update the other, so the buttons drifted.

What
- shell.tsx: palette now calls `backend.queryHistory({ q, limit, sort })`
  and maps `response.items` with the real HistoryEntry shape (id/url/
  domain/title/visitedAt/visitTime). Removed the orphan PaletteRow
  interface. shell.test.tsx mocks `backend.queryHistory` with valid
  HistoryQueryResponse fixtures instead of the legacy rows shape.
- i18n: added 3-language entries for the paper detail panel's char
  counter (singular + plural template), the remove-tag aria label, the
  calendar dialog aria, the year-rail now/first footer captions, and
  the dashboard morning/afternoon/evening greetings. The dashboard's
  hand-rolled greeting map is gone — it now reads
  `dashboard.greetingMorning/Afternoon/Evening` like every other copy
  in that route. PaperDetailPanelCopy + PaperCalendarPopoverCopy +
  PaperYearRailProps + paper-view.tsx copy interface all gained the
  new keys; buildPaperDetailPanelCopy + buildPaperContactSheetCopy
  thread them through. i18n parity 100% (2798 keys × 3 locales).
- paper-preferences.ts: applyPaperPreferences now dispatches a
  `pathkeep.paperPreferencesChanged` CustomEvent (with the resolved
  preferences in `detail.preferences`) after applying + persisting.
  shell.tsx subscribes to that event so the topbar theme button stays
  in sync with Settings → Appearance toggles; settings/appearance-
  section.tsx subscribes too so flipping theme via the shell button
  updates the radio without re-mount. shell.tsx's handleToggleTheme
  now routes through applyPaperPreferences instead of mutating a
  private useState — single source of truth, one persist call.

Context
- Codex findings #1, #5, #6. Findings #2 (paper pagination), #3
  (og:image fetch trigger), #4 (coverage gate restoration) tracked
  separately and remain pending in BACKLOG.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
t41372 added a commit that referenced this pull request May 22, 2026
…age gate

Why
- Codex review flagged three more issues:
  (2) Paper Explorer Browse exposed no pagination — the underlying
      useExplorerUrlState had `goToHistoryPage` / `setHistoryPageSize`
      handlers, but the paper UI dropped them. For a 1440 M-row archive
      this caps the user at the first response page (≤200 rows).
  (3) Card-mode og:image cache only loaded existing rows — there was no
      production path that enqueued a fetch for cache-miss URLs, so a
      fresh archive permanently rendered favicons.
  (4) `check:coverage` ran `coverage:rust:quality` (a triage slice) not
      the accepted full-scope `coverage:rust`. That's an unauthorised
      gate weakening vs. docs/plan/program/quality-matrix.md.

What
- PaperContactSheet: new optional `pagination` prop renders a footer
  with newer/older buttons (paper goes newest → oldest, so "next" is
  the older direction), a "page X of Y · N rows" summary, and a
  rows-per-page selector. Disabled buttons clamp at archive bounds.
  Footer omitted entirely when route doesn't supply pagination (e.g.
  the day-only insight surface).
- PaperExplorerView + Explorer route: thread the new pagination
  descriptor through from useExplorerUrlState's existing
  handleNextHistoryPage / handlePreviousHistoryPage / setHistoryPageSize
  handlers. `visibleTimeResults` carries the authoritative page /
  pageCount / total / hasNext / hasPrevious; the footer reads them.
- i18n: 5 new keys across all three locales — paginationOlder, Newer,
  Summary, SummaryPending, PageSizeLabel. 2803 keys × 3 locales,
  parity 100%.
- use-explorer-og-images.ts: after `loadHistoryOgImages` resolves,
  the hook now diffs the response and enqueues
  `triggerOgImageRefetch(batch)` for URLs that came back with a
  non-`ok` status (missing or never-cached). Bounded at 20 URLs per
  render so the worker pool can't be stampeded; `enqueuedFetchRef`
  prevents re-enqueuing within the same cache epoch. The promise's
  .catch swallows rate-limit / disabled-fetch rejections silently —
  the Rust worker persists negative-cache rows on its own.
- og_images_fetch.rs: extracted `read_capped_bytes<R: Read>` from
  `read_response_body` so the body-read fall-throughs (Io error,
  TooLarge) can be unit-tested directly with synthetic Read impls,
  closing line 336 of the production source. Three new cargo tests:
  errors-mid-stream → Io, oversize → TooLarge, short stream → Ok.
- package.json: check:coverage now calls `coverage:rust` (full
  scope), not the `:quality` triage slice. The Rust full gate still
  has ~20 uncovered defensive lines (worker pool mutex poison,
  sender disconnect, mid-stream Io in the live HTTP pipeline) — those
  surface on `bun run check` so a release gate failure is honest.

Coverage delta
- JS: unchanged at 99.71 stmts / 98.89 branches / 99.77 funcs /
  99.89 lines (existing threshold still 99/99/98/99 pending the
  separate JS residual sweep).
- Rust full scope: 12 → 7 uncovered lines in og_images_fetch.rs.
  archive_flows.rs worker pool internals (13 lines) still need an
  integration harness — tracked in WORK-V03-RUST-COVERAGE-RESIDUAL.

Context
- Codex findings #2, #3, #4. Codex flagged the gate-weakening change
  as a merge blocker — the check:coverage script is now restored to
  full coverage. The remaining residual is documented in BACKLOG and
  the gate fails until it closes, which matches the codex requirement
  of "merge 前必須恢復".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant