New
- Workspaces. One workspace is one company: its people, agents, sessions, connectors, files and billing. It replaces "project" and "account" in the web app, the desktop app, mobile, the CLI, the TUI and the docs, in 9 languages. Sign-up lands on "Create a workspace" or an invite, and the switcher lists workspaces. Old routes, SDK names,
kortix projects,--projectand existing URLs keep working. - One settings panel. Workspace settings holds everything an admin changes: the workspace, Library (models, connectors, secrets, skills, drives, triggers, sandbox, Git, repository), People, Billing and Advanced, with deep search. Customize now opens Workspace settings.
- API keys act as you, an agent or a bot. One API keys list replaces API keys and service account tokens. A key has read, full or custom access, expires after 90 days by default, and stops working when its creator leaves (a key for an agent or a bot keeps working). The CLI has
kortix keys. - Review moves into the Inbox as its own tab.
- One model picker with favorites, provider tabs and thinking levels. Connect ChatGPT and Connect Claude sit on the workspace home.
- Getting started: a workspace with no runnable agent shows a one-click setup prompt instead of an empty chat.
Improved
- The upgrade dialog shows the same plans as the pricing page, and no longer scrolls sideways at high credit tiers.
- Drive conflicts open in a small popover.
- Session logs and Models › Logs load faster on large workspaces.
kortix logoutrevokes the login token.- Kortix Cloud no longer offers account branding. Self-hosted installs keep it.
Fixed
- A tool call clicked in the chat no longer opens an empty side panel.
- A subagent runs as its parent agent, never as a guessed one.
- A failed Stripe check no longer moves a paid workspace to the free plan.
- A Platinum box whose daemon stops is restarted on the next request.
- Connector calls, webhooks, Slack messages, sandbox templates and public shares refuse more malformed or out-of-scope requests.
- Many quieter error reports, and fewer false alerts.
What's Changed
- refactor(tests): one repo-root reader, one flag parser, no dead exports (KRTX-4403) by @agent-kortix in #11988
- feat(workspaces): one workspace replaces projects and accounts on every surface by @markokraemer in #11857
- fix(api): a public-share mode the path edge has not heard of is read-only (KRTX-4406) by @agent-kortix in #11992
- fix(docker): keep colocated tests out of image builds so the API image builds again by @markokraemer in #12014
- fix(api): rethrow a failed Stripe subscription list instead of reverting to free (KRTX-4408) by @agent-kortix in #11993
- refactor(ci): dedupe the CI signing, comment and secret-sync ceremonies (KRTX-4410) by @agent-kortix in #11996
- fix(api): authenticate git-proxy GET routes before query validation (KRTX-3150) by @agent-kortix in #11997
- refactor(cli): move the goals client onto @kortix/sdk and delete its wire mirror (KRTX-4413) by @agent-kortix in #12015
- fix(web): stop paging on a crawler's CSP-blocked string eval (KRTX-4423) by @agent-kortix in #12016
- fix(api): a subagent may read its spawner's session log through the sandbox proxy (KRTX-4412) by @agent-kortix in #12002
- fix(api): mark public OpenAPI operations with security: [] (KRTX-3149) by @agent-kortix in #12009
- fix(connectors): a revoke with no revokedAt stays revoked (KRTX-4378) by @agent-kortix in #11970
- test(iam): pin that a service account's GET /v1/accounts creates no workspace (KRTX-4426) by @agent-kortix in #12017
- refactor(api): dedupe session reads: turn state, titles, git rows, attachment drains (KRTX-4429) by @agent-kortix in #12019
- fix(llm-gateway): list only the models the key can call on GET /v1/models (KRTX-4427) by @agent-kortix in #12020
- fix(web): stop paging on an extension main-world bridge's chrome.runtime TypeError (KRTX-4430) by @agent-kortix in #12021
- fix(api): list a service account's granted projects in GET /v1/projects (KRTX-4432) by @agent-kortix in #12022
- fix(web): stop reporting the locked Shield wallet rejection (KRTX-4433) by @agent-kortix in #12023
- fix(sdk): retry a sandbox_not_ready upload 503 across the wake (KRTX-4431) by @agent-kortix in #12024
- fix(api): never echo a database error's message from the gateway playground (KRTX-4400) by @agent-kortix in #11995
- refactor(api): break the BYO import cycle and extract OAuth start validation (KRTX-4440) by @agent-kortix in #12026
- fix(api): relaunch a dead Platinum daemon on the first edge 502 for :8000 (KRTX-4438) by @agent-kortix in #12025
- feat(ui)!: standardize web patterns and design-system guidance by @sutharjay1 in #12031
- refactor(white-label): one shared workbench kit for the reference apps (KRTX-4445) by @agent-kortix in #12029
- test(web): remove contradictory gateway reveal source assertion by @sutharjay1 in #12033
- feat(analytics): activation funnel splits invited from self-serve and counts every first prompt by @DimitrijeGlibic in #12034
- refactor(api): split the GET /:workspaceId/detail config+files half into a module (KRTX-4441) by @agent-kortix in #12030
- fix(api): rate-limit the invalid-or-expired-token 401 warn per route and window (KRTX-4442) by @agent-kortix in #12032
- fix(api): gateway usage series stays index-only and sorts latency once (KRTX-4022) by @agent-kortix in #11719
- fix(my-kortix): start a workflow only for many-part work or when asked by @DimitrijeGlibic in #12036
- fix(dev): pnpm dev and worktree start decrypt through the Armor login again by @DimitrijeGlibic in #12037
- fix(api): scope the Slack inbound-message claim to the receiving project (KRTX-4447) by @agent-kortix in #12035
- refactor(api): one errorMessage helper and three dedupes in projects/lib (KRTX-4453) by @agent-kortix in #12038
- fix(api): name a refused runtime-floor once per box and window (KRTX-4457) by @agent-kortix in #12039
- fix(api): rate-limit the upstream-failure warn per call path (KRTX-4446) by @agent-kortix in #12041
- fix(api): a racing change-request open retries instead of paging a 500 (KRTX-4458) by @agent-kortix in #12042
- refactor(api): compress api-git data access — one owner per repeated mechanic (KRTX-4461) by @agent-kortix in #12044
- refactor(api): one owner for the session-route gates and model-writer guards (KRTX-4437) by @agent-kortix in #12027
- fix(web): redirect the old /app path to /download (KRTX-4462) by @agent-kortix in #12045
- fix(api): rate-limit the per-prompt secret-grant refusal warn to one aggregate line per minute (KRTX-4016) by @agent-kortix in #12040
- fix(agents): refuse a subagent call that combines subagent_type with an inline agent spec (KRTX-4463) by @agent-kortix in #12046
- fix(api): bound GET /config's box-health probe at 3 s so a hung box stops holding pollers (KRTX-629) by @agent-kortix in #12048
- fix(kortixd): the turn relay stops retrying a refused credential (KRTX-4456) by @agent-kortix in #12050
- fix(api): scope the Slack event claim to the project that received it (KRTX-4443) by @agent-kortix in #12028
- fix(ui): the workflow run rows own their text-xs scale (KRTX-4452) by @agent-kortix in #12051
- refactor(api): one metadata patch and one platinum status parser (KRTX-4468) by @agent-kortix in #12052
- perf(db): gateway sources aggregate reads the covering index, not the heap (KRTX-4449) by @agent-kortix in #12043
- fix(api): scope the project sandbox template image identity to the owning tenant (KRTX-4469) by @agent-kortix in #12049
- feat(sandbox): ship the daemon's loop lag so slow proxied reads name their cause (KRTX-4459) by @agent-kortix in #12053
- fix(api): ship the throttled refusal line at a severity that follows its volume (KRTX-4454) by @agent-kortix in #12054
- fix(web): capture a typed answer for a docked question on an idle session (KRTX-4450) by @agent-kortix in #12056
- fix(api): refuse project-scoped rebuild of the shared platform default sandbox image (KRTX-4465) by @agent-kortix in #12047
- fix(web): Vercel stops building the frontend on every push by @DimitrijeGlibic in #12058
- fix(subagents): a colleague runs as its parent, never as a guessed agent by @DimitrijeGlibic in #12059
- fix(ui): a tool call clicked in the chat never opens an empty right panel (KRTX-4464) by @agent-kortix in #12055
- fix(api): bound the public trigger webhook body before it verifies the signature (KRTX-4473) by @agent-kortix in #12062
- refactor(api): delete the dead repo self-heal path and dedupe the peer-message module (KRTX-4475) by @agent-kortix in #12060
- refactor(api): session create paths resolve through named helpers, one post-create finalization (KRTX-4471) by @agent-kortix in #12061
- fix(iam): require project.secret.read to select a session provider-secret pool (KRTX-4472) by @agent-kortix in #12063
- refactor(mobile): unexport file-local skipReason and PastedTextState (KRTX-4282) by @agent-kortix in #12066
- refactor(api): split the preview proxy — one share helper, one fork parser, two module seams (KRTX-4477) by @agent-kortix in #12064
- fix(api): classify Composio 400 and INVALID_INPUT rejections as caller errors (KRTX-678) by @agent-kortix in #12067
- refactor(llm-gateway): one refusal family for audio and image requests (KRTX-4484) by @agent-kortix in #12068
- perf(kortixd): session-log reads stop digesting the whole log per poll (KRTX-4488) by @agent-kortix in #12071
- chore(env): drop the retired KORTIX_YOLO_URL endpoint plumbing (KRTX-4478) by @agent-kortix in #12069
- feat(web): settings drill-down sidebar with deep search and a 7-row workspace menu by @sutharjay1 in #12077
- fix(cli): revoke the login token on logout (KRTX-4493) by @agent-kortix in #12073
- refactor(contracts): single-source the wire-values mirror in @kortix/sdk (KRTX-4489) by @agent-kortix in #12075
- refactor(api): one scheduler for every scheduled job (KRTX-4486) by @agent-kortix in #12070
- refactor(session-shell): one useNow clock, one deadline module, one m:ss formatter (KRTX-4498) by @agent-kortix in #12078
- fix(api): title fallback stops warn-paging expected states (KRTX-4500) by @agent-kortix in #12079
- fix(voice): a no-source voice catalog is not kept — a source configured later is still fetched (KRTX-4507) by @agent-kortix in #12080
- fix(security): close the open repository advisories (Bun Brotli, tunnel, Apps, Firecrawl, asks) by @markokraemer in #12082
- chore(learnings): revoke leaked credentials same day; CI never uses a Cloudflare Global API Key by @markokraemer in #12083
- fix(gateway): make the dashboard aggregates index-only again (KRTX-4046) by @agent-kortix in #12076
- fix(ci): probe github.com releases with the printed HTTP status before installing Trivy (KRTX-4506) by @agent-kortix in #12081
- refactor(sdk): one home for the turns unit's untrusted-JSON guards (KRTX-4510) by @agent-kortix in #12086
- fix(ui): an agent row with a non-string slug renders a label instead of crashing the session page (KRTX-4511) by @agent-kortix in #12088
- refactor(sdk): one backend base, one query serializer, one App route pair (KRTX-4504) by @agent-kortix in #12087
- fix(api): state the upstream block-page title on an HTML error from Composio's edge (KRTX-4512) by @agent-kortix in #12089
- refactor(sdk): one sandbox request core for the daemon clients (KRTX-4515) by @agent-kortix in #12091
- perf(api): bound the session-log page read by bytes (KRTX-4508) by @agent-kortix in #12090
- fix(web): the hero walkthrough survives a throwing step timeline (KRTX-4513) by @agent-kortix in #12093
- refactor(sdk): split the SSE connection policy and LSP plumbing out of the React hooks (KRTX-4520) by @agent-kortix in #12094
- feat(onboarding): no runnable agent blocks the chat area; existing repos get a one-click setup prompt by @markokraemer in #12095
- feat(branding): Kortix Cloud no longer offers account branding by @markokraemer in #12096
- refactor(ui): move the session-tool tests into @kortix/ui, drop the vacuous wiring test (KRTX-4524) by @agent-kortix in #12097
- refactor(sdk): dedupe App mutation shells, control-frame dispatch and model-store default writes (KRTX-4522) by @agent-kortix in #12098
- fix(api): drop the unreachable public-share port-root redirect (KRTX-4518) by @agent-kortix in #12092
- fix(security): edge contract — Allow on 405, HTTP→HTTPS 308 (KRTX-3380) by @agent-kortix in #11707
- fix(security): Platinum sandbox webhook keys its replay guard on the delivery identity (KRTX-4502) by @agent-kortix in #12084
- refactor(sdk): one per-session mark record replaces the sync store's thirteen maps (KRTX-4526) by @agent-kortix in #12102
- fix(web): marketing dither fields degrade on a truthy non-WebGL context stub (KRTX-4536) by @agent-kortix in #12103
- chore(infra): refresh GitHub IP ranges by @github-actions[bot] in #12104
- refactor(kortixd): de-export internal harness names, one retry and fallback policy (KRTX-4538) by @agent-kortix in #12107
- fix(llm-gateway): charge unvalidated credentials to one shared bucket (KRTX-4528) by @agent-kortix in #12101
- refactor(web): the session panel tests move to @kortix/ui (KRTX-4543) by @agent-kortix in #12106
- refactor(api): unify connector policy row projection and duplicated helpers (KRTX-4553) by @agent-kortix in #12108
- feat(web): the upgrade modal's plan view matches the /pricing plans band by @sutharjay1 in #12110
- fix(web): withhold the /workspaces/new escapes while the create runs (KRTX-4551) by @agent-kortix in #12109
- fix(web): drive conflicts open in a bottom-right popover, no grow animation by @sutharjay1 in #12112
- fix(web): the upgrade modal no longer scrolls sideways at high credit tiers by @sutharjay1 in #12114
- feat(ui): Connect ChatGPT and Connect Claude on the project home by @sutharjay1 in #12111
- fix(session): My Kortix tool steps stay in the chat and never show the agent's instructions by @sutharjay1 in #12113
- fix(ui): one connect-a-model surface, the Connect ChatGPT and Claude rows by @sutharjay1 in #12115
- fix(api): deny connector calls with an empty path argument before the upstream call (KRTX-4539) by @agent-kortix in #12105
- feat(ui): one model picker with favorites, provider tabs and thinking levels by @sutharjay1 in #12116
- feat(web): the landing hero drops the four-trait line above the title (KRTX-4560) by @agent-kortix in #12119
- test(web): cover the static bottom-right Drive conflicts popover (KRTX-3609) by @agent-kortix in #11042
- refactor(sdk): every project's flag map resolves from one cached row (KRTX-4414) by @agent-kortix in #12121
- feat(customize): Customize is Workspace settings, Review joins the Inbox, Skills loads without kortix.yaml by @markokraemer in #12120
- fix(web): show the PostHog survey only after the first workspace (KRTX-4550) by @agent-kortix in #12124
- fix(ui): an inline agent hand-off row reads "Inline" instead of "General" (KRTX-4511) by @kubet in #12127
- fix(api): a thrown recovery probe no longer condemns a runtime as lost (KRTX-4567) by @agent-kortix in #12129
- fix(db): the gateway_logs backfill reads each page once, so the prod migrate job finishes by @markokraemer in #12131
- fix(ui): stop invalidation refetches of a drive file that is gone (KRTX-4563) by @agent-kortix in #12123
- Promote dev 1436e8d to staging by @github-actions[bot] in #12132
- fix: the nightly Tests lanes pass on dev; members pick their own provider keys again by @markokraemer in #12133
- chore(release): staging VERSION → 0.15.3 [skip ci] by @github-actions[bot] in #12134
- chore(release): VERSION → 0.15.3 [skip ci] by @github-actions[bot] in #12135
- Promote dev 569ce4b to staging by @github-actions[bot] in #12138
- docs(learnings): carry a prod-error fix to staging in the same session (KRTX-4511) by @kubet in #12140
- fix(tests): the remaining red Tests lanes on dev pass by @markokraemer in #12141
- fix(api): /v1/me lists a person's accounts in one fixed order by @markokraemer in #12143
- refactor(billing): split god functions, dedupe rotation loop and route schemas (KRTX-4566) by @agent-kortix in #12125
- fix(tests): token seeds lock the project first, so the trigger's NOWAIT never races by @markokraemer in #12145
- Promote dev 69691c0 to staging by @github-actions[bot] in #12146
- refactor(api): split the Telegram adapter and dedupe its shared channel code (KRTX-4562) by @agent-kortix in #12126
- feat(sessions): stateless sandboxes become the default on dev by @DimitrijeGlibic in #12147
- tests(flows): dedupe the git-token and create-repo flow bodies and drop two needless layers (KRTX-4569) by @agent-kortix in #12142
- feat(my-kortix): a colleague gets connectors and secrets only after a person allows them by @DimitrijeGlibic in #12149
- fix(web): bound the googletag-undefined noise guard to the throw-site frame (KRTX-4571) by @agent-kortix in #12148
- fix(api): a thrown /start recovery probe no longer marks a runtime lost (KRTX-4570) by @agent-kortix in #12139
- fix(tests): fund every fixture workspace, so the deployed smoke's first session is not 402 by @markokraemer in #12150
- fix(tests): fund every fixture workspace (stage fix for v0.16.0, from #12150) by @markokraemer in #12151
- fix(api): a v0.14 CLI can start a session with --model again by @kubet in #12152
- fix(api): a v0.14 CLI can start a session with --model again by @kubet in #12153
- docs(learnings): keep every key a released client sends in a strict request schema by @kubet in #12160
- refactor(slack): collapse five duplicated Slack channel paths onto one helper each (KRTX-4558) by @agent-kortix in #12118
- fix(secrets): the env separation gate judges every key by VALUE, not by its name (KRTX-4108) by @agent-kortix in #11796
- fix(tests): fixture workspaces get the OWNER's paid tier, so their sessions boot on staging by @markokraemer in #12166
- fix(tests): fixture workspaces get the OWNER's paid tier (stage fix for v0.16.0, from #12166) by @markokraemer in #12167
- fix(tests): the ke2e client honors the API's documented mirror-unavailable 503 (release suite, KRTX-4578) by @agent-kortix in #12158
- fix(tests): cherry-pick the ke2e mirror-503 retry (KRTX-4578) onto staging by @agent-kortix in #12168
- refactor(tests): split the preview reaper IO from the deploy module, fix 6 harness readability defects (KRTX-4393) by @agent-kortix in #11987
- test(api): pin audit webhook delivery to the SSRF guards (KRTX-4404) by @agent-kortix in #11998
- fix(tests): the ke2e client honors the API's documented mirror-unavailable 503 (release suite) by @agent-kortix in #12169
- Promote dev 6968a59 to staging by @github-actions[bot] in #12170
- fix(api): the mirror's transient retry out-waits GitHub's fresh-repo visibility window (KRTX-4576) by @agent-kortix in #12157
- stage-fix: the mirror's transient retry out-waits GitHub's fresh-repo visibility window (KRTX-4576) by @agent-kortix in #12171
- fix(tests): a failed status assert keeps the origin classification and the body (KRTX-4574) by @agent-kortix in #12154
- fix(api): colleague access asks move with a transferred project by @DimitrijeGlibic in #12173
- fix(ke2e): honor the API's typed pre-commit retryable 503 in the gate and the sandbox pre-build (KRTX-4579) by @agent-kortix in #12159
- fix(tests): a failed status assert keeps the origin classification and the body (staging pick of KRTX-4574) by @agent-kortix in #12174
- fix(db): kortix.ts declares the six account_id indexes the reconcile fill uses (KRTX-4581, release gate) by @agent-kortix in #12162
- chore(gitleaks): the WS-AUTH-10 minter Principal label is not a secret (KRTX-4583, release gate) by @agent-kortix in #12164
- fix(security): the release tree's nine new CodeQL alerts are fixed in code (KRTX-4584, release gate) by @agent-kortix in #12165
- stage-fix: schema contract + gitleaks ignore + CodeQL alert fixes (release train 2026-11-09) by @agent-kortix in #12176
- perf(webhooks): log webhook work that outlives its ack budget (KRTX-4015) by @agent-kortix in #12099
- fix(api): cherry-pick #12173 (colleague-access purge + transfer asks) onto the v0.15.3 candidate by @agent-kortix in #12177
- fix(api): colleague access asks move with a transferred project (staging cherry-pick of #12173) by @agent-kortix in #12178
- fix(api): a reserved host that never resolves is not retried for 8 s; gitleaks fixture assembled by @markokraemer in #12180
- fix(api): a reserved host that never resolves is not retried for 8 s; gitleaks fixture assembled (#12180, release gate) by @markokraemer in #12181
- stage-fix: assemble the ke2e redaction fixture's token + the two ignore fingerprints (release train 2026-11-09) by @agent-kortix in #12184
- fix(tests): four bun stubs spread the real module so re-linked exports resolve (release suite) (KRTX-4591) by @agent-kortix in #12186
- fix(tests): KRTX-4588 the audit-webhook SSRF fixture carries workspaceId (Workspaces R1 expand) by @agent-kortix in #12179
- Promote dev 98f43b7 to staging by @github-actions[bot] in #12187
- fix(tests): MCP-6 whoami runs as a one-workspace user; gitleaks-ignore scans only the flagged file (#12189, release gate) by @markokraemer in #12190
- fix(ci): the release gate's two infra-flake causes are picked onto staging (#12205, #12192) by @agent-kortix in #12206
- fix(tests): WS-ROUTE-3 compares the identity (stage fix for v0.15.3, from #12207) by @markokraemer in #12208
- Release v0.15.3 — Workspaces, one settings panel, and API keys that act as an agent or a bot by @github-actions[bot] in #12175
Full Changelog: v0.15.2...v0.15.3