Fifty-nine commits landed on the working branch since the last entry, one sprint closed and another opened. The app and the site are now joined end to end: a person signs in at app.gymai.coach in one step, carried across by signed hand-offs that can each be spent once. The key that protects what you record is held by your own devices and by your passkey, and two devices now agree about deletions as well as writes.
Sign in once, at the app’s own address
Three hand-offs carry a person between the hosts, and all three are built: an enrolment ticket, a link receipt and a sign-in assertion. Each is signed, addressed to the host it is meant for, and short-lived — fifteen minutes for the ticket, sixty seconds for the other two. Each is recorded as spent the moment it is used, so the same token never opens a second door.
What that buys is one step instead of two. A confirmed person is handed a ticket and arrives in the app already enrolled, under the username they chose, and the app signs a receipt back so the site knows which account was made. Going the other way, a signed assertion opens a session on the site from the app’s origin and nowhere else, and that session reaches only a person’s own routes.
One decision went in alongside the code: nobody under 16 signs up for the app on their own, refused at the door before anything about them is stored. Red first throughout, at 29 of 31 on enrolment and 19 of 19 on the person identity.
A content key your own devices hold
What you record in the app is encrypted with a key the server never sees in the clear, and this period built that key’s whole life. A device keeps its copy as a non-extractable key in the browser’s own store, so the page can use it and cannot read it out. A passkey opens the key as well, which makes a new laptop a passkey ceremony rather than a lost history. Recovery codes run through the same keyring.
The routes holding the wrapped copies answer to a session and carry no identifier, and a recovery code’s copy is never listed: it is answered once, to the check that asks for it. The review’s fixes went in the same way: a refused verification discards the released secret, secrets are zeroed after use, and deleting a credential removes the copy of the key that hung off it. Passkey registration and sign-in now complete on Chromium browsers too, green at 324 unit tests and 69 of 69 in the browser.
Two devices agree, deletions included
The server now keeps the deletion log, so a session you remove on your phone is gone on your laptop, and a conflict between two devices arrives with the tombstones it needs to merge. Identities in the log maps are blinded per device, so two devices that measured the same thing merge without either learning the other’s names for it.
On top of that sits the device’s sync engine: a debounced push, one re-push after a conflict, the pull rules, and a flag that survives a reload so a device knows it is unsynchronised. It is wired in now: it pulls when the key arrives, flushes when the tab is hidden, and retries when the connection returns. Saving a screen’s state pushes it by default, which is what the app’s twenty screen call sites expect. Unit suite green at 10,892.
The owner’s four acts on a gym account, all built
All four acts the moderation panel specifies exist in the code: suspend and reactivate an account, delete one down the holder’s own path, move a record to another gym account, and read one in full, with the last sign-in now recorded. The security review went in with them: those pages are never cached, a closing account and a non-gym target are both refused, and every act is written down.
One session layer, one limiter, one notice path
A sprint went on having one of each thing instead of three. One session cookie layer serves the app, the console and the keeper platform, minting a token and keeping only its hash. One passkey loader serves both site doors, one limiter and one mail budget serve both processes, and one notice path carries every mail and push. One actor vocabulary names all 30 actors once, and every owner-only check derives from it.
53 checks, 10,521 unit tests and 1,534 browser tests
The gate’s verdict line reads 53 checks, all green. Its last full run read 10,521 unit tests and 1,534 browser tests, up from 10,425 and 1,530. The standing counts, each written by the check that derives it: 55 routes, 27 rate-limited; 1,965 rule citations resolving by number, up from 1,943; documented coverage across 262 modules; 204 equipment rows; 81 artboards; 2,684 tracked text files read for a real person’s address, with nothing in them but reserved domains and twelve listed exceptions; 533 generated guide files; Node pinned at 22.23.2.
What comes next
More slices from the same queue, each starting from a failing test, and the work towards opening the free gym listing carries on behind them.
If you would rather be told when GymAI opens than keep checking, the waiting list is on gymai.coach.
No comments yet
Nobody has written anything here. You can be the first.