Scrub copies of live credentials from config and dumps
A sweep of every repo for the values of the cluster's live Secrets (2026-09-23) found copies here: the JWT signing secret as a `${JWT_SECRET:<literal>}` default...
Liveness probe on /actuator/health/liveness, not the DB-aware aggregate
The aggregate /actuator/health includes the DataSource indicator, so restarting the database failed liveness on every pod at once and restarted the whole platfo...
Release idle Hikari connections now that YSQL pooling is shared
The connection manager no longer pins sessions **************** so idle app connections no longer each hold a database backend. Keep the pool maximum, but stop ...
Accept OCI image indexes when resolving the built digest [skip ci]
The images are pushed as OCI image indexes, so asking the registry for a single image manifest only answered 404, the digest came back empty and the check faile...
Restart when a same-commit rebuild leaves pods on the old digest [skip ci]
The rollout step tried to detect a same-commit rebuild by comparing the Deployment's image reference before and after `set image`. "Apply manifests" has already...
Prove the deploy by digest, not by tag
The preceding commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and th...
A rebuild of the same commit deployed nothing and reported success
The image is tagged with the commit SHA, so rebuilding the same commit produces an identical image reference. `kubectl set image` then changes nothing, the Depl...
Lock every cron job that moves money, and run two pods
KamoLOS ran one pod and its ten cron jobs were correct only because of it. There is no ShedLock anywhere on this platform, so a second replica would have run ea...
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...
Pin kamo-shared-library 1.6.0
The library moved to 1.6.0 while every consumer stayed on 1.5.0. Consumer CI builds the library from a fresh clone into a cold ~/.m2 and ci-settings.xml mirrors...
Size the pod above its own JVM heap ceiling [skip ci]
The image starts the JVM with -XX:MaxRAMPercentage=70 -XX:+AlwaysPreTouch, so the heap alone may take 70% of the container limit and pre-touch keeps every commi...
Enable ProxyHmacFilter — step 2, X-Org-Id is now a proven header
los.proxy-hmac.enabled has been falling through to its false default since this service deployed, so ProxyHmacFilter existed and never ran. X-Org-Id — the heade...
Scope statements, draws and payments to the caller's organization
Same bug as LoanController.get(uid), repeated: these controllers took a loan id off the path and handed it to a repository, so GET /api/los/statements/by-loan/4...
A loan id is not a credential — scope every LoanController read to the org
LoanController.get(uid) took a loan id and returned whatever it found. Any caller who reached the service got the loan, balances and borrower included, whicheve...
Rebuild against shared-library @Lob LONGVARCHAR fix
Hibernate's PostgreSQL dialect read @Lob String columns as OIDs via getLong(). Affects notes, contacts, calendar, OAuth tokens, IMAP passwords, email campaign b...
Point at YugabyteDB and use PostgreSQLDialect
CockroachDB has been replaced by YugabyteDB. Connection strings move from cockroachdb-public:26257 to yb-tserver-service:5433, and the Hibernate dialect from **...
Retry the shared-library build, which the LAN uplink keeps corrupting
Three builds died today on "Tag mismatch" pulling a jar — and the mirror added an hour ago did not help, because kbservice, mcpgatewayservice and ragservice hit...
Mirror Maven Central through the Google GCS copy
Every Docker stage starts from a cold ~/.m2 and refetches the whole dependency tree, so Central sees the full weight of every concurrent service build. It answe...
Declare security matchers explicitly before the next build breaks startup
kamo-shared-library 1.5.0 was republished today with spring-ws-core as a new transitive dependency, so Spring Boot now auto-registers a second servlet (MessageD...
Harden the kubectl download against flaky egress [skip ci]
dl.k8s.io over the runner's egress intermittently drops mid-transfer: curl: (56) OpenSSL SSL_read: decryption failed or bad record mac which fails the deploy ...
Fix kubectl-cache find aborting under set -e + point at unified cluster
- CACHED_KUBECTL=$(find ... | head -1) aborted deploy_k1m1 under set -e/pipefail when the runner .cache/act dir is absent (never reached the curl-install fall...
Remove MLOS event-backbone wiring — KamoLOS is the personal-loans LOS, not MLOS
MLOS (mortgage) work must not touch KamoLOS (personal loans). The shared-lib com.kamo.z.shared.mlos.* substrate stays (generic, gated mlos.outbox.enabled=off); ...
Adopt MLOS transactional outbox (producer path)
Enables the Phase-0 event backbone in KamoLOS: adds com.kamo.z.shared.mlos.event to the @EnableJpaRepositories scan, mlos.* config (mlos.outbox.enabled=true, ML...
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...
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...
Per-offer overrides for rate, APR, and origination fee
LoanOfferCreateRequest gains three optional fields — interestRateBpsOverride, aprBpsOverride, originationFeeAmountOverride. createDraft applies them when set an...
Default empty STRIPE_CONNECT_WEBHOOK_SECRET so KamoLOS boots
The configmap referenced **************** without a default, so Spring's placeholder resolver threw before reaching the Java-level **************** which alread...
Track shared-lib LoanRepository → PersonalLoanRepository rename
Updates every import and field type from LoanRepository to PersonalLoanRepository across 20 KamoLOS source files + 1 test (Lombok-injected field names stay as l...
Tier 6+7+9+10 — frontend polish, org reports, OpenAPI, JaCoCo
T6 (frontend polish): - New /lib/format.ts: locale-aware formatCurrency / formatDate / formatDateTime / formatPercentBps via Intl APIs (replaces hardcoded t...
Tier 4 — LoanPaymentPostingService unit tests
Six mocked-repository unit tests covering the heart of the payment posting: - **************** payment of $100 against loan with $25 fees / $50 interest / la...
Tier 5 compliance batch
- OfacSanctionsService: Jaro-Winkler fuzzy match @ ≥0.92 after exact-match pass. Hits surface similarity score. Configurable via los.ofac.fuzzy-threshold. - A...
Tier 3 security + Tier 8 bug cleanup batch
T3 — Security: - New RateLimitFilter (Bucket4j): 1000/min per IP for webhooks, 10/min per session for offer accept/decoder/rescind, 60/min general. Register...
Tier 2 — Hikari + RestTemplate timeouts + Stripe SDK + Redis cache
- RestClientConfig: single shared RestTemplate bean with 5s connect / 30s read timeouts. MediaServiceClient / NotificationDispatchService / OfacSanctionsSer...
Tier 1 critical correctness pass
T1.1 Stripe disbursement strategy: TREASURY (stub — requires SDK upgrade or raw HTTP) / CONNECTED_ACCOUNT (Transfer.create — works in SDK 28.2.0) / MA...
Final batch — compliance, packets, adjustments, Grafana, tests
Compliance: - MlaCheckService — Military Lending Act covered-borrower lookup against DoD MDC single-record query. Returns NotCovered if unconfigured so dev ...
P2 batch — observability, tests, year-end tax, real Stripe IDs
Observability: - micrometer-registry-prometheus on the classpath - /actuator/prometheus exposed via management config (both local + k8s configmap) - LoanMetrics...
P1 batch — webhooks advance state, crons, commerce vertical
Money movement (the core P1): - LoanPaymentPostingService: markSucceededAndPost / markFailed / markReturnedAndReverse / markDisbursementSucceeded / markDrawDi...
P0 hardening — Stripe Connect endpoint + PDF flatten
- Fix EsignClient imports: EsignGenericEnvelopeRepository / EsignSignatureRepository live in .esign.repos, not .esign root - New StripeConnectController POST ...
Initial personal-loan origination + servicing service
New Spring Boot 3.1.5 / Java 21 microservice modeled on BillingService. Owns personal-loan domain end-to-end: - LoanProduct / LoanOffer / Loan CRUD with REST +...
Hide isActive=false programs from borrowers in real time
useProgramCatalog now filters out programs with isActive=false before returning them to the loan wizard. The flag is computed server-side as (base.isActive AND ...
Drive journey sky from SkyToggle, unstack from personality chip
- Move SkyToggle to its own top-right row at top-14 so the slider stops overlapping LoGuideChip, which is positioned at right-14 assuming it only needs to c...
Scrubbable day↔night theme with sun-moon SkyToggle
- Continuous t ∈ [0,1] scene position drives ~25 CSS custom properties on :root via linear RGB interpolation between warm-paper day and aurora night anchors...
Expose engagement/intent/commitment UIDs
AppMortgageDTO now carries the commerce-lifecycle identifiers that the SecurityService backend populates on every mortgage application. KamoLOS doesn't actively...
Lift home CTA cluster above the LenderFooter
Buttons at bottom-12/sm:bottom-14 were clipped by the lender attribution footer (~76px tall on desktop). Bumped offsets so the cluster clears it.
Glimmer the test banner, fit the viewport, add cookie consent
- TestModeBanner publishes its height to --kamolos-banner-h and globals.css subtracts it from min-h-screen so the home view no longer overflows the viewport...
Surface SAFE Act NMLS IDs for lender + assigned LO
Adds LoContactCard with avatar, presence pulse, verified NMLS link, and call/email/message actions in the top-left of hero and apply surfaces, so the borrower's...
Stop personality chip overlapping the SoundToggle
LoGuideChip was absolutely positioned at top-3/right-3 in JourneyHero and JourneyApplyLayout, the same spot as the global SoundToggle in app/layout.tsx. Shifted...
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.
