Security's MANAGE_ACCESS_RULES also administers the communication policy
The owner placed the communication policy "also under Security" so an organization without the Chat app can configure it. MANAGE_CHAT_SETTINGS is a Chat-app rig...
An SI shows "typing…" through an internal endpoint, and a message's badges are recounted off the sender's request
- POST /api/media/internal/chat/typing {memberId, conversationId, typing} (KamoAI internal secret, InteractionInternalAuth; under /api/media/internal, which the...
A person asks their manager to open a chat the communication policy holds for approval, and an approval opens a 30-day contact grant (KamoCollab CP04 T14)
Session endpoints POST|GET **************** GET …/{id}, POST …/{id}/decision; the administrator's GET **************** (MANAGE_CHAT_SETTINGS). CONTACT_REQUESTED...
Declare the disclosure ledger recorder, paired with its repository scan (KamoCollab CP08 Task 12)
DisclosureLedgerConfig declares DisclosureRecorder; MediaServiceApplication's @EnableJpaRepositories gains **************** in the same commit. DisclosureLedger...
REQUIRES_APPROVAL needs a CONTACT grant, an SI may answer the person who wrote first, overrides are recorded only when they lift a refusal, and AUDIT no longer blocks attachments (KamoCollab CP04 T13)
The chat chokepoints now ask the grant-aware communication policy. A REQUIRES_APPROVAL rule refuses find-or-create and send until a live CONTACT grant links the...
The CP05 DDL file — Confidential markers on chats and meetings, forwarded-message provenance (KamoCollab CP05 T3)
Webinar registrants' leads are indexed, so their calls, texts and emails link to them
PublicWebinarService creates a lead per public webinar registrant through LeadService.createLead, which indexes the lead's phones and addresses (LEAD_CONTACT_PO...
Pin what an org with no active chat-policy set answers (KamoCollab CP00 final fix)
sp00verify's only chat-policy set is CP02 Task 6's enforced version 1, now an inactive history row. The new test pins the facts CP00 Task 12's restore rests on ...
The wiring test no longer registers the legacy chat facts repository, which shared-lib removes (KamoCollab CP02 T18)
The CI image build compiles test sources (package -DskipTests), so this test must stop naming ChatPolicyFactsRepository before shared-lib drops it. It passes ag...
Build each chat snapshot from a graph loaded now, so a lost org-graph event costs one minute, not two (KamoCollab CP02 T17)
The chat policy snapshot is itself a 60 s cache of member facts. Built from OrgGraphCache.get, it could start from a graph already up to 60 s old and keep it fo...
The internal DM path goes through chat policy and the AI turn guard, and every chat line says who wrote it (KamoCollab CP00 T7)
POST **************** now requires source MEMBER or SYSTEM (else 400 SOURCE_REQUIRED). A MEMBER line is checked by chat policy as a member's own send (open-then...
MediaService caches the org graph, reads chat policy facts from it, and the managed tracking scope is the whole subtree (KamoCollab CP02 T17)
MediaService declares the org graph loader and its 60 s cache, and a listener on security.orggraph.changed.* that evicts the graph and then the chat policy snap...
The DDL for media_objs.source, who wrote a chat line (KamoCollab CP00 T1)
A nullable VARCHAR(16) column, re-runnable, with no CHECK and no backfill; NULL reads as MEMBER. Hand-applied by CP00 Task 3. **************** keeps the file ad...
The meeting page link is on the organization's console, chosen by OrgLinkHosts
MeetLinks.meetingPage read the console host off the Kamo Meet join URL: meet.<domain> became internal.<domain>. The join URL names whichever host the room's cre...
A reply may quote only a message in its own conversation
The member chat send resolved the client's parentId with a bare lookup by id and built the reply quote from whatever it found: the parent's text, its author's n...
A lender's website contact form files a ticket in their own queue
POST /api/media/public-chat/contact, reached through the gateway's site-key gate like every other public-chat call, so the key names the org and its allowed ori...
Trim the mirrored-alias check, and stop it forcing a lazy load per member
Review findings on the AI-full-name fix (4ea53c5): - LOW: the mirrored-username comparison didn't trim either side, so an alias saved with stray whitespace (...
An AI member's chat name is the full name, same as a human's
**************** trusted Member.usernameAlias over the account's own full name whenever the alias was non-blank. MemberCreationService mirrors the account's use...
The missed-message sweep reads the recipient's link hosts before its transaction
SP98-D-9. prepareSend read the recipient organization's domain rows lazily, as a late statement of the sweep's transaction, to choose the letter's console host;...
A turn-only fan-out reads no roster, ticket id or conversation title
SP98-D-6. ChatFanoutService.prepare resolved the roster, the support ticket's id and the conversation's title for every request, including the turn-only ones (a...
Chat cards queue boundedly, give up on a hung EmailService in seconds, and never double a mention
SP98-D-7: ChatNoticeDispatcher ran on two threads with an unbounded queue while MemberNotificationClient waited up to 5 s + 30 s (the letter client's chat.email...
A send looks up its AI turn limit and its sender's photo before its transaction opens
SP98-D-5 and D-9. A chat send asked SecurityService for an AI member's charter limit (up to 1 s + 2 s) inside the open send transaction, and read the sender org...
A recording's action item is never due before its meeting
Live (SP14 Task 31, Step 9), a recording made on 2026-09-28 said 'by October second' and the model wrote 'due 2024-10-02' into the summary emailed to the partic...
A stored recording is transcribed, under the id it was saved with
MeetingRecording.id is @GeneratedValue, so save() of the entity whose id ingest had set by hand merged it and the row got an id of its own. The pipeline was han...
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 co...
The bridge dials the room Meet uses; an AI joins a future meeting at its start; an AI that heard nobody is dialled again
- The dial-in resolver (I1), KM2's roomName and M1's join.roomName name the room Meet uses (the Kamo Meet provider's own room, else the typed name cleaned the...
OAuth return URLs accept both platform consoles; webinar cancel links keep the page that exists
kamouniverse.com is now the platform's primary apex (kamo-shared-library 0e8cf90f): OrgLinkHosts falls back to it, and ROOT_PREFERENCE makes it the platform org...
The viewer's theme host is read before the transaction, never inside it
The Exec2Exec roster, its participant list and every conversation's faces read the viewer's organization's domains lazily, as a late statement of a read-only tr...
A group chat of two AI members with identical columns holds both (SP10)
SP10 T47, live: chat_find_or_create_dm for the owner, Ava and Ben answered 400 "one or more memberIds not found": TeamMember's value equality kept one of the tw...
Relay media.feed.<orgId> to /topic/media/feed/<orgId>, guarded by org
A new post or lead note is announced on media.feed.<orgId>, and kamo-internal's MediaStream (a lead's Notes, the Clubhouse feed) listens on /topic/media/feed/<o...
An AI invite settles the caller's authority before it looks at the target
invite() answered 409 NOT_AN_ACTIVE_AI_MEMBER before 403 NOT_ALLOWED_TO_INVITE, so a member who could reach M1 but not invite could tell an active AI's member i...
An impersonating admin may not set the member's status text
PUT /api/media/presence/status accepted a sudo session. It is now refused 403: unlike the heartbeat, which nobody chose to send and is ignored quietly, setting ...
A session type without its own gate takes no messages, and a session is described only to its readers
POST **************** authorized CHAT, SUPPORT_TICKET and SOCIAL and then simply ended, so a POST, SYSTEM_BUG or EXEC2EXEC session fell through every gate: any ...
Another org's agent, topic or AI member is a 400 naming the field
The sales agent and support topic checks threw a bare IllegalArgumentException that nothing caught, so saving one the org does not own answered 500. They, and t...
One call per AI per meeting — a dial is claimed before kamoai-service is asked
Two overlapping requests to dial the same AI into the same meeting (a double click, two organizers, a person and the auto-join sweep) could each pass the not-li...
AI members join meetings — invite, auto-join at start, runtime state, companion context
Meeting history, meeting detail with dial-in and transcripts, inviteable AI members
M3 GET /api/meet/ai-candidates, M4 GET /api/meet/meetings, M5 GET /api/meet/meetings/{id} (spec §4.4.1). Every answer is application/json; a page never splits m...
Recording transcripts and summaries persisted, routed through the org's AI services with provenance
A transcript download answers 409 NOT_READY while the transcript is still being written
M7's errors are M6's plus INVALID_FORMAT (spec 4.4.1). A PENDING or TRANSCRIBING transcript answered 200 with an empty body for vtt and txt; it now answers 409 ...
Encrypted meeting transcripts and summaries, companion upload, downloads, retention
M6-M9 answer JSON whatever the client accepts and ignore unknown body fields (MediaService's bare ObjectMapper fails on them); M6 is NOT_READY while a transcrip...
The roster, participants, history and send survive a database conflict too
Completes 279a389. After it shipped, production logged the same YugabyteDB 40001 "Restart read required" on Exec2Exec's roster (09-27 16:00Z, and three times ea...
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.
