One table per game, and drop the cast the union forced
Follow-up polish on the Games entitlement gate. No behaviour change; the tests that pin it are unchanged and still pass. **************** was typed `GamesOrgan...
Stop pinning setThemeSlug's argument list in a source assertion
`tabOrgResolution` was red on main. It asserts on the SOURCE of app/validate/page.tsx and required the literal text `setThemeSlug(orgRef)`, so `f9bd7621` — whic...
Early Bird and Twenty Doors read the laptop's clock, not the member's
`check-server-timestamps` was red on main: `rememberToday` bucketed the day with `new **************** which is the BROWSER's zone. The guard exists because tha...
The Show button, and the clock hook mounted
The client half of showing a hand nobody made you show, plus the mount point for the turn-clock audio that landed dead in the previous commit. SHOWING OUTRANKS...
Your own clock, out loud
A thirty-second clock a player is not watching is a hand lost to a timeout while reading an email, and the felt's draining bar only helps somebody already looki...
The chips were on the table, not on the felt
A member reported that the player opposite them had chips half off the table. Measured in a browser: NINE of the ten piles were off the cloth. The reader's own ...
Every logo on the Branding card can be downloaded
The download control shipped on one of the six artwork slots — the compact company logo — because the row was written inline at that one call site. The other fi...
The computer's reply was silent against the quickest level
The four move cues carried an 80ms throttle. Each is raised once per published frame the board could prove it understood, and a frame is a move — so there was n...
Six the adversarial review upheld
Ten reviewers, three skeptics each. Twelve findings survived; most of the rest were refuted because they had already been fixed. Of the twelve, six were still r...
A table that has ended sends you to the lobby, with the news
An invitation card outlives the table it points at. Somebody follows one ten minutes later, the game is over, and the window answered with a red error bar over ...
The captures get the room the notation was taking
Two things the member asked for after seeing it. **The move list is gone.** Nobody was reading a column of notation; what two colleagues playing each other wan...
What an adversarial read of the whole thing found
Ten reviewers over the change, three skeptics per finding. These are the ones that survived, and most of them were in the wiring rather than in the parts that h...
Sweep the two locals the pot block left behind
`potTotal` and the component-level `t` were the only readers of the pot block I moved into the chip layer, and both survived it — read by nothing, flagged by no...
Looking at an organization is not being in it
A workspace signed in to KamoCRM repainted itself as BluEleven - logo, colours, favicon, tab title, and the feature set driving the navigation - while every rec...
Three things a browser said and jsdom could not
The panels were built and tested entirely in jsdom, which can say a label is present and cannot say how wide it ended up. Rendering them at the widths ChessTool...
The chips in the middle are worth what the number says
A settled pot draws the CONTESTED total now, not everything that went in. `hand.pot` keeps every chip that entered the hand; `totalPot` reports what was played...
The organisation's colour, and chips in the compact pot
Finishes two things the chip subsystem had built and not wired. THE BRAND, where a card never sits. The betting line, the wash under the pot and the lift under...
The board is a table now
The first move of every game was wrong. Pieces were keyed by their position in a FEN scan, and scan order is not identity: after 1.e4 the element that had been ...
The Games icon appeared for organizations that have no Games app
Reported on harmonyhomeloans, whose owner saw the icon in the top bar for an app their organization does not have, cannot enable in Apps & Features, and whose c...
The chips are objects on a table
A member asked for the poker chips to stop being decoration. They are a subsystem now: real denominations, real stacking, racks, a betting line, pots that add u...
The reveal turned your own cards face down, and four more from review
An adversarial review of the choreography commit, verified against the code. Six defects, two of which only a browser could have shown. YOUR OWN CARDS. The sho...
The compact rail clipped a payout flag off the top of the window
The rail reserves a fixed strip above the pucks so a label does not make the strip taller and move the board — but it reserved room for ONE row and the showdown...
The table says what just happened
The felt re-rendered a STATE. It never presented an EVENT. Of twenty-six things that happen in a hand of poker, exactly two had any presentation at all — a card...
The table list had nothing between it and the lobby header
The lobby's scroll container carried `px` and `pb` and no `pt` at all, so the first table's top border sat exactly on the container's edge, flush against the he...
Move the balance out of the top bar and into the Games menu
The bar is fixed chrome and already crowded — greeting, branches, availability, the compliance clock, the bell, chat, language, account — and a balance is not s...
The wedge is yellow, and it stops depending on the tenant's brand
`/icon/cheddar.svg` was five paths of pure #000000 — a black cheese wedge, which on the nav bar's dark ground was very nearly nothing at all. It is a real chedd...
Four defects only a real browser could show
Rendered the felt, the compact layout, the lobby and the action bar in headless Chrome against a fabricated table and MEASURED them. Four things were wrong, and...
A poker table in a tool window, and Cheddar in the nav bar
Two genuinely different layouts, a lobby, an invite path that reaches anyone in the organization, and the wallet readout that appears whenever Games does. ## T...
The chat entry opens the pair's board, and you can ask an opponent back
Two colleagues who have played once have a board together for good, so the chat entry stops offering to introduce them. It reads "Open your game" and goes strai...
A capture shelf where the move list was, and a hexhead that says it is your turn
THE SHELF. A move list is a record; between two colleagues playing for fun the pieces you have taken are the thing worth looking at, so they get that space and ...
The board you play on now lives in the same room as the pane that started it
You chose a game in a dark room of board lacquer and brass, pressed start, and landed on a white MUI form with a board floating on it — `var(--surface)`, `divid...
The two mode plates were clipped by their own scroller, at every size
The selected plate lifts 2px and carries a 1px ring, and it is the first child of an `overflow-y: auto` column — so its top border sat 3px above the clip edge a...
Starting a game from a chat asks once, then plays — it never asks who
Clicking chess in a conversation opened the new-game pane and asked whether you wanted to play the computer or a person, then made you pick the person. The pers...
The opening pane, rebuilt around a game instead of an icon
The pane you get when chess has no opponent yet was the SaaS-card kit: an icon in a rounded square, two tab-cards, two segmented rows, a button. It looked like ...
The proxy could still be walked out of, because a dot is not encoded
The catch-all re-encodes each segment, and the comment claimed that meant it could only ever address the chess API. `encodeURIComponent('..')` is `'..'` — dots ...
The error test did not typecheck, and next build runs tsc
`await promise.catch((e: Error) => e)` does not give you an Error. The catch handler's return type unions with the promise's resolve type, so the result is `Che...
The BFF route that was never written, and an error that was a megabyte of HTML
Pressing Start game returned 1,529,239 bytes of markup. `/api/media/*` is not a proxied prefix — every path under it is a hand-written Next route and there is n...
AppType hid two live apps, and the guard could not see the place they were hidden
The Java app enum is mirrored into TypeScript twice, and only one of the two was guarded. AppType.ts — the mirror Organization's app getters actually read — had...
Drop aiThinking from the client mirror too
It was always false on the wire and nothing rendered it. Removed alongside the server field so the two shapes stay identical — a mirror that keeps a field the s...
Stop the history fetch from deleting the text that just arrived
SmsThread loads its page and REPLACED the list with it. A message landing between the query executing and its response arriving was appended by the live subscri...
A black piece on the Kamo board was the colour of the square under it
Only a browser found this. The Kamo scheme derived its piece colours from `--color-primary` as well as its squares, and both mixed the same token into similar d...
@kamo/chat-core 0.1.18, for the game-invite fields
The lockfile is edited by hand — four lines: the root range, and the version, resolved URL and integrity of the one package. `npm install --package-lock-only` r...
Carry an arriving text across the boundary the dock sits above
An inbound SMS never reached an open SMS window, and the reason was not the transport everyone went looking at. SmsMessageProvider was mounted in Authenticated...
Dial the detail dialog's tel: through the shared normaliser
The dialog built `tel:${action.tel}` by hand because telHref() was not on main when it landed — it was in a concurrent branch, and importing it then would have ...
One formatter, and one dialable link, for every number on screen
Follow-on to the lead-view country-code fix, closing the places that still answered the same question their own way. `NumbersTab` kept a private US-only format...
Light the bell, and make a click mean something
Three defects behind one report: the browser tab alerted for an unread notification while the bell stayed dark, and clicking rows on /notifications went to the ...
Filter the bug and improvement reports by who filed them
Reuses /leads' Agent filter — the same field, the same picker, the same gesture — pointed at a different directory: everybody who has filed at least one report,...
Two more deadlines a background tab cannot meet
Swept the app for the failure the notification deck's repeat turned out to be: work whose correctness depends on a timer firing while nobody is looking. Chrome ...
The browser half of the fifty easter eggs
THE CLAIM ROUTE DID NOT EXIST. The Java endpoint has accepted CLIENT claims since the catalogue's first ones shipped, but nothing in Next forwarded to it and no...
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
