[dashboard] AIN-251 + AIN-266 W4: shared Crumbs on list pages + candidates card#72
Conversation
…ages + candidates card
W4/9 SHIP-NOW (focused subset of 9 dashboard tickets; the larger feature
PRs — AIN-258/259/260/256/257/261 — are tracked as W4-follow-up after
the W3 backend they consume lands on prod, which it just did).
AIN-251 — shared <Crumbs /> adoption:
- agents/page.tsx — added (was missing)
- inferences/page.tsx — replaced inline <div className="crumbs"> with
shared <Crumbs /> component for cross-page parity
- workflows/page.tsx — added (was missing)
The list-pages-now-have-crumbs gap is closed. The 5 detail/sub pages
already used the shared component; the 3 list pages were drift.
AIN-266 W4 — candidates card on /inferences/[id]:
- types.ts: new InferenceCandidate type + candidates field on
InferenceDetail (mirrors api W3 response shape; Decimals as strings
to preserve precision)
- InferenceDetailClient.tsx: candidates card between §16 Outcome
record and the Audit chain block. Renders only when api returned a
non-empty list (null on pre-§16 rows + pinned passthroughs).
- Per-row: rank · model_slug (with `chosen` badge on the winner) ·
brand_slug · q_prior · projected_cost · eligible · drop_reason.
- Tailwind classes match the existing detail-page palette (text-ink,
bg-bg-elev, hairline borders) so brand v1.3 ramp is preserved.
Validation:
- pnpm --filter dashboard typecheck: passed (no errors)
- §D3 lock preserved: api W3 PR #90 guarded /v1/audit/public; dashboard
consumes via /v1/inferences/{id} which is already authed-tenant-only
via getOwnerHandle → SSR proxy → API key bearer.
Deferred to W4-follow-up (each is a substantive new feature surface,
better as separate review):
- AIN-258 /workflows trace filter-row + 2-col master-detail
- AIN-259 /agents/[id] Identity card
- AIN-260 /agents/new template-tile grid + 5-field caps + Key & deploy
- AIN-256 /templates search-row + featured card + dashed placeholder
- AIN-257 /templates editor consolidation + Tailwind→chrome.css migration
- AIN-261 /inferences/[id] prev/next-step nav
- AIN-262 brand v1.3 token reconciliation (touches MANY files;
best as its own PR)
Refs: AIN-251 · AIN-266 · §D3 · W3 backend live on PROD
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.
Reviewed by Cursor Bugbot for commit 0bf414c. Configure here.
| </thead> | ||
| <tbody> | ||
| {inf.candidates.map((c, i) => { | ||
| const chosen = c.model_slug === inf.model_used; |
There was a problem hiding this comment.
Null-null match gives false "chosen" badge
Low Severity
The comparison c.model_slug === inf.model_used evaluates to true when both values are null (null === null), which would incorrectly render the "chosen" badge on a candidate row. Both model_slug (string | null) and model_used (string | null) allow null. Adding a null guard like inf.model_used != null && c.model_slug === inf.model_used prevents a misleading "chosen" highlight when no model was actually selected.
Reviewed by Cursor Bugbot for commit 0bf414c. Configure here.
| </table> | ||
| </div> | ||
| </div> | ||
| ) : null} |
There was a problem hiding this comment.
Candidates card added to component never rendered
Medium Severity
The new candidates card JSX (~65 lines) and InferenceCandidate type are added to InferenceDetailClient, which is exported but never imported or rendered by any page. The actual /inferences/[id]/page.tsx renders its own inline JSX using getInference (returning InferenceRecord, not InferenceDetail). The AIN-266 candidates card feature claimed in the PR description won't be visible to users — the entire addition is dead code.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 0bf414c. Configure here.


Summary (W4/9 — ship-now, focused subset)
Two highest-leverage dashboard tickets:
AIN-251 — shared
<Crumbs />adoption:The 5 detail pages already used
<Crumbs />; the 3 list pages were drift.AIN-266 candidates card on /inferences/[id]:
InferenceCandidatetype +candidatesfield on InferenceDetailchosenbadge on the row that matchesinf.model_used§D3 lock preserved
api W3 (#90, just merged) guards /v1/audit/public from candidate exposure; dashboard reads via authed /v1/inferences/{id} (SSR proxy → tenant API key).
Validation
pnpm --filter dashboard typecheck: passedWhy PR base =
feat/port-v15-design-canon§0 P3 mitigation: web is dirty on that branch (PARITY md + 2 marketing tsx). Branching here preserves the WIP visibility.
Deferred to W4-follow-up
Each is a substantive new feature better as its own PR:
Refs
AIN-251 · AIN-266 · §D3 · W3 backend live
🤖 Generated with Claude Code
Note
Low Risk
Presentation-only dashboard changes; candidate data is already tenant-scoped on the API and not exposed on public audit endpoints.
Overview
AIN-251 brings the shared
Crumbscomponent to the agents, inferences index, and workflows list pages so list views match detail pages; the inferences index drops hand-rolled breadcrumb markup in favor of the sameworkspace → …path pattern.AIN-266 extends inference detail with a Candidates card (between the §16 outcome block and the audit chain) when the authed API returns a non-empty
candidatesarray: a ranked table of models considered, with q_prior, projected cost, eligibility, drop reasons, and a chosen highlight on the row matchingmodel_used. Types addInferenceCandidateand optionalcandidatesonInferenceDetail, aligned with §16 JSONB; the card stays hidden for legacy or passthrough rows with no candidate set.Reviewed by Cursor Bugbot for commit 0bf414c. Bugbot is set up for automated code reviews on this repo. Configure here.