What actually shipped.
Dated, terse, and carrying the change it refers to. Nothing lands here until it is live — what is planned lives on the roadmap, and the two are deliberately different pages.
- runtime
One agent per book, inside the machine that book already had
Each book runs its own agent process inside its own machine — adopted rather than written, and small enough to add no machine.
#523
- product
A metered endpoint the agent buys its tokens through
Credits stopped being a number on a page: the agent now reaches a model through an endpoint of ours that measures and can refuse, rather than beside one that can only observe.
#522
- security
The Telegram bot, and the binding that makes a chat mean a book
One shared bot serves every customer, so a Telegram account id — which is not a credential — is bound to a book by a code produced by a signed-in human in a browser.
#524
- ops
A backup that re-creates the bundle instead of blaming the transfer
A backup run that could not find the bundle it had written was reporting a transfer failure; it now re-creates the bundle and says which of the two actually happened.
#510
- site
The marketing site counts visits, behind consent
countbean.com now counts visits through GA4 behind a consent banner, with the measurement id read from one file at build time so a renamed property cannot leave the site reporting into nowhere.
#512
- product
A persisted credit ledger — the gate the metered AI path spends against
Credits became a real ledger of grants and debits rather than a number stored beside the balance, which is the gate the metered agent path will spend against.
#493
- product
Solo is $15, and /billing finally has the price mapping
Solo moved from $9 to $15 — and the repricing had to build the plan-to-price mapping that /billing never had.
#496
- ops
The alarm for a backup that did not run at all
Every signal the nightly backup produced was a step inside its own job, so the one state none of them could describe was the job never starting — which is what happened on 2026-08-17.
#442
- product
Continue with Google on /signup can actually register
The button reached Google correctly and the callback bounced every new visitor back to /login, so the door carrying Google's attestation of mailbox control was the one refusing to create an account while the door carrying no proof at all created freely.
#433
- security
A concurrent sign-up is refused, not 500'd
Two sign-ups racing on the same address both reached the insert; the loser got a 500 that looked like an outage during a signup the database had just accepted.
#457
- runtime
The usage cap resets on a calendar month, not on a deploy
The hard-cap counter lived in memory for the life of the process, so a customer who capped out at 03:00 stayed locked out until we happened to deploy.
#338
- security
A password can be replaced, not only set once
Every credential write in the product was guarded on the password hash being null, so a customer who forgot theirs was locked out permanently unless the address they bought with happened to be a Google account.
#342
- runtime
A paused book is refused, not woken up
The proxied api-key path asked the platform whether the machine was running and started it if it was not, and never read the book's status — so two calls put a cancelled customer back to writing their ledger.
#367
- site
The marketing copy is bound to the capability flags now
Two sentences on countbean.com denied a feature customers could already use; the gate meant to prevent exactly that was never weak, it was just never pointed at the marketing tree.
#304
- site
The site became several pages, and the roadmap became public
The marketing site was one document wrapped in a head block hardcoded in the build script — a shape that works for exactly one page — and the privacy page proved it by carrying its own private copy of the entire stylesheet.
#265
- plugin
Assessment computes the facts and the model only writes them up
A language model handed a ledger produces a confident number, so the assessment tool decides what is true and returns an explicit not-enough-data with a reason wherever a metric cannot be computed honestly.
#257
- product
The plugin asks, the browser approves, and nobody handles an API key
Connecting the plugin meant visiting the book page, creating an API key and pasting it back; the device authorization grant inverts that, so the plugin prints a short code and collects the credential itself.
#256
- product
Something now checks that a buy button charges what the page says
The two Stripe price ids were swapped on the deployment and nothing in the codebase could have caught it, because every consumer treated them as identities to compare rather than as prices to check.
#255
- ops
Free provisioning is bounded by a ceiling on the whole fleet
Sign-up was open and book creation was unlimited, so any caller could create unbounded real Fly machines and 1 GB volumes, billed to us.
#242
- runtime
A book accepts ledger entries, and nothing else
The router sorted directives into files by kind and never asked whether a kind was allowed at all, so a plugin, option, include or custom line composed by a model out of a customer's prose travelled the same path as a transaction.
#105
- plugin
The plugin talks to the hosted book, not a directory on the laptop
The plugin opened a directory on the customer's own machine and edited it, so a customer got back a commit hash and a plausible net worth from a ledger we do not host, do not back up and do not serve.
#37
- security
Every book machine was published on one shared hostname
Every provisioned book published 80/443 behind a single app hostname that Fly load-balances across the whole app, so a request for one book could be answered by another book's machine.
#32
Nothing matches that.