Skip to content
KAMOUniverse

Changelog

What's new.

Every improvement to the platform, as it ships.

  1. · kamo-internal

    The Monitoring tab, the practice monitoring queue, and the organization's remote-monitoring switch

  2. · kamo-internal

    Wire remote monitoring into the chart, the practice queue, the masthead count, the chart summary and the patients tour

  3. · DaemonService

    DaemonService ticks remote-monitoring close/no-data hourly, reconciliation every 15 minutes, alert escalation every 5

  4. · kamo-shared-library

    Iot.alarm_notice email template

  5. · kamo-shared-library

    SP06 alarm logic — ISA-18.2 state machine, escalation, suppression, schedule, flood

  6. · kamo-shared-library

    SP06 rule logic — loop maths, fingerprints, fire keys, templating, reasons

  7. · kamo-shared-library

    SP06 rule logic — solar, schedules, site days, conditions, triggers

  8. · kamo-shared-library

    SP06 vocabulary, entities and read-only repositories

    25 enums (stored by name), IotServiceJobOrigin (SP13 ships on it), 17 entities matching the SP06 DDL and their read-only repositories; IotActivityKind += AUTOMATION_ENABLED, AUTOMATION_DISABLED (SP11-D6).

  9. · MediaService

    Share-card endpoint and server-only system events (IoT SP04)

    POST **************** IoTService posts the IOT_SHARE card into a members' support ticket or Exec2Exec conversation as the sharer's system event, through the one system-event writer (now also answering the stored message id). X-Internal-Auth = IOT_INTERNAL_AUTH_SECRET (Secret iot-internal-auth, already mounted for SP01's STOMP authz), constant-time; 503 blank, 403 mismatch. A Live Support (visitor) ticket is refused 409 SESSION_TYPE; a card may not carry a key the writer owns. Every client write path now refuses text that parses as a system event with 400 SYSTEM_EVENT_RESERVED: member send, message edit (into or out of a system event), Exec2Exec post, website visitor send, bug-report comment, and forwarding (a system event is not forwardable; a forged comment is refused). A consent card must not be forgeable by a participant.

  10. · EmailService

    NoReplySubsystem.IOT, the preview sample and mirrorToPush

    IoT Devices SP06: alarm letters (iot.alarm_notice) audit under IOT; the template preview has sample values; POST /api/internal/notifications takes an optional mirrorToPush (false = bell card only, no phone push). Producers that do not send it behave exactly as before. Also maps two canonical templates the guard **************** found unattributed on main: LEADS_AVAILABLE -> LEADS, SUSPICIOUS_SIGNIN_DETECTED -> SECURITY_ALERTS.

  11. · KBService

    Internal task endpoint for IoT automations

    POST /internal/checklists/iot/tasks: one task on behalf of an automation's owner, into the assignee's Inbox (SP06 CREATE_TASK). Notes must be on, the assignee eligible; a taken proposed id tells a retried run its task exists.

  12. · kamo-internal

    Settings → Phone → Do not block, next to Do not contact

    Owner 2026-10-15: "remove it and add it to a do-not-block list". The organization's own numbers and staff lines, which the do-not-contact list never blocks and no opt-out puts on it. - New tab do-not-block (MANAGE_VOIP_SETTINGS via VOIPService, settingsMenu sub entry, no admin-bar link): suggestions of the organization's numbers, main numbers and staff lines (kinds, label, whose line, already protected or still on the do-not-contact list), each with Protect, which only opens the add dialog prefilled; channel filter (calls, texts, email, every channel), search, add with a note, remove with a required reason, and the history, where an opt-out it kept off the do-not-contact list shows as "Opt-out not recorded" with its source and what was said. Every number and address is a PhoneNumber / EmailAddress. - Do not contact: the add dialog shows the server's do-not-block refusal as written; an import names the addresses it left out because they are protected. - Keys: kamo-translation-dictionary (pushed first). Tests: DoNotBlockTab.test.tsx (5), DoNotContactTab.test.tsx (import case RED, then GREEN), settingsMenuTabCoverage (RED with the tab and no menu entry, then GREEN), the 20 source guards and check-i18n-keys --require-messages; tsc on the changed files.

  13. · EmailService

    An unsubscribe from one of the organization's own protected addresses is noted, not listed

    Owner 2026-10-15: the do-not-block list beside the do-not-contact list. DoNotContactEmailBeans declares shared-lib's DoNotBlockList and hands it to the DoNotContactList: a protected address is never suppressed by the do-not-contact list, and EmailDoNotContactMirror's add for an unsubscribe of one leaves a SKIPPED note in the do-not-block history instead. Tests: DoNotContactEmailWiringTest (new; RED: the old beans did not compile against the new shared-lib), DoNotContactSuppressionTest, EmailDoNotContactMirrorTest, DisclosureLedgerWiringTest.

  14. · kamo-shared-library

    The do-not-block list, the allowlist beside the do-not-contact list

    Owner 2026-10-15: "remove it and add it to a do-not-block list" (the company's own main line had been put on the do-not-contact list by a test call). For an organization's own numbers and staff lines, so a test call or a misheard phrase never blocks them. - DO_NOT_BLOCK (unique ORG_ID, CHANNEL, ADDRESS; CHANNEL CALL | SMS | EMAIL | ALL, ALL = a phone number's calls and texts, an address's email) and the append-only DO_NOT_BLOCK_EVENT trail (ADDED, REMOVED with its required reason, SKIPPED). - DoNotBlockList: add (idempotent; refused while the do-not-contact list holds the address on a covered channel: remove it there first, with a reason), removeById (reason of 3+ characters), protecting/isProtected, search, history, activity, entriesFor, recordSkipped. - DoNotContactList now takes the DoNotBlockList (constructor change; VOIPService, EmailService and kamoai-service declare both beans in the same push): find/isBlocked/filterBlocked never block a protected address on its channels; add() of a protected address SKIPS an automatic opt-out (VOICE_OPT_OUT, SMS_STOP, EMAIL_UNSUBSCRIBE) with a SKIPPED note and Added(null, false, keptBy), and REFUSES a person's add (MANUAL, IMPORT) with field doNotBlock and the sentence "{address} is on the do-not-block list for {channel} ({note}), so it can't be added to the do-not-contact list. Take it off Settings -> Phone -> Do not block first." DDL: voipservice **************** (applied 2026-10-18 04:16Z). Tests: DoNotBlockListTest (7, RED: did not compile on origin/main), DoNotContactListTest, **************** (both repositories' finders), SharedLibBeanSafetyTest.

  15. · VOIPService

    Settings → Phone → Do not block — the API, the suggestions, and STOP texts that skip the company's own lines

    Owner 2026-10-15: "remove it and add it to a do-not-block list". The allowlist beside the do-not-contact list, for the organization's own numbers and staff lines. - DDL **************** (DO_NOT_BLOCK, DO_NOT_BLOCK_EVENT append-only for kamo_app), applied 2026-10-18 04:16Z; re-run is a no-op. - DoNotContactBeans declares shared-lib's DoNotBlockList and hands it to the DoNotContactList (VoipRepositoryScanTest pins both repositories). - /api/voip/do-not-block (MANAGE_VOIP_SETTINGS, as the do-not-contact admin): list and search, add {channel CALL|SMS|EMAIL|ALL, address, note}, POST /{id}/remove with a required reason, history, activity (with every opt-out it kept off the list), and /suggestions: the organization's numbers, phone-server main numbers and staff lines from VOIP_NUMBER_OWNERSHIP (by ORG_ID), one row per number with what protects or lists it. Suggestions add nothing. - Do not contact: a person's add of a protected address answers 409 field doNotBlock with the list's sentence; an import names those apart (protectedAddresses). - A STOP text from a protected number is not listed (the shared list skips it and notes it); the log line says so. Tests: DoNotBlockControllerTest, DoNotBlockSuggestionsTest, DoNotContactControllerTest, VoipRepositoryScanTest (RED: did not compile against the new shared-lib), SmsKeywordServiceTest, SmsGatewayTest, **************** VoipMessageServiceKeywordTest, InternalAuthFilterKamoaiTest — 98 green.

  16. · EmailService

    Gate the RPM_ALERT kind on REVIEW_CLINICAL_RESULTS and list it after LEAD_CALLBACK

  17. · kamo-shared-library

    Sharing enums, SHARE_* activity kinds, DomainAliasType.IOT

  18. · KlusterServices

    Pre-issue iot.<apex> certificates, PDB kamowebiot, availability probe

    iot joins BROWSER_ONLY_ALIASES and STATIC_DOMAINS on both platform apexes so the first share recipient never meets a missing certificate; monitoring/ is applied by hand (see runbook, Task 34).

  19. · SecurityService

    SP12 remote-monitoring endpoints, the portal connect-devices handler and their guards

  20. · SecurityService

    SP12 enrollment, consent, pause/resume/end/revoke and the connect link

  21. · SecurityService

    SP12 remote-monitoring management time entries

  22. · SecurityService

    SP12 clinician-set limits and the alert worklist

  23. · SecurityService

    SP12 RPM billing preview and the draft-claim handoff

  24. · SecurityService

    SP12 monitoring reads, the portal link, and home readings kept out of the chart's recent window

  25. · SecurityService

    SP12 remote-monitoring foundations — write gate, access, audit, IoT client, merge hook

  26. · kamo-internal

    A run's tool calls say when the SI acted on a teammate's order, and with which of their rights

    The No Insubordination Rule (owner 2026-10-15): a tool call an SI made on a teammate's direct order carries the order's basis, the teammate and the rights they lent (kamoai-service W4 audit rows). The run drawer adds "On {name}'s order, with their rights: …" to such a call (runs.onOrderOf / onOrderOfUnnamed, dictionary e3ba7e79). Tests: RunDetailOrderLine.test.tsx (3).

  27. · MCPGatewayService

    The No Insubordination Rule — an SI carries out a teammate's direct order on their rights

    Owner 2026-10-15, refined the same day: "It should apply to any team member. But just because a team member (human or SI) has more rights, does not mean that automatically means the SI they are talking to assume their rights. It has to be a direct request or anything similar to an order. Otherwise, the SI should reinforce they do not have that level of privilege." One delegation point (OrderDelegation): for an SI's call or tool list in a run, the order is the request the SI cited, else the message or task that woke the run, verified as SP95's requests are (team chat or task only, addressed to the SI, within the hour, among the run's wakes, no outside content read), by any team member, a person or another SI (RequestVerifier.verifyOrder / inferOrderFromRun), and only when its words are an order (DirectOrder) or it is a task assigned to the SI. SecurityService then mints the SI an order-scoped *** for the run; the call runs as the same SI with that principal, so the rights check here and every downstream service see the union. A question, news or chat lends nothing, and the RIGHTS refusal then tells the SI to say plainly it lacks that level of access. - Disclosure (CP07): the run reads for the requester (OrderPrincipal), and onward sharing carries the requester's VERIFIED_REQUEST grant, judged by their own release authority. - Audit: authority_basis REQUESTED_BY_TEAM_MEMBER_ORDER, on_behalf_of_member_id, borrowed_rights (DDL **************** applied). - tools/list names the order in _meta[com.kamocrm/orderedBy] so the runtime never keeps that list. - An order-scoped session presented for any other run is no session; nothing is lent on a lent session. - Unchanged: the kill switch and pauses at the door, the charter, the risk ceiling, PHI, limits, the outreach gate and the do-not-contact list. Tests: ToolCallPipelineOrderTest (13; 9 RED without the delegation point), DirectOrderTest, OrderPrincipalTest, RequestVerifierTest (+2), CallerContextFactoryTest (+1); with ToolCallPipeline*, McpServerController*, AudienceFilter*, ReadAudience*, DisclosureGate*, *Audit*, ToolListParity*, PhonePack*, *Coverage*: 300+ green.

  28. · SecurityService

    The No Insubordination Rule — a teammate's direct order lends an SI their rights for that run

    Owner 2026-10-15, refined the same day: any team member (a person or another SI) who gives an SI a direct order lends it their rights for the work that carries it out; talking with the SI lends nothing. POST **************** (KAMOAI internal secret) mints the SI an order-scoped *** for one run: its own rights UNION the requester's, less the SI floor (AiRightsFloor) and the SI's own explicit NUKE rows, closed over the rights hierarchy. A person lends their live session rights; an SI lends its standing rights only, computed from its rows, so nothing is lent on transitively. The session is the SI's own (memberID, actorType AI), lives 15 minutes, carries a delegation block {basis REQUESTED_BY_TEAM_MEMBER_ORDER, requesterMemberId, runId, orderRef, borrowedRights}, and starts nothing a sign-in starts. The exchange's stops (kill switch, org pause, the SI's pause or retirement, an inactive membership, no supervisor) refuse it, and are read again once it exists. A rights change of the SI ends such a session instead of rewriting it. The SI's standing session never gains a right. Tests: OrderDelegationServiceTest (8), KSessionServiceIdentityTest (12), AiSessionExchangeServiceTest, AiRightsChangeListenerTest, PostAuth****: 51 green.

  29. · kamo-internal

    Settings → Phone → Do not contact, and the softphone warns before calling a listed number

    Owner 2026-10-15: one company-wide do-not-contact list per organization, scoped per channel. - Settings → Phone → Do not contact (MANAGE_VOIP_SETTINGS, settingsMenu sub entry, no admin-bar link): the call mode (warn and dial on confirm, the default, or block), channel filter, search, add, import (paste or .csv/.txt, up to 1000), remove with a required reason, and the history (every add and removal, by whom, why). - The softphone: SoftphoneContext hands every consumer a guarded dial, so every person's call (the Softphone window's Call, and every Call elsewhere, which opens it prefilled; the JustCall external dialer too) asks GET /api/voip/do-not-contact/check first. A listed number shows "{number} asked not to be called on {date}" with Cancel / Call anyway, or, when the organization blocks, OK only. Only the CALL entry counts. A check that fails dials (an SI's call fails closed in kamoai-service). - Keys: kamo-translation-dictionary 7b74200b (pushed first). Tests: DoNotContactTab.test.tsx, DoNotContactDialGuard.test.tsx, doNotContactDial.test.ts (RED on origin/main, GREEN here), settings menu coverage; the 20 source guards and check-i18n-keys --require-messages against the pushed dictionary.

  30. · kamo-internal

    SI routing shows what SIs use now — the effective model per kind of work and whether the org's order or the automatic default chose it; for speech-to-text, the model on phone calls and in meetings, streamed or per sentence, with the automatic accuracy-ranking hint

    Owner 2026-10-15: "If a model is added and enabled to the SI Providers that supports speech to text, it should use the best one." Reads AIService's effective / effectiveCalls / effectiveMeetings on each routing entry; an AIService without them shows nothing new.

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