A catalog-version bump must not read as "this host has no organization"
Org resolution funnels every lookup through one query helper that swallows the exception and answers Optional.empty(). For an organization that genuinely is not...
Restore SpfAdvisoryService, which main no longer compiles without
45829a6 deleted this file. Nothing in that commit wanted it gone — it was a staged deletion of mine that a concurrent `git add -A` picked up, and the same commi...
Name the constructor Spring should use, or the context will not start
My own regression, and the second context-startup break on this service today: Error creating bean with name 'terminalTicketRegistry': Failed to inst...
Let Spring pick the terminal registry's constructor
SecurityService has been crash-looping on every new pod since the shared handoff store landed: "No default constructor found" for TerminalTicketRegistry, which ...
Resend the verification e-mail under the organization the member is actually on
Nobody at a white-labelled organization has been able to ask for a second verification e-mail. The screen said the letter was on its way every time, and no lett...
Share terminal tickets across pods, or half of them are refused
Opening a terminal fails about half the time with "The server refused the terminal connection. Your ticket may have expired", and the log says: Terminal ha...
Answer "who owns this account" about the member, not the reader
The member payload now carries accountOwnedByThisOrg. The console used to work this out for itself by comparing the READER's securityOrgId to the current organi...
Restore the @Lazy that stops the context depending on itself
Every SecurityService pod built since 4bd25e7 fails to start: The dependencies of some of the beans in the application context form a cycle: ┌──->──┐ ...
The operator write must answer in the same shape it was asked in
The console adopts this response as its new state. It returned the address and `canChange` but not `mode` or `isSelf`, so after a successful operator write `mod...
A god may fix their own address from any workspace
The tenancy rule refused a god-eligible caller on their OWN record whenever their session was in an organization other than the one that owns the account. That ...
Make a System User session terminal, so entry cannot chain
The System User is god by construction, so every session minted for it carries GD and offers break glass. That is fine only because the identity does not compos...
Say whether an org HAS a logo instead of guessing a URL for one
Every "which networks can I reach" row carried logoUrl and logoSimpleUrl derived from the org's alias alone, for any org whose alias was path-safe — which is al...
Read the account inside a transaction before sending a reset
sendPasswordReset had no transaction, so the User came back detached and `securityProvider` stayed an unresolvable lazy proxy. Working out which organization's ...
Let a rollout finish what the old pod was doing
Deploys replaced the only pod of each service with nothing to catch the requests in flight. Three settings, applied across the fleet: - preStop sleeps 10s befo...
A member's work address must name them without a mail provider
Forgot-password resolved the address typed on the form against two sources: the account e-mail, and the org mailbox flagged Primary on the member's settings. Th...
Only the member or god may set a member's password
MANAGE_MEMBER_SECURITY passed the change-password gate, which made "can administer members" and "can take over any member's account" the same right. They are no...
Every terminal handshake was 403 behind the edge proxy
The reported symptom was a terminal that opened and immediately said "Disconnected", with nothing to act on. Reproduced end to end: the ticket mints fine (200) ...
Assert the mask obfuscates, and skip the gate for callers with no leads
LeadFieldMaskTest still expected a null e-mail. The mask now obfuscates rather than blanks — a blank field reads as "this lead has no e-mail", which is a differ...
A refused terminal handshake answered 200
Found by probing the deployed endpoint, not by reading it. Returning false from a HandshakeInterceptor aborts the handshake but sets nothing on the response, so...
Do not mail a tenant its own domain until that domain is verified
A domain typed into the create form is a CLAIM, not a host. Ownership is proven by a DNS TXT record afterwards and a certificate is issued after that, so betwee...
Stop a failed welcome email from destroying the member
MemberCreationService documented steps 4-6 as best effort, and for the emails it was not true. sendVerificationEmail is @Transactional, so it joined the member-...
Open a workspace on its OWN domain, not the host the sign-in was served from
A member who signed in on login.kamocrm.com, picked a workspace from the chooser, and landed inside it — on internal.kamocrm.com, wearing the platform's hostnam...
Stop dropping setupFee on save, and unbreak the build
withTermsUnchanged rebuilds UpdateQuoteRequest positionally for a member who may not rewrite the terms. setupFee was added to that record and not added here, so...
A share link's email was dropped twice before it could be sent
"I created a link and got no email." Two independent silent drops, both of which return a swallowed false that the panel rendered as plain success. 1. kamo.ema...
Accept a blank status label as the removal it is
The PUT is the org's complete set of custom labels, so it has to be able to carry an emptied box. Two things stopped it: an empty list was rejected as a malform...
The agent health preflight must fail in seconds, not twenty
health() inherited the client's 20-second default. It is a liveness check in front of every KamoDesktop launch, and when the dev machine ran out of memory on 20...
Stop refusing a domain because somebody else typed it first
Creating an organization 409'd on any existing row for the domain, which meant the first organization to enter "acme.com" locked out every other one — including...
Give the generated favicons the same revalidation requirement as every other theme asset
Replacing an org's simple logo updated every surface that reads img/logo.svg and left the browser tab on the old mark. Generation was never the problem: provisi...
A transient database fault must not 500 the request
The lead Communications tab reported "We couldn't load this lead's communications" for org 1168485648209608710 on 2026-08-28. The endpoint returned 500 five tim...
Require an open god-mode window, not eligibility alone, for CONFIGURE_SYSTEM
hasRight was granting the bypass on the raw GD session flag, which SessionPlatformFacts's own javadoc names as the exact anti-pattern it exists to prevent: GD i...
Make seeded and uploaded branding revalidate, so an org stops being served the base theme it was seeded with
A new organization is seeded with the base theme — the platform's own logo and backgrounds copied to the new org's keys — and those keys never change when the o...
A video on a report never reaches an AI dispatch
file and cannot watch one. The desktop agent already magic-byte-checks every attachment, but it refuses the DISPATCH rather than the one file — so a single vide...
Gate the order and pricing surfaces on a right
Thirty-nine endpoints were protected only by "are you signed in". Every order handler on POSController and every pricing and tax handler on CommerceMarketContro...
The outbound audit row was written by an inert REQUIRES_NEW
It was a method on ExchangeQueryService annotated @Transactional(REQUIRES_NEW), called from two private helpers on the same class. Spring's transaction advice l...
Main did not test-compile — PhiExportAuditTest missed a constructor arg
SystemConfigurationController gained a twelfth parameter, PlatformSecretCipher, when platform secrets began being encrypted at rest. This test still passed elev...
A picture-frame image whose bytes are gone answers 410, not 500
The frame stream caught everything as stream_failed and returned 500, so a photo whose object is not in storage rendered as a broken image with no explanation -...
A CCD preview is not a disclosure
Previewing a summary recorded a disclosure naming the recipient — so a patient asking who has their record under §164.528 would be told it went to somebody who ...
Nothing returned an account id, so nothing could be withdrawn
Withdrawing portal access and granting a proxy both take an account id, and no endpoint ever returned one. A practice could invite a patient to the portal and t...
22 of the 26 clinical rights were never enforced
Only the four population-level rights — bulk export, quality measures, portal administration and EHR settings — were ever checked. Prescribe, sign, cosign, plac...
An organization can be looked up by the reference ?org= carries
GET /org/ref/{ref} — the same projected record as /org/domain/{host}, for an organization named by its id or its web alias. Nothing could answer for one. The s...
Actually measure the bulk-export bucket
StorageDomain.BULK_EXPORTS shipped declared, documented as "measured by scanning the object store", and referenced by nothing. It reported zero for every practi...
Create returns the domain its theme is provisioned under
The caller cannot work this out and must stop trying. GET /org/{id} answers with the entity, whose `domains` is LAZY and serializes as null outside a transactio...
A push token may be claimed by one device row, not every past sign-in
Companion to MediaService 8a809b3, which stopped members getting the same chat message three-plus times on their phone. That change made dispatch collapse dupli...
Recover a lost background count from the images themselves
commitBackgroundOrder writes the images to STAGING, and imageBgCount is only a record of how many it wrote — which made that one column a single point of failur...
Gate the nine Service Work endpoints on a right
They shipped checking only that the caller had a session, so any member of an org could read and mutate every work order in it regardless of role. ASSIGN_SERVI...
Drop the nine Service Work endpoints from the unguarded baseline
They are gated as of e6e1d02, so their baseline entries no longer match an unguarded endpoint and **************** fails on the stale lines. Requiring the remov...
Stop the customer **************** rights reading every tenant's rows
Every endpoint that accepted a VIEW_OWN_* right as an OR-alternative loaded its record by primary key alone, never checking who it belonged to: getSubscription,...
Serve a tenant's assets from a host that resolves, and stop deleting its backgrounds
Two faults found while working out why a new org opened with no logo and no colours. THEME DELIVERY. Assets were requested from theme.<the org's own domain>. A...
Show one call once in a rollup, and stop 500ing on unworked leads
Two fixes the account rollup made visible. A phone number can be a contact point on more than one owner at the same time, and two leads on one account sharing ...
Make the KamoDesktop SSO link redeemable exactly once
The link is delivered as a URL, so it lands in browser history and in the reopen-closed-tab list, where it long outlives the session it was minted for. Until 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.
