Basecamp Bench

eval 2026-07-11.2 · September 5, 2026

Basecamp Bench measures a model's ability to ship production-grade software from a fixed specification on a well-known application. Each workspace begins like a real greenfield project: AGENTS.md maps the source material and sets its order of precedence, DESIGN.md provides production design tokens, and INIT.md specifies the product, domain model, and sample data. Each project item uses a shared Recording model that unifies identity, lifecycle, visibility, comments, reactions, subscriptions, and events across tools. Agents build two parts of a Basecamp 5 clone: a single-file frontend SPA evaluated as a release-ready product across 11 weighted dimensions and nine reference screenshots, and a production-ready backend API implementing all 203 operations in the canonical OpenAPI contract across 9 weighted dimensions. All implementation and architecture decisions are evaluated as written for direct production use. Each model starts without an existing implementation, so it must translate the same complete requirements and reference materials into its own architecture and product decisions. The benchmark reveals how well each model exercises greenfield engineering judgment, prioritizes competing concerns, and carries those decisions through to working software.

Fable 5.1 leads frontend at 8.183 through exceptional product fidelity, surface coverage, and working workflows. GPT-6 Astra leads backend at 9.305 through contract fidelity, deterministic seed data, durable state, and explicit unsupported-operation handling. Astra's frontend scores 7.607, just ahead of Opus 5 and Fable 5, and its $25.57 combined cost is about 28% of Fable 5.1's $92.96. Grok 4.6 improves on Grok 4.5 in both tracks for $10.85, with frontend content safety and backend credential disclosure driving its largest deductions. These ten model results separate product breadth from the validation, lifecycle, and contract work needed to make that breadth dependable.

ModelFE scoreFE timeFE costBE scoreBE timeBE costTotal cost
Fable 5.18.1831:43:01$44.608.9651:21:05$48.35$92.96
GPT-6 Astra7.60750:19$13.169.30546:12$12.40$25.57
Opus 57.5831:17:36$42.018.3901:08:55$36.11$78.11
Fable 57.5781:02:14$32.408.3921:04:26$53.47$85.87
Grok 4.67.10425:32$3.897.92632:26$6.96$10.85
Sonnet 56.98244:17$14.227.24342:52$22.01$36.23
Opus 4.86.58743:28$11.586.59047:53$18.26$29.83
Grok 4.56.38415:22$3.957.27821:26$5.35$9.30
GPT-5.6 Sol5.76525:45$7.967.31034:03$7.17$15.13
GPT-5.55.67018:21$4.737.08425:53$6.21$10.94

Scores are weighted composites computed by the benchmark runner from per-dimension judge scores (0–10). Cost and time winners require an FE score of at least 6.0 or a BE score of at least 7.0 on the corresponding track.

Charts

Quality versus cost

Each model appears twice: circle = frontend, triangle = backend

Frontend dimensions

Functional depth spans 3.5 to 9.1, Fable 5.1 leads accessibility at 7.6

Backend dimensions

Nine perfect 10s on coverage, scope honesty spans 4.5 to 10.0

Frontend versus backend gap

All models score higher on backend, gaps +0.003 to +1.698

Model deep dives

8.0–10 Strong 7.0–7.9 Good 6.0–6.9 Mixed 5.0–5.9 Weak 0–4.9 Poor

Fable 5.1 — highest frontend score with exceptional product depth

FE 8.183 · BE 8.965 · $92.96 total · 3:04:06 total

Fable 5.1 builds the broadest frontend in this report and a complete, stateful backend. Shared Recording primitives carry identity, visibility, lifecycle, events, and search across tools. Its frontend passes 3,485 executable checks, while its backend preserves created state across a snapshot reload. Remaining defects concentrate in persisted-state trust, secondary input methods, reset isolation, and shutdown durability.

Where it shines

  • Product breadth backed by executable workflowsRequired screens, account-wide destinations, reporting, administration, detail views, and overlays share one recording graph. The submitted harness exercises production actions and forms through creation, editing, completion, notifications, move/copy, deletion, reload, and reset.
  • Detailed reference-derived componentsThe shell, Home, dock previews, and Card Table encode reference-scale geometry. Canonical light and dark tokens support consistent controls, surfaces, focus states, print rules, and reduced motion.
  • Complete routes with coherent lifecycle behaviorAll 203 canonical operations match their methods and paths. Runtime probes verify parent archive/restore, preservation of independently trashed children, card completion transitions, cross-resource events, and state recovery from a snapshot.

Where it's okay

  • Rich keyboard support with incomplete containmentGlobal and contextual shortcuts, named controls, confirmations, undo, and focus restoration support ordinary workflows. Dialogs lack a Tab trap, and card movement has no keyboard or touch alternative.
  • Strong request handling with specific mismatchesAuthentication, privacy-preserving errors, pagination, ETags, conditional requests, sanitization, and client visibility work. Binary uploads accept text/plain despite the declared media type, and root-tool serializers can emit invalid fields.

Where it underperforms

  • Persisted data bypasses defensive boundariesA malformed version-1 object crashes boot, trusted stored rich HTML retains an injected onerror attribute, and denied storage removal breaks reset. Ordinary editor sanitization does not protect the persisted-state path.
  • Reset and shutdown leave state inconsistenciesReset retains idempotency and rate-limit caches. A replay can return 201 for a resource that no longer exists, and shutdown does not await an in-flight snapshot. The backend ships without an automated suite or package metadata.
  • Sample identity and cleanup driftBlob keys vary between fixed-time boots, and deleting the sample project does not remove unused sample people.

Failure modes

Fable 5.1 delivers unusually broad normal-path behavior, but its weaker paths cross persistence boundaries. The frontend trusts restored data more than new editor input, while the backend resets its domain graph without resetting related caches. Production work should prioritize stored-state validation and sanitization, atomic reset behavior, snapshot shutdown, and accessible alternatives to drag-only movement.

Dimension scores
FRONTEND
8.3Ref 8.5Craft 9.5Model 9.5Surf 9.1Depth 7.9Inter 6.6State 7.4Resp 7.6A11y 7.8Arch 6.5Rely
BACKEND
9.0Arch 10.0Surf 9.0Depth 9.0HTTP 9.0Seed 9.0Valid 8.0Ops 8.0Code 8.5Hnsty

GPT-6 Astra — highest backend score with durable, well-hardened behavior

FE 7.607 · BE 9.305 · $25.57 total · 1:36:31 total

Astra combines substantial frontend workflows with the strongest backend result in this report. Its backend registers all 203 operations, returns documented success for 192, and explicitly rejects 11 unsupported operations. Deterministic seed data, atomic snapshots, schema-aware responses, and failure-oriented tests support its 9.305 backend score. The frontend reaches 7.607 with simpler visual details and incomplete persisted-state validation.

Where it shines

  • Complete registration and explicit limitsThe operation-wide suite checks documented statuses and response shapes across all 203 routes. Capabilities output names exactly 11 unavailable operations, and structured 501 responses disclose integration and scheduler gaps.
  • Durable state and tested invariantsIndependent probes retain a created project across snapshot restart, preserve archive protection and inherited status, reject cross-project card movement without partial mutation, and round-trip attachment bytes. Locked atomic snapshots and failure-oriented tests support recovery.
  • Deterministic content and strong request boundariesFixed-time stores serialize identically and every advertised dock child is reachable. Malformed framing, duplicate queries, stale ETags, wrong record types, and unauthorized requests return safe errors.
  • Real local workflows across a shared storeNineteen route states generate cleanly. A controlled create-to-do, comment, complete, trash, and restore sequence persists its final record and emits the corresponding lifecycle events.

Where it's okay

  • Coherent styling with simplified Basecamp detailsThe prototype uses the supplied color ramps, typography, themes, focus styling, and motion rules. First boot is light against the dark references, while Jump recents, the Sample Project tab, and parts of Docs and Chat are simplified.
  • Useful keyboard and feedback foundationsShortcuts, native dialogs, inline errors, undo, and named controls support core actions. Jump navigation stops at the first result, and Escape bypasses the focus-restoring modal-close path.

Where it underperforms

  • Current-version storage is trusted too earlyA version-1 object missing required collections is accepted and crashes startup. Cross-tab updates use the same shallow version check, and persisted upload URLs bypass normal input validation.
  • Two concrete specification mismatchesNew projects receive eight enabled tools instead of an empty dock. Boost creation accepts up to 100 characters although the OpenAPI contract limits it to 16.
  • Large single-file implementations concentrate change riskCentral helpers and resource-family logic support reuse, but global frontend state and a 4,109-line backend dispatcher couple rendering, persistence, validation, and behavior.

Failure modes

Astra handles many backend failure paths explicitly, with remaining verified defects concentrated in new-project defaults and boost validation. The frontend still treats a version number as sufficient proof of a valid stored graph. Completing production readiness requires validating restored state and persisted URLs, repairing focus behavior, and implementing the disclosed service gaps.

Dimension scores
FRONTEND
7.0Ref 7.7Craft 8.5Model 8.6Surf 8.4Depth 7.7Inter 7.0State 7.0Resp 7.0A11y 7.3Arch 7.0Rely
BACKEND
8.8Arch 10.0Surf 8.9Depth 9.5HTTP 10.0Seed 9.0Valid 9.3Ops 8.3Code 10.0Hnsty

Opus 5 — broad frontend surface and substantial backend depth

FE 7.583 · BE 8.390 · $78.11 total · 2:26:31 total

Opus 5 scores 7.583 on frontend and finishes 0.002 behind Fable on backend. Its shared Recording model supports 69 frontend routes and all 203 canonical backend operations, with strong product fidelity, seed fidelity, architecture, and operability. The remaining production blockers concentrate at trust boundaries, persisted-state validation, lifecycle invariants, and schema conformance.

Where it shines

  • A broadly connected frontendThe shared Recording graph connects roles, client visibility, lifecycle, comments, subscriptions, search, personal views, reports, and all required project tools. The evaluator rendered 69 routes and verified substantive creation, editing, commenting, assignment, completion, and card movement.
  • Reference-derived visual systemIts geometry follows the supplied captures, while a coherent token and component system covers both themes, motion, focus, overlays, cards, chat, empty states, and mobile adaptations.
  • Complete contract over a coherent domain coreAll 203 canonical operations are registered and runtime-reachable. Shared Recording indexes support lifecycle, authorization, comments, boosts, subscriptions, events, search, and stateful project, message, and todo workflows.
  • Dense seed and explicit operational boundariesThe deterministic sample graph is deeply interconnected, while configuration, health, logging, rate limits, graceful shutdown, and production-only restrictions are implemented. Unsupported product surfaces and deliberate simplifications are disclosed.

Where it's okay

  • Substantive workflows with uneven lifecycle recoveryCore mutations work and persist, but archived projects still accept new messages, trashed projects have no reachable restore action, and rerenders can disrupt keyboard focus.
  • Strong foundations without browser proofSemantic landmarks, named controls, focus styling, reduced motion, mobile layout rules, and touch affordances are present. Real phone overflow, drag behavior, and focus execution could not be verified in the evaluator sandbox.
  • Deep process-lifetime behavior with protocol driftProjects, messages, comments, todos, search, reset, ETags, pagination, HEAD, CORS, and rate limits work through the real request pipeline. Storage is process-local, and serializers emit invalid nulls across many successful response families.

Where it underperforms

  • Persisted state can become unsafe or unrecoverableA same-schema object missing required collections is accepted and can brick boot. Delayed writes have no unload flush, raw editor drafts are rehydrated before sanitization, and permanent deletion leaves dangling events.
  • Unsafe frontend URLs and incomplete focus behaviorA javascript: cloud-file URL is accepted and rendered as a link. Menus declare ARIA menu roles without the required keyboard behavior, and modal focus is not consistently moved or restored.
  • Attachment and webhook trust boundaries failA client restricted to another project can receive private attachment metadata and a signed download. Webhook creation blocks private addresses, while updating a valid webhook to a loopback target succeeds.
  • Schema and lifecycle invariants driftThirty of 34 sampled successful response families emit at least one non-nullable OpenAPI field as null. Restoring a parent can reactivate a child that was independently trashed, and permissive parsing accepts invalid dates and JSON-looking text/plain.

Failure modes

Opus 5's breadth is real, but its most serious defects appear where broad generic systems meet adversarial state. Whole-snapshot frontend persistence trusts incomplete shapes, shared lifecycle propagation overwrites independent child state, and backend helpers apply inconsistent authorization and URL-validation rules. The result is a high-quality starting point that still requires attachment authorization, webhook SSRF protection, schema-conformance repair, persisted-state validation, and frontend content-safety work before release.

Dimension scores
FRONTEND
8.0Ref 8.3Craft 9.2Model 9.1Surf 7.8Depth 7.0Inter 6.2State 6.5Resp 6.5A11y 7.4Arch 6.0Rely
BACKEND
8.8Arch 10.0Surf 8.6Depth 7.4HTTP 9.1Seed 6.5Valid 8.3Ops 8.0Code 9.2Hnsty

Fable 5 — broad workflows built around shared state

FE 7.578 · BE 8.392 · $85.87 total · 2:06:40 total

Fable treated both tracks as systems problems. Its backend registered all 203 operations with explicit handlers and no stubs, and its frontend routes every screen through one shared recording store, so activity, search, trash, and notifications read the same data. Its lifecycle invariants held under testing: archiving a parent propagated to children, archived content rejected mutation, and unarchiving reversed it.

Where it shines

  • Complete API with deep workflows203/203 operations implemented, 35 of 37 state assertions passed, cross-resource invariants enforced explicitly: assignees must see the project, todo moves stay in-bucket, card moves stay in-board.
  • Exact seed across both tracksThe exact nine-person cast, five threaded messages with mentions and boosts, the full Kanban state, and a 16-line chat, reproduced nearly verbatim.
  • Broad product with persistent workflowsNine required surfaces plus Adminland, Trash, Reports, Search, and profiles, with create/edit/comment/move/archive/restore workflows that mutate and persist.
  • HTTP plumbingETags with 304s, HEAD, 405 + Allow, pagination with Link headers, consistent error envelopes, graceful shutdown.

Where it's okay

  • Malformed input and SSRF checks remain weakAccepts 2025-02-31 as a date, accepts JSON without a Content-Type, coerces active: "false" to true, and webhook SSRF checks compare URL strings and never resolve DNS, so a hostname pointing at an internal IP passes.
  • Healthy runtime with an incomplete resetZero-install with health endpoints and structured logs, but no tests, no manifest, and reset doesn't clear the rate limiter: requests stayed 429-limited after reset.
  • Persistent shared state with weak modal UXNearly every mutation persists through one graph, but modals don't trap or restore focus and editing leans on deprecated execCommand and native prompts.

Where it underperforms

  • Mobile controls lose accessible namesBelow 760px five fixed controls lose their accessible names entirely, star buttons nest inside links, menus lack menu-item semantics.
  • Stored HTML creates an XSS riskRich text is stored from innerHTML and rendered raw across comments, docs, chat, and notes, so any markup that reaches storage executes on render. URLs accepted without scheme validation.
  • Data integrity"Make a copy" passes an undefined ID that overwrites the generated one, corrupting the copied record. Permanent delete removes a record and its direct children only, leaving grandchildren, events, boosts, and bookmarks pointing at dead IDs.

Failure modes

Fable's remaining defects cluster in security, configuration, and data-integrity review. The submission renders stored HTML without sanitization, prints production tokens by default, allows wildcard CORS with Authorization, and overstates support for operations whose prerequisite state remains unreachable. A sanitizer, safer configuration defaults, and a corrected copy operation address these defects within the existing architecture.

Dimension scores
FRONTEND
8.0Ref 8.1Craft 9.2Model 9.0Surf 8.1Depth 7.2Inter 6.8State 6.5Resp 5.0A11y 7.5Arch 6.2Rely
BACKEND
8.4Arch 10.0Surf 8.6Depth 8.2HTTP 8.8Seed 7.3Valid 7.4Ops 7.9Code 7.9Hnsty

Grok 4.6 — higher scores at low cost with critical safety gaps

FE 7.104 · BE 7.926 · $10.85 total · 57:58 total

Grok 4.6 improves on Grok 4.5 by 0.720 on frontend and 0.648 on backend for $10.85 across both tracks. Its frontend closely follows the product structure and reference anatomy, while its backend registers all 203 operations over shared recording and lifecycle helpers. Content injection, exposed credentials, and unrestricted webhook destinations account for its most serious defects.

Where it shines

  • Faithful shell and interconnected sample contentRequired surfaces reproduce the Basecamp shell and canonical dark hierarchy. The sample graph links people, projects, tools, and recording content through common selectors and routes.
  • Complete routes and coherent in-process workflowsAll 131 paths and 203 method-path-operation triples match the contract. Runtime message/comment/boost/archive and to-do completion/trash flows write events and preserve state across requests, with parent-type and ownership checks.
  • Rich deterministic seedRequired people, tools, and linked content closely match the specification. The main sample-model mismatch is the project admission mode.

Where it's okay

  • Broad source-traced behavior with unfinished controlsCreate, edit, comment, filter, move, and trash paths connect to persistence. Check-ins, Forwards, and several secondary screens remain shallow, stubbed, or unreachable.
  • Useful protocol and operational foundationsPagination, errors, headers, health, reset, configuration, and self-checks support local operation. Eleven operations return success statuses that contradict OpenAPI, and some null fields violate response schemas.

Where it underperforms

  • Credentials and webhook destinations are unsafePublic credential disclosure and unrestricted webhook destinations defeat otherwise substantial authentication and permission handling.
  • Stored content can execute markupContenteditable HTML and personal notes enter persistent state and return to raw HTML without sanitization. Unsafe URL schemes and malformed versioned storage add further failure paths, and a search predicate can include inactive records.
  • Focus and control semantics are incompleteGeneric dialogs lack accessible naming, containment, and focus restoration. To-do completion nests a button inside another button, and narrow-screen My Bar rules hide labels without replacement icons.
  • Configured persistence never writes stateBASECAMP_DATA_FILE is configured but unused. A fresh store is empty, and the backend lacks automated tests, worker draining, and durable storage.

Failure modes

Grok 4.6 spends its effort on product breadth and shared domain behavior, while trust boundaries remain uneven. The frontend reuses raw stored HTML, and the backend exposes credentials and accepts unsafe webhook targets. Production work must address those boundaries before the broader workflow coverage can be relied upon, then repair persistence, response contracts, and accessible control behavior.

Dimension scores
FRONTEND
8.2Ref 8.1Craft 9.0Model 8.6Surf 7.2Depth 6.3Inter 6.1State 6.4Resp 5.0A11y 6.4Arch 4.2Rely
BACKEND
8.7Arch 10.0Surf 8.6Depth 7.3HTTP 9.2Seed 4.6Valid 7.2Ops 7.0Code 8.0Hnsty

Sonnet 5 — strong frontend with critical backend authorization defects

FE 6.982 · BE 7.243 · $36.23 total · 1:27:09 total

Sonnet builds a 6.982-scoring frontend with a shared recordings map, faithful sample data, and persistent workflows. Its backend scores 8.0 on architecture and modeling. Backend authorization defects drive its largest deductions.

Where it shines

  • One shared graph powers every surface74 recordings with events, comments, boosts, readings, and bookmarks in one deterministic graph. All eight screenshot surfaces reachable plus ten optional destinations.
  • FE workflowsVerified creation of messages, docs, to-dos, cards, projects, and columns, plus completion, comments, boosts, card moves, and trash/restore, all surviving reload.
  • Rich-text sanitizerAn allowlist sanitizer protects rich-text input before rendering.
  • Complete routes with working lifecyclesVerified end-to-end project, message, and todo lifecycles, 403 on non-owner edits, reset invalidating pre-reset tokens.

Where it's okay

  • Pagination and response schemas driftCorrect statuses and envelopes, but 18 of 44 paginated operations skip pagination, sort/direction params are ignored, and nulls appear where the schema requires strings.
  • Rerenders break focus and mobile actionsWhole-app rerenders drop focus, hover-only actions vanish on touch, the calendar stays seven columns at every width.
  • Healthy runtime with memory-only stateHealth checks, structured logs, graceful shutdown. State is memory-only and there are no tests.

Where it underperforms

  • Client tokens can trash projectsA client token issued DELETE /1/projects/1011 and got 204, trashing the sample project. Unauthenticated GET /_seed/tokens returns every raw bearer credential, and reset ships enabled by default.
  • Broken emitted URLsResource URLs append .json where the registered routes don't, so following a returned project URL yields 400. Navigability breaks on the API's own links.
  • FE loose ends19 explicit no-op controls, and the primary Message Board "New message" button has no dispatch case at all while the quick-add path works. Reset leaves bookmarks, readings, and notes behind.

Failure modes

Sonnet implements substantial functionality but leaves 19 controls and several primary actions disconnected from their handlers. The frontend's New message button has no dispatch case. The backend exposes credentials by default, and its notImplemented error helper is never called. Partial features return successful empty responses.

Dimension scores
FRONTEND
7.8Ref 7.5Craft 8.8Model 8.2Surf 7.1Depth 6.0Inter 5.8State 5.9Resp 5.2A11y 6.5Arch 6.5Rely
BACKEND
8.0Arch 10.0Surf 7.5Depth 6.8HTTP 7.5Seed 4.5Valid 7.5Ops 6.5Code 5.0Hnsty

Opus 4.8 — broad product depth with unsafe trust boundaries

FE 6.587 · BE 6.590 · $29.83 total · 1:31:21 total

Opus 4.8 builds substantial, usable prototypes on both tracks. Its frontend covers every screenshot-backed surface and many optional destinations through a rich local model with persisted mutations. Its backend registers all 203 operations and implements broad process-lifetime CRUD on a shared Recording spine. Security and relationship invariants are the limiting factors: owner credentials leak through health, reset is unauthenticated, project membership is not enforced, and cross-project moves can corrupt hierarchy.

Where it shines

  • Rich product model and broad UIAll screenshot-backed surfaces are reachable alongside calendars, Activity, Everything, Reports, Adminland, assignments, profiles, notifications, pings, and My Bar trays.
  • Strong visual correspondenceThe centered navigation, layered sheets, three-column home, project dock, fixed My Bar, overlays, dark/light tokens, and component treatments closely follow the supplied references.
  • Complete routes on a shared stateful modelAll 203 canonical method/path shapes register with zero missing routes. Shared recordings, hierarchy, lifecycle, subscriptions, events, comments, and boosts support real cross-request behavior.

Where it's okay

  • Meaningful persisted workflowsFrontend creation, completion, comments, card movement, docs, chat, pings, notes, and preferences persist locally. Backend create/read/update/reset probes preserve process-lifetime state.
  • Solid HTTP and runtime foundationsCentral JSON headers, ETags, request IDs, errors, pagination, health, logging, body limits, and signal shutdown work, while canonical request shapes, durability, readiness, and safe operational endpoints remain incomplete.
  • Readable monoliths with uneven claimsBoth large single-file submissions are systematically sectioned with reusable helpers, but transport, state, rendering, authorization, and domain behavior remain tightly coupled, and several documented completeness claims exceed verified behavior.

Where it underperforms

  • Critical trust-boundary failuresUnauthenticated health exposes the owner bearer token, unauthenticated reset destroys mutable state, and an employee outside a project's membership can read and rename it.
  • Hierarchy invariants breakA cross-project card move keeps the old bucket while adopting a parent from another project, and trashing a project leaves its child Card Table directly readable.
  • Visible breadth includes false-success controlsNineteen controls are explicit stubs. Archive and trash only toast or navigate without changing state, while copy-link writes only # and still reports success.
  • Mobile and accessibility need another passClickable divs remain keyboard-inaccessible, dialogs lack focus management, toasts lack live regions, and one breakpoint leaves fixed navigation, calendars, catalogs, and My Bar fragile on phones.
  • Unsafe persistence and operationsStored project descriptions can inject markup into innerHTML, malformed stored state can crash boot, backend state is memory-only, and wildcard credentialed CORS ships as the default.

Failure modes

Opus 4.8 fails at the boundary between broad implementation and production safety. The backend exposes the plaintext owner bearer token through unauthenticated health, lets unauthenticated callers reset all mutable state, ships wildcard credentialed CORS, and allows a nonmember employee to read and rename another project. Its domain model accepts cross-project card moves that split parent and bucket identity, leaves child tools readable after project trash, and reports success for empty template construction, fabricated upload metadata, and arbitrary occurrence dates. The frontend stores project descriptions as raw HTML and renders them through innerHTML, accepts malformed persisted shapes that can crash boot, and tells users archive, trash, and copy-link actions succeeded when no valid state change occurred. These failures come from maximizing surface area inside two large monoliths without adversarial tests for authorization, hierarchy, schema conformance, stored content, or false-success behavior. The result needs security-boundary repair and invariant reconstruction before feature iteration can be trusted.

Dimension scores
FRONTEND
7.5Ref 7.5Craft 8.5Model 8.0Surf 6.0Depth 5.8Inter 6.5State 5.0Resp 4.0A11y 6.5Arch 5.3Rely
BACKEND
7.0Arch 10.0Surf 6.5Depth 6.5HTTP 7.0Seed 3.0Valid 6.0Ops 6.5Code 5.5Hnsty

Grok 4.5 — lowest cost with competitive scores

FE 6.384 · BE 7.278 · $9.30 total · 36:48 total

Grok produces roughly 85% of Fable's score for 11% of the cost and 29% of the time. Its backend earns a seed-data score of 9.0, and its frontend has stronger functional depth than GPT-5.6 Sol and GPT-5.5. The lower cost corresponds with weaker input validation, edge-case handling, and reporting of incomplete features.

Where it shines

  • Speed and costBoth tracks finish in 37 minutes for under $10, producing the strongest value result among models scoring above 6 on FE and above 7 on BE.
  • Rich seed data with stable API IDsThe full verified inventory of five messages, ten todos, thirteen cards, and sixteen chat lines, navigable through the live API with stable IDs.
  • Verified stateful flowsProject and todo CRUD with lifecycle, comments incrementing counts, boosts, subscriptions, and correct pagination across 21 projects with proper Link headers.
  • Dense sample data connects every toolCategories, pinned messages, watchers, on-hold lanes, and a coherent cross-tool narrative.

Where it's okay

  • Core workflows persist, but editing is absentCreation, completion, comments, boosts, card moves, and chat all work and persist. Editing and deletion don't exist, and Bubble Up is a toast with no state change.
  • Shared recordings stop cascading too earlyA real shared recording table with generic events and lifecycle actions, but cascade stops at immediate children: archiving a board archived its message and left the message's comment active.
  • Response statuses drift at the edgesRich canonical shapes and correct statuses in most places, undermined by two operations returning 200 bodies where the spec requires 204.

Where it underperforms

  • Invalid input reaches server errorsAn invalid numeric ID returns 500, router literals are compiled as unescaped regex so /projects/1000Xjson matched and returned project 1000, and the default unauthenticated reset destroyed runtime state in testing.
  • Route shadowingThe canonical projects/recordings.json operation is intercepted by an earlier route and 500s, the only unreachable canonical operation in the field.
  • Mobile layouts and malformed state breakNo mobile navigation model, a fixed footer that overflows at every narrow width, and stored state containing only {version: 1} crashes boot. Creating projects across a reload produces duplicate IDs.
  • Partial features report successThe header claims no hollow surface while cloning copies the tool container and none of its content yet reports success, template construction reports completion on an empty project, and reminders always return an empty success.

Failure modes

Grok's failures concentrate in validation, malformed state, responsive behavior, and partial features. Client mistakes become 500s, malformed persistence causes crashes, partial features report success, and the public root response exposes credentials. Its four lowest dimensions are responsive adaptation at 4.0, scope honesty at 4.5, accessibility at 4.8, and validation at 5.0. Addressing these dimensions requires additional implementation and review time.

Dimension scores
FRONTEND
7.0Ref 7.2Craft 8.0Model 7.5Surf 6.5Depth 6.1Inter 6.0State 4.0Resp 4.8A11y 5.5Arch 6.0Rely
BACKEND
7.5Arch 9.7Surf 7.5Depth 7.0HTTP 9.0Seed 5.0Valid 6.5Ops 6.5Code 4.5Hnsty

GPT-5.6 Sol — strong operability with explicit backend limitations

FE 5.765 · BE 7.310 · $15.13 total · 59:48 total

Sol implements 132 backend operations, marks the remaining 71 with explicit 501 responses, and provides strong operational scaffolding. These decisions earn it sixth place on BE. Its frontend leaves twelve controls marked as prototypes and provides no complete create, edit, comment, or delete workflow.

Where it shines

  • Unsupported operations return explicit 501sEvery unimplemented operation returns an explicit 501 not_implemented. Binary and multipart uploads return explicit 501s instead of pretending to store files. No fabricated CRUD.
  • Strong production scaffoldingEnvironment validation, allowlisted CORS, atomic mode-0600 state persistence, structured logs with request IDs, graceful shutdown, and exported router/state/reset functions so tests can drive it without a socket.
  • Genuinely stateful idempotencyReplaying a creation key returned the same ID with Idempotency-Replayed: true, and changing the payload under that key returned 409.
  • The contract generates every routeCompiles all 203 operations directly from the OpenAPI document and asserts the count, giving coverage by construction.

Where it's okay

  • Core seed data omits events and assigneesThe right project, cast, dock, and counts, with specific gaps: missing assignees on the Review card, eight chat authors instead of five, absent completion events.
  • Coherent design with weak iconographyCoherent tokens, dark/light themes, reduced motion, and detailed empty states, all wrapped around emoji icons and gradient-initial avatars.
  • Explicit focus managementLabeled jump dialog, focus restoration, inert closed layers, foundations most other models skipped. It restores focus to the triggering control.

Where it underperforms

  • The generic router erases typesA GET for a todo returned a Message with 200, and a POST created a Todo whose parent was a Message. Both defects trace to one function, routedRecording(), which resolves an ID without ever checking resource type or parent.
  • Explicit stubs limit workflow depth71 stubs cap it, trashed todos still appear in normal lists, archive doesn't cascade despite serializing inherits_status, and a valid chunked request body is rejected for lacking Content-Length.
  • Core workflows remain prototypesTwelve controls self-report prototype status and more are silently inert. No create, edit, comment, or delete workflow exists end to end. Persistence covers four localStorage keys.
  • FE state handlingMalformed JSON aborts boot, wrong-shaped data crashes renderers, and invalid detail IDs silently render the first record, so a broken link shows wrong data with no error.

Failure modes

Sol's backend reports 71 unsupported operations explicitly. Its frontend leaves twelve controls marked as prototypes, keeps other controls inert without feedback, and routes invalid detail links to the wrong record. The generic recording router simplifies dispatch but removes type context, causing the submission's most serious correctness defects. This loss of type context makes each new handler vulnerable to the same errors.

Dimension scores
FRONTEND
6.5Ref 7.0Craft 6.5Model 7.0Surf 4.0Depth 5.0Inter 4.5State 6.5Resp 6.0A11y 5.0Arch 5.0Rely
BACKEND
7.0Arch 10.0Surf 6.0Depth 6.0HTTP 8.0Seed 6.5Valid 8.5Ops 7.0Code 8.0Hnsty

GPT-5.5 — durable backend with limited frontend behavior

FE 5.670 · BE 7.084 · $10.94 total · 44:14 total

GPT-5.5 ships a backend with durable persistence: a SQLite store whose created todos and comments survive a full restart. Complete route coverage and solid hardening basics support its 7.084 backend score. Its frontend scores 5.670, tenth overall. All nine required screens render, but no creation, editing, commenting, or movement works, and toasts confirm actions that never ran.

Where it shines

  • DurabilityVerified restart persistence over the same SQLite file, WAL mode, atomic idempotency replay with 409 on conflict, and owner reset restoring the stable seed. No other model kept state across a process.
  • Every contract operation is registeredAll 203 operations loaded from the spec into the route table with zero collisions.
  • Hardening basics415 on wrong media types, 413 over 10 MiB, 405 with Allow, malformed JSON errors with line and column, client-mutation 403s, and client tokens blocked from reading internal-only content.
  • Cheap and fast$10.94 and 44 minutes for both tracks.

Where it's okay

  • Shared records develop projection driftA real shared recording foundation over SQLite, weakened by projection drift: disabling a tool updated the tool row while the project's embedded dock still said enabled.
  • Seed data is incomplete and nondeterministicThe main graph matches the specification, but subscriptions, chat volume, and deterministic timestamps do not. The kickoff has zero required subscriptions, the seed contains eight chat lines instead of sixteen, and wall-clock timestamps break the determinism requirement.
  • Polished shell with disciplined tokensA coherent token system and disciplined dark shell give GPT-5.5 higher visual-craft scores than Grok 4.5 and Sol.

Where it underperforms

  • Schemas and success statuses drift16 of 26 seeded responses failed schema validation, 14 operations returned undocumented success statuses, and a spec-valid schedule entry was rejected because the generic creator demands a title.
  • Missing parents still return successCreating an answer under nonexistent question 999999 returned 201, template construction under a nonexistent template returned 201, and MarkAsRead reports success while every notification stays unread.
  • Controls confirm actions without mutationsToasts announce "Comment posted" and "Chat line posted" without reading the textarea or touching state. No creation, editing, commenting, movement, or deletion works anywhere.
  • FE fragilityStored state is parsed with no try/catch, so malformed JSON prevents startup. The filter rerenders the whole app per keystroke and drops focus after one character. Jump's Enter key ignores the filtered results.

Failure modes

GPT-5.5 frequently reports success without completing the requested behavior. Examples include orphan-resource creation, unchanged notification state, and frontend confirmation messages that perform no mutation. Nonnumeric IDs and invalid UTF-8 produce uncaught exceptions and 500 responses. In-memory mode fails across threads because each thread receives a separate SQLite database. Sol returns explicit 501 responses for missing features. GPT-5.5 returns 200 and 201 responses for several incomplete operations.

Dimension scores
FRONTEND
6.5Ref 7.5Craft 8.0Model 7.5Surf 3.5Depth 4.0Inter 4.5State 5.5Resp 4.0A11y 5.5Arch 5.0Rely
BACKEND
7.2Arch 10.0Surf 7.3Depth 5.3HTTP 7.0Seed 7.0Valid 7.3Ops 6.5Code 4.5Hnsty

Best of N

To see how much a model's output changes from run to run, we ran Sonnet 5 and GPT-5.6 Sol five additional times. Frontend scores spread 0.74 points across the five runs for Sonnet and 0.71 for Sol, while backend scores spread 0.40 and 0.64. Stronger runs turned more of the requested product into working, persistent behavior and handled API contracts and validation more carefully, while weaker runs often looked similarly complete at a glance but hid up to 20 explicit no-op controls, stored state that can crash boot, and one backend that left 42 operations as explicit 501 responses. This five-run sample shows that a single reported score is one possible outcome rather than a stable description of the model.

Score variability across five runs

Five-run ranges, medians, scores, and thresholds

Five-run results

Model / trackPublished runMedianObserved rangeMedian costBest of 5Five-run cost
Sonnet 5 FE6.9826.5856.178–6.922$13.726.922$88.55
GPT-5.6 Sol FE5.7656.0265.780–6.489$6.476.489$34.05
Sonnet 5 BE7.2437.4607.346–7.743$24.047.743$114.76
GPT-5.6 Sol BE7.3106.9956.675–7.313$11.407.313$57.30

Sonnet 5 — implementation completeness drives the spread

Medians · FE 6.585 · BE 7.460 · $41.92 · 1:40:07

Sonnet's product model remains stable across attempts, scoring 8.0 to 9.0 in all five frontend runs. The spread appears when mutations and reloads stress that model, exposing duplicate IDs, orphaned project content, and cross-project relationships in weaker runs. Frontend variance tracks how many visible surfaces are wired to durable mutations and survive reload. The weakest artifact scores 0.4 higher on craft, 0.4 on product modeling, and 0.1 on surface coverage while falling sharply on interaction, persistence, responsiveness, and accessibility. Backend variance is narrower and moves with HTTP correctness, seed fidelity, and operability even though behavioral depth stays within 7.5–8.0 across all five backends. The published frontend score sits 0.060 above the five-run maximum while the published backend is 0.103 below the five-run minimum, overstating Sonnet's frontend advantage and understating its typical backend.

Where stronger runs gain

  • Working frontend workflowsThe strongest frontend connects more visible controls to real mutations and reload persistence. It leads the weakest run by 1.4 points in functional depth, 1.9 in interaction quality, 1.9 in state and persistence, 1.7 in responsive adaptation, and 1.6 in accessibility.
  • Contract and seed fidelityThe strongest backend improves HTTP fidelity from 6.8 to 8.2, seed fidelity from 7.0 to 8.5, operability from 6.6 to 7.2, and scope honesty from 7.6 to 8.2 over the weakest run. Behavioral depth changes little between the two extremes.

Where weaker runs fail

  • Visual breadth without state integrityThe weakest frontend scores slightly higher on craft, product modeling, and surface coverage, then resets its ID counter to 1000 on reload and creates duplicate record IDs, crashes on malformed stored state, leaves project content orphaned, and reports unverified clipboard success.
  • Loose request and startup handlingThe weakest backend accepts unsupported text and XML bodies with successful responses, shadows one canonical route, and logs a failed startup while exiting successfully.

Failure modes

Across the other Sonnet attempts, 200 ms debounced writes can lose the final action, partial current-version state can crash boot, and singleton Card Table, Chat, and Schedule data can bleed across projects. Four of five frontends interpolate stored cloud-link URLs into href unsanitized, permitting javascript: URLs or attribute injection, and one sanitizer promotes unsanitized descendants. Backend variants accept cross-project moves and leave children active after parent lifecycle changes, and one run failed OpenAPI validation on 52 of 58 sampled responses while advertising .json detail URLs that return 404. All five generated backends use process-local storage and include no model-authored test suite.

GPT-5.6 Sol — usability and hardening drive the spread

Medians · FE 6.026 · BE 6.995 · $20.73 · 1:05:20

Sol's variance tracks how far each run moves beyond a convincing shell and generic router into real product behavior. Frontend variance tracks whether its broad product surface becomes working interaction or remains an inert demo shell. Backend variance comes mainly from validation (5.5–8.0), HTTP handling (5.5–7.5), seed fidelity (6.0–8.5), and scope honesty (3.0–5.5). All five runs persist durably to SQLite and register all 203 operations, while behavioral depth never exceeds 6.5. The published run sits 0.015 below the five-run frontend minimum and within 0.003 of the backend maximum, making Sol look more polarized than its typical run.

Where stronger runs gain

  • A more usable responsive frontendThe strongest frontend gains 1.5 points in functional depth, 1.3 in interaction quality, 1.6 in responsive adaptation, and 0.6 in accessibility. More controls behave coherently across viewport sizes, though transient actions and state-integrity failures remain.
  • Stronger backend hardeningThe strongest backend improves HTTP fidelity from 5.5 to 6.8 and request hardening from 5.5 to 8.0, with smaller gains in behavioral depth, seed fidelity, and operability.

Where weaker runs fail

  • Visible controls end in a demo shellThe weakest frontend scores 0.5 higher on surface coverage while leaving creation, editing, commenting, filtering, and deletion inert or toast-only. Malformed persisted state crashes the app, and stored chat content flows into innerHTML.
  • Route coverage outruns domain behaviorThe weakest backend leaves 42 operations as explicit 501 responses, mishandles project access and subscriptions, permits interactions with unreadable recordings, exposes request-ID header injection, and turns oversized queries into server errors. Even the strongest run remains generic in important domain behavior and can record malformed state before returning an error.

Failure modes

Malformed persisted state crashes boot or a core route in every Sol frontend, while separate runs introduce injection through toast titles, stored Chat, and notes. Whole-view rerendering breaks focus, live Jump handlers, and route announcements. One mobile layout hides My Events and My Bookmarks, and another blanks all five My Bar buttons with a font-size: 0 rule. Backend variants create children under nonexistent parents, one persisting a todo beneath to-do list 999999999, patch or move the wrong resource kind, commit invalid comments before returning 500, and leave completion timestamps inconsistent. Response hydration invents required values, unsupported collections return empty 200 responses, and readiness reports all 203 routes without distinguishing real domain behavior from generic or missing semantics.

Commentary

Software teams rarely expect a model to produce finished production software from one prompt and a specification. They work iteratively, review the output, run tests, identify gaps, and ask the model to refine what it built. Basecamp Bench removes that correction loop for the initial build, revealing the decisions and failure modes each model introduces before an engineer intervenes.

Fable 5.1 and Astra now lead different tracks. Fable's frontend advantage is 0.576, supported by deeper product coverage and a substantial executable workflow suite. Astra's backend advantage is 0.340, supported by tighter contracts, deterministic seed data, atomic persistence, and candid unsupported-operation handling. Astra costs about a quarter as much as Fable 5.1 across both tracks.

Every model leaves different work for the engineer. Opus 5 produces a broad combined starting point, with unusually broad connected product behavior and a complete backend surface, yet still exposes private attachments, permits unsafe webhook updates, trusts malformed persisted state, and drifts from response schemas. Fable builds equally deep workflows with stronger frontend persistence and backend hardening, while still shipping unsafe stored content, schema errors, and exposed credentials. Sonnet builds many working workflows but misses critical authorization, reset, and state-integrity safeguards. Opus 4.8 builds a broad, visually strong frontend and a genuinely stateful backend, but exposes owner credentials and fails core membership and cross-project invariants. Grok moves quickly and covers substantial ground while cutting depth in validation, mobile behavior, and lifecycle handling. Sol clearly marks unsupported backend operations, but leaves 71 of them unfinished and produces a shallow frontend. GPT-5.5 builds a durable backend, yet its frontend leaves core controls inert and its API drifts from the contract.

The earlier entries illustrate the same value question. Opus 5 and Fable 5 are effectively tied on quality: Opus leads FE by 0.005, Fable leads BE by 0.002, and Opus costs about 91% as much while taking roughly twenty minutes longer across both evaluated tracks. Grok 4.5 reaches roughly 84–87% of either model's score for about 11–12% of their total cost and finishes in 37 minutes instead of more than two hours. Opus 4.8 costs more than three times as much as Grok while scoring only slightly higher on frontend and materially lower on backend, making its stronger visual and product-model work expensive relative to its trust-boundary defects. Teams must decide whether higher initial quality justifies the higher cost, or whether a cheaper model plus deliberate engineering iteration produces better overall value.

The results suggest that a skilled prompter and experienced engineer can use any of these agent combinations to reach a strong result through iteration. Model choice primarily changes the starting point, working style, and review burden. Preference for output style and the time available for review may matter more than the final attainable outcome.

Methodology

Prompts

Each model receives one prompt per track. The frontend prompt asks for a complete single-file SPA prototype of Basecamp 5, built from the product specification and reference screenshots, with every decision suitable for direct inclusion in the final production release. The backend prompt asks for a single-file production-ready API implementing the canonical SDK contract. Both tracks carry the same standing instruction from the spec. Prefer explicit stubs over fake success. When the spec and instinct disagree, the spec wins.

Resources in the seed repo

Every model starts from an identical repository containing everything needed to score 10 on every dimension. INIT.md (572 lines) defines the product model, the shell and its nine tools, the shared Recording domain rules, and a per-screen surface checklist. It also specifies the deterministic "Launch the new website" sample seed down to named people, message threads, card lanes, and chat lines. DESIGN.md (681 lines) supplies the production design tokens for light and dark color ramps, the 10px root scale, spacing, radii, shadows, and motion, and instructs the model to use these values rather than invent its own. reference/screens/ holds nine 3456×1780 dark-mode captures of the real app covering Home, Jump, the project dock, and all six core tools. reference/basecamp-sdk/ is the backend contract. It contains openapi.json with 131 path templates, 203 operations, and full request and response schemas, plus a 1,403-line SPEC.md and behavior-model.json. AGENTS.md orients the agent and sets precedence between these sources of truth.

Evaluation criteria

The frontend rubric scores submissions on 11 weighted dimensions: reference fidelity (14%), functional depth (12%), visual craft (10%), surface coverage (10%), state and persistence (10%), product-model fidelity (9%), interaction quality (8%), responsive adaptation (8%), accessibility (7%), code architecture (6%), and reliability, safety, and performance (6%).

The backend rubric scores submissions on 9 dimensions: architecture and domain modeling, endpoint surface coverage, behavioral depth and statefulness, HTTP and schema contract fidelity, seed data fidelity, validation and hardening, operability and packaging, code quality, and scope honesty.

The judge scores each dimension 0 to 10 from direct evidence, and the benchmark runner computes the weighted overall. The rubric requires the judge to distinguish absent, visually present, stubbed, working, and persistent functionality, and forbids crediting the same capability twice.

Evaluator

GPT-5.6 Sol, at high reasoning effort, judges every submission and produces one review each. The evaluator bases its scores on repository diffs, executed code, schema validation, and cited file evidence. It diffs the full seed-to-submission delta, enumerates every route against the OpenAPI document, and executes each submission's actual code, using in-process request handlers for backends and DOM and localStorage harnesses for frontends. Where applicable it sweeps all 203 operations, validates responses against their schemas, and probes malformed input, authorization boundaries, lifecycle cascades, and reload persistence. The evaluation sandbox denies socket binding and browser startup, so the judge exercises servers through their real handlers in process and withholds pixel-level claims rather than assuming them. Every score cites file and line evidence.

The September update adds Fable 5.1 (September 2), Grok 4.6 (August 12), and GPT-6 Astra (September 5) under contract 2026-07-11.2. Each runs at high reasoning effort in its configured harness. Astra's implementation threads use Sol and Terra helper agents. The new frontend evaluations use source inspection and controlled rendering or DOM probes. They do not supply pixel-level browser captures.

Cost

Evaluation is a separate spend from implementation. Judging the twenty submissions in this report with Sol 5.6 at high reasoning effort cost $59.86 in 3:35:35 of evaluator time, averaging $2.99 per review, against $334.91 of implementation spend.

Benchmarked modelFE review costFE review timeBE review costBE review timeCombined
Fable 5.1$2.8018:40$2.4016:51$5.20 · 35:31
GPT-6 Astra$3.5412:30$3.3312:55$6.87 · 25:25
Grok 4.6$2.948:21$4.7013:18$7.64 · 21:39
Opus 5$5.2912:46$3.2214:46$8.51 · 27:32
Fable 5$3.018:26$2.168:08$5.17 · 16:33
Sonnet 5$3.5811:17$2.458:05$6.03 · 19:22
Opus 4.8$2.608:07$2.158:04$4.75 · 16:11
Grok 4.5$2.858:15$3.2312:31$6.08 · 20:46
GPT-5.6 Sol$3.419:15$1.378:32$4.77 · 17:47
GPT-5.5$2.366:56$2.487:53$4.84 · 14:49
All$32.371:44:33$27.491:51:02$59.86 · 3:35:35

Track costs and times include implementation and evaluation. Combined time sums both tracks. Astra pricing was added after its run. Its implementation cost is calculated from captured usage at $10 per million input tokens, $1 per million cached input tokens, and $50 per million output tokens. The original immutable run retains its missing-price flag. The comparison data records the calculation and source runs.

Bias

The exploratory baseline records one attempt per model, so sampling variance can materially affect close scores, costs, and completion times. Testing one well-known application may reward prior familiarity with Basecamp, while the prescribed Recording model and single-file constraint favor specification adherence, long-context synthesis, and monolithic implementation over repository-scale engineering. Harness-specific tools and stopping behavior also contribute to each result. Evaluation-adjacent terms such as “scope honesty” and “stubbed vs working” may cue rewarded behavior. Because the evaluator selects its own test strategy for each implementation, test coverage can vary across submissions, although the completed reviews show no evidence that this affected the rankings. Evaluator trials with Fable, Grok, and Sol produced the same rankings and directionally similar findings. Sol was selected for greater attention to detail and showed no self-preference when judging its own work, which ranks sixth on backend and ninth on frontend. Readers should treat small score differences as provisional, compare FE and BE separately, and interpret quality, cost, and time as outcomes for these exact model-harness configurations and inputs.

Code

The complete benchmark is open source at 0xSMW/basecamp-bench under Apache-2.0.

basecamp_bench/   runner, adapters, aggregation, reporting
benchmarks/       prompts, rubrics, versioned contracts
Repo/             seed pack agents receive
baseline/         verified runs behind this report

basecamp-bench run executes a fresh comparison against any configured harness, report regenerates the self-contained HTML report from any set of run directories, and reevaluate re-judges immutable submissions under current contracts. The runner takes the median evaluator score per dimension, computes the weighted overall, and rejects unknown dimensions, out-of-range scores, hash mismatches, and any evidence mutation. It currently supports the Codex, Claude Code, Grok, Pi, and Google Antigravity harnesses, and adding a model to an existing harness is configuration only. Submit a verified run for a new harness or model and a future revision of this report will include it.

smw.ai · basecamp-bench report updated September 5, 2026