AI Dossier

Model Scorecard

Generated: 2026-10-05T05:00:54.191Z | Window: 2026-09-05 β†’ 2026-10-05

Cost, quality, and speed per LLM, joined from runstate trails (GitHub), runs.jsonl (token/cost telemetry), and events.jsonl (dispatch tier, stall/escalation counts). Regenerate with npm run scorecard -- --days 30. See #566.

n is a confidence column, not a metric β€” a row with n=1 is one data point, not a trend. Read cost/delivered and delivery rate alongside n, never alone.

Per model Γ— repo Γ— tier

ModelRepoTierAgent CLInDeliveredDelivery rateAC metCost/deliveredMedian API-minMedian wall-clock-minReview fixed/issueStallsEscalationsUnverified exits
<unknown>imboard-ai/ai-dossierunknown19632%98% (n=6)N/AN/A104.417.4 (n=8)000
<unknown>imboard-ai/ai-dossiermidclaude900%N/AN/AN/AN/A0.5 (n=8)000
<unknown>imboard-ai/imboard-monorepounknown54611%98% (n=10)N/AN/A176.58.9 (n=19)000
<unknown>imboard-ai/imboard-monorepomechanicalopencode100%N/AN/AN/AN/A0.0 (n=1)000
<unknown>imboard-ai/imboard-monorepomidclaude,opencode600%N/AN/AN/AN/A1.0 (n=6)000
claude-fable-5-1imboard-ai/imboard-monorepounknown77100%100% (n=4)N/AN/A182.116.2 (n=6)000
claude-haiku-4-5-20251001imboard-ai/imboard-monorepomechanicalclaude11100%N/A$1.564 (n=1)86.11075.61.0 (n=1)000
claude-opus-5imboard-ai/ai-dossierunknown4375%100% (n=3)N/AN/A57.134.0 (n=3)000
claude-opus-5imboard-ai/ai-dossierstrongunknown11100%N/A$45.562 (n=1)198.0196.521.0 (n=1)000
claude-opus-5imboard-ai/imboard-monorepounknown161275%99% (n=7)N/AN/A210.422.2 (n=13)000
claude-opus-5imboard-ai/imboard-monorepomechanicalclaude55100%100% (n=4)$29.145 (n=5)154.8646.518.8 (n=5)02 (0.40/issue)4 (0.80/issue)
claude-opus-5imboard-ai/imboard-monorepomid,strongunknown100%75% (n=1)N/AN/AN/A35.0 (n=1)000
claude-opus-5-5imboard-ai/ai-dossierunknown262596%98% (n=11)N/AN/A35.214.6 (n=26)000
claude-opus-5-5imboard-ai/ai-dossiermid,strongunknown11100%100% (n=1)$29.941 (n=1)98.089.04.0 (n=1)000
claude-opus-5-5imboard-ai/imboard-monorepounknown777496%91% (n=47)N/AN/A107.914.1 (n=76)000
claude-opus-5-5imboard-ai/imboard-monorepomidclaude11100%100% (n=1)$4.933 (n=1)38.668.314.0 (n=1)000
claude-sonnet-5imboard-ai/ai-dossierunknown2323100%97% (n=18)N/AN/A54.38.1 (n=23)000
claude-sonnet-5imboard-ai/ai-dossiermidclaude100%N/AN/AN/AN/A0.0 (n=1)000
claude-sonnet-5imboard-ai/ai-dossierstrongclaude100%100% (n=1)N/AN/AN/A27.0 (n=1)01 (1.00/issue)1 (1.00/issue)
claude-sonnet-5imboard-ai/imboard-monorepounknown363494%98% (n=26)N/AN/A171.78.6 (n=34)000
claude-sonnet-5imboard-ai/imboard-monorepomechanicalclaude55100%100% (n=4)$50.413 (n=5)228.41188.318.4 (n=5)06 (1.20/issue)6 (1.20/issue)
claude-sonnet-5imboard-ai/imboard-monorepomidclaude100%N/AN/AN/AN/AN/A000
claude-sonnet-5imboard-ai/imboard-monorepomid,strongunknown100%N/AN/AN/AN/AN/A000
claude-sonnet-5imboard-ai/imboard-monorepostrongclaude100%N/AN/AN/AN/AN/A01 (1.00/issue)1 (1.00/issue)
claude-sonnet-5-5imboard-ai/ai-dossierunknown2150%N/AN/AN/A18.624.0 (n=1)000
claude-sonnet-5-5imboard-ai/imboard-monorepounknown11100%N/AN/AN/A42.30.0 (n=1)000
fableimboard-ai/imboard-monorepounknown100%N/AN/AN/AN/AN/A000
glm-5.3imboard-ai/imboard-monorepounknown4375%89% (n=3)N/AN/A233.510.0 (n=3)000
glm-5.3-flashimboard-ai/ai-dossierunknown141393%100% (n=9)N/AN/A57.65.0 (n=13)000
glm-5.3-flashimboard-ai/imboard-monorepounknown1313100%93% (n=12)N/AN/A227.911.1 (n=13)000
gpt-5.6-lunaimboard-ai/ai-dossierunknown100%N/AN/AN/AN/AN/A000
gpt-5.6-lunaimboard-ai/imboard-monorepounknown5240%100% (n=2)N/AN/A2416.429.0 (n=2)000
gpt-5.6-terraimboard-ai/ai-dossierunknown211676%99% (n=16)N/AN/A36.22.4 (n=17)000
gpt-5.6-terraimboard-ai/imboard-monorepounknown16956%100% (n=2)N/AN/A102.16.0 (n=10)000
gpt-5.6-terraimboard-ai/imboard-monorepomechanicalopencode11100%100% (n=1)N/A78.1886.82.0 (n=1)000
gpt-6-astraimboard-ai/imboard-monorepounknown22100%92% (n=2)N/AN/A384.410.0 (n=2)000
gpt-6-lunaimboard-ai/ai-dossierunknown33100%93% (n=3)N/AN/A176.32.0 (n=3)000
gpt-6-lunaimboard-ai/imboard-monorepounknown2150%29% (n=2)N/AN/A842.81.0 (n=2)000
gpt-6.1-solimboard-ai/imboard-monorepounknown11100%75% (n=1)N/AN/A236.78.0 (n=1)000
kimi-k3imboard-ai/imboard-monorepounknown100%N/AN/AN/AN/AN/A000

Totals per model (all repos/tiers)

One row per model, with the gateways it was served through as ↳ sub-rows whenever there is more than one β€” the fold that makes the model row readable would otherwise hide a gateway costing more or delivering less than the same weights elsewhere.

Billable tokens count uncached input + cache-creation + cache-read + output β€” cache reads are billed and, on this fleet, are the dominant term (issue #540: 262 uncached vs 13.4M cache-read). That is the same total batch-pilot-2-execution.md Β§13 publishes.

ModelProviderAgent CLInDeliveredDelivery rateΞ” vs prevAC metCost/deliveredBillable tokens/deliveredMedian API-minMedian wall-clock-minReview fixed/issueStallsEscalationsUnverified exits
<unknown>directclaude,opencode891213%+4pt98% (n=16)N/AN/AN/A130.37.6 (n=42)000
claude-fable-5-1directunknown77100%+0pt100% (n=4)N/AN/AN/A182.116.2 (n=6)000
claude-haiku-4-5-20251001directclaude11100%+0ptN/A$1.564 (n=1)7,602,537 (n=1)86.11075.61.0 (n=1)000
claude-opus-5directclaude272178%-1pt98% (n=15)$31.881 (n=6)42,098,134 (n=6)176.4196.523.5 (n=23)02 (0.07/issue)4 (0.15/issue)
claude-opus-5-5directclaude10510196%-2pt92% (n=60)$17.437 (n=2)20,329,788 (n=2)68.381.214.1 (n=104)000
claude-sonnet-5directclaude696290%+1pt98% (n=49)$50.413 (n=5)113,302,920 (n=5)228.4119.89.4 (n=64)08 (0.12/issue)8 (0.12/issue)
claude-sonnet-5-5directunknown3267%β€”N/AN/AN/AN/A30.512.0 (n=2)000
fabledirectunknown100%+0ptN/AN/AN/AN/AN/AN/A000
glm-5.32 providers ↓unknown4375%-14pt89% (n=3)N/AN/AN/A233.510.0 (n=3)000
↳directunknown33100%β€”89% (n=3)N/AN/AN/A233.510.0 (n=3)000
↳z-aiunknown100%β€”N/AN/AN/AN/AN/AN/A000
glm-5.3-flash2 providers ↓unknown272696%-1pt96% (n=21)N/AN/AN/A125.28.0 (n=26)000
↳directunknown1919100%β€”95% (n=18)N/AN/AN/A105.26.4 (n=19)000
↳zai-coding-planunknown8788%β€”100% (n=3)N/AN/AN/A137.312.6 (n=7)000
gpt-5.6-luna2 providers ↓unknown6233%+0pt100% (n=2)N/AN/AN/A2416.429.0 (n=2)000
↳directunknown100%β€”N/AN/AN/AN/AN/AN/A000
↳openaiunknown5240%β€”100% (n=2)N/AN/AN/A2416.429.0 (n=2)000
gpt-5.6-terra2 providers ↓opencode382668%+4pt99% (n=19)N/A23,354,866 (n=1)78.178.03.7 (n=28)000
↳llmgatewayunknown100%β€”N/AN/AN/AN/AN/AN/A000
↳openaiopencode372670%β€”99% (n=19)N/A23,354,866 (n=1)78.178.03.7 (n=28)000
gpt-6-astraopenaiunknown22100%+0pt92% (n=2)N/AN/AN/A384.410.0 (n=2)000
gpt-6-luna2 providers ↓unknown5480%β€”73% (n=5)N/AN/AN/A304.81.6 (n=5)000
↳directunknown100%β€”0% (n=1)N/AN/AN/AN/A2.0 (n=1)000
↳openaiunknown44100%β€”89% (n=4)N/AN/AN/A304.81.5 (n=4)000
gpt-6.1-solopenaiunknown11100%β€”75% (n=1)N/AN/AN/A236.78.0 (n=1)000
kimi-k3directunknown100%+0ptN/AN/AN/AN/AN/AN/A000
TOTALβ€”claude,opencode38627070%β€”96% (n=197)$34.271 (n=14)59,381,359 (n=15)148.0107.511.3 (n=309)010 (0.03/issue)12 (0.03/issue)

Batch amortization

Batching exists to pay the CI gate once for N issues (#770), so the headline is issues shipped per gate run. A gate run is one CI gate on one PR: 1 + ci_fix_attempts for a merged PR (batch or full-cycle alike), 0 for a batch that never merged. Shipped members are the merged batch PR’s closing references β€” a batch blocked at batch-validate and recovered by hand never posts batch-ship, so its trail alone reads it as unshipped.

RepoKindBatchesSingle-memberShipped / dissolved / blockedEnqueuedShipped issuesEvictionsGate runsIssues/gate runMedian gate wall-clockWall-clock/shipped issueBillable tokens/shipped issue (excl. prep)Prep tokens/shipped issue (separate)Cost/shipped issue
imboard-ai/ai-dossierscheduler batches80 (0%)5 / 2 / 02012852.404 min61 min31.4M (n=4)N/A$17.415 (n=4)
imboard-ai/ai-dossierfull-cycle (1 PR per issue)β€”β€”β€”10487β€”950.92N/A89 min52.7M (n=2)N/A$37.752 (n=2)
imboard-ai/imboard-monoreposcheduler batches132 (17%)10 / 1 / 228243102.4014 min187 min19.8M (n=4)N/A$11.352 (n=3)
imboard-ai/imboard-monorepomanual batch-cycle PRs40 (0%)4 / 0 / 02020045.0033 min35 minN/AN/AN/A
imboard-ai/imboard-monorepofull-cycle (1 PR per issue)β€”β€”β€”211172β€”1860.92N/A300 min74.9M (n=10)N/A$39.779 (n=10)

Per batch

BatchRepoKindAnchorOutcomeEnqueuedShippedEvictionsGate runsPRGate wall-clockTokens by modelPrep tokens (separate)
b-20260906-01imboard-ai/ai-dossiersched#600dissolved (eviction-threshold)2020β€”N/Aclaude-sonnet-5 967kN/A
b-20260906-02imboard-ai/ai-dossiersched#604open2010β€”N/Aclaude-sonnet-5,claude-opus-5[1m] 10.5M, claude-sonnet-5 5.1MN/A
b-20260906-03imboard-ai/ai-dossiersched#608shipped2201#6124 minclaude-sonnet-5,claude-opus-5[1m] 28.2M, claude-opus-5 26.5M, claude-haiku-4-5-20251001 520kN/A
b-20260906-04imboard-ai/ai-dossiersched#614shipped4221#6193 minclaude-sonnet-5,claude-opus-5[1m] 39.6M, claude-opus-5 30.1M, claude-sonnet-5 1.2M, claude-haiku-4-5-20251001 558kN/A
b-20260906-05imboard-ai/ai-dossiersched#621shipped3311#6245 minclaude-sonnet-5,claude-opus-5[1m] 52.0M, claude-opus-5 37.5M, claude-haiku-4-5-20251001 784kN/A
b-20260906-07imboard-ai/ai-dossiersched#631dissolved (eviction-threshold)2020β€”N/Aclaude-sonnet-5,claude-opus-5[1m] 17.1M, claude-sonnet-5 7.2MN/A
b-20260906-08imboard-ai/ai-dossiersched#633shipped2201#639129 minclaude-sonnet-5,claude-opus-5[1m] 40.5M, claude-opus-5 24.9M, claude-haiku-4-5-20251001 318kN/A
b-20260929-01imboard-ai/ai-dossiersched#876shipped3301#8923 minN/A (not on this host)N/A
b-20260906-06imboard-ai/imboard-monoreposched#4063shipped2201#40699 minclaude-opus-5 34.9M, claude-sonnet-5,claude-opus-5[1m] 26.2M, claude-sonnet-5,claude-haiku-4-5-20251001,claude-opus-5[1m] 25.5M, claude-haiku-4-5-20251001 590kN/A
b-20260909-01imboard-ai/imboard-monoreposched#4170shipped2111#417315 minclaude-sonnet-5,claude-opus-5[1m] 48.0M, claude-haiku-4-5-20251001 220kN/A
b-20260912-01imboard-ai/imboard-monoreposched#4221shipped2201#422812 minopenai/gpt-5.6-luna 15.4MN/A
b-20260912-02imboard-ai/imboard-monoreposched#4244blocked (suite-unreadable)2010β€”N/Azai-coding-plan/glm-5.3-flash 23.7MN/A
b-20260913-01imboard-ai/imboard-monoreposched#4253shipped1101#42557 minN/A (not on this host)N/A
b-20260915-01imboard-ai/imboard-monoreposched#4281shipped3301#432112 minclaude-haiku-4-5-20251001,claude-opus-5 7.8MN/A
b-20260920-01imboard-ai/imboard-monoreposched#4362shipped3301#436412 minN/A (not on this host)N/A
b-20260924-01imboard-ai/imboard-monoreposched#4399shipped2201#440630 minN/A (not on this host)N/A
b-20260924-02imboard-ai/imboard-monoreposched#4410dissolved (eviction-threshold)1010β€”N/AN/A (not on this host)N/A
b-20260924-03imboard-ai/imboard-monoreposched#4411shipped4401#441519 minN/A (not on this host)N/A
b-20260924-04imboard-ai/imboard-monoreposched#4418blocked (members-mismatch)β€”000β€”N/AN/A (not on this host)N/A
b-20260929-01imboard-ai/imboard-monoreposched#4494shipped3301#449618 minN/A (not on this host)N/A
b-20260929-02imboard-ai/imboard-monoreposched#4519shipped3301#453718 minN/A (not on this host)N/A
m2imboard-ai/imboard-monorepomanualβ€”shipped5501#412513 minN/A (not on this host)N/A
m3imboard-ai/imboard-monorepomanualβ€”shipped6601#4140622 minN/A (not on this host)N/A
proofimboard-ai/imboard-monorepomanualβ€”shipped3301#411353 minN/A (not on this host)N/A
qa-round-10imboard-ai/imboard-monorepomanualβ€”shipped6601#42757 minN/A (not on this host)N/A
  • Tokens per shipped issue EXCLUDES prep; prep is disclosed in its own column (#796). batch-issues-preparation (the classifier agents that pick members) runs in the operator session, not a scheduler dispatch. sched enqueue records the calling session id (CLAUDE_CODE_SESSION_ID) per batch in <sched-dir>/batch-prep.jsonl, and the usage ledger attributes that session’s tokens (subagents included) from the previous enqueue of the same session (max 6h back) to this one. It is an upper bound: unrelated operator work in that window counts too. N/A = no prep session recorded on this host (batches formed before #796 cannot be backfilled; a batch prepared on another host reads N/A).
  • A dissolved batch counts every requeued member as evicted β€” the dissolve requeues all unshipped members as full-cycle runs, so none of them shipped with the batch.
  • A hand-recovered batch PR records no ci_fix_attempts and counts as one gate run.
  • Wall-clock/shipped issue is amortized throughput for batches, latency for full-cycle. A batch row is Ξ£ batch wall-clock Γ· Ξ£ shipped issues (a 300-min 3-member batch reads 100 min); the full-cycle row is the mean per-issue span. Batch token/cost figures include evicted members’ dispatch spend, while full-cycle averages delivered issues only.
  • Tokens by model are per-host. They come from ~/.dossier/sched/<slug>/runs/ (ai-dossier sched stats --batch <id> reads the same logs); a batch run elsewhere reads N/A (not on this host), and a subscription-plan model is tokens without cost.
  • Full-cycle Wall-clock/shipped issue is the milestone span; batch is batch-setup β†’ PR merge. Gate wall-clock is PR open β†’ merge, which includes CI and review waits.

Wall-clock per phase (all models)

Median seconds between a phase’s milestone and the previous one, from the trails’ own at= stamps. Wall-clock is the only per-phase measure available: cost AND API-minutes both come from one agent session that usually spans several phases, so neither can be attributed to a phase (see Limitations).

PhasenMedian
batch-validate2179.9m
batch-review850.2m
implement29426.0m
review30316.7m
merge-wait23416.4m
batch-report610.1m
gate288.5m
plan2944.9m
ship2723.4m
batch-ship53.0m
setup2931.6m
report25824s

Reconciliation

This is a regenerated snapshot, not the first one β€” see git history for docs/reports/model-scorecard.md for prior windows. The first-snapshot reconciliation against batch-pilot-2-execution.md Β§13.3 and model-agnostic-fleet.md ran once, at #566.

Limitations

  • A moving version tag folds onto its pin only where someone declared the mapping. glm-latest β†’ glm-5.3 is declared (MODEL_ALIASES in cli/src/runstate-stats.ts, the mapping #566 states) and folds, along with every routed spelling of it. Which pin a -latest tag points at is a fact about the provider’s state, not about the string, so it cannot be derived here and it goes stale the moment the provider ships a new version under the same tag β€” when that happens, update the value in MODEL_ALIASES rather than reading the row as one version. Undeclared tags (kimi-latest, which has both kimi-k3 and kimi-k3-fast as plausible pins) keep their own row and are named in Data warnings β€” a guessed alias misattributes cost and quality silently, a missing one only splits a row.
  • A context-window variant keeps its own row. claude-opus-5[1m] does not fold into claude-opus-5: the milestone protocol says the suffix should never have been written (gate records the bare model id), but 1M-context is billed differently, so folding it would blend two cost profiles to fix a formatting slip. Read the two rows together when judging quality, separately when judging cost.
  • Cost comes from two sources, and the column says which. ~/.dossier/runs.jsonl is authoritative; where a dispatch predates the telemetry fix (#564) and left it null, the figure is recovered from that dispatch’s own agent log under ~/.dossier/sched/<slug>/runs/. Both are on-host only β€” a dispatch run from another machine has neither, and its row reads N/A because the data is elsewhere, not because it was free.
  • Ξ” vs prev is snapshot-over-snapshot, not a strict 7-day delta. It compares this run against whatever sidecar is on the base branch β€” two overlapping 30-day windows when the weekly cron produced both, and a longer gap whenever a weekly PR went unmerged. A baseline older than the window raises its own data warning naming the age, so the column is never silently stale; read it as β€œsince the last published snapshot”.
  • The window selects ISSUES by last update, not runs by date. The trail read is gh issue list --search "updated:>=<start>", and a matched issue contributes its whole dispatch history β€” so an old run on an issue merely touched inside the window counts in full. Read the window as β€œevery run on an issue active in the last N days”, not β€œevery run started in the last N days”.
  • A <unknown> tier is usually an artifact of that mismatch, not an untiered dispatch. Tier and agent CLI come from events.jsonl events inside the window, while the trail data behind the same row is not time-filtered β€” so a run whose dispatch event predates the window keeps its outcome columns and loses its tier. The per-model totals fold tiers away and are unaffected; only the per-tier rows split.
  • Cost and API-minutes per phase are not separable. A dispatch is usually one continuous agent session covering several phases, so both are recorded per issue, not per phase β€” the per-phase section above reports wall-clock only, which the milestone at= stamps do carry. For a per-phase breakdown of a single run rather than a median across many, run ai-dossier runstate stats directly.
  • Stall/escalation/unverified-exit counts are a per-host gap. They come from ~/.dossier/sched/<project>/events.jsonl, which only exists on the machine that ran the dispatch. A run dispatched from another host reports 0 for these columns here even if it really stalled β€” fleet-cli-audit.sh documents which hosts exist; this script does not collect across them.
  • Cost/delivered averages only delivered issues. Work that was dispatched and then blocked, evicted, or abandoned is not in the denominator or the numerator β€” see the n vs Delivered columns for how much of a bucket that excludes.

Data warnings

  • imboard-ai/ai-dossier: 31 run(s) recorded no model= β€” their row is bucketed as , and its outcome columns are not attributable to any model
  • imboard-ai/ai-dossier: 20 of 150 run(s) are classifier dispatches (classify milestones only) β€” excluded from the by-model and by-class tables, since they record no model= and never ship
  • imboard-ai/ai-dossier: 112 of 130 run(s) (86%) carry no classifier risk= verdict β€” they are bucketed as , so the class rows describe only the classified remainder
  • imboard-ai/imboard-monorepo: 54 run(s) recorded no model= β€” their row is bucketed as , and its outcome columns are not attributable to any model
  • imboard-ai/imboard-monorepo: 80 of 336 run(s) are classifier dispatches (classify milestones only) β€” excluded from the by-model and by-class tables, since they record no model= and never ship
  • imboard-ai/imboard-monorepo: 198 of 256 run(s) (77%) carry no classifier risk= verdict β€” they are bucketed as , so the class rows describe only the classified remainder

Rendered from docs/reports/model-scorecard.md in the repository. Edit it there.