Correct FPBXCONF heredoc + repoint universe Scylla
- freepbx: the FPBXCONF here-document closing delimiter was indented (8 spaces); bash requires <<WORD delimiters at column 0, so startup.sh died with 'unexpec...
Canonicalize webhook repo name to public-projects casing
After the cluster migration the Forgejo repos were recreated lower-cased (securityservice), but historical rows and the public-projects filter use canonical cas...
Node-local MinIO + failover template read + ImgDat dedup (fixes new-doc about:blank)
New-document creation hung ~5 min and the new tab stayed at about:blank. Root cause: DocsService pods scheduled on k3m1 read the blank template from MinIO at th...
Generate favicons via multi-node logo read, not single-node exists()
generateAndUploadFavicons() gated on minioService.exists(), which only stats the current MinIO host. When the simple logo was written to (or only replicated ont...
Re-apply live stylesheet after branding save so new colors show without hard reload
DynamicMetaLoader injects the org globals.css only once on mount, so after a color save (which correctly re-provisions globals.css + bumps themeRevision) the pa...
Pin kamo Traefik to k1m1; make auto-cert single-cluster
SSL errors: kamo Traefik is a LoadBalancer with externalIPs 192.168.4.22 (k1m1) + externalTrafficPolicy=Local, so it MUST run on k1m1 — the pod rebalance moved ...
Null-safe split of the AiPullThroughPolicy single-active index (doc 09 §8)
CRDB is NULLs-distinct, so the single (lender_profile_id, market_id) WHERE status='ACTIVE' index did NOT backstop the org-wide (market_id IS NULL) grain — two c...
Recreate deploy strategy so NATS durable consumers rebind on deploy
DaemonService binds EXCLUSIVE JetStream durable consumers (daemon-sync-trigger, **************** [the §2.8 breach loop], daemon-recording-received) in @PostCons...
Enable OutboxRelay @Scheduled backstop + @Async hot path
DaemonService activates the MLOS transactional outbox (mlos.outbox.enabled) and produces events (the compliance-timer breach emitter), but lacked @EnableSchedul...
Register com.kamo.z.shared.mlos.event repos (OutboxWriter dep)
Enabling mlos.outbox activates OutboxWriter, which requires MlosOutboxEventRepository (+ ProcessedEvent /DeadLetter) from com.kamo.z.shared.mlos.event — add tha...
PublishAck is in io.nats.client.api, not io.nats.client
Test-only import fix that was breaking shared-lib compilation (caught by the now-required local mvn install). Main code was unaffected (OutboxRelay ignores the ...
Indent heredoc bodies so the startup.sh configmap is valid YAML
The startup.sh block scalar embedded 5 shell heredocs (rtp.conf, http.conf, an SQL block, WebRTC endpoints, freepbx.conf) whose bodies sat at column 0 — less in...
Point Docs deployment at k1m1 registry
The Docs-online image host was the bogus **************** (Redis DNS, never a registry), so every DocsService deploy re-applied an unpullable image. Point it at...
Page reflects superseded edt + road-less transport cells honestly
The Services tab read as incomplete for two stages that are actually done: - edt showed an empty 0% bar though EDT4 (hydro) supersedes the EDT2 base and the p...
Show the live heartbeat tile count, not the stale per-pass value
Progress read status.have first, which the initial 'running' event sets to 0 — and `0 ?? count` keeps 0, so the live count never showed (and hydro mis-counted a...
Add Universe to the settings slide-out (NavPri)
The Universe page was registered on the settings landing cards but not in the SettingsStatusWindow slide-out that NavPri actually opens, so it didn't appear und...
Expose GD (god eligibility) in /user-info for kamo-universe
The session stores the GD flag (KSessionService) but /user-info never returned it, so kamo-universe's KamoIdentity always deserialized is_god=false and the god/...
Don't save transactional NoReply sends to a Sent folder
NoReply is a send-only address with no mailbox, but every transactional send still attempted an IMAP append to its Sent folder, producing a noisy AUTHENTICATION...
Case-insensitive email lookup so reset emails send
Password recovery lowercased the input but findByEmailEmail does a case-sensitive match against the stored email (e.g. Sage@KamoCRM.com), so the user was never ...
Proxy password-reset to SecurityService internal DNS
The /api/recover proxy defaulted to api.kamocrm.com, which Traefik routes to APIService (no recover controller) → 404 → "Something went wrong" on /reset-passwor...
Move Dovecot maildirs to a local-path PVC (off rclone/MinIO FUSE)
Maildirs were on hostPath /mnt/shared-files/email/mail — the rclone FUSE mount backed by MinIO object storage, which can't safely host a maildir (no atomic rena...
Put MySQL datadir on a local-path PVC instead of rclone/MinIO FUSE
The mail MySQL datadir (and maildirs) were on hostPath /mnt/shared-files, an rclone FUSE mount backed by MinIO object storage, which cannot durably or consisten...
Mailbox list API returns UI-shaped ****************
GET /api/email/mailboxes returned the raw entity (providerStatus, lastSyncedAt, no member count). The settings UI reads **************** so status was always un...
Carry impersonation audit trail across org jumps
When the caller is already an impersonation session (a god admin acting as another member, carrying SUDO_MEMBER_ID), entering another org from /network minted t...
Authorize privilege-based mailbox access for read + send-as
resolveForMailbox only granted access via a direct MemberMailbox assignment, so mailboxes surfaced through **************** rights threw NoSuchElementException ...
Stop gating pages on the *** cookie in proxy middleware
proxy.ts (Next middleware) redirected every page request with no *** cookie to /logout. Since the session id now lives in sessionStorage — which a document requ...
Stop touching cookies; send token explicitly on auth calls
Rip out all the legacy-cookie clearing/migration. The token lives in sessionStorage (key ***) and travels as the X-***-Token header, which the backend already p...
Don't adopt the legacy *** cookie; clear it instead
Right after the sessionStorage switch ships, every browser still has its old *** cookie. The migration adopted that value into sessionStorage (and the server co...
Fall back to my-networks when all-networks 403s
hasPlatformAdminAccess is derived client-side (owner-of-session-org AND host-org-is-top-level). A child-org owner whose session lands on the top-level host is m...
Gate KamoUniverse launcher on ACCESS_KAMOWORLD right alone (drop org games flag)
Backup verified working — DB-scoped backup, MinIO region us-west-ca-s-1, EXTERNALIOIMPLICITACCESS grant in bootstrap
Drop WITH revision_history from backup (enterprise-only); core BACKUP is OSS
Loki 6.x SingleBinary needs zeroed scalable targets; crdb exec via localhost (cert SANs)
Register esign repositories for the meter submission bean
EsignMeterSubmissionService needs EsignUsageRecordRepository, but @EnableJpaRepositories didn't scan com.kamo.z.shared.esign.repos, so the context failed to sta...
Back metered add-on prices with a Billing Meter
Stripe (>= 2025-03-31.basil) rejects the legacy usage_type+aggregate_usage metered model ('metered prices must be backed by meters'), so USAGE_BASED add-on pric...
Select the SUBSCRIPTION market for platform setup
KamoCRM owns several markets **************** so resolveProductMarket must pick the SUBSCRIPTION-type (platform-access) market rather than the first active one....
Product root = owns SUBSCRIPTION market, not any market
A customer org (e.g. BluEleven) owns its OWN business markets (RETAIL/MORTGAGE) to run its company while remaining a customer of the KamoCRM platform — its memb...
Keep org list on background refetch; dedupe session calls
/network re-fired fetchNetworks on every background session refresh and hid the whole list on any fetch error, so a transient blip or a stale hasPlatformAdminAc...
Revert email link click handlers, isolate cause
User reports email-preview link clicks still do nothing AND text selection is killed mid-drag. Right-click and hover both work, so the anchor element is intact ...
Regenerate favicons on labeling save; sniff real logo type
provisionUpdate (run on every custom-labeling save) wrote config/css/manifest but never regenerated favicons — those were only produced by provisionFull. An org...
Seed globals.css from template when org folder lacks it
provisionUpdate (run on every color save) rewrote the org's css/globals.css in place, but that object only exists once provisionFull has copied it from the defa...
Show full logo with its real extension, not hardcoded .svg
The branding tab built logoFullUrl as logo-full.svg on mount, ignoring the org's logoFullExt. Full logos uploaded as png/jpg/etc. live at logo-full.{ext} in Min...
Refresh TLSStore every loop so newly-issued certs get served
update_tls_store() only ran at startup and on shared-storage imports, so a cert freshly issued by cert-manager (HTTP-01) was Ready with a tls-* secret but never...
Give redirect-only route a backend so Traefik v3 enables it
Traefik v3 disables an IngressRoute router with services: [] when allowEmptyServices is off (as it is here), so the domain-agnostic HTTP->HTTPS redirect router ...
Redirect all HTTP hosts to HTTPS + gate auto-cert to real org domains
Custom org domains (e.g. login.sign.pink) returned Traefik's bare "404 page not found" over plain HTTP: the only port-80 redirect router was hardcoded to *.kamo...
Persist conversion_error instead of failing silently
Both the template and regular upload conversion pipelines swallowed Docs conversion failures (logged only), leaving is_converted=false with no recorded reason —...
Install turbo via npm in Docker pruner stage; pin pnpm; add .dockerignore
The pruner stage ran `pnpm add -g turbo` before any package.json existed, so corepack grabbed pnpm 11 and failed with "global bin directory /pnpm/bin not in PAT...
Default empty STRIPE_CONNECT_WEBHOOK_SECRET so KamoLOS boots
The configmap referenced **************** without a default, so Spring's placeholder resolver threw before reaching the Java-level **************** which alread...
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.
