Worked productSoftware · an AI chat workspace with its own meter

Nothing here stores what a conversation costs.

A chat workspace for an eight-person team, with the context window, the cycle bill and the seat count all derived from the messages and the fixture arrays. Looking at it should settle whether an assistant product can show its own arithmetic without a single stored total.

Preview interactive design
OperatorA product leadowns the workspace and the bill
The clockOne billing cycle1 Aug to today, derived
Declared statusFour vocabulariesfourteen values, five fields
The dataTen threads, nine filestwo of them unreadable
The composer is the whole screen. · 0 of 200k in context before a word is typed, and the three most-used prompts sitting under itthe screen the day starts on
The screensIn the order the work happens

Five screens, one set of turns.

Twenty-one registered routes: six sidebar destinations, six off it, four settings and five auth. There is deliberately no list screen for turns — a turn is only ever reached through the thread that holds it.

02The status set →
Screen 01

The conversation, with what it is reading beside it

The thread owes an answer for how full the window is and what the reply was based on. It shows the cited files under each turn, and refuses to imply a file is in context when the index could not read it.

  • 23k of 200k, counting six messages and two indexed files
  • The files cited are named under the turn that cited them
  • Three billed turns and $0.22, stated on the thread itself
/chats/:idrecord · reconciliation
Screen 02

Files, and the two the index could not read

The index is the honest part of an assistant product. Every row says whether the model can read the file, and a row that cannot carries the reason and the one move that helps. Nothing falls back to a zero token count.

  • “2 of 9 files could not be read”, in the screen’s own lede
  • Six readable files carrying 77k tokens between them
  • The failed row offers Reindex; the archive is told to be unpacked instead
/filestable · act-ability
Screen 03

What the week’s turns actually cost

The day chart, the model table and the person table are the same fourteen turns grouped three ways, so no two of them can disagree. It declines to chart a day with no turn on it as a zero.

  • 218k tokens, $0.35, 14 billed turns across 9 threads
  • 218k of the 1.2M included in the plan — 18%
  • 8 of the 25 days had a turn on them, and the bars are those same 14
/usagefigures · derived
Screen 04

Seats, and the difference between paying and using

A seat is held by a person or by an invite still standing, so the figure is people plus unexpired invites and never a stored count. A dormant member is recessed with the reason rather than disabled or hidden.

  • 10 of 10 seats used — eight people and two invites still standing
  • One expired invite, holding no seat
  • “Not in 71 days, still holding a seat” on the dormant row
/settings/workspacetable · capacity
Screen 05

The bill, including the one that did not go through

The current cycle has never been invoiced, so it is derived from the same turns the usage screen charts. The failed invoice is not a badge on its own — it carries the reason it failed and the thing that fixes it.

  • $240.00 this cycle — ten seats at $24.00, nothing over the allowance yet
  • One invoice unpaid: $251.80, for the month before
  • A $400.00 spend cap, 60% used, seats included
/settings/billingrecord · money
StatusA closed set with defined transitions

Three of the four things you would look for are missing.

Four vocabularies over five fields, and none of them holds what an assistant product is expected to store: whether a thread is near its context limit, whether a prompt has gone stale, whether an invite still holds a seat, whether a card has expired. All four are computed at render.

03The awkward cases →
indexingreadyfailedunsupported
Failed is the one where the operator is being waited on, so it is the one that offers Reindex. Unsupported is terminal because nothing in the product can read an archive — the way out is a person converting the file. Fourteen values over four vocabularies and five fields, six of them terminal, and visibility is a single vocabulary shared by threads and projects because it means the same thing on each. Void on an invoice is deliberately neutral: it was withdrawn before it was ever charged, which is why it is excluded from every total that claims to be money.
The dataThree records that break a screen

The fixtures were written to be difficult.

Each of these is a real record in the fixture, and each one is the reason a figure on some other screen is derived rather than stored.

04The audit →
Case 01A turn that produced nothing
NaivelyThe turn renders as an empty bubble or an em dash, and the usage total counts it anyway — a row in the table with no tokens and a cost of $0.00.
HereOne thread holds a turn that failed after 41 seconds. It is not billed and not counted: fourteen billed turns, not fifteen. The turn says what happened and offers Retry, and nothing else on the screen moves.
Case 02A 24.8 MB archive attached to a thread
NaivelyThe file joins the attachment list and quietly contributes to a context figure claiming the model has read twelve interviews it has never seen.
HereIt reads Unsupported, contributes nothing to the 23k window figure, and its Reindex is disabled: “Archives are not read. Unpack it and upload the transcripts.” The project card says two the index could not read.
Case 03An invoice charged to a card that expired
NaivelyThe invoice shows Payment failed with a Retry that appears to work, or the card section shows an expiry date and nothing else.
Here$251.80, failed against a card that expired on 31 July. The card block says nothing can be charged until it is replaced, the retry included — and replacing the card retries that invoice rather than leaving it stranded.
The auditWhat the pass found

The arithmetic held; the chrome did not.

Every derived figure was walked against the array under it and none disagreed — fourteen billed turns reconcile across the usage table, the person table and the cycle charge, and ten of ten seats reconciles with eight people and two standing invites. What the pass changed was interface: the composer carried a duplicated focus treatment, and the brand mark was sized by an inline style on one screen and by a rule everywhere else.

05Back to the top →
Two the index could not read · the same two the files screen names, counted again on a project card three screens from itcheckable

Reckon

The meter is portable.
The domain is not.

Threads, files and seats are this template’s nouns, but the rule underneath travels: if a screen shows a total, the array that makes it is on the same page.

Built for Claude Design · plain markdown · nothing to run