Changelog
Every release the studio has shipped, newest first. Anything marked in grease pencil needs a decision from you before you upgrade.
2026
Seventy-seven commits. The benchmark measures something harder now, and a pool no longer has to be reset by hand.
The task changed
get_legal_movesno longer says which move is mate. Thecheckandcheckmateflags were a one-ply search with terminal evaluation — run by us, handed to every seat, on every move of every turn. No model playing Chessmark had ever had to find mate in one. The same facts were then stripped out of the SAN string, where they had survived as#.- A third version of the prompt. It states the silence forfeit it has always
enforced, describes the turn loop it actually has rather than one that ended
at
make_move, and names no tool the model cannot see. Three rules that decided games were not in it. - A pool balances its pairings. The matchmaker optimised for information and had no fairness term at all — 44% pair coverage, one entrant on 25 pairings and another on 1. Simulated over 19 entrants and 800 pairings, a greedy incremental round robin takes coverage to 100%.
Harness bounds stopped becoming findings about models
- A turn ends when the model stops, not when it moves — and a turn could previously end between a tool call and its result, leaving a transcript every provider refuses for the rest of the game. That corrupted 242 rows across 14 seats with the test suite green throughout.
- The window is sized for the request going out, not the previous one.
- A halt does not spend a game’s patience. The daily free allowance runs out most days and the halt holds to UTC midnight — about 8.3 hours, a third of the abandonment window, charged to games we had chosen not to play.
Upgrading
Four migrations, all safe to apply with the old code still running. There is no backfill. A running pool opens a new era on its next tick and starts a fresh table; games played under earlier prompt and tool versions keep their results and drop out of the rated set, which is what an era is for.
Phase 0 — toolchain, design tokens, content pipeline, and a verification loop.
Added
- Next.js 16 on a fully static export, with both themes resolving before paint.
- The magnitude scale, doubling as the project status system.
- A build-time content layer with schema-validated frontmatter.
- A screenshot harness, so changes get looked at rather than assumed.
The Now card explains itself and splits by time as well as by account, and a loan stops being filed as a card.
Added
- Now explains itself. The header’s running position reconciles exactly with the Accounts total, and the card now shows the working rather than asking you to trust the number.
- The breakdown splits by time as well as by account.
Fixed
- A loan is not a credit card. It was being drawn as one, with a credit limit it does not have.
Tags — the axis categories cannot be. Many per record, crossing categories, and archivable when the project they name is over.
Added
- Tags. A category answers “what kind of spending was this” and can only answer once. A tag answers “what was this for”, as many times as it needs to, across categories — so “where did the kitchen money go” is still a ring, and the tag can be archived when the kitchen is finished.
Upcoming payments lifted above the ledger, where a thing you have not paid yet belongs.
Changed
- Upcoming occurrences sit above the records list rather than below it. A payment you have not made is a decision waiting, not history.
- Nine screenshots in the README, all generated by a flow that asserts the totals it is about to photograph — so a wrong screen fails the build rather than being quietly captured.
The first tagged release, and three fixes found by reading the live pool rather than by testing it.
0.xmeans what it says: Chessmark is in beta, and anything may change.Fixed
- The pool no longer re-pairs a fixture it can never play. One pairing was scheduled seven times over five days without a move: an abandoned pairing carries no score, deliberately, and the matchmaker read that absence as “these two have never met.” Attempted pairings now count as meetings.
- An endpoint’s output ceiling is no longer a finding about a model. We asked for 64,000 output tokens against an endpoint that stops at 32,768, so every truncation stopped short of our own request — the exact signature the harness read as the model’s failure. It cost one model a game it had already won.
- A forfeit flag follows the game’s ending, not the turn’s status. Two games were budget-stopped, reopened, and played on to a real checkmate and a real threefold draw while still carrying a forfeit on the leaderboard.
Added
./chessmark repair-forfeits, which reconciles forfeit flags against the game record. It reports by default and changes no result.
Reverse a transfer, let a refund say what it refunds, and hide every amount behind one tap in the header.
Added
- One tap hides every amount. The eye in the header masks each figure on every screen, for reading your ledger with someone beside you. It persists, so the eye stays in the header as the way back. Shoulder privacy only — it does not touch screenshots or the recents thumbnail.
- Reversing a transfer, and a refund that names the purchase it undid.
Fixed
- Search finds a transfer by where it landed, rather than by a category a transfer cannot have.
- A reading fills the note in; it no longer overwrites what you had typed.
- Pickers open on the current selection instead of at the top.
- The update-balance sheet and the budget editor both sat under the keyboard.
Eight fixes to the reader after a week of real use — a cash withdrawal is a transfer, not an expense — and a relicence to GPL-3.0.
Fixed
- A withdrawal is a transfer. Cash out of a machine has not been spent; it is spent later, one purchase at a time. Filing it as an expense counted it twice and left the cash account permanently empty. Both halves looked individually plausible, which is why it survived a glance.
- Bank messages get a category. The prompt never asked for one, so every bank record arrived uncategorised — which read as the model declining to guess, and was the app never putting the question.
- The currency the message named is the currency entered. The screen took
its currency from the account and nothing else, so a correctly-read
USD 50.00was saved as fifty pounds. Not displayed wrong — saved wrong. - The message survives a failed reading. The app had the bank’s own words, showed them in the grey row, and threw them away at the one moment they became permanent.
Changed
- Relicensed under GPL-3.0, so anything distributed from this comes back rather than disappearing into a closed fork. The name and the icon stay reserved.
Bank notifications read into records for approval, editable prompts, and a Settings screen that holds your rules rather than the app’s wiring.
Added
- Bank alerts captured and offered as records to approve, never written
behind your back. Android hands over the notification your messaging app
already showed — the same text you read off a lock screen. No
READ_SMS, no conversation history, and the sender list starts empty. - The finance half of each prompt is yours to edit, so “the card ending 0042 is Kenana” resolves against your real accounts.
Changed
- Captured messages join the records list instead of living on a page of their own.
- Two permissions the app never used are no longer declared.
Fixed
- A busy model no longer burns the message it failed to read.
- The app says when messages are waiting on a key you have not supplied.
- Bank alerts captured and offered as records to approve, never written
behind your back. Android hands over the notification your messaging app
already showed — the same text you read off a lock screen. No
Daily totals in the records list, and a settings row deleted rather than wired to nothing.
Added
- A total on each day heading, so the month reads as a sequence of days that each net themselves.
Fixed
- The day heading was clipped by the total sitting beside it.
First light. The whole ledger in one version — keypad entry, budgets, analysis, credit cards, refunds, backups, receipts and recurring payments.
The version stayed at 1.0.0 for seventy-five builds while the app was built, so this is less a release than the shape of the thing when it was first worth installing.
Added
- Recording — a calculator keypad, two-tier categories, transfers written as one atomic pair, refunds that net against the purchase they reverse, and multi-currency with the rate stored per record.
- Making sense of it — records grouped by day and netted, a category ring with a ranked breakdown, budgets suggested from what you actually spend, free-text search with a total, and balances derived from the ledger rather than stored.
- Credit cards as money owed rather than an emptied wallet, with per-card fee profiles and balance corrections that move your position without counting as spending.
- Keeping it — a backup that is a plain zip you can open anywhere, an undo for the last restore, optional Drive backup sealed with a passphrase, and a CSV export that carries both legs of a transfer.
- Receipts read by Gemini, with your own key, off until you supply one.
- Recurring payments and portfolio rebalancing, the latter deliberately not wired into the ledger — it never tells you to sell.