This release is a big push on identity unification and task scheduling robustness. Every user-owned entity (User, Agent, App, McpServer, Channel) now carries a Handle
newtype, Policy principals are reshaped as {user_handle}/{entity_handle}
under a User parent, and all storage and routing paths are keyed by handle. Tasks gain a required result_schema
that drives how cron and one-shot results render back into source chats, with a fix for a long-standing CronRun crash-recovery race. The chat UI now paginates history on scroll-up and shows day separators with per-message hover times. Under the hood, Policy decisions and per-agent permitted tool sets are now cached, sandbox limits accept partial saves, and a Handle migration carries existing installs forward.
Supported channels: Slack, Discord, Telegram, Signal, SMS, WhatsApp Cloud, WhatsApp Personal.
Identity / Handles
- Add a
Handle
newtype with sanitization rules and a build-script-generated reserved-name list; renameUser.username
tohandle
and requireAgent.user_id
+Agent.handle
. - Add
App.handle
,Channel.handle
, and renameMcpServer.slug
tohandle
; switch all four to handle-keyed paths. - Unify on-disk storage under
`data/users/{handle}/{subsystem}`
with per-channel storage paths. - Switch Cedar entity UIDs to
Kind::"{user_handle}/{entity_handle}"
with User parent; refactorSandboxPrincipalRef
into a struct + Kind enum and rewirepolicy::service
accordingly. - Update the Cedar schema, db init indexes, and add a
handle_unification
migration (cutover at`2026-05-24T00:00:00Z`
); drop`seed_config_agents`
. - Reshape
CandidateEvent
to carry typedUser
/Channel
/Chat
/Message
/Contact
references. - Carry user handle through the auth middleware and all API routes: admin/auth, agents, app proxy, files, MCP, browser, skills, tools, messages.
- Scope agent skills by
user_handle/agent_handle
; update content + sandbox tools, the tool manager, and agent-affecting tools to use Handle paths. - Thread Handle through chat, channel, credential, notification, memory, and inference services.
- Refresh built-in agent prompts and the
manage_service
prompt + manifest schema for handle-keyed URLs.
Tasks / Cron
- Add a
result_schema
classifier and renderer for task result delivery; requireresult_schema
oncreate_task
/create_recurring_task
and schema-drive source-chat delivery. - Plumb
result_schema
throughcreate_cron_template
+spawn_cron_run
; acceptcomplete_task.result
as any JSON value and validate against the schema. - Restrict
send_message
to the agent's heartbeat chat so tasks deliver throughcomplete_task.result
. - Fix CronRun crash-recovery race by narrowing the orphan query and reordering
resume_all
. - Thread
space_id
through cron templates so CronRuns deliver into the right space. - Wrap the initial task instruction in
<task>
regardless of authoring agent. - Hide task-execution chats from the navigation space view; demote empty task-completion history rows from warn to debug.
- Remove the unused
SCHEDULED_TASK.md
prompt; advertise recurring digests and briefs as researcher responsibilities.
Chat / Frontend
- Load older chat messages on scroll-to-top and merge historical messages with SSE-buffered ones when a chat.
- Show day separators, conversation gaps, and per-message time on hover.
- Split auth, navigation, and session contexts; replace
AuthGuard
withAppGate
+RequireAuth
and rewire auth/setup/main layout for the new gating model. - Route apps, notifications, and settings by handle; switch main pages and the conversation panel to the new context APIs; update types and the api-client for handle-based responses.
Channels
- Skip
setWebhook
when the URL is already ours and drop the queue when replacing a stale URL. - Warn when an inbound webhook arrives for an unknown channel.
- Store
Channel.id
as a bare UUID instead of a SurrealDB record literal. - Cover channel-delete with a test that asserts the spawned task is cancelled and
on_disconnect
runs.
Policy / Performance
- Add a policy decision cache with prefix-scoped invalidation.
- Cache per-agent permitted tool sets to cut
/api/agents
from O(N·M²) to O(N·M).
Sandbox
- Smooth tracked CPU via EWMA to absorb transient bursts.
- Fill missing sandbox limits with server defaults on partial save.
- Fix
sandbox_cache
invalidation by aligningcache_key
touser_id
.
Build / Infra
- Add a docker task for publishing prod images to a personal preview registry; share constants/helpers via
common.sh
and annotate the image index for GHCR. - Persist cargo registry and git caches across dev container restarts.
- Send a
User-Agent
header on crates.io requests inupdate-versions
; bumpsmbclient
anduv
package pins.