Make the logo-preview checker mid-grey, so a white logo shows
The checker shipped in 5e0fb7b2 at #e0e0e0/#fff, matching the image-to-svg tools. Rendered against real logo geometry that is wrong for this screen: a pure-whit...
Stop an indexed source turning the tab icon into a black box
A tab icon uploaded as a transparent PNG-8 arrived in the browser tab as a black square with a ragged logo on it. Measured on the upload that exposed it: of the...
Carry a referral code through to the register link
The referral code normally travels in the apex cookie the marketing site sets (kdsc_src on .<apex>), which register.<apex> reads for itself, so this link does n...
Log a referral code that arrives with no visitor guid
A signup carrying a marketing code but no visitor guid had its referral dropped in complete silence — the branch that publishes the attribution event is gated o...
Credit a signup whose page views were never recorded
**************** was the ONLY thing in the fleet that ever inserted into MARKETING_VISITORS, so the whole conversion pipeline silently depended on a browser bea...
Mint a visitor id when a referral code arrives without one
RegisterFlow already read `?discount=` for visitors who reached the form without passing through the marketing middleware — a code pasted into an ad, an email o...
Stop losing referral attribution on the marketing site
Two ways a member's referral was being dropped, both silent. 1. Every register/login CTA was the string literal `https://register.kamocrm.com`, while this s...
Give the member Careers tab the route its own gate asks for
The tab was invisible to every team member in every organization, including one looking at an open posting. Not a rights problem, though it was shaped exactly l...
Stop the header eating the priority badge in a narrow window
The ticket number and both badges sit in one nowrap row, and none of the three can give way. The number is a 19-digit int64 that must not be abbreviated. The ba...
Stop a hover control giving the message list a scrollbar
The support chat window drew a horizontal scrollbar under a conversation that had nothing to scroll sideways to. Each message's reply button is absolutely posi...
Let the document scroll, so the scrollbar is the browser's own
Third attempt at this, and the first two were aimed at the wrong thing because the harness was lying. Puppeteer launches Chrome with --hide-scrollbars by defaul...
Make /settings/member/me the real address three callers already assume
RestrictedMembershipGuard builds it when the session's member id has not settled, the sign page's back link builds it, and kamo-login now lands a candidate on i...
Let a manager accept the web chat they were just paged about
Clicking Accept on a web-chat request closed the popup and reopened it a moment later, unassigned and with no chat window — the same card, over and over, with n...
Give the right-click menu the copy and paste it never had
Suppressing the browser's context menu (734f68cb) took the only copy/paste the terminal window actually had. That is not what it looked like — there are Copy an...
Put the scrollbar where the artwork cannot paint over it
The last fix reserved the scrollbar's space but it still could not be seen, and the reason was not the scrollbar. BackgroundStage is `position: fixed` with the ...
One refused request no longer ends the call and the session
The last way a member could lose a live call and everything in their tool windows without doing anything wrong. `authenticatedFetch` answered EVERY 401 with `w...
Give the pane a real scrollbar, and the gap the lender's colour
The scroller had an OVERLAY scrollbar: Chrome's default for an inner scroll container, taking no layout space and fading out when idle. On a document you tolera...
Don't file chats into a support topic the org deactivated
resolveTopic honoured a configured topic by id alone, so deactivating one left the integration still pointing at it and new website chats still landing there — ...
Pin the background and the support bubble, and point the way on
The pane could not both anchor `position: fixed` children and scroll them, and was being asked to do both. Its transform is what makes it their containing block...
Every tool window keeps what the member typed, not just one
Follow-up to c45b3857, which fixed the bug/improvement window and left four others named in a "known gaps" list. That list was the wrong answer: a gap recorded ...
Tell the widget the org's name so it stops speaking as Kamo
The public-chat bootstrap payload carried orgId but no org name, so the widget had nothing to brand the assistant with and fell back to a hardcoded "Kamo AI". A...
Publishing an application opens its chat key to the page it is on
The support widget on a published application loaded with Kamo's default config instead of the org's: it auto-opened on desktop with auto-open turned off, wore ...
The scrollers styled with classes rather than sx get the bar too
Reported against /hr/overview, and the page itself is innocent — it declares no overflow at all. Its scroller is one line in app/hr/layout.tsx: <div classN...
A populated bug report survives a page change
Reported again: a fully filled-in bug/improvement window came back empty after switching to /hr, and again from the analytics nav icon. The window was never los...
The rail's own scrollbar is not an exit from the rail
The previous attempt at this fixed the wrong handler. It taught the reconcile in useNavHoverPeek to see through the bar, which was worth doing and was not what ...
Resting on the rail's own scrollbar no longer flaps it open and shut
Reported as the rail switching between expanded and collapsed rapidly with the pointer held still over its scrollbar, which is exactly what it did. useNavHover...
Give the expanded rail back the width the scrollbar took
The rail is the one place where the app's scrollbar was paid for out of somebody else's layout. Expanded, it has always reserved a gutter — 20px, for the bar it...
The scrollbar moves the content over instead of sitting on it
Painting the bar over the last 32px is fine over a background — the launchpad's wallpaper does not mind — and wrong everywhere else. In a chat log it lands on t...
Close the last two catalog-bump gaps, and stop echoing exceptions
Two reads and nine response bodies, both halves of the same report. SessionRefreshController loaded the member one statement before the rights read that was fi...
Stop reporting a catalog bump as a missing SystemConfiguration row
Three scheduled jobs read a row and skip the whole tick if they cannot. All three were skipping ticks during schema changes, and two of them said so in a way th...
A catalog bump emptied the sweep instead of failing it
Both reads the sweep depends on already sat inside a catch that logs and carries on, so a Yugabyte conflict never surfaced as an error — it surfaced as a tick t...
Retry the two reads a catalog bump broke document editing with
WopiController.checkFileInfo is called repeatedly through an editing session — on open, around locks, after every save — so a conflict on its organization looku...
Every scrollbar keeps all five controls, at every size
The first cut dropped the four buttons on any bar shorter than 140px, on the argument that 96px of them leaves a 250px popover with a stub of track. That was th...
Retry the member load every authenticated request makes
AuthHelper.getCurrentMember was the single most common casualty of a Yugabyte catalog bump in this service — eight of the conflicts logged across both pods in o...
Cover the three shared reads a catalog bump still reached users through
Same defect as the sign-in fix, found by reading the fleet's logs rather than one report: eight hours of pod logs across email, media, docs, daemon and security...
The *** never ran, and seven things around it
**The *** could not work.** This fork of Capcha declares its endpoint attribute as `challenge`; I had set `challengeurl`, upstream's name. The widget was theref...
Move the lender's logo off the brand rail — it was disappearing into it
Caught on the live page for a real customer. ABC Mortgage's logo is navy and orange; their brand colour is that same navy; the rail is painted in it. So the mar...
Stop handing the database's own error text to whoever is signing in
The catch-all at the end of login() put e.getMessage() in the response body, and that body is rendered verbatim on the sign-in screen. On 2026-09-05 the excepti...
Retry the two rights reads that stand between a password and a session
MemberRightsAppliedService carried @RetryOnDbConflict on its WRITE entry points only. The class therefore read as covered while the two methods the authenticate...
Send the application receipt after the commit, not inside it
The submit handler is @Transactional, and it was calling EmailService inline — blocking HTTP into blocking SMTP with a 30-second read timeout, while holding a d...
The update DTO needs the first-time-buyer field too
68ce0e0f added `isFirstTimeBuyer` to the CREATE request and wired both call sites in LeadService — but the second one reads UpdateLeadRequest's own nested Mortg...
Put back the CRLF a Python edit stripped from two files
Both files are CRLF in this repo, and rewriting them through Python's text mode converted every line — turning a fifteen-line addition into a 771-line diff in 6...
Stop stranding phones on a rotation they never received
KamoMobile was signing itself out at random, most visibly across app updates, and the exchange endpoint was doing it. Three separate ways: The secret rotated F...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.