## kodustech/kodus-ai — web-1.2.2…web-1.2.3

_177+ commits._

### Features
- **feat(preview): bake the preview base image nightly from main** (f0b0bed)
- **feat(preview): render .env from the template, then strip every credential** (3d232cd)
- **feat(preview): one full-stack preview environment per PR, on runo** (e9587ca)
- **feat: send the billing service token; charges journal is Billing-gated** (3f59a24)
- **feat(kodus-provider): env allow-list ahead of the PostHog flag (dev/e2e, PostHog-down fallback)** (d15586a)
- **feat(kodus-provider): private alpha behind the kodus-provider feature flag** (8d8c982)
- **feat(web): Kodus credits UX — first funding, discovery, auto top-up, tariff on rows** (a6a8e0e)
- **feat(kodus-provider): curate the catalog to Fireworks-hosted open models** (89f7821)
- **feat(web): drop the navbar credits chip; hint the balance on the BYOK menu entry** (724997b)
- **feat(web): fold the Kodus credits wallet into the provider card, drop the Credits tab** (4bc88ad)
- **feat(web): move the Kodus credits wallet next to the provider it funds** (b4126aa)
- **feat(credits): shared platform limiter, catalog price-drift check, e2e contract** (8c3ec8c)
- **feat(credits): balance, top-up and ledger UI for Kodus credits** (8af50fd)
- **feat(credits): gate, meter and debit Kodus-routed usage against prepaid credits** (6af3948)
- **feat(byok): add Kodus as a keyless BYOK provider routed over platform accounts** (c683361)
- **feat(kody-rules): scope a rule by file extension, compound suffixes included** (90ac4a2)
- **feat(kody-rules): give the context-need classifier a test, not a description** (a88e8ba)
- **feat(kody-rules): let a rule declare it needs the rest of its file** (830d57b)

### Fixes
- **Merge pull request #1919 from kodustech/fix/sso-e2e-ci-droplet-namespace** (fda99f1)
- **fix(e2e): include GITHUB_RUN_ATTEMPT in the CI droplet name** (ca7045c)
- **fix(e2e): derive the CI droplet name per-run to close a CI-vs-CI collision** (89fcb45)
- **fix(e2e): give CI its own SSO droplet name so it never collides with local debugging** (656610e)
- **Downgrade unusable fixes instead of dropping** — Code review suggestions with invalid proposed fixes are now published as plain comments rather than being discarded entirely. This ensures users still see the feedback, just without the code suggestion block. (8759b39)
- **Fix SAML API URL configuration** — Updated the API URL resolution to prioritize the public API_URL environment variable over the internal cluster proxy host, ensuring SAML callbacks and browser-facing API calls use the correct public origin. The change includes comprehensive tests to verify the correct fallback behavior when API_URL is not configured. (11f5223)
- **fix(code-review): downgrade suggestions with unusable improvedCode instead of dropping them** (5f3e5cd)
- **fix(web): prefer API_URL for browser-facing API origin in getApiPublicUrl (#1903)** (beaff45)
- **fix(preview): say so when the signing seed is missing** (6472932)
- **fix(preview): separate the signing seed from the shared login password** (de6f676)
- **fix(preview): address the review — stable secrets, honest teardown, no baked .env** (1d7f506)
- **fix(preview): leave the datastore URLs empty, as a developer's .env does** (2ab22a4)
- **fix(preview): let the vault render speak for itself under a service account** (7733428)
- **fix(preview): pass the branch to runo push as well** (317633b)
- **fix(preview): skip quietly when the preview secrets are absent** (f72a1cc)
- **Delete requests now sign their body** — Fixed billing signature generation for DELETE requests to sign the actual request body instead of always signing an empty string. This ensures DELETE requests with a body are properly authenticated by the billing service, while requests without a body continue to sign the empty string. (9826f73)
- **fix(e2e): treat a null body like no body when signing** (5ac7633)
- **fix(credits): sign a DELETE body instead of zeroing it** (251f550)
- **fix(credits): never downgrade to unsigned in silence** (0202129)
- **fix(credits): derive signability from the serialization, not a prediction** (b6d8745)
- **fix(credits): decide signability by exclusion, not by prototype** (b19ee86)
- **fix(credits): never sign a body the request will not send** (5ffec70)
- **fix(credits): sign the whole wire request, not most of it** (f238248)
- **fix(e2e): sign the billing URL the harness actually requests** (d3af665)
- **fix(credits): sign the query and a timestamp on billing's money routes** (dd0e5ac)
- **fix(e2e): never send the billing service secret to the Kodus API** (c09c231)
- **Merge pull request #1905 from kodustech/hotfix/kody-rules-editor-cursor** (7c905d7)
- **Merge pull request #1904 from kodustech/fix/bedrock-byok-connection-listing** (b9799d3)
- **fix(byok): treat an empty Bedrock outputModalities array as unknown, not non-TEXT** (8b189a7)
- **fix(byok): filter Bedrock listing to TEXT models, stop over-triggering strict mode** (e79b3f1)
- **fix(web): restore Kody Rules / Custom Prompts rich-text editing** (6e022a8)
- **fix(byok): let a fresh Bedrock connect live-list every model, not just Anthropic** (5ffba08)
- **fix(byok): encrypt Bedrock aws* credentials before probing the connection** (dbc8e3c)
- **Merge pull request #1900 from kodustech/fix/1880-opencode-go-session-header** (5095c7b)
- **fix(llm): match on host only, aligned with jcode's own validated fix for #1167** (de8c679)
- **fix(llm): anchor OpenCode Go detection to the URL authority, not a substring scan** (043a126)
- **fix(llm): revert the /go narrowing — real prod orgs are on bare opencode.ai/zen/v1** (1b21359)
- **fix(llm): scope the OpenCode Go URL match to /go specifically, add brand-composition test** (56efb03)
- **fix(llm): fail loud on missing API_CRYPTO_KEY, wire the header into the self-hosted inline path** (420b666)
- **fix(llm): HMAC the last-resort x-opencode-session fallback with the deployment's crypto key** (ded7b1b)
- **fix(llm): also attach x-opencode-session on the native openai branch** (26b3a9c)
- **fix(llm): stop hashing the apiKey for x-opencode-session — use credentialId** (ebb6430)
- **fix(llm): derive the x-opencode-session fallback from the credential's own apiKey** (9112487)
- **fix(llm): salt the x-opencode-session fallback so orgs on env-mode never collide** (ce79e72)
- **fix(llm): hash the x-opencode-session seed instead of sending our internal id raw** (20e94d1)
- **fix(ci): availability spec passes the alpha gate; declare per-upstream cap overrides in .env.schema** (d2ab2b8)
- **fix(llm): send x-opencode-session header for OpenCode Go BYOK reviews** (8594e98)
- **Merge pull request #1896 from kodustech/fix/rbac-get-route-exists** (c8952ef)
- **fix: second round of review follow-ups** (71f4422)
- **fix: permission check reads the API's bare boolean; e2e assert every /credits route is proxy-denied** (405f793)
- **fix(e2e): confirm route absence before tolerating a GET 404 in the RBAC release-gap guard** (9e75823)
- **fix(web): balance and ledger reads need the Billing read permission server-side** (1774467)
- **fix: address Kody's review on the Kodus provider / credits PR** (d558967)
- **Merge pull request #1820 from andyst-dev/fix/rbac-manifest-release-tolerant** (14054bf)
- **fix(web): bounce the Kodus add-model form for orgs outside the alpha** (a46a137)
- **Merge pull request #1819 from andyst-dev/fix/searchdocs-distinguish-unavailable** (b5a38c1)
- **Merge pull request #1818 from andyst-dev/fix/task-context-use-known-issue-numbers** (a09ed6f)
- **Merge pull request #1857 from 27Bslash6/fix/kody-rules-sync-delete-all-matching-source-path** (af0cbf5)
- **Merge pull request #1876 from KminekMatej/fix/pr-summary-receives-review-findings** (fdd35cb)
- **Merge pull request #1894 from andyst-dev/fix/1885-notifications-mark-read** (ba31b9e)
- **Merge pull request #1893 from kodustech/fix/1833-bad-fix-gate** (07f28b5)
- **fix(code-review): drop prose-only detection from the bad-fix gate entirely** (09516cd)
- **fix(code-review): use existingCode as evidence for stop-word-valued key:value pairs** (2a9ce43)
- **fix(code-review): revert tight-pair key gate, address sixth Kody round** (b1a0bf7)
- **fix(code-review): address fifth Kody review round on the bad-fix gate** (5e0e401)
- **fix(code-review): address fourth Kody review round on the bad-fix gate** (3a7bd2e)
- **fix(code-review): address third Kody review round on the bad-fix gate** (eb5c99e)
- **fix(code-review): address second Kody review round on the bad-fix gate** (48fb41e)
- **fix(code-review): protect Python triple-quotes, Ruby %-literals, smart quotes; catch list-marker leaks** (828adc2)
- **fix(code-review): catch scaffolding-label and diff-hunk leaks into improvedCode** (b6c3762)
- **fix(code-review): recognize bare control-flow statements as usable fixes** (71fe261)
- **fix(code-review): harden the bad-fix gate against multi-language false positives** (d726dd2)
- **fix(notifications): mark-as-read paths 500 on TypeORM nested update criteria** (1c0e345)
- **fix(llm): read Fireworks version spelling and snapshot dates in model labels** (08c146c)
- **fix(web): let the credits history drawer take its full width** (8658e74)
- **fix(web): keep the credit balance on the nested trial license; widen custom top-up input** (aeb9513)
- **fix(credits): read Kodus-routed spans through an aggregation pipeline** (3481f23)
- **fix(credits): match Kodus-routed spans by dotted key; carry the provider flag into the nested subscription provider** (54e9a10)
- **fix(code-review): drop suggestions with unusable improvedCode** (071ef99)
- **fix(sandbox): bound the reaper's retry loop with a second hard cap** (7ad5152)
- **fix(sandbox): never delete a lease on a kill failure, even past the cap** (9113635)
- **fix(sandbox): long-lived lease TTL for graph/safeguard, bound kill retries** (95ea77b)
- **fix(kody-rules): gate full-file budget, parallelize detector saves** (a665116)
- **fix(kody-rules): trace claim drops per org, precompute file-rule map** (2eb70d9)
- **fix(kody-rules): group claim checks by the unit that gets published** (a317108)
- **fix(kody-rules): group claim checks by the unit that gets published** (7c5d87d)
- **fix(kody-rules): stop sending the changed file twice in one shard prompt** (ef38364)
- **fix(byok): route implementation-check and validation LLM calls through org BYOK** (0063635)
- **fix(kody-rules): resolve the enclosing scope by indentation, not by keyword** (4d6aad2)
- **fix(sandbox): make the repository lookup answer its contract on both providers** (460a3c8)
- **fix(code-review): drop replaced originals and fence findings as data** (727fd41)
- **fix(code-review): count the same population in both findings branches** (ad1c976)
- **fix(code-review): don't report an undelivered review as a clean one** (69d915d)
- **fix(code-review): count only delivered findings, size chunks per path** (745a18d)
- **fix(code-review): include PR-level findings and keep the block out of chunk prompts** (e1b815d)
- **fix(code-review): pass review findings into the PR-summary prompt** (66a4196)
- **fix(code-review): carry an agent's warnings through the error it throws** (ce4bb32)
- **fix(kody-rules): type the probe mock so the spec stops adding a tsc error** (8f49583)
- **fix(kody-rules): reuse a settled context need for unchanged rule text** (7cb4f5c)
- **fix(kody-rules): bind claim checks to the shard limit, not a copy of it** (9cbc4af)
- **fix(kody-rules): wire the empty-read probe and share one lookup per review** (01b5b78)

### UI
- **Unified preview environments per PR** — Replaced separate Railway and Vercel preview deployments with a single full-stack environment that runs on AWS per pull request. Each PR now gets its own complete application instance that is automatically created when pushed and destroyed when the PR closes. (065d52e)

### Backend
- **Merge pull request #1892 from kodustech/feat/kodus-provider-credits** (1381f8f)
- **Merge pull request #1887 from kodustech/feat/kody-rules-1826-context** (9631b05)
- **Merge pull request #1888 from kodustech/feat/kody-rules-context-need** (1870ab0)
- **Merge pull request #1878 from kodustech/codex/changelog-september-8-2026** (71f0c6d)

### Tests
- **test(rbac): record that the charge journal is billing-scoped** (9258b75)
- **test(e2e): add kodus-credits-review to the full matrix** (4c1edce)
- **test(e2e): make the credits matrix cell honest on any environment** (ca0123b)
- **test(llm): assert the native openai branch withholds x-opencode-session on non-OpenCode baseURLs** (27b0868)
- **test(e2e): harden the browser-driven auto top-up check** (5c20ac5)
- **test(e2e): browser-driven auto top-up check (remove/save card, declined card, recovery, first save)** (d935942)
- **test(e2e): prove the off-session auto top-up live; disable thresholds above the amount** (6e491d1)
- **test(code-review): cover the bad-fix gate's wiring inside AgentReviewStage** (b458ca2)
- **test(kody-rules): record the post-fix E2B measurement** (c42bfb1)
- **test(kody-rules): make the eval send the prompt production actually sends** (9807a71)
- **test(kody-rules): record the closing #1826 measurement** (a62cab4)
- **test(kody-rules): drive the #1826 evals through a real sandbox, not a stub** (4e7c18e)
- **test(kody-rules): guard the half that puts the names on the error** (b021471)
- **test(kody-rules): pin that retrieval never reads a whole file** (0e93b22)
- **test(code-review): pin every review-warning pass to the PR comment** (7e80f19)

### Docs
- **docs(preview): state the signup password policy where the secret is set** (b1d8f87)
- **docs(code-review): document the label-glued-noop scope boundary** (e3c2256)
- **docs(changelog): add September 8, 2026 release notes** (fb7ec65)

### Chore
- **refactor(credits): read the charge journal through a use-case** (2bb2386)
- **refactor: sign billing credit calls with the secret both services already share** (054e6b8)
- **refactor(llm): move OpenCode Go session-header logic to a shared leaf; cover the anthropic transport too** (b6c0a8e)
- **chore(env): declare the Kodus provider vars in .env.schema and regenerate outputs** (1ee1ac2)
- **chore(compose): give the dev webhooks service 2G** (0fef9b8)
- **ci(tests): install ripgrep in the full backend test job too** (543b789)
- **ci(contract-tests): install ripgrep, which the local sandbox shells out to** (a59e8e4)
- **chore(kody-rules): keep the #1826 analysis scripts and eval outputs** (d6347d7)

_Recap by [Repo Wrapped](https://repowrapped.com/gh/kodustech/kodus-ai?utm_source=github-action)._