v0.13.0 — Apps goes stable, Monitors lands experimental, and a big session-reliability pass
LatestNew
- Apps is now a stable feature — it moved out of experimental status and sits in the sidebar under Customize. Apps open instantly (no more loading flash), show their desktop layout on the preview card instead of mobile, and get their own IAM permissions and per-team scoping. Non-public Apps are now usable and honest about who can access them; self-host installs can serve Apps even though they can't publish to kortix.com.
- Invite-time project grants — inviting someone to a project now grants both the account role and project access in one step, instead of two separate actions.
- Settings unified into one tabbed panel, and the Billing pane was rebuilt with fewer boxes and a single credits card.
- Chat input rebuilt to stop duplicate and lost sends; triple-tapping Escape now stops the agent even while you're typing.
- Easy panel overhaul (the non-technical-user view): memory updates are now visible and plainly labelled, skill and task calls expand with live sub-agent activity, and a connect-apps strip and context-card actions were added.
- Session usage modal reworked for clarity and speed; the model switcher and session usage view now show the real upstream provider instead of "Kortix".
- Monitors (experimental): a new trigger type that runs on its own provisioned box, with its own CLI command group and MCP surface.
- Network-boundary secrets on Daytona: an in-guest egress shim scopes a secret to the sandbox it was issued to, replacing the old operator-wide env var.
- Presentations framework at
/presentations, including a diagram-led security deck. - Added managed models: DeepSeek V4 Pro 0813 and Grok 4.6.
- The CLI now shows the identity behind a minted agent token instead of reporting "not logged in".
Fixed
- A cluster of stuck-session bugs: sessions could get wedged on boot with no retry, get stuck in a runaway self-repeating turn, show phantom interrupts, or strand mid-workspace-switch. A failed direct send now lands in the failed lane instead of disappearing, and prompts no longer get lost around session hand-off.
- Session truth now reads from a durable server-side turn ledger over HTTP, replacing several client-side guesses about whether a session is still working.
- Self-host: Storage now hands out public URLs instead of an internal Docker host address, and updates auto-heal from unlogged-table fork corruption that used to block them.
- The gateway reports what an LLM request actually cost, not what Kortix billed; it no longer kills slow reasoning turns at a hard 90-second timeout, drops the trailing-assistant prefill that made strict backends fail, and its body size ceiling is raised to 1 GiB (was rejecting large multimodal requests).
- MCP catalog discovery is now authenticated, and private sessions are no longer discoverable by other connectors.
- Creating a duplicate App slug now returns 409 instead of 500.
- The Vercel production frontend build now pins its runtime version so it can't get stranded on a stale one.
- Cleaned up frontend error noise from bot/automation scripts and third-party scripts on Safari.
- The reasoning-effort icon for Auto is now visually distinct, and agent names are capitalized consistently.
Notes
This release also includes a large internal hardening pass: an in-guest network-boundary/egress-secrets system, a warm-session simplification (session pooling now reuses ordinary sessions instead of a separate warm-session concept), a large API route-file split for maintainability, and expanded test coverage across sessions, monitors, and the deployed staging gate.
Also in this release
- Security hardening — the sandbox egress pin now trusts the edge-populated client IP rather than spoofable forwarding headers; the App public proxy honors a token's project/session scope when authorizing App access; trigger-session manager visibility no longer extends to session-bound agent tokens; a deleted session is no longer readable by id.
- Release-pipeline reliability — the release gate is sharded into parallel jobs, cleans up its own test debris, and runs against a right-sized staging; several long-standing test-suite defects that kept the gate red were fixed.
What's Changed
- chore(release): VERSION → 0.12.9 [skip ci] by @github-actions[bot] in #6399
- test(deployed): make the staging release gate resilient to origin load + dead email key by @markokraemer in #6397
- fix(deploy-prod): pin the Vercel RUNTIME version env so the prod FE isn't stranded by @markokraemer in #6401
- fix(web): de-noise three Better Stack frontend prod error classes (OneTrust JSON parse, Firefox DOM mutation, WebSocket Failed to send message) by @agent-kortix in #6398
- test(deployed): serialize staging lanes + self-heal AgentMail quota (gate stabilization r2) by @markokraemer in #6404
- feat: tell the agent what the network boundary is doing by @Ino-Bagaric in #6406
- fix: the connectors MCP server never started; add a broker tool to it by @Ino-Bagaric in #6407
- feat: turn the connectors MCP face on for every session by @Ino-Bagaric in #6408
- test(deployed): retry transient gateway errors in ALL clients (fixture clients too) by @markokraemer in #6411
- fix(web): suppress bot/automation
webdriverredefine + transientsignal timed outnoise (BS ee14e84d…, 73e683c3…) by @agent-kortix in #6410 - feat: Monitors — 24/7 watchers as a third trigger type (experimental flag) by @markokraemer in #6413
- test(deployed): send Vercel SSO bypass header in the browser lane (+ weak-ETag tolerance) by @markokraemer in #6415
- feat(web): unify settings into one tabbed panel by @sutharjay1 in #6396
- test(deployed): 90m timeout + cap sandbox concurrency (final gate stabilization) by @markokraemer in #6418
- fix(monitors): monitor-box git-proxy access + stale-agent recycle by @markokraemer in #6417
- feat(web): show when each user message was sent by @sutharjay1 in #6420
- fix(monitors): stale-agent probe uses resolveEndpoint (authed edge) by @markokraemer in #6421
- test(deployed): serialize the two staging lanes (Daytona provisioning throughput) by @markokraemer in #6422
- enh(web): send all queued messages on the next turn by @sutharjay1 in #6423
- docs: broker end-to-end result, and the premise it disproved by @Ino-Bagaric in #6409
- fix: mint the session handle row for network-boundary secrets by @Ino-Bagaric in #6425
- feat(web): dot-matrix busy glyphs and conversation density by @sutharjay1 in #6426
- feat(models): add managed Grok 4.6 by @markokraemer in #6427
- feat(secrets): boundary delivery is a project flag, not an operator env var by @Ino-Bagaric in #6428
- fix(secrets): close the audit findings against the boundary-shim flag by @Ino-Bagaric in #6430
- feat(models): add managed DeepSeek V4 Pro 0813 by @markokraemer in #6432
- test(deployed): revert serialize — RUN-* timeouts were a transient staging outage by @markokraemer in #6434
- fix(self-host): auto-heal unlogged-table fork corruption that blocks updates by @markokraemer in #6433
- fix(agent-tunnel): re-authorize when a saved token is rejected by @markokraemer in #6431
- fix(compliance): resolve Drata IaC critical/high findings by @markokraemer in #6392
- feat: keep a warm session ready while a user is present on a project by @markokraemer in #6437
- fix(runtime): detect, report and survive a provider losing a session's sandbox by @markokraemer in #6438
- fix(web): de-noise Safari frameless third-party 'Can't find variable' ReferenceError by @agent-kortix in #6429
- fix(api): never warm into the last concurrent-session slot by @markokraemer in #6439
- feat(web): presentations framework at /presentations + diagram-led security deck by @markokraemer in #6440
- fix(web): end a workspace switch instead of stranding it by @markokraemer in #6441
- test(e2e): cover repeated workspace switching in the browser lane by @markokraemer in #6442
- fix(iam): report the constraint that actually denied a project request by @markokraemer in #6443
- fix(meta): stop the per-prompt re-mint from destroying the coordinator's grant by @markokraemer in #6444
- refactor(sessions): a warm session is an ordinary session (-1,446 lines) by @markokraemer in #6445
- refactor(api): split r7.ts (3,499 lines) into nine focused route modules by @markokraemer in #6446
- feat(sandbox): the in-guest egress shim — network boundary without Platinum by @Ino-Bagaric in #6447
- fix(secrets): the boundary echo guidance was lying to shim-backed agents by @Ino-Bagaric in #6448
- fix(sandbox): the shim CA was unusable by python — missing key identifiers by @Ino-Bagaric in #6449
- docs: network-boundary secrets work on Daytona — measured, not argued by @Ino-Bagaric in #6450
- feat(secrets): bind a session credential to the sandbox it was issued to by @Ino-Bagaric in #6451
- docs: the session credential is bound to its sandbox — verified on dev by @Ino-Bagaric in #6452
- enh: rebuild the chat input, end duplicate and lost sends by @sutharjay1 in #6314
- fix(api): never render a boot failure as a provider-side loss by @sutharjay1 in #6456
- Remove the agent-switch 409, and fix file upload end to end by @markokraemer in #6457
- feat(apps): real permissions, resource controls, E2B parity and self-host hosting by @markokraemer in #6453
- fix(self-host): hand out public Storage URLs, not the internal Docker host by @markokraemer in #6461
- Apps: show only what you can open, and open it in place by @markokraemer in #6462
- fix(apps): return 409 (not 500) on duplicate App slug by @markokraemer in #6465
- fix(api): don't gate turn-stream lifecycle reports on connector.write by @markokraemer in #6464
- enh(web): rework session usage modal for clarity and speed by @sutharjay1 in #6459
- fix(web): align the Apps sidebar row with the group it moved into by @markokraemer in #6463
- fix(web): never land existing users on "No workspace yet" by @sutharjay1 in #6460
- feat: personalize project-home starter prompts by @sutharjay1 in #6467
- fix(cli): show the minted agent token's identity, not "not logged in" by @markokraemer in #6470
- fix(apps): frame self-host App previews from the operator frontend origin by @markokraemer in #6471
- enh(web): overhaul the easy panel for non-technical users by @sutharjay1 in #6472
- fix(apps): don't 500 App teardown when a runtime's provider is disabled/retired by @markokraemer in #6474
- fix(gateway): stop killing slow reasoning turns at 90,000ms by @markokraemer in #6473
- docs(learnings): a resource-scaled timeout moves the cliff, never removes it by @markokraemer in #6476
- fix: end phantom interrupts, stop replays, slow switches by @sutharjay1 in #6468
- feat(triggers): control created session access by @markokraemer in #6477
- fix(triggers): enforce private session discovery by @markokraemer in #6479
- fix(sandbox): renew lifecycle from active OpenCode turns by @markokraemer in #6480
- fix(sandbox): harden provider lifecycle renewal by @markokraemer in #6481
- fix(sandbox): revoke turn authority on stop by @markokraemer in #6482
- fix(sandbox): renew active turns on fast cadence by @markokraemer in #6484
- fix: close three prompt-loss holes around session hand-off by @sutharjay1 in #6486
- fix: stop home sends landing in used warm sessions by @sutharjay1 in #6485
- fix(web): resolve react-doctor bug, security, perf findings by @sutharjay1 in #6487
- Use a minimal icon for shared sessions by @markokraemer in #6488
- fix(llm-gateway): drop trailing assistant prefill so strict backends stop failing by @markokraemer in #6489
- enh(web): overhaul the easy panel for non-technical users by @sutharjay1 in #6475
- fix(llm-gateway): stop 413-ing large multimodal requests; raise body ceiling to 1 GiB by @markokraemer in #6490
- Apps: open an App instantly, and stop hiding Apps inside the SDK docs by @markokraemer in #6492
- fix(sdk): bound the prompt busy override and un-park status reconciliation by @markokraemer in #6494
- fix(gateway): report what an LLM request actually cost you, not what Kortix billed by @markokraemer in #6491
- fix(web): make triple-ESC stop the agent from inside the composer by @sutharjay1 in #6493
- fix(sdk): stop pinning content-length when forwarding a request by @markokraemer in #6495
- fix(manifest): refuse reserved App env names in validate, not only at deploy by @markokraemer in #6496
- Connectors: no Pipedream on this deployment, no Discovery tab by @markokraemer in #6498
- fix(web): drop the Apps subtitle and stop Learn more pressing the edge by @markokraemer in #6499
- Apps: show the App's desktop layout on a card, not its mobile one by @markokraemer in #6500
- fix(web): bring the permission-approval card onto the design system by @markokraemer in #6501
- fix: adversarial-audit hardening of the stuck-session fixes by @markokraemer in #6497
- fix(web): show real upstream provider, not "Kortix", in session usage + model switcher by @markokraemer in #6504
- Revamp Customize IA, permissions, and shared page shells by @markokraemer in #6503
- fix(members): repair Groups/Roles links + multi-select grant dialogs by @markokraemer in #6505
- fix(web): distinct Auto reasoning-effort icon + capitalize agent names by @markokraemer in #6508
- fix(connectors): authenticate MCP catalog discovery by @markokraemer in #6507
- feat(iam): remove duplicate Access cards, fix Customize discoverability by @markokraemer in #6506
- fix: bound two stuck-runtime states — a wedged boot with no retry, and a runaway self-repeating turn by @markokraemer in #6509
- feat(iam): invite-time project grants — one invite, account role + project access by @markokraemer in #6510
- feat(secrets): make network-boundary parity across sandbox providers contractual by @Ino-Bagaric in #6511
- Server-truth M1: turn lifecycle moves to the control plane; the client stops guessing by @markokraemer in #6512
- fix(web): unify "No second factor enrolled" alert tone + icon by @markokraemer in #6513
- docs: the egress pin survives a stop/resume — measured on both shim providers by @Ino-Bagaric in #6514
- fix(web): stop the animated logo splash on account/group navigation by @markokraemer in #6515
- feat(web): assign a custom role from inside a group, clarify Agent copy by @markokraemer in #6516
- fix(daemon): do not arm the in-guest shim where a provider edge owns the destination by @Ino-Bagaric in #6517
- docs(runbook): enabling a sandbox provider is one atomic secret edit by @Ino-Bagaric in #6518
- enh(web): rework the public share page chrome by @sutharjay1 in #6519
- fix(api): a spawned sub-session inherits its parent's sharing, not private by @markokraemer in #6521
- iam: strip Agents/Connectors/Skills/Customize from the member floor role by @markokraemer in #6522
- fix(gateway): log the full request/response body, never a capped preview by @markokraemer in #6523
- feat(web): unify secret Delivery + "Used by" into one Access picker by @markokraemer in #6525
- Session truth M1.5: queue forwards between turns, first prompt is a durable row, dead-code sweep, sub-session integrity by @markokraemer in #6527
- refactor(github): prove account-linking identity via the App's own OAuth, not Supabase by @markokraemer in #6526
- Access control: one hub, one dialog, one row, one picker — agents deny-by-default, Editor removed, tokens IA by @markokraemer in #6531
- feat(worktree): nuke --all with time rules for bulk teardown by @markokraemer in #6529
- enh(web): bake a 110% UI scale into the default by @markokraemer in #6524
- fix(desktop): answer HTTP Basic challenges instead of rendering a dead 401 by @markokraemer in #6455
- chore(deps): bump pnpm/action-setup from 4 to 6 by @dependabot[bot] in #6343
- chore(deps): bump bridgecrewio/checkov-action from 12.3114.0 to 12.3117.0 by @dependabot[bot] in #6342
- chore(deps): bump actions/attest-build-provenance from 4.1.1 to 4.2.2 by @dependabot[bot] in #6341
- chore(deps): bump github/codeql-action from 4.37.4 to 4.37.7 by @dependabot[bot] in #6340
- chore(deps): bump github/codeql-action/upload-sarif from 4.37.4 to 4.37.7 by @dependabot[bot] in #6339
- chore(deps): bump golang from 1.25-bookworm to 1.26-bookworm in /apps/api by @dependabot[bot] in #6338
- docs(monitors): internal shipping/verification/ops/removal record by @markokraemer in #6436
- fix(billing): one grant idempotency key per subscription activation by @markokraemer in #6534
- test(ke2e): GW-13 exhausts /v1/usage group_by enum, row shapes, malformed timestamps, empty window by @agent-kortix in #5254
- fix: image/video show tool now wraps in ViewerFrame with toolbar actions by @agent-kortix in #6033
- feat(selfhost): serve deployed Apps through the bundled Caddy ingress by @markokraemer in #6469
- chore(deps): bump pypdf from 6.14.2 to 6.15.0 in /packages/starter/templates/general-knowledge-worker/.kortix/opencode/skills/presentations/scripts by @dependabot[bot] in #6262
- feat(platinum-provider): idempotent create dedup + decoupled build-size knob by @allenabraham999 in #5411
- docs(learnings): correct the tests-release entry; add the half-deployed-staging rule by @markokraemer in #6537
- fix(web): keep capability-tab-routes server-safe — unblocks Deploy Dev frontend build by @markokraemer in #6533
- fix(worktree): create --branch checks out a remote-only branch instead of forking HEAD by @markokraemer in #6536
- feat(gateway): per-project OTLP trace export + Observability tab by @markokraemer in #4987
- Revert "feat(gateway): per-project OTLP trace export + Observability tab (#4987)" by @markokraemer in #6538
- test(apps): APP-4 teammate is a project member (editor role removed) by @markokraemer in #6532
- fix(iam): don't cache empty agent-grant maps — grants visible on all replicas immediately by @markokraemer in #6535
- Queue: one prompt per turn, chained on turn end, <1s delivery, instant Enter by @markokraemer in #6530
- Revert "enh(web): bake a 110% UI scale into the default (#6524)" by @markokraemer in #6539
- test(release-gate): make the gate passable — drop 5 permanent todo stubs, fix 7 stale/over-strict deployed-target flows by @markokraemer in #6542
- perf(ke2e): overlap the serial lane, stop retrying timeouts, fail fast on funding, backoff+breaker in the client by @markokraemer in #6543
- ci(release-gate): shard into parallel api/browser jobs, sweep test debris pre/post-run, assert browser env up front by @markokraemer in #6545
- infra(staging): right-size for the release gate (2 tasks, on-demand base, bigger box), record DB tier, let CI see real origin status at the edge by @markokraemer in #6544
- fix(security): close 3 Strix findings — egress-pin spoofing, trigger-session manager override, App proxy token scope by @markokraemer in #6541
- test(ke2e): declare daytona on 3 flows that boot a real sandbox (P1.6) by @markokraemer in #6546
- test(ke2e): send the edge CI-passthrough header so the release gate sees real origin status by @markokraemer in #6547
- infra(ecs-api): force_new_deployment when the capacity-provider strategy changes (fixes staging TF apply) by @markokraemer in #6549
- test(ke2e): fix the two runtime defects that failed the first sharded release-gate run by @markokraemer in #6552
- Canonical RBAC: one model (role_assignments), one engine (authorize), one write path (assignRole) — dual-read window by @markokraemer in #6554
- ci(release-gate): the pre-run sweep can never skip the shards by @markokraemer in #6556
- fix(iam): don't cache empty agent object-grant maps (canonical engine) — grants take effect on all replicas immediately by @markokraemer in #6558
- fix(iam): GET /projects/:id/group-grants requires project.members.manage (Strix MEDIUM) by @markokraemer in #6560
- ci(release-gate): halve the shard fleet (26→15 workers) and retry a timed-out flow once by @markokraemer in #6561
- feat(sandbox): add flagged fast cold boot runtime by @Ino-Bagaric in #6562
- fix(sandbox): harden lazy tool dispatch by @Ino-Bagaric in #6565
- fix(dev): apply fast cold boot flag to ECS tasks by @Ino-Bagaric in #6566
- fix(api): ship fast runtime build artifacts by @Ino-Bagaric in #6567
Full Changelog: v0.12.8...v0.13.0