Skip to content
KAMOUniverse

Changelog

What's new.

Every improvement to the platform, as it ships.

  1. · AIService

    The ai_member_voices table and the charter voice-pin migration, as hand-applied SQL

    SP96 Task 2. The table remembers an AI member's voice per TTS model (spec 5.1); the migration moves every charter VOICE pin to a CHOSEN, MIGRATED, preferred row and clears only a pin whose exact voice is now remembered (spec 5.9). It is run once by Task 11, after Task 10 has deployed. Sp96VoiceDdlContractTest keeps both files re-runnable, additive and exactly the contract.

  2. · SecurityService

    SP96 DDL for members.sex, pinned by a contract test

    A member's sex is a nullable VARCHAR(16) (FEMALE | MALE, NULL = not specified), hand-applied in SP96 Task 3. The contract test keeps the file re-runnable, with no NOT NULL lacking a DEFAULT and no CHECK, JSON or DROP.

  3. · kamo-internal

    The voicemail list updates live (SP98-Q-3)

    Nothing in the browser subscribed to /topic/voip/voicemail/<member>, where MediaService relays VOIPService's new-voicemail frame, so the card arrived and the list did not change. Every tab now listens there on the chat socket it already holds (the call socket is only open in the tab that owns the line, and only for an org that can take calls), and folds the mailbox's first page into the list, keeping the pages already scrolled into. A reconnect catches up the same way. The dead VOICEMAIL_DEPOSITED branch on the SMS topic is gone.

  4. · TranslateService

    Send en->ta to Kamo IndicTrans, and log which engine answered

    No provider claimed en->ta (LibreTranslate lists no Tamil, Bergamot serves German only), so the router returned the English source for every Tamil request, and the dictionary sync wrote it as the value: kamo-internal's ta.json equalled English in 34,549 of 34,779 keys. IndicTransProvider claims exactly en->ta, the pair the klusterservices indictrans/ pod serves; ta->en would need the indic->en model, which is not deployed, so it stays unclaimed. It speaks the engine's LibreTranslate-shaped API behind the same auth proxy token, with LibreTranslateProvider's retry policy (a 4xx other than 429 is final; a 503 busy is tried again inside a 100 s budget). The router tries it after Bergamot and before LibreTranslate. ProviderRouter now logs one line per translation: the pair, the provider that actually answered, the sizes and the time, never the text ("translated en->ta provider=indictrans chars=21->34 ms=412"). translate.indictrans.base-url goes into application.yml and the k8s ConfigMap, which replaces it in production.

  5. · KlusterServices

    An English-to-Tamil engine, so Tamil stops being English

    LibreTranslate lists no Tamil and Bergamot serves German only, so every en->ta request (the dictionary sync, Help Center articles, chat) matched no provider and came back as its English source: kamo-internal's ta.json equalled English in 34,549 of 34,779 keys. Kamo IndicTrans serves IndicTrans2's distilled en->indic 200M model (MIT; the rotary-position variant by its authors, as converted to CTranslate2) on CPU on k3m1, behind the same Kamo auth proxy as bergamot and libretranslate (kamo-translate-auth). It speaks LibreTranslate's API and serves en->ta only; any other pair is a 400, never an English echo. - scripts/server.py: IndicTransToolkit's IndicProcessor for an English source, ported; Kamo's KMPH<n> sentinels ride as the model's own <ID n> entities (150 of 150 kept); and four output repairs measured on kamo-internal strings: spaced dashes kept, the model's visarga-for-colon (Tamil aytham) turned back into a colon, the ellipsis character kept, and no full stop added to a label. Logs sizes and timings, never text. SIGTERM finishes the requests in flight. - scripts/fetch_models.py: Job indictrans-models fetches the model by revision and SHA-256 and the packages by requirements.txt with --require-hashes into a local-path PVC; a file that does not verify never takes the served name. The serving pod mounts it read-only and has no egress (CiliumNetworkPolicy); only translateservice reaches the proxy. - Sizing (measured): 0.9 GB peak RSS, 0.5-0.6 GB serving; p50 0.16 s per string at 4 threads. Requests 2 CPU / 1Gi, limit 2Gi, no CPU limit. - Workflow step Deploy IndicTrans (K3M1), before the audit; a changed script or proxy config restarts a running server. SECRETS.md lists the new consumer of kamo-translate-auth. Tests: python3 -m unittest discover -s indictrans/tests (70; the two real-model tests run with INDICTRANS_MODEL_DIR set).

  6. · kamo-register

    A visitor handed over from another apex as ?vid= keeps their identity

    www.kamocrm.com's sign-up now opens register.kamouniverse.com (owner, 2026-09-28). Its kdsc_vid cookie is scoped to .kamocrm.com and can't follow, so kamo-marketing carries the GUID as ?vid= next to ?discount= (app/lib/register-link.ts). resolveMarketingTracking now adopts a well-formed carried GUID, and persists it with the code on this apex, instead of minting a new identity. The signup then lands on the same visitor timeline the referring member sees. It is adopted only alongside a code, a cookie identity on this apex still wins, and a malformed value is never adopted.

  7. · kamo-marketing

    Www.kamocrm.com signs in and signs up at the KamoUniverse doors

    The owner asked for this on 2026-09-28: the Log in and sign-up buttons on www.kamocrm.com open login.kamouniverse.com and register.kamouniverse.com. www.kamocrm.com stays a live KamoCRM product site; the platform's doors moved to the KamoUniverse brand. - rehostAuthLink: a platform auth link (register./login. on either platform apex) goes to the PRIMARY apex's door when the site is served on a platform apex, and to the tenant's own door otherwise, unchanged for white-label tenants. The baked-in hrefs, the markup crawlers and pre-hydration clicks follow, name kamouniverse.com. Links naming the legacy apex are still recognised. - Referral attribution survives the hop to another registrable domain. The kdsc_* cookies are scoped to .kamocrm.com and can't follow, so the code rides as ?discount= (as before) and the visitor GUID as ?vid=. kamo-register adopts vid rather than minting a new identity. The GUID is only added on a cross-domain hop, and a malformed one is never reflected into a link. - CSP connect-src gains the kamouniverse doors and keeps the kamocrm ones (add-only). - check-register-links: the tenant invariant (the link stays under the cookie domain) plus the platform cases, 35 checks.

  8. · VOIPService

    Teams calling connects send the api.kamouniverse.com redirect

    The owner has added **************** to the platform Microsoft app, keeping the api.kamocrm.com one. Both hosts serve the path. Completes aa7b608, which moved RingCentral.

  9. · EmailService

    Personal-mailbox connects send the api.kamouniverse.com redirect

    The owner has added **************** to the platform Google and Microsoft consoles, keeping the api.kamocrm.com one. Both hosts serve the path.

  10. · VOIPService

    RingCentral connects send the api.kamouniverse.com redirect

    The owner added **************** to the platform RingCentral app and kept the api.kamocrm.com one; both hosts serve the path. Teams calling uses the same path on the platform Microsoft app, whose console holds only the legacy host, so its DEFAULT_REDIRECT_URI stays on api.kamocrm.com.

  11. · MediaService

    Meeting-provider connects send the api.kamouniverse.com redirect

    The owner added **************** to the platform Microsoft app and kept the api.kamocrm.com one. Both hosts serve the path, so a connect started under either completes.

  12. · EmailService

    The platform's Gmail, Microsoft 365 and Zoho connects send api.kamouniverse.com redirects

    The owner added **************** (Google) and **************** (Microsoft, Zoho) to the platform apps' consoles and kept the api.kamocrm.com ones, so both are valid. The platform now sends the new host. api.kamocrm.com keeps serving both paths, so anything already registered or in flight completes. Personal-mailbox connects stay on api.kamocrm.com until their redirect is added to the Google and Microsoft consoles too.

  13. · kamo-shared-library

    The platform API host is api.kamouniverse.com

    The platform's OAuth apps now hold api.kamouniverse.com redirect URIs. The owner added them to every console (Google, Microsoft Entra, Zoho, RingCentral) and kept the api.kamocrm.com ones, so the platform can send the new host. Both hosts serve every callback path, so a flow started under either completes. No existing org's own app depended on this fallback: the one org with its own app has a verified domain and is sent api.<its domain>.

  14. · EmailService

    The platform organization's letters are signed KamoUniverse, not its legal name

    The platform org's title is the company's legal name, "KamoCRM Inc.", and it stays in legal text. Its letters now carry the brand, its short title "KamoUniverse", in the From display name. Only the platform org is affected; every other org keeps its title. The owner decided this on 2026-09-28.

  15. · SecurityService

    Theme folders still showing the retired KamoCRM placeholder move to the KamoUniverse one

    Every new org's theme folder is seeded from public/default/. Until today its full logo was the KamoCRM wordmark. The seed is now the KamoUniverse wordmark, built as a RasterSvgStandIn of the owner's **************** The old bytes are kept at **************** nothing was deleted. ThemeSvgStandInBackfillService finds untouched seeds by comparing bytes with the CURRENT seed, so on its own the new seed would have made it blind to every folder provisioned before today. The retired seed is now known by its SHA-256 (LEGACY_SEED_LOGO_SHA256, the same bytes as **************** - An org with a raster logo whose .svg is still the retired seed gets its stand-in, as before. - An org with no logo of its own (ext blank or svg) whose .svg is exactly the retired seed now gets the current seed, so its workspace stops wearing the retired brand. - An .svg that is not a retired seed byte for byte is never touched, and nothing moves while the seed itself is still the retired one. The backfill runs on every boot, so this takes effect on the next rollout. A second constructor exists for tests, so the Spring one is @Autowired. The whole-application context test is disabled (it needs Redis), so a Spring-built test now guards the constructor choice.

  16. · kamo-apps

    The application pages fall back to the kamouniverse.com theme host

    kamouniverse.com is now the platform's primary apex (kamocrm.com stays a fully served legacy apex). The platform's application host that actually resolves is apply.kamouniverse.com — apply.kamocrm.com has no DNS record. - Theme.tsx: PLATFORM_APEX, the theme host used before the browser knows its host, is kamouniverse.com. A page on any real host still asks theme.<its own apex>. - The support widget loads from theme.kamouniverse.com. Its loader fetches the hashed bundle relative to its own URL, and MinIO serves the identical loader under both theme hosts (verified byte-for-byte); theme.kamocrm.com keeps serving every embed that names it. - ThemeLogo's doc comment matches its real default ("Logo"). Kept: the BFF's api.kamocrm.com (the shared platform API host stays, and it is a server-to-server call).

  17. · SecurityService

    New authenticator enrollments are labelled KamoUniverse

    The otpauth issuer was the literal "KamoCRM". Only new enrollments change. An existing authenticator entry keeps its label and keeps working, because the code comes from the secret, not the label.

  18. · EmailService

    EmailService sends, links and names the platform as kamouniverse.com

    The platform's primary apex is kamouniverse.com; kamocrm.com stays served in full. What EmailService writes today now names the primary apex, and what it recognises still accepts both. Sender and fallbacks (C1, C3) - platform.mail.domain defaults to PlatformDomains.PRIMARY_APEX (k8s already set kamouniverse.com; the code default no longer disagrees with it). The NoReply audit defaults to the same. - The theme host of last resort for letter logos is **************** (theme.kamouniverse.com serves every org's folder byte-for-byte like theme.kamocrm.com). - HostTester's test-send From and MessageIds' no-domain fallback use the primary apex. - The platform organization holds both apexes; with shared-lib 0e8cf90f its preferred root (OrgPrimaryDomain -> OrgApiHosts.preferred) is kamouniverse.com, so its letters go out From NoReply@kamouniverse.com with Reply-To NoReply@kamouniverse.com — never the legacy apex. Tests updated from "the platform keeps kamocrm.com" to the primary apex, and pinned. Links (C2) - Campaign/article-share opt-out and open/click tracking links are minted on api.kamouniverse.com (k8s/configmap.yaml + application.yml). api.kamocrm.com serves the same paths, so every link already sent keeps working (GET, one-click POST and tracking verified identical on both hosts); signatures never included the host. - The article-share sign-up link is register.<primary apex>/member. Its article link stays on www.kamocrm.com: the shareable article exists only there (www.kamouniverse.com: 404). Recognition stays add-only (K4) - TrackingLinks.isOurs and the composer's opt-out exclusion recognise their base on EVERY platform apex (new util PlatformUrls), so a legacy-apex tracked or opt-out link pasted from an earlier campaign is not wrapped a second time. - The NoReply audit records NoReply@ on either platform apex, not only the configured one. - Sending domains: a tenant may not add a domain under kamouniverse.com as well as kamocrm.com **************** whole labels — notkamouniverse.com is fine). - KamoMailDomainValidator's apex list is PlatformDomains.APEXES. Brand name (C4): the user-facing outbound-host and sending-domain messages say KamoUniverse. Kept: OAuth redirect URIs on api.kamocrm.com (K1); hello.kamocrm.com, contact.kamocrm.com, unsubscribe@hello.kamocrm.com, mail.kamocrm.com (K2); Feedback-ID "campaign:kamocrm" and the kamocrm-com theme folder (K8); legacy-apex test fixtures (K7). Verified: mvn clean test against shared-lib origin/main (0e8cf90f): 2863 tests, 0 failures. The same suite on origin/main had exactly 3 failures — the tests the shared-lib primary-apex change broke (ComposeAssetUrls, the preference page's logo host, OrgPrimaryDomain) — updated here to the primary apex, with legacy-apex cases kept beside them.

  19. · kamo-internal

    The help center's source speaks as KamoUniverse

    tools/help-center/content: "KamoCRM" becomes "KamoUniverse" in 70 articles — 105 places, three of them titles (What KamoUniverse Is, How to Search Across KamoUniverse, How KamoUniverse Is Built). Slugs and file names are untouched: they are the articles' public addresses and the importer's key, and renaming one would publish a second copy. Also untouched: "KamoCRM Platform", the name of a lead market a reader finds in the dropdown, and "KamoCRM" in quotes, a vendor's name in a list. clean-source.mjs gains rebrand(), run by cleanBody after the cross-references, so rebuilding the articles from the drafts keeps the new name; "kamouniverse" joins the relation stop-words and the title casings. The live articles change only when import.mjs is run against KBService, which this commit does not do. Dry run: 307 articles, 181 cross-references, 73,432 words — as before.

  20. · kamo-internal

    The help center's source speaks as KamoUniverse

    tools/help-center/content: "KamoCRM" becomes "KamoUniverse" in 70 articles — 105 places, three of them titles (What KamoUniverse Is, How to Search Across KamoUniverse, How KamoUniverse Is Built). Slugs and file names are untouched: they are the articles' public addresses and the importer's key, and renaming one would publish a second copy. Also untouched: "KamoCRM Platform", the name of a lead market a reader finds in the dropdown, and "KamoCRM" in quotes, a vendor's name in a list. clean-source.mjs gains rebrand(), run by cleanBody after the cross-references, so rebuilding the articles from the drafts keeps the new name; "kamouniverse" joins the relation stop-words and the title casings. The live articles change only when import.mjs is run against KBService, which this commit does not do. Dry run: 307 articles, 181 cross-references, 73,432 words — as before.

  21. · kamo-internal

    Platform links on the primary apex, and the platform named KamoUniverse

    Links the app generates for the platform are built from PLATFORM_APEX, so they follow the primary apex (kamouniverse.com). Every kamocrm.com link already handed out keeps working, because both apexes serve the same thing — verified: identical ETag for the APK and the chat loader on both theme hosts, the same DAV 401 ("Kamo Calendar") on both api hosts: - the KamoMobile install QR and link, the web-chat embed snippet, the CalDAV/CardDAV server URL and SRV target, and the example values in the agreement-template and email-template editors. Where the app speaks for the platform rather than a tenant, the platform's name is KamoUniverse, held once in app/lib/platformBrand.ts: the root layout's fallback organization, the loading and /validate logo alts, the email-template editor's org-name fallbacks, the outbound-host route diagram, the bulk relay preset and the image proxy's User-Agent. The legal entity stays "KamoCRM Inc." (company line in Contact Sales, the "<org> Inc." template fallbacks). Organization creation previews KamoUniverse.com/o/<alias>, and a test holds that display form to the real apex. Contact Sales names Sales@KamoUniverse.com: kamouniverse.com mail is live and lands in the kamocrm.com mailbox (RCPT sales@kamouniverse.com answered 250; nothing was sent).

  22. · kamo-internal

    Platform links on the primary apex, and the platform named KamoUniverse

    Links the app generates for the platform are built from PLATFORM_APEX, so they follow the primary apex (kamouniverse.com). Every kamocrm.com link already handed out keeps working, because both apexes serve the same thing — verified: identical ETag for the APK and the chat loader on both theme hosts, the same DAV 401 ("Kamo Calendar") on both api hosts: - the KamoMobile install QR and link, the web-chat embed snippet, the CalDAV/CardDAV server URL and SRV target, and the example values in the agreement-template and email-template editors. Where the app speaks for the platform rather than a tenant, the platform's name is KamoUniverse, held once in app/lib/platformBrand.ts: the root layout's fallback organization, the loading and /validate logo alts, the email-template editor's org-name fallbacks, the outbound-host route diagram, the bulk relay preset and the image proxy's User-Agent. The legal entity stays "KamoCRM Inc." (company line in Contact Sales, the "<org> Inc." template fallbacks). Organization creation previews KamoUniverse.com/o/<alias>, and a test holds that display form to the real apex. Contact Sales names Sales@KamoUniverse.com: kamouniverse.com mail is live and lands in the kamocrm.com mailbox (RCPT sales@kamouniverse.com answered 250; nothing was sent).

  23. · kamo-internal

    Recognise both platform apexes wherever the app tells a platform host from a tenant's

    kamouniverse.com is now the platform's primary apex and kamocrm.com stays fully served, so every check that asks "is this one of the platform's hosts?" has to answer yes for both, by whole label: - proxy.ts: on a platform host the page's img-src names theme.<apex> and *.<apex> for EVERY platform apex. internal.kamouniverse.com (live today) blocked every stored theme.kamocrm.com picture, and internal.kamocrm.com would block the theme.kamouniverse.com URLs servers build on the primary apex. A tenant's own apex still names only itself. - networkModel.isCustomDomain, which FirstOrgCta now reuses instead of a copy: acme.kamouniverse.com read as a custom domain, so Enter opened **************** — no such host. - OrgOAuthAppSection: a callback on api.kamouniverse.com was described as the org's own domain. - LeadVendorManager: SecurityService builds apply.<primary apex> for an org without a domain, and the check only knew apply.kamocrm.com, so the platform's form read as the org's own host. - /api/org/[...domain]: the platform's client-credentials entry exists under every platform apex. - next.config allowedDevOrigins and the CSP image-host guard accept kamouniverse.com too. Built on isPlatformHost / PLATFORM_APEXES from app/lib/platformApex.ts; no new list of apexes.

  24. · kamo-internal

    Recognise both platform apexes wherever the app tells a platform host from a tenant's

    kamouniverse.com is now the platform's primary apex and kamocrm.com stays fully served, so every check that asks "is this one of the platform's hosts?" has to answer yes for both, by whole label: - proxy.ts: on a platform host the page's img-src names theme.<apex> and *.<apex> for EVERY platform apex. internal.kamouniverse.com (live today) blocked every stored theme.kamocrm.com picture, and internal.kamocrm.com would block the theme.kamouniverse.com URLs servers build on the primary apex. A tenant's own apex still names only itself. - networkModel.isCustomDomain, which FirstOrgCta now reuses instead of a copy: acme.kamouniverse.com read as a custom domain, so Enter opened **************** — no such host. - OrgOAuthAppSection: a callback on api.kamouniverse.com was described as the org's own domain. - LeadVendorManager: SecurityService builds apply.<primary apex> for an org without a domain, and the check only knew apply.kamocrm.com, so the platform's form read as the org's own host. - /api/org/[...domain]: the platform's client-credentials entry exists under every platform apex. - next.config allowedDevOrigins and the CSP image-host guard accept kamouniverse.com too. Built on isPlatformHost / PLATFORM_APEXES from app/lib/platformApex.ts; no new list of apexes.

  25. · DocsService

    The platform's careers site is careers.kamouniverse.com, and careers.kamocrm.com keeps its board

    kamouniverse.com is the platform's primary apex; kamocrm.com stays a fully served legacy apex. - careers.platform-apex (where a job advert, an applicant's receipt, a talent-alert letter and a network-board card point for an organization with no live domain of its own) now defaults to **************** in all five classes, and k8s/configmap.yaml sets it to kamouniverse.com explicitly so the running value does not wait on a rebuild. careers.kamouniverse.com serves with a valid certificate and resolves to the platform organization exactly as careers.kamocrm.com does. - CareersPublicController recognised the platform's careers site by the ONE configured apex, so moving the setting would have taken the cross-org network board away from careers.kamocrm.com (a 404, fail-closed). It now accepts careers.<every PlatformDomains apex> plus the configured one, comparing the whole apex so careers.acme.kamocrm.com and careers.evil-kamocrm.com are still refused. Tests: **************** pins both doors and the look-alikes; DocsAliasHostTest gains the kamouniverse.com cases for the aliasgroup1 change in fab3d80; the three link tests that pinned the platform-console fallback now expect internal.kamouniverse.com, which is what OrgLinkHosts answers since kamo-shared-library 0e8cf90f. mvn clean test: 848 run, 0 failures.

  26. · SecurityService

    Kamouniverse.com is the primary apex, and a domain is verified by where it resolves

    "Changed the domain from kamocrm.com to kamouniverse.com on /setup/dns. It said it set it but could not verify anything, and after a refresh it still said kamocrm.com." There were three faults. 1. The org's domain was chosen alphabetically. The platform org holds both apexes as verified roots, and kamocrm.com sorts first, so links, sign-in, Behavior & Labeling and the DNS page could never follow the brand. OrgDomains now shares shared-lib **************** which ranks the primary apex first. PLATFORM_APEX is kamouniverse.com. PlatformApexes is kamouniverse.com,kamocrm.com, primary first, and every kamo.platform.apex default reads the constant. Domainless workspaces now open on internal.kamouniverse.com from either door, and login.kamocrm.com keeps working. The domains list also returns primaryDomain and platformApexes, so the page stops re-deriving them. 2. Verification compared a CNAME's target with the literal "kamocrm.com". Every host on kamouniverse.com CNAMEs to kamouniverse.com, so all of them failed. So did an A record straight at the platform, and a CNAME chain. verifyPointsAtPlatform replaces it everywhere: verify-dns, both DomainVerificationWatcher sweeps, and the provisioning target. It follows the host through any A record or CNAME chain to its final addresses and compares them with what kamouniverse.com resolves to now. That address is read live and cached for 60s, with the last good reading kept for an hour if a read fails; it is never configured. A stray AAAA fails the check, because Let's Encrypt prefers IPv6. An unreadable platform address, NXDOMAIN or SERVFAIL are pending, never error. verify-dns returns cnameTarget and platformAddresses so the page can offer the A-record alternative. 3. "Change domain" meant deleting the domain in use. For a platform apex that is refused (409 PLATFORM_APEX, a5bcbd2); the page stops offering it. Recognition stays add-only: ApplicationChatOriginService allows apply. on both apexes, because loan-application links on kamocrm.com live on in sent emails. apply.kamocrm.com has no DNS record today, so the fallback link moving to apply.kamouniverse.com (which serves) also fixes links that were dead.

  27. · KlusterServices

    Auto-cert pre-issues analytics, desktop and myloan on kamouniverse.com

    - STATIC_DOMAINS gains analytics.kamouniverse.com, desktop.kamouniverse.com and myloan.kamouniverse.com, twins of kamocrm.com hosts that are reached only through a link. A host with no certificate never produces the access-log line the dynamic scan needs. analytics.: kamo-internal frames analytics.<its own apex>. desktop.: KamoDesktop's new route. myloan.: SecurityService PortalUrls builds https://myloan.<live root>, and the platform's live root is now kamouniverse.com. myloan has no DNS record yet; the loop skips it until the owner adds the CNAME. - ALWAYS_ALLOW_APEXES names kamouniverse.com outright next to kamocrm.com, so hosts under the primary apex stay allowed whatever STATIC_DOMAINS holds. - Comments and one log line stop calling the static list "kamocrm-specific", and the SUBDOMAINS note says the labels serve both platform apexes. The default certificate (tls-kamocrm-com) is unchanged on purpose: it is what an SNI-less client calling kamocrm.com validates against.

  28. · KlusterServices

    Serve desktop.kamouniverse.com, and bounce a bare computers.kamouniverse.com to its login

    desktop.kamouniverse.com had DNS but no route, so it answered Traefik's 404 behind the default certificate. It now serves KamoDesktop through desktop-https-kamouniverse. That route has the same four rules, priorities and middlewares as the desktop.kamocrm.com routes, uses tls: {}, and bounces a bare visit to login.kamouniverse.com. It lives in traefik/routes/ because a push to desktop/ restarts SecurityService, re-runs the Guacamole bootstrap job and re-applies the KubeVirt VM. desktop.kamocrm.com is untouched. computers.kamouniverse.com is served by the org-domain routes, and it is now where SecurityService sends the platform organization, because the platform's live root domain is kamouniverse.com. hc-to-login only recognised computers.kamocrm.com, so a bare visit showed Guacamole's password box, which can never succeed. The new hc-to-login-kamouniverse sends it to login.kamouniverse.com. Every other organization's host matches neither regex and behaves as before.

  29. · kamo-shared-library

    Kamouniverse.com is the platform's primary apex

    The brand moved from kamocrm.com to kamouniverse.com, but nothing the platform generates could follow it. Every "which of this org's domains" rule ranked by fewest labels then alphabetical, so the platform organization, which holds both apexes as verified roots, always came out as kamocrm.com. Changing the domain on /setup/dns therefore never took. PlatformDomains is now the one list: PRIMARY_APEX kamouniverse.com, LEGACY_APEX kamocrm.com, and ROOT_PREFERENCE, which ranks the primary apex first. OrgApiHosts, OrgThemeAssets and SecurityService OrgDomains share that rule. **************** the host a link falls back to for an org without a live domain of its own, is the primary apex. OrgApiHosts.PLATFORM_API_HOST deliberately stays api.kamocrm.com. The platform's OAuth apps are registered there in Google's, Microsoft's and RingCentral's consoles. Moving it needs those consoles changed first.

  30. · kamo-register

    The sign-up screens credit KamoUniverse and fall back to its apex

    kamouniverse.com is now the platform's primary apex (kamocrm.com stays a fully served legacy apex): - Theme.tsx: PLATFORM_APEX, the theme host used before the browser knows its host or on a host with no apex, is kamouniverse.com. Any real host still asks theme.<its own apex>. - RegisterFlow: the server-render placeholders for the sign-in link and the org domain are login.kamouniverse.com / kamouniverse.com. The browser replaces both with this site's own login.<apex> on mount, as before. - "Powered by / Built on / Running on" pill names KamoUniverse on every door without an apex brand of its own and links to www.kamouniverse.com (its business-OS page and product line stand in for kamocrm.com's /product and /features, which that site does not have). - ThemeLogo's default alt is a neutral "Logo" (it paints any org's logo). - The sorry page's "Contact Support" is support@kamouniverse.com: the mail stream verified kamouniverse.com inbound is live and aliased to the same mailbox. Kept: JAVA_API_BASE = api.kamocrm.com in the BFF routes. It is the shared platform API host (OrgApiHosts.PLATFORM_API_HOST stays) and a server-to-server call; api.kamouniverse.com routes identically, so moving it buys nothing. Cookie scoping and the checkout hand-off are host-derived and untouched.

Your universe is waiting.

Start free in minutes. Add products whenever you are ready — no migration, no new logins.

Free forever — no credit card required