Let a rollout finish what the old pod was doing
Deploys replaced the only pod of each service with nothing to catch the requests in flight. Three settings, applied across the fleet: - preStop sleeps 10s befo...
Change a personal address by proving it, and administer accounts
Two surfaces on the USER account, which until now had no server of its own — the account's fields were reachable only through MemberController, an endpoint scop...
Read a domain's live SPF record and say what it actually needs
GET /api/security/domains/{id}/spf, for the SPF step on /setup/dns. The setup page cannot give one set of SPF instructions to everybody, because the right inst...
A member's work address must name them without a mail provider
Forgot-password resolved the address typed on the form against two sources: the account e-mail, and the org mailbox flagged Primary on the member's settings. Th...
Name the allow-list this PUT actually goes through, and rebuild on it
Two things, one of which is the point of the commit. The comment: patchOrganization is an ALLOW-LIST and it lives in the shared library, not here. This control...
Force KamoMobile Logout — revoke a member's mobile devices
Force-logout deletes *** sessions, which ends a browser. It does NOT end a phone: KamoMobile holds a durable device token and mints a fresh *** from it the mome...
Org-side CRUD for an organization's own OAuth2 client
The org-scoped twin of PlatformOAuthClientController, behind **************** Same DTO shape, same encrypt-on-write, same never-return-a-secret rule, plus platf...
Baseline the by-host branding endpoint
**************** refused /org/public/by-host/{host}, which is exactly its job — a new mapping that resolves no session is reachable without credentials through ...
Serve an org's branding from the host it is browsed on
A white-label sign-in screen is reached at login.<customer domain> with no ?org= on the URL and nothing in sessionStorage, so the front end has no way to name t...
Send to AI now runs in a Remote Terminal the operator can watch
The dispatch prepares the hand-off on the dev machine — screenshots, video and the composed prompt written to disk — and answers with the terminal it will run i...
Seed the two careers rights onto HR's existing authoring group
MANAGE_JOB_POSTINGS and VIEW_JOB_LISTINGS are inserted as NOT_SPECIFIED like every new right, so without a seed the /hr/careers tab and the member Careers tab w...
List, rename and end a member's terminals
GET **************** DELETE and PATCH on /terminals/{id}. Every one of them resolves the Linux account from the CALLER'S OWN SESSION and passes no account name...
Only the member or god may set a member's password
MANAGE_MEMBER_SECURITY passed the change-password gate, which made "can administer members" and "can take over any member's account" the same right. They are no...
Every terminal handshake was 403 behind the edge proxy
The reported symptom was a terminal that opened and immediately said "Disconnected", with nothing to act on. Reproduced end to end: the ticket mints fine (200) ...
Assert the mask obfuscates, and skip the gate for callers with no leads
LeadFieldMaskTest still expected a null e-mail. The mask now obfuscates rather than blanks — a blank field reads as "this lead has no e-mail", which is a differ...
Serve the widened accept gate, add self-assignment, and close two contact-mask bypasses
**Endpoints for the new gate.** /leads/available-summary and /leads/available now report both reasons a member is blocked — leads owed a note since they were as...
Move the terminal IngressRoute to where something applies it
This repo's workflow applies exactly configmap.yaml, deployment.yaml and service.yaml, so a fourth manifest beside them was never applied by anything — the rout...
A refused terminal handshake answered 200
Found by probing the deployed endpoint, not by reading it. Returning false from a HandshakeInterceptor aborts the handshake but sets nothing on the response, so...
Rebuild — the last run died fetching actions/checkout
Run 5861 failed in two seconds, before any compilation: the runner could not reach data.forgejo.org to fetch actions/checkout. Nothing to do with the tree, and ...
State why the 101 is read before anything is written
The agent parses the request with a buffered reader and then pumps the raw socket, so a byte sent ahead of the status line would be stranded in that buffer and ...
Serve Remote Terminal — a real shell over a WebSocket
Bridges a browser to a PTY on the member's own dev machine. Binary frames are the terminal, text frames are control; on the far hop an HTTP 101 onto a length-pr...
Send the company alongside the contact wherever a record is labelled
A record that is both an organisation and a person is named "Harmony Home Loans (Nickolas McGarry)" — the company leads, the contact qualifies. That rule lives ...
A communications timeline over the whole /leads filter, not one lead
GET **************** takes the SAME query string GET the lead detail page draws — across every lead the filter bar matches. "What has been said to the leads I a...
Rebuild against kamo-shared-library 8dc3ea4c
Picks up entitlement-cache invalidation on comp provisioning. This service owns both halves: it approves the order and it serves the cached entitlements, so wit...
Rebuild against kamo-shared-library 31b72fe9
Picks up the draft-order reprice fix: changing a draft's seat count or billing cycle left every money field and line item describing the order's previous shape,...
Rebuild against kamo-shared-library 63827887
Picks up the comp-provisioning fix. A comped order granted its plan and none of the add-ons it sold, because provisionCompSubscription never wrote active_addon_...
Do not mail a tenant its own domain until that domain is verified
A domain typed into the create form is a CLAIM, not a host. Ownership is proven by a DNS TXT record afterwards and a certificate is issued after that, so betwee...
Stop a failed welcome email from destroying the member
MemberCreationService documented steps 4-6 as best effort, and for the emails it was not true. sendVerificationEmail is @Transactional, so it joined the member-...
Enter a tenant organization as one of its members, from /network
A second door beside the same-org god-mode one. Gated on the new IMPERSONATE platform right via @RequirePlatformRight, where the existing door is gated on the s...
Open a workspace on its OWN domain, not the host the sign-in was served from
A member who signed in on login.kamocrm.com, picked a workspace from the chooser, and landed inside it — on internal.kamocrm.com, wearing the platform's hostnam...
Rebuild against kamo-shared-library HEAD
Ships the lead contact location fix, which lives in the shared library: LeadDTO now returns the lead's own country, subdivision and timezone, so the three Prima...
Hold withTermsUnchanged to carrying every field
The method rebuilds UpdateQuoteRequest positionally, so a field added to that record and forgotten here is dropped from every save by a member without EDIT_QUOT...
Stop dropping setupFee on save, and unbreak the build
withTermsUnchanged rebuilds UpdateQuoteRequest positionally for a member who may not rewrite the terms. setupFee was added to that record and not added here, so...
Rebuild against kamo-shared-library HEAD
Ships the quote document work, all of which lives in the shared library: - a one-off setup fee on a single-price quote (commerce_quotes.setup_fee, which is a...
A share link's email was dropped twice before it could be sent
"I created a link and got no email." Two independent silent drops, both of which return a swallowed false that the panel rendered as plain success. 1. kamo.ema...
Rebuild against kamo-shared-library HEAD
Ships the quote pricing fix: a unit price is a per-month rate, so a term multiplies it rather than the engine dividing down to it. An annual option quoted one m...
Rebuild against kamo-shared-library HEAD
Ships the quote total fixes: a committed term now totals the term rather than one period of it, and a multi-option quote is no longer headlined by whichever alt...
A member address signs you into its own org, not every org
A member who signs in with the org mailbox flagged Primary on their member settings was being offered every workspace their user account belongs to. The address...
Rebuild against kamo-shared-library HEAD
Ships the quote money fixes, which live entirely in the shared library and so reach production only when this service is rebuilt: - a quote's headline total no...
Enforce the platform's visibility, and let it be edited
GET/PUT /api/security/reports/catalog, both gated on MANAGE_REPORTS on the platform spine. The list comes from the REGISTRY, not the override table: an operator...
Run the reports that are due, and send them
One internal endpoint, X-Internal-Auth gated and constant-time compared, that DaemonService ticks. The cron stays in the daemon because it is replicas: 1 with s...
The lists a share dialog picks from, and a share target that fits every id
GET **************** returns the organization's people, departments and roles as picker options, in one call and in one shape. Built on the reporting option pro...
Run, export and schedule the Report Studio's reports
The service half of the framework: the catalogue, the run, the pickers, four exporters, saved views and schedules. Authorization is explicit on every path, bec...
Pin the status-label body an org sends to drop a label
The two shapes that used to fail: an empty list, which is what clearing the last remaining label sends and what the handler rejected as malformed, and an entry ...
Accept a blank status label as the removal it is
The PUT is the org's complete set of custom labels, so it has to be able to carry an emptied box. Two things stopped it: an empty list was rejected as a malform...
Rebuild against the shared library that persists the quote contact
The market writer landed one commit after this service was last built, and CI clones kamo-shared-library at image-build time — so the deployed jar still has the...
Honour a market's contact rule wherever a quote names somebody
The staff detail, the staff preview and the customer's own page now resolve the contact through one method, so they cannot disagree about who is printed on the ...
Page and search the org directory, and stop two row builders drifting
The networks endpoints answer with the whole set in one body. That is fine for a member of a dozen orgs and impossible for an operator on an estate meant to rea...
Rebuild to pick up BillingCycle.TRIENNIAL
No source change. SecurityService clones kamo-shared-library at image-build time, and the catalog it serves is about to carry TRIENNIAL price rows. @Enumerated ...
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.
