Require an open god-mode window, not eligibility alone, for CONFIGURE_SYSTEM
hasRight was granting the bypass on the raw GD session flag, which SessionPlatformFacts's own javadoc names as the exact anti-pattern it exists to prevent: GD i...
Gate the web-alias path on parent context, not model alone
withBranchType previously turned useWebAlias on whenever the SELECTED MODEL allowed ROOT or a custom alias, ignoring the three parent-org preconditions BasicsSt...
Getting Started wizard step model and client
Adds the client-side step model (app/lib/orgSetupWizard.ts), a thin API client for GET/PUT/DELETE /api/security/org-setup-wizard (app/lib/orgSetupWizardApi.ts),...
Add progress service and endpoints behind the Getting Started wizard
Org-scoped GET/PUT/DELETE under /api/security/org-setup-wizard track which of the nine Getting Started steps an organization has completed. A read never creates...
The maximized pane zooms into the conversation you picked
Switching conversations in the maximized view was an 8px nudge and a 180ms fade — close enough to nothing that the pane looked like it had simply repainted. It ...
Three-column widgets and per-widget minimum sizes
Widens WidgetWidth to 1 | 2 | 3 | 'full' and lets a WidgetDefinition declare minWidth/minHeight. widgetMinSize(definition) converts that into a PaneSize floor (...
Touch up a traced logo by hand, and download the converted file
Four things on the raster-to-vector converter and the simple logo slot. **The scroll bar on the raster options is three times wider.** 4px was a hard target to...
Stop treating an already-transparent background as black, and remove the region not the colour
Two reported faults with one root cause: colour-based removal overwrote the alpha channel outright and never read the incoming one. An HTML canvas stores premu...
One-page field set and the defaults that replace the dropped steps
CreateOrgFields is what the new single-page /network/create form actually asks for: a branch type, name, alias, the app switches, and a handful of optional fiel...
Create My Free Org widget rights and Getting Started wizard progress
Adds RoleRightType 288-292 (CREATE_FREE_ORG_WIDGET and its four ADDED/OPTIONAL/ REQUIRED/MOVABLE policy children), hung off CREATE_CHILD_ORG (131). Adds OrgSetu...
Per-pane minimum size, applied on read as well as on drag
Threads an optional `min?: PaneSize | null` through clampPaneSize, the two resize-delta helpers, and the two preference read/write functions in the pure launchp...
Switching conversations no longer stacks windows behind the maximized pane
Takes @kamo/tool-core 0.1.5, where leaving the maximized pane became two gestures instead of one. A navigator row click hands the pane to another conversation a...
Restore the verification screen's wallpaper, drop its ***, modernise its status plate
Three things wrong with /verification, all visible on one screen. The wallpaper never loaded. PostCompletionScreen called **************** but that parameter i...
Put a real time budget on resend-verification
The endpoint had no limit of any kind. The *** the register screen demanded before enabling its resend button was never read here — the request body is three fi...
Give the new tab a session, instead of one that bounces to login
"Open in new tab" was `window.open(location.href, '_blank', 'noopener,noreferrer')`. The session id is not in a cookie — it lives in sessionStorage, per tab, be...
Let a seeded org omit its year established
createOrg took the year as a primitive int, so every seed had to supply one even though YEAR_EST is nullable and the field is optional platform-wide. Integer, s...
Record that Organization.YEAR_EST is optional and may be cleared
The column was always nullable and both server paths already handled null — CreateOrganizationPayloadParser maps an empty or unparseable value to null, and patc...
YearEst is optional on the org, so admit the null that arrives
Year established is nullable on the Organization entity and SecurityService serializes the null explicitly, so the declared `number` was never the whole wire sh...
The org's year established is optional, and unset renders as absent
Nothing on the server ever required it — the column is nullable, the create parser maps an empty value to null, and patchOrganization applies only the keys a PU...
A conversation outlives the window showing it
Opening a chat window cost seven requests before a message rendered — history, members, receipts, mark-read, the unread snapshot, the counterpart's avatar and t...
Show a member only the tabs that are theirs to see
Three member-settings surfaces were open to people they cannot mean anything for. Each gate is on the MEMBER TYPE or the org's apps, never on checkRight — check...
KB audience tiers are cumulative, matching KbReaderScope
The retrieval filter matched a reader's tier exactly: a TEAM_MEMBER had to match aiVisibleToTeamMembers and nothing else. So an article an author had deliberate...
Serve a reopened window only what it missed, and audit a page in one write
Two costs, both paid on every single open of a chat window. ?since on GET /sessions/{guid}/messages. A window being reopened wants the messages after the one i...
Centre the launchpad tiles that are only an icon and a name
A leaf app pane in its compact form shows no sub-item rows and no description, so the icon/title row was heading a column with nothing in it — pinned to the top...
Offer a member only the kinds they can receive
The notification centre and its settings drew every kind to everybody. A member with no Leads app was shown a "Lead callback" filter that could only ever return...
A member is only told about apps they have
A notification kind belongs to an app — a lead callback is Leads, a meeting reminder is Meetings — but raise() asked only whether the member had muted it. So a ...
The console shows a reader what they may have, and no more
Two things the /kb page reported to anyone holding VIEW_KB_ARTICLES. The corpus. The audience chips an author ticks in the composer — Members, Team Members, Pu...
Enforce the audience chips on every human read
The composer has always offered an author three chips under "Visible to" — Members, Team Members, Public. They were written to the row and indexed into Qdrant s...
Restore the image-proxy and wallpaper work 266357d0 reverted, and land the permissions change it was meant to carry
266357d0 was built with the wrong index. Its tree came from a stale local HEAD rather than from the staged one, so it carried none of the permissions work its m...
A group per app, a console to grant them, and master notes as widgets
Three changes that turned out to be one. THE HOME PAGE. "My Master Note" and "Our Master Note" were bespoke panes rendered straight out of page.tsx, gated on n...
GET /master takes VIEW_NOTES, like every other read here
It was the one read in this controller that took no right, deliberately: the two master notes were called fixtures of the home launchpad rather than the Notes a...
Delete /api/auto-login, which no longer has a caller
The endpoint existed to turn an existing *** cookie into an OTK and a redirect so the login page could forward a signed-in member straight into their workspace....
Seed the master-note widgets from VIEW_NOTES
The two master-note panes shipped with no right at all — "My Master Note" and "Our Master Note" were on every member's launchpad unconditionally — and this is t...
A security group per app, and the master notes as widgets
Ten new rights, 278-287: NOTES_MASTER_MINE_WIDGET and NOTES_MASTER_OURS_WIDGET, each with the four policy children every home widget carries. Both hang off VIEW...
Swap the voicemail greeting to KamoCRM-LeaveVM
24.9s, down from 27.9s. Uploaded alongside the previous recording rather than over it, so rolling back is a one-line change to KAMO_VOICEMAIL_GREETING plus a di...
The invoice takes REVOKE DELETE, not REVOKE UPDATE
attachPdf writes PDF_BLOB_ID after the finalize transaction commits, on purpose: rendering inside it would hold the document-counter row lock across a MinIO rou...
Let a signed-in member reach the sign-in form, and back out of the workspace picker
Two halves of the same problem: the login page was a one-way street. It validated any existing *** cookie on load and, when the session was still good, redirec...
Stop force-cache pinning "this org has no wallpapers" forever
The console backdrop and the member Wallpaper editor both read the tenant's `config.json` for `backgroundImageCount`, and both asked for it with `cache: 'force-...
The grid fetched every page twice, then blanked itself to do it
Opening /leads showed the rows, dropped back to a loading state, and showed them again. It was fetching twice. STOMP raises onConnect on the INITIAL connect ex...
The credit note, the only correction path for a finalized invoice
B3: Kamo owns everything before finalize() and the provider owns everything after, and every provider on the roadmap treats a finalized invoice as immutable. So...
The document counter, and a number that cannot fork
Every existing document number on this platform is a check-then-insert race with no unique constraint behind it: quote numbers are COUNT(...)+1, subscription in...
The invoice entity, with every tax field and no tax engine
Kamo's own invoice, written only by InvoicingService. Nothing on it is supplied by a caller: every figure is derived from the lines on every write, which is the...
Stop the image proxy serving an hour-old copy of another org's branding
Theme asset URLs are stable and say nothing about their contents: an org's simple logo is always `<alias>/img/logo.svg`. Every org is also seeded with the base ...
Make seeded and uploaded branding revalidate, so an org stops being served the base theme it was seeded with
A new organization is seeded with the base theme — the platform's own logo and backgrounds copied to the new org's keys — and those keys never change when the o...
Plans for BL2 (the KAMO_NATIVE invoice) and SW8 (in-home contract compliance)
Choose the KamoDesktop resolution, and stop hiding why a launch failed
The remote desktop tracks the browser window and always has, so there was no way to have MORE desktop than window. A picker now sets a fixed size, stored per br...
Let the caller choose a fixed KamoDesktop resolution
The remote desktop was never locked to a resolution — it tracks the browser window, and always has. guacd honours the client's size and xorgxrdp resizes the X s...
Check in the useUserInfo shared-store handoff
The "no .md in repos" rule is retired. This handoff doc had been kept local-only; it belongs next to the code it describes.
Stop ignoring markdown
The "no .md in repos" rule is retired; docs, plans and READMEs are tracked like any other source file.
Je, unaona nini kuhusu usafiri?
Kila moja ya hizi updates ardhi katika nafasi yako ya kazi moja kwa moja. Kuanza bure na kuangalia kukua wiki baada ya wiki.