Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .claude/harness-candidates.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,45 @@ Deferred lint/test guardrails surfaced during reviews. Promote to a `CExxx` rule
caught them. The cleanup plan explicitly deferred this as YAGNI for the
one-time purge, but any future doc rename/deletion re-opens the same blind
spot — caught in the 2026-07-03 open-source-docs-cleanup implementation run.

## From 2026-07-30 evalboard multi-harness charts + pricing SSOT

- [ ] **CI never runs the `evalboard/` test suite — the highest-value gap here.**
`grep -rn evalboard .github/workflows/ .pre-commit-config.yaml Makefile` yields
exactly one hit: a comment in `pr-checks.yml` saying `evalboard/pnpm-lock.yaml`
is *out of scope*. `pnpm verify` (`tsc --noEmit && vitest run && next build`)
exists in `evalboard/package.json` but nothing invokes it. Consequence: the
pricing drift guard that the whole generated-SSOT design rests on is never
executed. A Python dev edits a rate in `src/coder_eval/pricing.py`, never opens
`evalboard/`, and the PR goes green while every rendered USD figure keeps the
stale rate — precisely how the 7 wrong rates (Opus 4.6/4.7/4.8 at 3× actual)
accumulated in the first place. Flagged independently by two reviewers.
*Not done here because adding a required check to `pr-checks.yml` is a repo-wide
CI-policy change affecting every contributor's PR, outside a plan scoped to
`evalboard/`.* Ready to apply: a job mirroring the existing `setup-node` steps
(`pnpm install --frozen-lockfile` + `pnpm verify` with `working-directory:
evalboard`), ideally non-blocking first. Alternatively a Python-side CExxx rule
asserting `lib/pricing.generated.ts` is current, which would put the guard on
the side that actually edits rates.
- [ ] **One shared normalizer fixture for `normalizeModel` (TS) and
`_normalize_model` (Python).** They have drifted in *both* directions: TS strips
a trailing `-YYYYMMDD`, Python does not — so `claude-opus-4-6-20250514` prices
in the evalboard and is unpriced in the backend, and the frontend "estimated"
cost can disagree with the backend's authoritative Cost for dated ids. Neither
side's tests can see the other. Needs a decision on which behaviour is the
reference before a fixture can be written; the plan lists it under Open
Questions. Note also that plugin rates registered via `register_pricing` (e.g.
`coder_eval_uipath`) can never reach the generated table at all.
- [ ] **No test can see `app/page.tsx`'s self-link scope threading.** `hParam`,
`base` and `buildHref` are module-private inside an async server component and
there is no test for that file. The plan calls a dropped `?h=` the phase's main
risk — a future seventh self-link spelled `buildHref({ window, tag })` silently
resets the user's harness scope with the whole suite green. Guarding it means
extracting `buildHref` + a `selfLinkBase` helper into a testable module.
- [ ] **"Any chart with ≥2 series must have a hover-attribution test."** Nothing
in the suite mounted a chart tooltip before this run, which is how two real
misattribution bugs survived a spec review: recharts silently ignores
`shared={false}` on `LineChart`, and with the default `allowDuplicatedCategory`
each `<Line>` indexes its own points with an index into the concatenation of
all series. Closed for the two overview charts; nothing enforces it for the next
multi-series chart someone adds.
51 changes: 51 additions & 0 deletions evalboard/app/_components/__tests__/harness-badge.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { render } from "@testing-library/react";
import { describe, expect, test, vi } from "vitest";

// next/image needs no runtime here, but stub it to a plain <img> so the rendered
// attributes are asserted directly rather than through the loader's transform.
vi.mock("next/image", () => ({
default: (props: Record<string, unknown>) => (
<img {...(props as { src: string; alt: string })} />
),
}));

const { HarnessBadge } = await import("../harness-badge");

describe("HarnessBadge", () => {
test("renders the vendor logo for a harness that has one", () => {
const { container } = render(<HarnessBadge harness="codex" />);
const img = container.querySelector("img");
expect(img).not.toBeNull();
expect(img!.getAttribute("src")).toBe("/harness/codex.png");
expect(img!.getAttribute("title")).toBe("Codex · OpenAI");
});

test("the logo is decorative — empty alt, so the name isn't announced twice", () => {
// Every call site renders harnessShortLabel beside the badge; alt text
// here would make a screen reader say "Codex · OpenAI Codex".
const { container } = render(<HarnessBadge harness="codex" />);
expect(container.querySelector("img")!.getAttribute("alt")).toBe("");
});

test("renders NOTHING for an unknown harness — the B2 fix", () => {
// It used to print the raw id, which callers then printed again beside it.
const { container } = render(
<HarnessBadge harness="some-future-harness" />,
);
expect(container).toBeEmptyDOMElement();
});

test("renders nothing for a known harness with no logo yet", () => {
const { container } = render(<HarnessBadge harness="delegate-sdk" />);
expect(container).toBeEmptyDOMElement();
});

test("a missing harness folds to claude-code (legacy unstamped runs)", () => {
for (const harness of [null, undefined]) {
const { container } = render(<HarnessBadge harness={harness} />);
expect(container.querySelector("img")!.getAttribute("src")).toBe(
"/harness/claude-code.png",
);
}
});
});
207 changes: 207 additions & 0 deletions evalboard/app/_components/__tests__/harness-selector.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import { fireEvent, render, screen } from "@testing-library/react";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { harnessColor } from "@/lib/harness";

// The selector reads router/params hooks; stub them so it renders in jsdom
// without a provider, and capture `replace` to assert the resulting URL.
const replace = vi.fn();
let searchParams = new URLSearchParams();

vi.mock("next/navigation", () => ({
useRouter: () => ({ replace }),
usePathname: () => "/",
useSearchParams: () => searchParams,
}));

const { HarnessSelector } = await import("../harness-selector");

const HARNESSES = ["claude-code", "codex", "antigravity"];

beforeEach(() => {
replace.mockClear();
searchParams = new URLSearchParams();
});

// The vendor logo is decorative (alt=""), so a chip's accessible name is exactly
// its label — no duplication to work around.
function chip(label: string) {
return screen.getByRole("button", { name: label });
}
function lastUrl(): string {
expect(replace).toHaveBeenCalledTimes(1);
return replace.mock.calls[0][0] as string;
}

describe("the All chip (allowAll)", () => {
test("renders and is the only pressed chip when current is null", () => {
render(
<HarnessSelector current={null} harnesses={HARNESSES} allowAll />,
);
expect(chip("All")).toBeInTheDocument();
const pressed = screen
.getAllByRole("button")
.filter((b) => b.getAttribute("aria-pressed") === "true");
expect(pressed).toHaveLength(1);
expect(pressed[0]).toHaveTextContent("All");
});

test("clicking All removes h and preserves every other param", () => {
searchParams = new URLSearchParams("window=7d&tag=foo&h=codex");
render(
<HarnessSelector current="codex" harnesses={HARNESSES} allowAll />,
);
fireEvent.click(chip("All"));
const url = lastUrl();
expect(url).not.toContain("h=");
expect(url).toContain("window=7d");
expect(url).toContain("tag=foo");
});

test("clicking All when h is the only param leaves no trailing ?", () => {
searchParams = new URLSearchParams("h=codex");
render(
<HarnessSelector current="codex" harnesses={HARNESSES} allowAll />,
);
fireEvent.click(chip("All"));
expect(lastUrl()).toBe("/");
});

test("a harness chip is pressed instead of All once one is selected", () => {
render(
<HarnessSelector
current="codex"
harnesses={HARNESSES}
allowAll
/>,
);
expect(chip("All")).toHaveAttribute("aria-pressed", "false");
expect(chip("Codex")).toHaveAttribute("aria-pressed", "true");
});

test("the All chip carries no colour swatch — it is not a series", () => {
render(
<HarnessSelector current={null} harnesses={HARNESSES} allowAll />,
);
expect(chip("All").querySelectorAll("span[style]")).toHaveLength(0);
});
});

describe("selecting a harness", () => {
test("clicking a chip sets h to that harness", () => {
render(
<HarnessSelector current={null} harnesses={HARNESSES} allowAll />,
);
fireEvent.click(chip("Codex"));
expect(lastUrl()).toContain("h=codex");
});

test("selecting preserves the other params", () => {
searchParams = new URLSearchParams("window=14d&q=needle");
render(
<HarnessSelector current={null} harnesses={HARNESSES} allowAll />,
);
fireEvent.click(chip("Antigravity"));
const url = lastUrl();
expect(url).toContain("h=antigravity");
expect(url).toContain("window=14d");
expect(url).toContain("q=needle");
});

test("each harness chip carries a swatch matching its series colour", () => {
render(
<HarnessSelector current={null} harnesses={HARNESSES} allowAll />,
);
// Assert against harnessColor rather than hardcoded hexes, so the test
// stays honest if the palette is re-validated — and so a chip and its
// chart line are provably the same colour.
for (const [harness, label] of [
["claude-code", "Claude Code"],
["codex", "Codex"],
["antigravity", "Antigravity"],
] as const) {
const swatch = chip(label).querySelector(
"span[style]",
) as HTMLElement | null;
expect(swatch, `${label} chip has no swatch`).not.toBeNull();
expect(swatch!.style.backgroundColor).toBe(
hexToRgb(harnessColor(harness)),
);
}
});
});

describe("without allowAll (the /trends, /watchlist, /path-to-ga shape)", () => {
test("no All chip is rendered", () => {
render(<HarnessSelector current="claude-code" harnesses={HARNESSES} />);
expect(screen.queryByRole("button", { name: "All" })).toBeNull();
});

test("the current harness is still marked active", () => {
render(<HarnessSelector current="claude-code" harnesses={HARNESSES} />);
expect(chip("Claude Code")).toHaveAttribute("aria-pressed", "true");
});
});

describe("an active harness absent from the recent window", () => {
test("is still rendered and active (a deep-linked ?h= reads as selected)", () => {
render(
<HarnessSelector
current="delegate-sdk"
harnesses={["claude-code", "codex"]}
/>,
);
expect(chip("Delegate SDK")).toHaveAttribute("aria-pressed", "true");
});

test("the null (All) case does not prepend a phantom chip", () => {
render(
<HarnessSelector
current={null}
harnesses={["claude-code", "codex"]}
allowAll
/>,
);
// All + exactly the two supplied harnesses.
expect(screen.getAllByRole("button")).toHaveLength(3);
});
});

function hexToRgb(hex: string): string {
const n = parseInt(hex.slice(1), 16);
return `rgb(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255})`;
}

// B2: a harness with no vendor mark used to have its id rendered twice — once by
// HarnessBadge's text fallback and once by the chip's own harnessShortLabel.
describe("a harness with no vendor logo (B2)", () => {
test("its label appears exactly once in the chip", () => {
render(
<HarnessSelector
current="delegate-sdk"
harnesses={["delegate-sdk"]}
/>,
);
// textContent equality, not containment: "delegate-sdkDelegate SDK"
// would satisfy a contains() assertion.
expect(chip("Delegate SDK").textContent).toBe("Delegate SDK");
});

test("an unknown harness likewise shows its id exactly once", () => {
render(
<HarnessSelector
current="some-future-harness"
harnesses={["some-future-harness"]}
/>,
);
expect(chip("some-future-harness").textContent).toBe(
"some-future-harness",
);
});

test("a known harness keeps its logo AND exactly one label", () => {
render(<HarnessSelector current="codex" harnesses={["codex"]} />);
const c = chip("Codex");
expect(c.querySelector("img")).not.toBeNull();
expect(c.textContent).toBe("Codex");
});
});
63 changes: 28 additions & 35 deletions evalboard/app/_components/harness-badge.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,40 @@
import Image from "next/image";
import { harnessRow, normalizeHarness } from "@/lib/harness";

// Canonical harness constants live in the leaf lib/harness module (shared by
// the server data layer); re-exported here so existing badge importers are
// unaffected.
export { KNOWN_HARNESSES, type KnownHarness } from "@/lib/harness";

// Vendor logo + labels for a run's harness (RunConfig). Renders the recognizable
// vendor mark instead of raw "claude-code"/"codex"/"antigravity" text,
// mirroring the Slack rollup's vendor emoji. A missing harness defaults to
// claude-code (the nightly). This is an internal-only column — the caller
// gates it behind isInternal (see lib/edition.ts).
const HARNESS_LOGO: Record<string, { src: string; label: string; short: string }> = {
"claude-code": {
src: "/harness/claude-code.png",
label: "Claude Code · Anthropic",
short: "Claude Code",
},
codex: { src: "/harness/codex.png", label: "Codex · OpenAI", short: "Codex" },
antigravity: {
src: "/harness/antigravity.png",
label: "Antigravity · Google Gemini",
short: "Antigravity",
},
};

// Short human label for a harness id ("Claude Code"), for selectors and prose.
// Unknown ids fall through to the raw id.
export function harnessShortLabel(harness: string): string {
return HARNESS_LOGO[harness]?.short ?? harness;
}
export {
KNOWN_HARNESSES,
harnessShortLabel,
type KnownHarness,
} from "@/lib/harness";

// Vendor logo for a run's harness (RunConfig). Renders the recognizable vendor
// mark instead of raw "claude-code"/"codex"/"antigravity" text, mirroring the
// Slack rollup's vendor emoji. Labels, logo paths and the claude-code default
// all come from the HARNESSES table — this component is only the <Image>. A
// missing harness folds to claude-code (the nightly). This is an internal-only
// column — the caller gates it behind isInternal (see lib/edition.ts).
export function HarnessBadge({ harness }: { harness?: string | null }) {
const key = harness ?? "claude-code";
const logo = HARNESS_LOGO[key];
// Unknown harness: show the raw id rather than a misleading logo.
if (!logo) {
return <span className="text-xs text-gray-700">{key}</span>;
}
const row = harnessRow(normalizeHarness(harness));
// No vendor mark for this harness — an unknown one, or a known one with no
// logo yet: render NOTHING. "No logo → no image" lives here and only here.
//
// This deliberately does not fall back to printing the raw id: every caller
// already renders harnessShortLabel beside the badge, so a text fallback
// showed the id twice ("delegate-sdk delegate-sdk"). Pair the badge with
// harnessShortLabel rather than expecting it to name the harness itself.
if (!row?.logo) return null;
return (
<Image
src={logo.src}
alt={logo.label}
title={logo.label}
src={row.logo}
// Decorative: every call site renders the harness's label as text
// beside this, so alt text would make screen readers announce the
// name twice ("Codex · OpenAI Codex"). title still gives the vendor
// detail on hover for sighted users.
alt=""
title={row.label}
width={20}
height={20}
className="rounded-sm"
Expand Down
Loading
Loading