Colleagues in the invite list, and an invitation from a chat that arrives
Two reported defects, both in who a table can reach. **The invite dialog offered accounts.** `invitableFor` read `members.findByOrganizationId`, and an organiz...
Categories are a table, and each one opens as its own page
/settings/features/docs carried eight tabs: General, then seven that each mounted the same three managers against a different ordinal. Seven copies of one scree...
Cover the topInset the maximized window already honours
ToolWindowShell has taken a topInset since the tab strip landed — it starts the window below the strip and stops it short by the same amount, or the strip is dr...
Publish the packages from CI, with a token that can actually publish
The secret exists now — a Forgejo token scoped to `write:package`, added to this repository — so `publish_packages` does the publishing instead of a person doin...
Serve the document categories from the enum that defines them
The docs settings page named its own categories and sent the ordinal it believed each one had. Those ordinals were written when ImageAssocType was six constants...
The certificate must not claim a disclosure nobody was shown
Verified against a real completed envelope on the cluster, and the closing paragraph read "Each signer was shown, and accepted, the consumer disclosure required...
Why AssuranceLevel only ever reports SES
ESigService reports SES and only SES now. eIDAS Article 26 lets a signature call itself ADVANCED only if the signature creation data is something the signatory ...
Stop asserting an eIDAS assurance tier this product does not implement
`buildSession` reported `stepUpRequired ? "AES" : "SES"`, so requiring a one-time passcode made every signing session assert an ADVANCED electronic signature — ...
Stop forking the signing surface, and offer the whole signed record
kamo-internal carried a hand-copied fork of the external signer app — fifteen files under app/lib/esign, app/stores/esign and app/components/esign/signing, each...
A compact trigger for the signed-copy menu
The sender's envelope list and any table of assigned packages have a row, not a hero slot, and the labelled pill does not fit one. `iconOnly` gives the SAME men...
The § 7001(c) disclosure ships with the code, in twenty-two languages
`@kamo/esign-core` now carries the consumer disclosure itself — six clauses, every language the product signs in, and `consentDisclosure(locale, brand)` to fill...
Publish the packages from a job of their own, and never nest a second pdf.js
The publish steps sat inside `build`, so run 12014 failed and took the image with it — and `pnpm install --frozen-lockfile` was clean locally, which is the tell...
A real Certificate of Completion, and the three copies of a signed record
What the flatten pipeline appended was one page per signature carrying seven lines: name, email, member id, timestamp, capture method, IP, user agent. No routin...
Record WHICH consent disclosure a signer accepted, and in which language
`consentedAt` records that somebody ticked a box. 15 U.S.C. § 7001(c) is a list of specific things a consumer must be told BEFORE consenting — the right to pape...
One signing surface for both apps, and the white label finally paints
The signing UI existed twice — here, and hand-copied into kamo-internal's legal execution wizard — and the two had drifted in both directions. `@kamo/esign-core...
The envelope dashboard could not tell "not emailed" from "not opened"
The warning naming an undelivered invitation lives in the send response, so it is gone the moment the dialog closes. After that the dashboard is all there is — ...
Prove submit actually writes the signature date, and ignores the wire
The unit tests around this cover the pieces — the format, the type predicate, the required-field exclusion — and none of them can see the wiring. A signature_da...
Render the Signature Date field, and make readOnly mean something
Three changes, of which only the first is new work. **`signature_date`** is a field ESigService fills at the instant the signer signs — never the browser, whos...
A Signature Date field, and a send that admits when nothing was emailed
**"Sent" was not the same thing as "delivered", and the dialog never said so.** ESigService discarded the result of every invitation email, so a send whose mail...
A rename answered with no Url skips Docs's rename callback
Docs shares one client-side callback between RenameFile and Save As, and **************** skips its whole body — the File_Rename event the embedding page listen...
Losing the race to store identical content is not a failed save
The look-up before the ImgDat insert is not a lock, and kamowsdocs runs two replicas behind one gateway — two documents whose bytes are identical (two members c...
Every e-signature email was a silent 403, and a Signature Date field
**No e-sign email had been leaving the cluster.** EmailService gates /api/email/templates/send on the cluster-wide internal-auth secret (mlos-internal-auth -> I...
A Save As that changes format is not the source document's type
uploadDocument refuses an upload whose claimed MIME type disagrees with what it detects from the bytes, and saveAsNewDocument claimed the type of the row it was...
A Docs save could not store bytes the platform already held
Saving a document twice, and renaming one, both ended in "Document cannot be saved, please check your permissions" — and after five retries Docs gave up and dis...
Open at the front of a new session, stay put inside one
Two rules that only make sense together, and the panel did the opposite of both. A member arriving in a NEW browser tab — a fresh sign-in, a second tab opened ...
The offer countdown could not hydrate, so React threw the banner away on every load
The homepage has been throwing React #418 — "the server rendered text didn't match the client" — on every load, in production as well as locally. The mismatch i...
Give the film a watch page, because Google will not index it from the homepage
Search Console reports the one video on this site as "video is not on a watch page". That is not a bug in the hero — it is Google saying the homepage is about t...
Twelve endings, and every one of them looks different
A hand ends for everyone at the table at once and it ends differently for each of them. Until now it ended one way: somebody won a pot, and the window played th...
An org without the app must not accrue achievements either
The award gate asked for VIEW_ACHIEVEMENTS and stopped there. Rights are not entitlement-filtered, so that right stays granted — and keeps answering true — in a...
A side pot says who is playing for it
The last "consider" left in the request, and the one question a short stack actually has: when the middle splits in two, both piles look like money and only one...
The particles ran at the monitor's speed, and the chips were unreadable on two denominations
Two deferred things finished, both measured rather than eyeballed. THE PARTICLE LOOP IS TIME-STEPPED. `PixelParticles` advanced physics once per FRAME — every ...
Four things about the celebration only a browser could say
Measured in Chrome against the real component, not reasoned about. The headline was sized at a flat 13cqw, which is right for a number and wrong for a word: CH...
One table at a time, and a table you can name
The felt half of the four rules MediaService started enforcing in a02dd1d. ONE WINDOW. The registry said `maxInstances: Infinity`, reasoning in a comment that ...
The whole window celebrates when somebody wins
A win used to be a sentence in a strip under the board. It is now the entire tool window: an impact flash and a shockwave, light turning behind the board, firew...
Refuse to award a member whose security type excludes it
AchievementController checks VIEW_ACHIEVEMENTS on all four of its endpoints, and that read like the rule being enforced. It was not: it is the rule enforced on ...
Rank only members whose security type includes achievements
The leaderboard grouped every member holding an achievement row, so a member whose role denies VIEW_ACHIEVEMENTS — who cannot open the page, the trophy or the w...
The Directory leads the tab strip, Chats follows
Flips the two always-present tabs. The strip now reads Directory, Chats, Sales Scripts, Terminals. The panel still OPENS on Chats: the button that opens it is ...
No empty tables, numbered tables, and one table per member
Four rules, all of them things a member reported seeing broken. EMPTY TABLES. A lobby showed three tables while one game was being played. Two had no seats at ...
The motion guard matched a form, and longhand opted out of it
The reduced-motion walker scanned for the `animation:` shorthand. Writing the same animation as `animationName:` plus longhand properties — the first refactor a...
Prove the chat window's menu consults the entitlement too
The companion to the MediaService endpoint test, at the second door. The chat games menu had the entitlement hole independently of the nav icon — it asked for t...
The ramp-order fallback was a branch no test took
The invariant added in 80aee0ee falls back to the whole allowance when `clockStages` reports no critical boundary — which happens when the clock opens critical ...
The two clock ramps are independent, but not unordered
The colour and the sound escalate on deliberately different beats — a rate and a state are different vocabularies, and each says something the other cannot. Tha...
Prove the endpoints actually CONSULT the entitlement, not just that it works
GamesEntitlementTest proves the gate answers correctly. Nothing proved the three controllers ask it — and that distinction is the entire defect this change set ...
The clock drains on the compositor, not on a timer
The felt's turn clock ran off a 200ms setInterval writing a fraction into React. That is an honest way to build a bar that must track a server deadline, and it ...
The same-commit-rebuild guard could never fire, and the digest check failed open
Both protections against a deploy that deploys nothing were inert, so the pipeline reported two green jobs while the pods stayed on the previous digest. That is...
A catalog row naming an app this build cannot resolve is not for sale
ServiceTypeConverter stopped throwing on an unknown app id and started resolving it to null, which is what a service must do — the enum ships inside each jar wh...
The opening effect's cancel guards were guarding nothing
`cancelled` was declared, read seven times, and never assigned — the effect returned no cleanup — so every `if (!cancelled)` in the load that opens a window was...
A put-away table says you are on the clock
The other half of the hexhead turn indicator. A minimized Hold'em window now lights its head while the action is on you, and drains the head's own outline — gre...
A minimized game says it is your move
A head could already say a message had arrived. It could not say a game was waiting on you — chess tinted its border brass, which on a forty-pixel hexagon at th...
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...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.