Files
zeekayandClaude Code fff270c488 Compare against the alternatives, with the provenance on every row
A buyer asking "Enso vs OpenRouter" found nothing to answer it. The winning
artifact in every category we lose is the vendor-level comparison page, and
we had none — /comparison is build-vs-buy, a different axis.

Two rules hold the page honest. A row is either measured or reported, never
both: mixing a number we produced with one a vendor published, under one
heading, is how a comparison lies without any single cell being false. The
page opens on measured and puts reported behind a toggle. And rows we lose
stay in — Enso reaches 600+ models against LiteLLM's 1,800+, and that is on
the page.

Reading the vendors' own pages also killed a claim we would otherwise have
made: all three already serve a native Anthropic /v1/messages, so dual
endpoint compatibility is table stakes, not a differentiator. What none of
them publish is a cost quoted before the call runs — all three only cap
after the fact, two of them at enterprise tier.

Co-Authored-By: Claude Code <[email protected]>
2026-10-04 17:04:34 -07:00

75 lines
2.8 KiB
TypeScript

/**
* A side-by-side of Hanzo against the named alternatives in one category.
*
* THE ONE RULE: a row carries ONE provenance, never two. Either we ran it
* (`measured`) or somebody published it (`reported`). A measured figure sitting
* beside a quoted one under the same heading reads as two of the same kind, and
* they are not — one is a number we produced and can reproduce, the other is a
* number someone else published and we only relay. Mixing them in a row is how a
* comparison starts lying without any single cell being false.
*
* The page defaults to the measured rows and holds the reported ones behind a
* toggle, so the relayed part never outranks the reproducible part by accident.
*
* THE SECOND RULE: a row is published even when we lose it. The point of the page
* is that a reader can trust it, and a page with no column where a rival is ahead
* is not a comparison. Model count goes up even though 600+ is behind 1,800+.
*
* Where a vendor has not published something, the cell says so. An empty cell
* reads as zero; `not published` reads as what it is.
*/
/**
* How the row's number came to be.
*
* `measured` means we ran it. `reported` means somebody published it. The page
* shows measured rows by default and puts the reported ones behind a toggle, so
* the first thing a reader sees is the part that can be reproduced, and the
* relayed part arrives only when they ask for it — rather than the two sitting
* side by side reading as one kind of claim.
*/
export type Provenance = 'measured' | 'reported'
/** Where a value came from, so a reader can go check it. */
export interface Ref {
href: string
/** The day the value was read. A citation without a date is unverifiable. */
date: string
}
export interface Rival {
/** Column key, and the slug used in `theirs`. */
id: string
name: string
href: string
}
export interface CompareRow {
attribute: string
/** One provenance for the whole row — never a measured cell beside a cited one. */
source: Provenance
ours: string
/** Required on a `measured` row: the run or benchmark page behind our cell. */
oursRef?: Ref
/** On a `cited` row, keyed by rival id. A rival with no value says `not published`. */
theirs: Record<string, string>
/** Per-rival source, required for every rival that states a value. */
theirRefs?: Record<string, Ref>
/** A caveat that belongs on the row and nowhere else. */
note?: string
}
export interface Comparison {
/** Route segment under /compare. */
slug: string
/** The category a buyer is shopping in. */
category: string
/** The buyer question this page answers, phrased the way a buyer phrases it. */
question: string
/** One sentence on what these things all are, before any scoring. */
framing: string
subject: { name: string; href: string }
rivals: Rival[]
rows: CompareRow[]
}