Drop the decommissioned k2m1 cluster section
k2m1 (10.8.2.1:6443) is decommissioned and unreachable; its steps lived in the same deploy_services job and failed it (missing kubeconfig / no route) even when ...
Indent heredoc bodies so the startup.sh configmap is valid YAML
The startup.sh block scalar embedded 5 shell heredocs (rtp.conf, http.conf, an SQL block, WebRTC endpoints, freepbx.conf) whose bodies sat at column 0 — less in...
Don't let a missing kubectl cache dir kill the whole job
The kubectl-install step runs 'set -eo pipefail' then find **************** -name kubectl ... | head -1 When that cache dir is absent (cleared between runner ...
Upgrade v3.0 -> v3.3 (fix intermittent WebSocket disconnect)
v3.0.0 intermittently completes the WS 101 upgrade then closes the socket before any frame flows — the recurring 'disconnect on load' in the universe game clien...
Clone shared-lib with GIT_CLONE_TOKEN (not registry token)
The registry token authenticates to the k1m1 Docker registry (htpasswd), not to Forgejo git, so the shared-lib clone failed auth. Use the Forgejo git token like...
Point Docs deployment at k1m1 registry
The Docs-online image host was the bogus **************** (Redis DNS, never a registry), so every DocsService deploy re-applied an unpullable image. Point it at...
Drop dead deploy_k2m1 job, rebuild to k1m1 registry
kamowebsigner ran on a stale cached k0m1:5000 image, never re-pushed to the k1m1 registry after k0m1 retirement; disk-pressure eviction wiped the cache (ImagePu...
Drop offline-k2m1 deploy job + orphaned k2m1 manifests
Service ran on a stale cached k0m1:5000 image, never re-pushed to the k1m1 registry after k0m1 retirement; disk-pressure eviction wiped the cache (ImagePullBack...
Build on k1m1 — clone shared-lib from k1m1, drop k2m1, fix image host
CI cloned kamo-shared-library from the retired k0m1:3000 Forgejo, so the build failed and los-service was never pushed to the k1m1 registry; it survived on a st...
Page reflects superseded edt + road-less transport cells honestly
The Services tab read as incomplete for two stages that are actually done: - edt showed an empty 0% bar though EDT4 (hydro) supersedes the EDT2 base and the p...
Install script deps after standalone copy; bump PRISMA_VERSION to 7.6.0
The runner stage installed script deps (semver/chalk/prisma/...) BEFORE copying the Next.js standalone output. Next traces a partial, index.js-less semver into ...
Universe admin: per-shard hosted-region list + plain-message broadcast
#4 Cold-region visibility: the world beacon now carries regions_list, so each shard card in the Live tab lists the exact region addresses it hosts (not just a c...
Pin pnpm to 10.34.3 so build-script review lists are honored
Unpinned 'npm install -g pnpm' now resolves to pnpm 11.8.0, which dropped **************** in favour of allowBuilds. The repo's review lists were therefore igno...
Copy pnpm-workspace.yaml + review remaining build scripts
The deps stage only copied package.json+lockfile, so pnpm could not see the **************** review lists (they live in pnpm-workspace.yaml). With strictDepBuil...
Allow prisma build script so pnpm add does not exit non-zero
Newer pnpm fails the build with ERR_PNPM_IGNORED_BUILDS when prisma's postinstall is ignored. Only @prisma/engines was allow-listed, so every image build since ...
Universe admin: live operator actions (Phase 3)
Actions tab gains a Live operations section that drives the live game's existing gRPC admin surface, each behind a confirm dialog and recorded to a capped Redis...
Universe admin: live datastore/gateway health + worldgen run history
Live tab now consumes the new universe.gateway.health and universe.persistence.health beacons alongside universe.world.load: a datastores strip (CockroachDB quo...
Universe admin: add Live tab — real-time game shards, players & regions
New read-only platform-admin view of the running game (not just the offline worldgen pipeline). Subscribes once per process to the universe.world.load beacon ev...
Show per-stage data layers incl. EDT4 ocean mask + TRF2 markings
The worldgen dashboard's stage cards now list the data layers each tile stage bakes, accenting the newly-added ones: the EDT4 ocean (sea-connectivity) mask unde...
Fix kubectl install step (GITHUB_PATH not active in same step)
The install step verified with 'kubectl version --client' in the same step that appended its dir to GITHUB_PATH — but GITHUB_PATH only applies to later steps, s...
Drop decommissioned k2m1 deploy job
k2m1 is offline/decommissioned; the deploy_k2m1 job only ever failed and marked the whole pipeline red after k1m1 deployed fine. k1m1 is now the sole build+depl...
Lower PoW difficulty (cost 1000, counter 2000-4000)
Solve cost is the product of CHALLENGE_COST x counter range; both were over-cranked (~37.5M PBKDF2 rounds, ~40-75x a stock Capcha), making the widget slow on lo...
Surface tile staleness + targeted "Regenerate N" on the page
The agent snapshot now carries per-recipe staleness (up-to-date / stale / missing); plumb it through the API + SSE to the page: - Services tab shows a freshne...
Show the live heartbeat tile count, not the stale per-pass value
Progress read status.have first, which the initial 'running' event sets to 0 — and `0 ?? count` keeps 0, so the live count never showed (and hydro mis-counted a...
Add Universe to the settings slide-out (NavPri)
The Universe page was registered on the settings landing cards but not in the SettingsStatusWindow slide-out that NavPri actually opens, so it didn't appear und...
Universe world-generation admin page
Adds /settings/platform/universe under Platform Administration — its own platform card + three sub-tabs (Overview, Services, Actions) — to start and monitor the...
Expose GD (god eligibility) in /user-info for kamo-universe
The session stores the GD flag (KSessionService) but /user-info never returned it, so kamo-universe's KamoIdentity always deserialized is_god=false and the god/...
Don't save transactional NoReply sends to a Sent folder
NoReply is a send-only address with no mailbox, but every transactional send still attempted an IMAP append to its Sent folder, producing a noisy AUTHENTICATION...
Case-insensitive email lookup so reset emails send
Password recovery lowercased the input but findByEmailEmail does a case-sensitive match against the stored email (e.g. Sage@KamoCRM.com), so the user was never ...
Add case-insensitive findByEmailEmailIgnoreCase
Emails are stored with inconsistent case (e.g. Sage@KamoCRM.com) and CockroachDB string equality is case-sensitive, so findByEmailEmail misses on case alone. Ne...
Proxy password-reset to SecurityService internal DNS
The /api/recover proxy defaulted to api.kamocrm.com, which Traefik routes to APIService (no recover controller) → 404 → "Something went wrong" on /reset-passwor...
Move Dovecot maildirs to a local-path PVC (off rclone/MinIO FUSE)
Maildirs were on hostPath /mnt/shared-files/email/mail — the rclone FUSE mount backed by MinIO object storage, which can't safely host a maildir (no atomic rena...
Self-heal mailbox accounts from app DB (drift recovery)
The app DB is the source of truth for which mailboxes should exist; KamoMail accounts live in the mail server's virtual_users. If the mail DB loses data, mailbo...
Put MySQL datadir on a local-path PVC instead of rclone/MinIO FUSE
The mail MySQL datadir (and maildirs) were on hostPath /mnt/shared-files, an rclone FUSE mount backed by MinIO object storage, which cannot durably or consisten...
Mailbox list API returns UI-shaped ****************
GET /api/email/mailboxes returned the raw entity (providerStatus, lastSyncedAt, no member count). The settings UI reads **************** so status was always un...
Carry impersonation audit trail across org jumps
When the caller is already an impersonation session (a god admin acting as another member, carrying SUDO_MEMBER_ID), entering another org from /network minted t...
Compose/send on behalf of switched member mailbox
- Thread mailbox owner memberId from the switcher through activeMailbox into the compose context (event + URL param). - New Message / reply / forward open com...
Authorize privilege-based mailbox access for read + send-as
resolveForMailbox only granted access via a direct MemberMailbox assignment, so mailboxes surfaced through **************** rights threw NoSuchElementException ...
Stop gating pages on the *** cookie in proxy middleware
proxy.ts (Next middleware) redirected every page request with no *** cookie to /logout. Since the session id now lives in sessionStorage — which a document requ...
Stop touching cookies; send token explicitly on auth calls
Rip out all the legacy-cookie clearing/migration. The token lives in sessionStorage (key ***) and travels as the X-***-Token header, which the backend already p...
Don't adopt the legacy *** cookie; clear it instead
Right after the sessionStorage switch ships, every browser still has its old *** cookie. The migration adopted that value into sessionStorage (and the server co...
Fall back to my-networks when all-networks 403s
hasPlatformAdminAccess is derived client-side (owner-of-session-org AND host-org-is-top-level). A child-org owner whose session lands on the top-level host is m...
Carry *** in per-tab sessionStorage instead of a shared cookie
The session id lived in a browser cookie shared across all tabs of an origin, so a second tab (impersonation) could not hold its own session. Move the carrier t...
God-mode Impersonate button on member settings header
Adds a top-right 'Impersonate' action on /settings/member/[id], visible only when the signed-in session carries god mode (getIsGod) and the target isn't self/ne...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.