Skip to content
KAMOUniverse

Changelog

What's new.

Every improvement to the platform, as it ships.

  1. · AIService

    The SI Assistant's voice turn for Alexa

    Voice Assistant program (2026-10-27) P3-1, P3-5. POST **************** (internal, X-Internal-Auth): the member's own assistant conversation through the same sync orchestration, with a voice style (two short spoken sentences, nothing clinical or secret), no PHI tools (EHR/health packs never, and PHI-sensitive tools in PHI organizations), risky calls held and asked as 'Shall I ...? Say yes or no.' (sends, money, security and devices need the spoken PIN before the yes is taken), a deadline after which the turn keeps running and raises SI_ASSISTANT_REPLY with phone push, 'put me through to <SI>' with that SI's own session (kamoai-service K5; paused or retired SIs refused), and 'send that to my phone'. Orchestration hooks are additive: TurnOptions on handleMessageSyncDetailed, SyncTurn.held, a tool filter on AssistantService.withTools, PlaneTool.phiSensitive from the Tool Plane's _meta.

  2. · EmailService

    Per-kind phone and voice channels, the voice mirror, and SI_ASSISTANT_REPLY

    Voice Assistant program (2026-10-27) P3-5, P4-1, P4-2, P4-4. - GET/PUT /api/notifications/channels and PUT **************** per-kind PHONE/VOICE choices (BELL always on), voice quiet hours (default 21:00-08:00 member zone), voice daily cap (default 10). - raise(): the phone push honours the PHONE choice; NotificationVoiceSender sends a passing card after commit to IoTService /api/iot/internal/voice/notify (voice quiet hours, Kamo Do Not Disturb, a running calendar event and the cap hold it unless URGENT; RPM_ALERT and SI_AUTH_REQUEST never). Titles spoken are voice-safe. - **************** and /read for 'ask Kamo Universe what's new'. - SI_ASSISTANT_REPLY belongs to no app; listed after SI_AUTH_REQUEST.

  3. · SecurityService

    Terminate an SI from its status, status counts, no deletes on /account

    - An SI's Terminated status runs the SI retire lifecycle after the rest of the save (runs stopped, phone line, seat and licence released, credential and sessions revoked, tasks handed off, history kept). Needs MANAGE_AI_WORKFORCE as Retire does, plus the status's own MANAGE_MEMBER_SECURITY; an SI never terminates itself; the workstation choice rides along. Other statuses are refused in plain SI words; a terminated SI is told plainly it can't return. - GET **************** **************** customers/status-counts: one grouped, org-bounded query each. - POST members-subscribers/status (Terminate/Activate: members.is_active only, never the user; MANAGE_MEMBERS) and customers/status (Deactivate/Activate: accounts.is_active only; EDIT_ACCOUNTS or DELETE_ACCOUNTS). - members-subscribers?include=all lists terminated members for /account. - DELETE customers/{uid} is for platform operators (open god window) only.

  4. · kamo-shared-library

    Per-kind channel choices, voice quiet hours and cap, SI_ASSISTANT_REPLY, voice activity kinds

    Voice Assistant program (2026-10-27) P3-5, P3-6, P4-1. Declares what was applied by hand: member_notification_channels (member, kind, PHONE|VOICE, enabled), **************** **************** **************** and IotActivityKind VOICE_ASSISTANT_TURN, VOICE_ALERT_SENT appended last.

  5. · kamo-internal

    Alias domain DNS records, a colleague's default alias, the real send-as address

    Settings -> Email -> Domains -> Alias domains: each domain shows whether it is ready or waiting for DNS, and a DNS records dialog lists the MX, SPF and DKIM records it needs (from EmailService), each checked live, with copy buttons. Composing as a colleague now opens on their default alias, the same rule the member's own default follows (colleagueDefaultAlias). The member tab's "Goes out as" reads the server's sendsAs instead of guessing from the first alias-domain copy, which was wrong when no alias domain is the default.

  6. · kamo-shared-library

    Declare the voice-assistant link columns and tables (personal links, last error, PINs, voice profiles)

    Columns on iot_alexa_links (last_error_code/at, pending_grant_choice, owner_kind, owner_member_id, site_id, notifications_enabled) and the tables iot_voice_org_settings, iot_voice_persons, iot_voice_pins, applied by hand from iot-service **************** so KamoInitializer can recreate them.

  7. · MCPGatewayService

    Meetings_join_external, **************** meetings_cancel_external (TPEXTMEET)

    An SI joins an outside meeting (Zoom, Teams, Meet, Webex, GoTo, any provider) from the details a teammate gave it, now or at the invitation's start, by phone. JOIN_MEETING (the identity guard holds it on unproven channels), rights VIEW_MEETINGS + ACCESS_VOIP (checked again in kamoai-service with the requester's union), only on a verified request (cited, the run's own, a confirmation, or a signed-in teammate's meeting line); never on the SI's own initiative. Passcodes and keys never come back to the model. meetings_join points outside links here. Guards: not disclosing (the call's audience is outsiders), not content, approval phrases, goldens regenerated.

  8. · kamo-internal

    Mortgage Lending reports reachable from every MLOS screen, opened already filtered

    - Report links can now pre-fill parameters: **************** (date presets or start..end ranges, comma lists for multi-selects). Only parameters the report declares are honoured; a link never widens what a member sees. - ReportQuickLinks: a work screen's Reports menu. It asks the server which reports the member may run (once per page) and offers only those, so it renders nothing for a member who can open none. - Placed on the Pipeline toolbar, HMDA LAR page, Board, Documents, Capital & Risk, Underwriting, Pricing and Governance screens; on the loan page every report opens filtered to that loan (status audit, TRID timing, conditions, documents, locks, lock events, vendor orders, SI decisions); market settings link licensing and the full configuration history (the readiness panel shows only the last six). - Governance's "Fair lending — coming soon" strip is gone: Fair Lending Outcomes is a real report now. - The Mortgage Lending shelf type and icons. Pairs with kamo-shared-library 17a7a233 and SecurityService 6ce48d17.

  9. · kamo-internal

    Administrators can edit the Administrator role, with its lock-out right pinned on

    The Administrator (Full Access) role showed as Protected and could not be opened. When the server sends lockedRights (the caller holds that role), the role opens with its rights editable and those rights shown with a lock and the reason, read-only. Branch grant/revoke now passes over forced and locked rows, as each row's own switch already did. The role's security models stay read-only.

  10. · KlusterServices

    Postfix learns alias domains from the mail database

    An organization's alias domains (Settings -> Email -> Domains) used to need virtual_alias_domains and a hand-written map edited here. EmailService now keeps an alias_domains table in mailserver (KamoMailAliasDomains), and postfix reads it: mysql-virtual-alias-domains.cf accepts the domain, and **************** delivers local@alias to local@target only when that is a real account or alias, so unknown names are refused at RCPT. Additive: the static domains and the kamouniverse.com platform map stay ahead of it. The table already exists live (created by hand and by EmailService at start); a map naming a missing table would fail every lookup, so it is also in mysql-init-configmap.yaml for a fresh database.

  11. · SecurityService

    Members holding the Administrator role can edit its rights

    PUT /api/security/roles/{id} routes the Administrator role's rights through **************** BEFORE any other write so a refused save writes nothing. Only a caller who holds that role (or has an open god window) may; CONFIGURE_SYSTEM alone is not enough. A save that would switch off CONFIGURE_SYSTEM is a 400 with a plain reason. The role reads carry lockedRights for such a caller. Security models on the role stay locked.

  12. · kamo-shared-library

    Administrators may edit the Administrator role's rights, never switching off CONFIGURE_SYSTEM

    The Administrator (Full Access) role is stored isAllowEditSecurity=false, so no one could change its rights. **************** is the one door in: it accepts only the org's role_admin_id role and refuses any save (after normalizing the level) that leaves a right in **************** short of GRANTED. That set is CONFIGURE_SYSTEM plus its ancestors: the right that opens Settings > Essential and every role write, so its holders can always come back. SecurityRoleDTO.lockedRights tells the editor which switches are pinned.

  13. · EmailService

    Alias domains receive and sign on their own; colleague and self defaults

    The mail server now learns an org's alias domains from EmailService instead of hand-edited postfix config. KamoMailAliasDomains keeps an alias_domains table in the KamoMail MySQL database (created at start; postfix reads it - see klusterservices mail/), routing local@alias to local@target where that is a real account or alias. Add/remove sync it, and a startup reconcile routes rows that predate it. Every alias domain that is not a platform host gets a DKIM key there, and EmailSmtpService.sendAsMember signs a member's mail from it with the existing DkimSigner. Platform hosts keep rspamd's keys, so kamouniverse.com mail is unchanged. GET **************** lists the MX, SPF and DKIM records the domain needs, each checked live. Also: - AliasView.sendsAs: the address a default alias actually goes out as (its copy on the org's DEFAULT alias domain, else itself) - the settings tab guessed. - /sendable marks a colleague's primary mailbox (isPrimary), so composing as them can open on their default alias. - A member may set their own default sender without MANAGE_EMAIL_ACCOUNTS.

  14. · SecurityService

    Loan officer and investor pickers for the Mortgage Lending reports, proven on the fleet's Hibernate

    - mortgageLoanOfficers: members assigned as loan officer on at least one of the organization's deals (narrower than every member, so the picker lists names that match loans). - mortgageInvestors: investor names on the organization's pricing snapshots. **************** runs all eighteen reports (kamo-shared-library 17a7a233) on THIS service's Hibernate 6.2 with no database: every statement each report builds is compiled against the real mapping, with defaults and with every parameter set, and the organization's loan query answers a synthetic loan so the follow-up queries are compiled too. The library builds on 6.5, and Java CI runs no tests, so this is the only place a 6.2 incompatibility would show before a member opened the report.

  15. · kamo-shared-library

    A Mortgage Lending shelf of eighteen audit, compliance and operations reports

    Report Studio had no mortgage reports; the MLOS had one real compliance report (the HMDA LAR page) and a set of work screens that could not filter, export or schedule. This adds a Mortgage Lending folder and eighteen reports, all organization-scoped, all gated on View Mortgage Pipeline, all with drill-through, saved views, scheduling and CSV/Excel/PDF export: - Regulatory: HMDA LAR Review, HMDA Edit Checks, Fair Lending Outcomes (screening by applicant group, four-fifths flag), Mortgage Call Report Worksheet, TRID Disclosure Timing (general vs specific business days, mailbox rule), Adverse Action Timeliness (Reg B 30 days) - Pipeline & Production: Pipeline Aging, Production & Cycle Time, Fallout & Pull-Through - Lock Desk: Rate Lock Expiration, Lock Extensions, Relocks & Breaks - Underwriting & Operations: Conditions Aging & Waivers, Document Requirements, Vendor Order Turnaround - Audit: Loan Status Change Audit, SI Decision & Override Audit, Licensing Compliance, Configuration Change Audit Framework: ReportFolder.MORTGAGE, and ReportRowFilter — a member's filter applied to finished rows, with the same operator meanings as the SQL path, for reports whose columns are calculated (days in status, deadline results). MortgageReportSupport keeps every loan read a scalar projection bounded by the organization (LoanFile -> AppMortgage -> organization), since most mortgage tables carry no organization column and entity loads fire a query per one-to-one child. Each report's help text says what it cannot see: no itemised fees (no tolerance check), no intent-to-proceed record, notices sent outside the system, unfilled LAR

  16. · kamo-shared-library

    AiExternalMeeting entity for SI joins of third-party meetings (TPEXTMEET)

    Declares ai_external_meeting (kamoai-service **************** applied) so KamoInitializer can recreate it.

  17. · AIService

    GPT-Live sessions through the relay (LIVE_AUDIO tickets), probed with a live session

    TPGPTLIVE (owner 2026-10-27, pilot). GPT-Live's primary WebSocket takes the project key only, so a LIVE_AUDIO ticket routes the org's REALTIME_AUDIO order, keeps its live models and relays wss://…/v1/live/sessions with the key added server-side (metered per second as REALTIME_AUDIO). A Realtime client secret is never minted for a live model; the REALTIME_AUDIO probe of a live model opens a GPT-Live session (session.start -> session.started -> close). The relay takes <base>/live/sessions, the LiveKit plugin's path. Name hint gpt-live-* = REALTIME_AUDIO; known model gpt-live-1.

  18. · SecurityService

    Seed the ten Mortgage calculator rights from CALC_SIMPLE

    Whoever can open the calculator today finds Calculator -> Mortgage on the boot that adds CALC_MORTGAGE_* (shared-lib 1ae01ae8); each is then granted or withdrawn on its own.

  19. · kamo-internal

    Alias domains in Settings, and on the member's mailbox tab

    Settings -> Email -> Domains gains an Alias domains card: add a verified domain, remove one, choose the default or none. The member's Email & Mailbox tab now shows the primary mailbox's addresses on each alias domain (Dylan@kamocrm.com is also Dylan@kamouniverse.com), and the add-alias form gets a domain picker so an alias can go straight onto an alias domain. The proxy no longer limits aliases to the org's single default domain; EmailService already refuses a domain the org does not hold.

  20. · EmailService

    Manage the org's alias domains, and allow aliases on them

    org_alias_domains only ever existed by hand-written SQL. New /api/email/alias-domains lists them (any member of the org) and adds, removes and sets the default (MANAGE_EMAIL_ACCOUNTS). A domain can only be added when the org has proven it holds it, and never one its mailboxes already live on. KamoMail createAlias now accepts an alias on an alias domain (sales@kamouniverse.com): the domain has no virtual_domains row, so the alias is filed under the destination mailbox's domain; postfix looks aliases up by source alone and already lists the domain in virtual_alias_domains. Also fixes AliasResponseMemberIsTextTest, which the previous commit broke by adding aliasDomainAddresses to AliasView.

  21. · kamo-internal

    Ten Mortgage calculators under Calculator → Mortgage

    Monthly Payment, Purchase Affordability, Loan Amount from Payment, Down Payment, Closing Costs Estimator, Cash to Close, DTI, LTV (with CLTV and HCLTV), Extra Payment / Early Payoff and an Amortization Schedule, each a calculator mode in its own tool window, built from one shared kit (mortgageUi.tsx): counting-up results, brand-tinted donuts, bars, gauges and balance curves, money and percent fields with sliders, inputs kept with the window, reduced motion respected. Each is gated by its own CALC_MORTGAGE_* right (shared-lib 1ae01ae8, ids 650-659). The nav groups them under a Mortgage parent; a member holding only one gets that calculator in its place. The math lives in lib/mortgage/calculatorMath.ts on top of payment.ts/affordability.ts, with tests. The calculator tour gains a Mortgage step; copy is in the dictionary (aa98d5f2).

  22. · kamo-shared-library

    Ten Mortgage calculator rights under Calculator (650-659)

    CALC_MORTGAGE_PAYMENT, _AFFORDABILITY, _LOAN_FROM_PAYMENT, _DOWN_PAYMENT, _CLOSING_COSTS, _CASH_TO_CLOSE, _DTI, _LTV, _EXTRA_PAYMENT and _AMORTIZATION: one per Mortgage calculator, ServiceType.CALCULATOR beside the nine existing modes, each a standalone root. RoleRightHierarchyTest: values 403 -> 413, standalone 79 -> 89, roots 124 -> 134.

  23. · KlusterServices

    Every meeting occupant's identity is its own verified session's (mod_kamo_presence_identity)

    TPMEETAUTH (owner order 2026-10-26): the SI's ear reads who each endpoint is from its presence identity. The stock presence_identity strips a client's own <identity> only for token sessions, so an anonymous guest.meet.Meet or a Jigasi leg could present a forged one. This MUC module strips every client identity and writes only the session's JWT context (the sidecar signs it from the member's own ***; guests carry guest-<hex>). Unit-tested in the Prosody pod (forged identity removed, token identity written). Applied 2026-10-27 04:32Z with no live conference (jicofo stats: 0 conferences, 0 participants); Jicofo and Jigasi reconnected, guests get tokens.

  24. · MCPGatewayService

    In a meeting, the line's own speaker decides authority (signed-in supervisor orders, teammate asks, guest is anyone)

    TPMEETAUTH (owner order 2026-10-26). kamoai-voice names the meeting line a call answers (X-Kamo-Meeting-Turn, never the model); MeetingTurns asks kamoai-service who said it, from that endpoint's own stream and verified identity: - SUPERVISOR (signed in, or a guest they confirmed): their order, the No Insubordination union (orderRef meet:<turn> or auth:<id>), no popup; - TEAM_MEMBER: authenticated, the identity guard lets the SI act with its OWN rights only; - NONE / unread / not matched on the speaker's stream: anyone-level. Orders are kept per line, never under the run's key, so one speaker's order never carries to the next. identity_request_confirmation in a meeting is for the line's speaker (about=meet-turn:<turn>). Tests: ToolCallPipelineMeetingTest (6), IdentityPackTest (+1); full suite 2013 green.

  25. · SecurityService

    A meeting line a signed-in supervisor said is an order the Tool Plane may lend on (meet:<turn id>)

    TPMEETAUTH (owner order 2026-10-26): in Kamo Meet a signed-in supervisor's request is their direct order (No Insubordination union). The Tool Plane verifies the line through kamoai-service's speaker attribution (each participant's own microphone) and cites it as meet:<turn id>.

  26. · kamo-internal

    Show an alias's addresses on the org's alias domains

    Under each alias on the member's Email & Mailbox tab, list the same alias on the org's alias domains, and under the default sender chip, the address it actually goes out as.

  27. · EmailService

    An alias works on every alias domain, like the primary mailbox

    The org's alias domains (org_alias_domains) already mirrored the member's primary mailbox into the composer (erik@kamocrm.com also offered as erik@kamouniverse.com) but never their aliases, so eric.white@kamocrm.com could not send as eric.white@kamouniverse.com - though postfix's platform alias map already delivers that address to the alias. Each alias now gets the same mirror rows in /sendable, which canSendAs reads, so the send path accepts them. A default alias's copy on the org's default alias domain takes the default, as the primary's does. The member alias listing returns aliasDomainAddresses so Settings can show them.

  28. · MCPGatewayService

    Anti-impersonation guard — an unverified conversation gets only what anyone may ask until the member confirms in Kamo

    Owner 2026-10-26 (TPCALLTOOLS B): someone who only CLAIMS to be a member, a supervisor or someone in authority must not get the SI to do anything harmful or that relies on that claim, even within the SI's own rights; enforced server-side. IdentityGuard (new bean, one constructor; wired by setter): for an SI's write in a run on a channel that proves nobody (call, meeting, text, unproven email, web/social chat, their follow-ups; kamoai-service /auth-requests/identity), with no standing confirmation, teammate order, verified onRequestOf or human approval, only anyone-level writes pass (internal messages, new records, tasks, notes, bookings, own bookkeeping) and replies to the conversation's own counterparty without attachments. Everything else answers IDENTITY_UNVERIFIED (audited DENIED) naming identity_request_confirmation. A failed lookup holds guarded writes. identity_request_confirmation answers the request id (a live call waits on it); an APPROVED answer marks the run confirmed so OrderDelegation lifts its kept 'no order' at once (the confirmation is then the run's order, auth:<id>, No Insubordination union rights).

  29. · kamo-internal

    Choose an alias as a member's default sender

    The member's Email & Mailbox tab gains a Default sender column on the aliases table: make one alias the default, or hand it back to the primary mailbox. The composer opens its From field on that alias wherever it would otherwise open on the member's primary mailbox: a new message, and new, reply and forward from their own inbox. A shared, secondary or colleague's mailbox is a deliberate pick and is left alone. The alias keeps the primary's send identity and signature template, as a hand-picked alias already did.

  30. · EmailService

    A member can send from an alias by default

    PUT **************** chooses which alias stands in for the member's primary mailbox (null clears it). One alias per member at most carries is_default; the column already existed and was never set. /sendable and /from-addresses now report isDefault on alias rows, which is what the composer opens its From field on.

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