A tenant on the shared meet host is painted and configured as itself
On meet.kamocrm.com the hostname is the platform's for every organization that has no domain of its own, and nothing on the page ever told the sidecar which org...
The tab title reads the organization's own folder too
title.html is SSI-included into the room page and most of static/ (both close pages, 404, oauth, offline, dialInInfo, prejoin, whiteboard). Its script still der...
Paint a tenant's lobby from its alias folder, with the logo it uploaded
On meet.makeitpopsigns.com every logo, background, stylesheet and favicon 404'd. The sidecar resolved the host's organization for its meet settings but never as...
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...
A rebuild of the same commit deployed nothing and reported success
The image is tagged with the commit SHA, so rebuilding the same commit produces an identical image reference. `kubectl set image` then changes nothing, the Depl...
Rebuild now the registry's stale blob-descriptor cache is cleared
ROOT CAUSE, for the next person who sees "short read: expected N bytes but got 0: unexpected EOF". The registry runs storage.cache.blobdescriptor: inmemory. Bl...
Rebuild after clearing the registry's dangling layer links
The previous two builds (2862548, dd323bc) both produced images that could not be pulled: short read: expected 3985350 bytes but got 0: unexpected EOF Cause...
Rebuild β the previous push left the registry without its layers
The image built for 2862548 cannot be pulled: failed to pull and unpack image "...kamo-meet:28625480...": short read: expected 3985350 bytes but got 0: une...
Answer a readiness probe, and run two pods
This deployment had no readiness probe, so a pod counted as Ready the instant its container process started. With maxUnavailable 0 Kubernetes reads that as "the...
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...
Put asking for control on the screen it would control
The feature worked, and almost nobody would have found it. The only way to ask was an item in a thumbnail's overflow menu β hover the right person in the filmst...
The control helper installs itself, so there is one file to get
Setting the helper up meant downloading two files, opening a terminal and running a script with sudo. That is a flow people abandon, and an abandoned install is...
Hand mouse and keyboard control of a shared screen to someone else
Wires the fork's dormant remote-control feature to the companion agent, and fixes the things that would have made it unusable even once it was reachable. The r...
A companion agent that can actually move the remote mouse
The fork already carries Meet's whole remote-control feature, and none of it has ever been reachable. The receiver half waits on a PostMessage transport for a h...
The lobby wears the meeting owner's brand, not the platform's
The overlay derived its theme folder from the browser's hostname. On the shared meet host that is the platform's for every tenant, so the CSS, favicon and logo ...
A member's identity and their org stop leaking between tabs
meet.<platform> is shared by every organization without a host of its own, and localStorage is per ORIGIN. The signed-in member's name, email and avatar were wr...
Retry npm ci, which is where this image actually fails
The build has failed on every push since 2026-08-15 and it is not the code. The log shows npm ci dying with ERR_SSL_CIPHER_OPERATION_FAILED and ossl_gcm_stream_...
Resolve the lobby's org from the room or ?org=, not the host
/api/config and /api/branding read the organization from the hostname. On the shared meet host that is the platform organization for every tenant, so each of th...
Scope rooms to their organization on the shared meet host
Room isolation was the HOST. A member of org B could not present a *** cookie on meet.<org-A-domain>, so knowing org A's room name got them nowhere. Serving org...
Paint the org logo as a solid silhouette when asked
An org can now choose a solid colour for the pre-meeting logo, set from kamo-internal's Branding settings and applied here. This side never sees the token voca...
The column tint over the slideshow is 90%, not 50%
Half strength let too much of the photography through the join column and the preview pane. Both are now 90% of their own colour, so the background reads as a f...
The slideshow covered both columns instead of sitting behind them
#preview is a plain flex item with no position, so the slideshow layer β positioned, z-index 0 β painted over its background and, worse, over the member avatar ...
Org background slideshow, and honour the shuffle setting
The welcome page already rotated the org's themed backgrounds; it now reads backgroundOrder from the same config.json so an org that picked shuffle gets a fresh...
Size the org logo to 80% of the join column
The join screen capped the branding logo at 40px tall with objectFit contain, so it rendered letterboxed inside the 300px column and looked undersized no matter...
Browsers kept serving a stale app bundle after every deploy
index.html shipped a hardcoded `libs/app.bundle.min.js?v=139` that no build ever changed, the bundle filenames are stable, and nginx sent no Cache-Control at al...
The avatar fallback URL could never resolve
Both avatar-lookup catch blocks built **************** Avatars moved to the fixed, domain-independent `platform/` prefix (SecurityService AvatarObjectPaths) whe...
Colibri-ws proxying always 502'd β nginx had no resolver
The /colibri-ws/<jvb-id>/ location builds its upstream from a capture group. nginx resolves such names at request time and only when a resolver is configured, s...
A dead avatar URL rendered a permanent broken image instead of initials
A participant whose photo is missing from storage showed a broken-image icon to everyone else in the call, forever β it never degraded to initials. Upstream ca...
Harden the kubectl download against flaky egress [skip ci]
dl.k8s.io over the runner's egress intermittently drops mid-transfer: curl: (56) OpenSSL SSL_read: decryption failed or bad record mac which fails the deploy ...
Require-password gate for anonymous guests (members bypass)
When an org enables requirePassword, anonymous link visitors must enter the room password; authenticated members are never prompted. - sidecar: no anonymousdom...
Auto-record + recording watermark from org settings
overrides.js loadOrgMeetSettings now, when recording is enabled: - watermarkOnRecordings β shows an org "REC" watermark overlay while a recording is active (J...
Close JWT-forge hole, fix guest join, add "Sign in with Kamo"
- sidecar /api/auth/jwt: derive the member identity (id/name/email/org) from the server-side *** session, not the request body. Previously anyone could POST...
Migrate to k1m1 (clone+registry+kubeconfig from k1m1, drop k2m1, simple kubectl install)
Scope concurrency to build jobs, not Kubernetes deploys
Workflow-level concurrency serialized the whole pipeline (including kubectl rollouts). Move the group to the build job only so deploy jobs from different runs c...
Dynamic title and description from org config.json
Inline JS in title.html derives the themed CDN path from the hostname, fetches config.json, and sets the title to "Meets - {siteNameShort}" and description meta...
Add Powered by KamoCRM backlink to /welcome landing page
The actual meet.{domain} landing page is welcome/index.html β a static HTML page served directly by nginx that handles the pre-auth flow (capture display name /...
Make PoweredByKamo match kamo-login β white on brand color
The KamoMeet welcome page already had the PoweredByKamo backlink wired up, but its styling was still the original low-opacity currentColor treatment that was vi...
Add subtle KamoCRM backlink to welcome and in-meeting UI
Mirrors the PoweredByKamo pattern shipped in kamo-login and kamo-register to the KamoMeet (Meet fork) web surfaces. Each client's KamoMeet deployment serves on ...
Add public webinar cancellation page with org-branded styling
Adds /cancel?inv={token} page for public attendees to cancel webinar registrations. Includes sidecar API proxy endpoints, nginx routing, and a fully branded can...
Extend JWT expiry from 5 minutes to 24 hours
Prosody re-validates the JWT when new participants join or conference state changes. With a 5-minute expiry, the presenter's JWT expired mid-meeting causing "Un...
Force-set avatar via Redux dispatch after JWT redirect
The JWT delayed-load pipeline for avatars fails silently with disableThirdPartyRequests. Three-layer approach now: 1. Avatar.tsx _mapStateToProps falls back to...
Use participant avatarURL directly as fallback in Avatar component
The loadableAvatarUrl pipeline (preload check β setLoadableAvatarUrl) was never setting the URL due to disableThirdPartyRequests and the delayed-load flow clear...
Extract CockroachDB IDs as strings before JSON.parse loses precision
CockroachDB unique_rowid() IDs (e.g. 1161936315562426374) exceed JavaScript's Number.MAX_SAFE_INTEGER (9007199254740991). JSON.parse silently corrupts them β 11...
Fetch avatar URL from SecurityService API instead of constructing from hash
The static URL construction from the session hash was returning 404/500 because Avatar Creator SVGs aren't always stored at the expected MinIO path. Now the si...
Set avatar URL directly without preload check, add sidecar logging
The preload check in _getFirstLoadableAvatarUrl was failing because the theme CDN URL couldn't be preloaded from within the browser's security context with disa...
Logo variant race condition, defaultLobbyEnabled ignored, and whoCanRecord not passed to config
- Defer logoUrl resolution in overrides.js until org config loads to prevent flashing the wrong logo variant (SIMPLE vs FULL) - Fire kamo-branding-loaded even...
Allow avatar photos when disableThirdPartyRequests is true and redesign virtual background settings layout
Avatar URLs from the JWT context are first-party theme CDN URLs, not third-party requests. The disableThirdPartyRequests guard was preventing them from loading,...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.