v0.9.5
Released: 2026-09-17
Tag: v0.9.5 · Diff: v0.9.0...v0.9.5
405 commits · 1,570 files (+253k/−32k) · 152 public + 76 private-tracker issues · enterprise submodule 65182c1 → 08cd4dd · release candidates rc1–rc4 cut from dev along the way.
Freeze plan and coherence review: v0.9.5-freeze-plan.md. Includes the post-v0.9.0 sanitizer hotfix promoted to main on 2026-08-26 (#2406, for #2398).
Highlights
- Workspace becomes where the work happens. The agent workspace merged into
Workspace and every agent gets a canvas (ent#438). A conversation rail sits
beside the chat with Info, Loops, Files and Canvas tabs, and all three columns
are resizable and remembered per user (ent#474/#475/#492/#608, #2617). An agent
holds several topic-scoped chats as tabs, with a pinned Main chat and Reset
(ent#451/#523). Running work shows up in the chat: a live execution card
that says in one line what the agent is doing, plus a Work tab history
(ent#457/#525/#620), and loops can be started, stopped and watched from chat
(ent#458). Agents can ask a named person a question, answered inline on any
of three surfaces, and an answer can wake the agent back up (ent#364/#428–#430,
ent#329). Also: deliverables as first-class objects, message and deliverable
ratings with report-a-problem (ent#365/#366/#499), multi-file drag-and-drop and
a file preview (ent#524/#548), unread markers (ent#557), chat rename
(ent#473), agent search and recency ordering (ent#402/#491), a model dropdown
(ent#403), a light/dark/system switch (ent#625), Escape/Stop cancels a turn
(ent#155), and multi-agent rooms moved into OSS core (ent#443). - Voice mode in the Workspace. A real-time call runs over the current chat:
the orb takes the conversation, the canvas stays in the right column, and the
transcript is written back into the thread (ent#440/#534). The call acts as the
agent with a per-agent tool manifest (ent#535). A long task runs in the
background while you keep talking, and the result is brought back when it lands
(ent#551), with spoken etiquette for the whole tool cycle (ent#576). - Canvas. One rich block vocabulary (charts, images, diagrams) rendered the
same everywhere (ent#536), a platform design kit plus acanvaslibrary skill
(ent#537), canvas lifecycle with sort, search, pin and bulk delete (ent#553),
read-only share links and PDF export (ent#554), and the open canvas is shared
context the agent can see and operate on (ent#555). - DigitalOcean install. A guided installer
(scripts/deploy/trinity-do-create.sh) takes you from your own terminal to
Trinity on its own Droplet, behind HTTPS, in about ten minutes. You install and
authorisedoctl, create a Claude subscription token, choose the admin
password, and run one command. Guide:
Deploy on DigitalOcean.
Underneath it: prebuilt GHCR images, a pull-only hosted compose
(start.sh --hosted, pinned byTRINITY_IMAGE_TAG) and an unattended
cloud-init first boot (#2280). The DigitalOcean Marketplace image also ships;
its listing follows vendor review. Marketplace installs record their provenance
and show a first-run hardening guide (#2380/#2692). First-run setup happens in
the browser: a Marketplace admin is claimed there (ent#580), one setup overlay
(ent#581) configures the Claude, GitHub, email and Gemini keys (ent#582), a
front-desk agent demonstrates the primitive (ent#319), and the Trinity plugin
really is pre-installed in agents now (ent#411, #2305). - Subscription usage you can see. A 5h/7d usage dashboard with per-agent
breakdown and rate-limit history (#471), a Subscription pressure grid tile
(ent#259), durable headroom history (ent#433), and an operator alert at ≥75% of
the weekly limit (ent#434). Auto-switch now ranks alternatives by headroom
(#2409). A sweep fixed subscriptions misreported as rate-limited and gaps in the
switch-and-retry path (#2352/#2353/#2396/#2419, ent#447, #2638/#2643/#2789,
#2572, #2766). - Opt-in instance telemetry. Anonymised operational signal from self-hosted
installs, off until an admin consents (ent#437). Product-update consent gets a
Settings home (ent#463), the send log records where each share went (#2571),
and the sharing heartbeat survives daily restarts (#2618). - Pull dispatch keeps maturing (still opt-in). Scheduled work can reach the
durable queue (#2391), loops are terminal-driven (#2523), fan-out joins
asynchronously (#2524), and a pulled turn once again carries its model, tools,
turn cap, timeout and session (#2317). - Reliability. Agent containers come back after a host reboot (#2541).
Fixed: agent-server event-loop starvation (#2398) and the reader-thread drain
deadlock (#2455); watchdog mislabelling and overflow (#2433/#2434); background
work killed at CLI exit leaving no trace (#2467); headless runs being offered
wake-ups and loops that never fire (#2454/#2468); the sync-health poller taking
.git/index.lock(#2742); PostgreSQL int4 overflows inagent_sync_state
(#2240/#2800/#2827); multi-agent rooms going dead after ~6h (#2610); missing
gateway-timeout receipts on sync/taskandfan_out(#2661/#2670). Also:
an integrity contract fordeploy_local_agent(#2060), Codex API-key auth
that works (#2208), and Push no longer untracks committed files (#2529). - Security. Fixed: on a fresh install, an unauthenticated setup endpoint
could overwrite the admin password (#2381). New: machine identities for
admin/ops APIs that survive enforced 2FA (#2323), and/tokenno longer returns
an unusable token while a 2FA challenge is pending (#2322). Credential settings
are encrypted at rest (ent#435, rotation needed, see upgrade notes). Git
asks a credential helper for the token, so it is no longer in agent remote
URLs,.git/configor process listings (ent#615). Guardrail hooks are out of an agent's reach
(ent#345)./wsactivity is scoped to the agents a user can access (ent#467).
Audit attribution is honest, and denied calls are logged as refusals (ent#614,
#2807).run_agent_loopenforces the permission edge (ent#628). Approval
integrity: a mobile Deny no longer records as an approval, and responses are
validated against the offered options (#2370/#2375/#2376). The platform and
Workspace sessions now agree (#2261/#2791), and an agent can no longer switch on
its own paid wake-ups. - Engineering health.
task_execution_service.pydecomposed (#2314), the
remaining oversized backend modules split (#1028), ~2,800 lines of dead Vue plus
a dead-module sweep removed (#2492/#2493), andarchitecture.mdsplit into a
lean core plus on-demand area files (#2306/#2642). A user-journey test tier
arrives with a per-PR journey-smoke gate and Journey Impact declarations
(#2335–#2339/#2349/#2350). Loading states use skeleton placeholders, and
background polls no longer re-flash content (#1921/#1927/#2540, ent#253).
Features
- #471 Subscription usage observability — 5h/7d usage dashboard, per-agent breakdown, and rate-limit event history
- #848 MCP inline email auth — frictionless onboarding without a pre-existing Trinity account
- #2277 escape-first markdown→HTML converter — headers/links/blockquotes/code-language, entity-safe splitting
- #2280 prebuilt images + pull-only hosted compose + unattended cloud-init first boot — the gate for every hosted / marketplace install channel
- #2335
tests/journeys/tier +run-full.sh --tier journeys - #2336 per-PR journey-smoke gate — first agent turn + start/stop against a prebuilt stack
- #2338 journey catalog (intent only) + generated JOURNEYS.md
- #2349 J10: Agent calls agent — journey harness
- #2350 Journey Impact declaration on epic + PR templates, enforced at merge
- #2380 record install provenance (DO Marketplace) + first-run HTTPS/VPN hardening guide
- #2391 let scheduled work reach the durable queue — Option 2 deferred from #2048
- #2523 make loops terminal-driven so they can run on the durable queue
- #2524 async fan-out join + sync edge adapter — the last blocking dispatch caller
Private tracker (trinity-enterprise):
- ent#155 Chat: Escape key + Stop button cancel the in-flight turn and restore the message to the input field
- ent#253 Consistent data-refresh treatment across all polled surfaces — invisible background refresh, standard first-load motion
- ent#259 Grid tile: Subscription pressure — per-subscription 5h/7d usage, headroom estimate, rate-limit events
- ent#319 first-run front desk — one agent that demonstrates the primitive and routes the three doors
- ent#329 operator-queue respond → re-trigger dispatch (async human-gate resolution re-entry)
- ent#364 Workspace: agent-initiated asks — one item, three renderings
- ent#365 Workspace: deliverables as first-class objects in chat and on the agent page
- ent#366 Workspace: rate a message and rate a deliverable
- ent#386 Assign and unassign skills from the Library — the write half split out of ent#384
- ent#387 Workspace: where do room budgets get set, now that the Sessions page is gone?
- ent#402 Workspace sidebar search should filter agents, not just chats
- ent#403 Workspace chat: user-friendly model dropdown
- ent#411 deploy-as-is → onboard-in-place — pre-install the trinity plugin in the agent base image so any bare repo can make itself Trinity-compatible
- ent#413 Dashboard Grid: make layouts user-specific and server-persisted (not browser-global localStorage)
- ent#428 addressed asks — the column, its roster validation, and the portal read/answer path (ent#364 slice 1+2)
- ent#429 render an ask in all three surfaces, attach it to a chat, and show it expiring (ent#364 slice 3+4)
- ent#430 wire an answered ask to the ent#329 resume dispatch, and turn the flag on (ent#364 slice 5 — the gate)
- ent#433 Subscription headroom history — persist probe snapshots for utilization trends
- ent#434 Alert the operator at ≥75% of the weekly subscription limit (per subscription + all-subscriptions-saturated escalation)
- ent#437 opt-in instance telemetry — anonymised operational signal from self-hosted installs
- ent#438 merge the agent workspace into the Workspace + give every agent a canvas
- ent#440 voice in the agent Workspace — one conversation, two modalities
- ent#447 Subscription pressure: a recovered subscription must stop claiming it is rate-limited, and the row must say when the limit comes back
- ent#449 Grid view: adopt the standard scanline loading motion on the execution tile chart
- ent#451 Workspace: multiple chats per agent — topic-scoped conversations instead of one running chat
- ent#456 Workspace opens in a new browser tab by default
- ent#457 Workspace: live execution visibility — dispatch → monitor → report back, rendered in chat
- ent#458 Workspace: run and watch loops from chat — start/stop with visible guardrails + live loop panel
- ent#463 product-updates opt-in needs a Settings home — today it exists only on the first-run welcome form
- ent#468 Workspace: decide whether an answered ask tells the client that work started
- ent#473 Workspace: rename a chat or room, and make generated titles trustworthy
- ent#474 Workspace rail: the shell + design pass — layout, collapsed-state signal, tab contract, room grouping, mobile sheet
- ent#475 Workspace rail: re-home loops, files and the canvas into their tabs
- ent#491 Workspace sidebar: order agents by most recent collaboration — the agent you last worked with on top
- ent#492 Workspace: resizable columns — sidebar, conversation, rail — drag handles, per-user persisted widths, sane clamps
- ent#498 Workspace: brief delivery into the 1:1 thread — a schedule delivers its output to a named user's Workspace conversation (API/MCP only; split from #442)
- ent#499 Workspace: report-a-problem — a negative rating raises a bounded operator-queue alert
- ent#523 Workspace: agents at the centre — clicking an agent opens its most recent chat; a pinned Main chat with Reset; chats as tabs; New chat with a hotkey
- ent#524 Workspace: drag and drop files onto the conversation, and accept several files at once
- ent#525 Workspace: the live execution card in chat + the Work tab history — the visual half of ent#457
- ent#534 Workspace voice mode: the orb takes the conversation — real-time call over the current chat, canvas in the right column, transcript back into the chat
- ent#535 Voice tool set: the call acts as the agent — run_task runs in the Workspace chat's agent session, tool manifest locked per agent, no fleet tools in v1
- ent#536 Canvas: one rich block vocabulary for the agent and its voice mode — charts beyond a trend line, images, diagrams, rendered the same everywhere
- ent#537 Canvas design kit: a platform stylesheet, starter layouts and a
canvaslibrary skill — an agent's canvas looks designed without touching CSS - ent#547 Workspace header, compact: activity chart without legend or period selector (7 days), Agent info as a rail tab, one paperclip, voice button beside the composer
- ent#548 Workspace Files tab: preview images and text files in a modal with next/previous, and delete files
- ent#551 Voice mode: a long task runs in the background while the conversation continues — spoken acknowledgement on dispatch, result brought back when it lands
- ent#553 Canvas lifecycle: delete canvases from the Workspace, in bulk, and live with a lot of them — sort, search, pin, and a stated bound
- ent#554 Canvas share and export: a read-only share link that never widens the audience, and download as PDF
- ent#555 The open canvas is shared context: the agent sees and operates on whatever canvas the user has selected
- ent#556 Workspace branding: the Trinity logo and "Trinity Workspace" in the top left, on the shell and the sign-in screen
- ent#557 Workspace unread: an agent's reply you have not seen shows on its sidebar row — including in a never-opened chat — and in the browser tab title
- ent#576 Voice mode: say it once — spoken etiquette for the whole tool cycle (announce a wait, report the result, never narrate the canvas twice)
- ent#581 one holistic first-run overlay — replace the card ladder with a designed, blocking setup flow
- ent#582 configure Claude, GitHub, email and Gemini keys inside first-run — no terminal
- ent#608 Workspace rail: thinner scrollbars, hidden at rest and revealed on hover — no layout shift, human feel check before the PR
- ent#620 Workspace: the Work card says what the agent is doing — one short line that slides up, and the chat scrolls to the card when a sent message starts work
- ent#625 theme switch (light / dark / system) at the top right of the central column
Fixes
- #1855 test_ent183_skill_packages poisons sys.modules — test_ent125_resilient_system_deploy fails collection when run after it
- #1927 background polls re-flash loaded content and reset UI state (design-system p13/p14)
- #2029 both nightlies post a false ✅ "clean" to PRs whose suite never ran
- #2060 deploy_local_agent (archive path) silently deploys incomplete agents — archive rides the LLM turn, symlinks dereferenced/fatal, zero integrity verification
- #2106 abnormal task terminations are labelled
Task execution timed out after N secondswhen the run never approached N - #2110
DashboardPanel.vuehas notype: chartrenderer, soD-002is unfixable for agents whose generator emits chart widgets - #2208 Codex API-key auth is inert — every turn 401s because nothing writes $CODEX_HOME/auth.json
- #2240 git_dir_bytes is int32 on PostgreSQL — git-bloat alerting is inoperable above ~2 GiB
- #2246 dev deploy silently ships OSS-only — enterprise submodule init fails on SSH host-key verification, and the diagnostic blames access
- #2305 plugin install always withheld —
claude plugin install --yesuses a flag the CLI doesn't have (#1704/ent#411 delivery broken) - #2317 claim envelope reads task_overrides, a key no producer writes — every pulled turn drops the row's model, tools, turn cap, timeout and session
- #2320 failed turns are invisible to the client — fast failures misreported as "lost track", backend error discarded, Retry suppressed where it is safe
- #2352 subscription reports "rate-limited" for auth failures — is_subscription_rate_limited ignores failure_kind
- #2353 subscription pressure tile shows "rate-limited" for a rejected provider token (invalid_token hidden in tooltip)
- #2358 Dashboard List view columns don't align, and a labelled agent hides its slug (FR-4)
- #2370 /m mobile admin approval card records every option tap as response:"approved" (a Deny becomes an approval) and lacks the desktop note field
- #2373 post-deploy system endpoints — schedules silently dropped (nonexistent DB method), ungated restart, export round-trip breakage, prefix-collision membership
- #2374 stale avatar shown when cycling emotion modes after avatar change/regeneration
- #2375 Workspace asks panel sends a typed answer as response_text (the agent reads response: "") and answers approval asks one-tap — same class as #2370
- #2376 POST /api/operator-queue/{id}/respond accepts any string as an approval decision — no layer checks response ∈ options
- #2396 subscription reports "rate-limited" for the provider's own warning tier — allowed_warning fails the _headroom_indicates_limited catch-all
- #2398 agent-server event loop starves under sustained parallel headless_executor load — 1 core pegged, localhost:8000 stops accepting, DORMANT breaker fires
- #2409 auto-switch picks an alternative subscription without checking headroom — it can move agents onto a nearly-exhausted one
- #2419
_parse_utilizationreads a >1.0 fraction as an already-percent value — an overage subscription would display and rank as ~1% - #2423 Workspace shows a client 12 loop runs it cannot open, control, or explain
- #2424 Workspace says 2 asks are waiting and gives you no way to find them
- #2426 Workspace report-back can't fire on the synchronous chat path — the pre-created row has no session binding
- #2433 watchdog fails admitted-but-undispatched executions as "completed on agent but status not reported", releasing their slots and masking the real terminal
- #2434 watchdog cannot close an execution stale >24.8 days — fabricated duration_ms overflows PostgreSQL INTEGER, and the sweep then fails every cycle forever
- #2443 _believed_limited makes a sync DB call on the event loop — once per subscription per recovery sweep, can block /health and WS dispatch
- #2446 a respond POST that never settles pins the Send guard and makes the card state unprunable — add a per-request timeout
- #2448 the #2433 stdin-write/unregister guard enumerates two files, so it does not guard (and misses a live fourth site)
- #2449 Workspace agent page renders every ask twice, and the second copy cannot show expiry
- #2454 agents route "run a loop" to Claude Code's built-in /loop + ScheduleWakeup — success is reported, nothing ever fires in headless runs
- #2455 reader-thread drain deadlock discards a COMPLETED headless run as timeout, then wedges agent-server — #1502 mitigation fails (reader stuck 600s post-SIGKILL)
- #2462 the nightly cross-PR regression net has been dead for 12+ nights — every leg is capped at 25 min while it runs 6 full suites
- #2464 operator-intake fields render as borderless unpadded bars — the repo has no @tailwindcss/forms
- #2467 Background task killed at CLI exit leaves no trace — execution records clean success while the work is lost
- #2468 ScheduleWakeup is offered in one-shot headless runs — it schedules a wakeup that never fires and tells the model it WILL be re-invoked
- #2469 dev push gate red — #2314 carve pin tests compare against live origin/dev and fail permanently once the carve merges
- #2515 code blocks in agent replies are unreadable — same-tint block, ~11px type, horizontal scroll — and nothing in the thread can be copied
- #2528 compose file combo is broken two ways — plain 'up -d' uses wrong data volume; base+prod merge duplicates break validation and frontend networking
- #2529 Push untracks already-committed files — the appended canonical .gitignore block overrides the agent's own negations, and .env.example (F-004) is a casualty
- #2533 pre-merge Alembic head check is stale-by-construction when dev advances
- #2536 view-mode switcher jumps when grid-only controls appear — pin its position and add a keyboard shortcut to cycle Timeline / Grid / List
- #2538 Brain Orb: trackpad momentum after a panel hits its scroll edge leaks into camera zoom
- #2539 Brain Orb: node inspector overlaps the state card — both right-anchored at the same z-index
- #2541 created containers get restart=no — a third of the fleet silently does not survive a host reboot
- #2550 a tag-pinned source is refused as moved on every sync after the first when the tag is annotated
- #2571 the send log does not record where a share went, so a test-receiver 200 reads as a production acknowledgement
- #2572 adding the first subscription leaves every credential-less agent stranded on API-Key auth — fleet stays "Not logged in"
- #2578 Deploy to Dev fails on every submodule pointer bump — the superproject fetch recurses into the enterprise submodule before the PAT transport block runs
- #2579 New chat shows no tab and no focus, Main tab absent, titles fall back to the first message, tabs not fixed-width
- #2580 activity chart re-renders on every chat-tab switch; agent-list dates not right-aligned; copy/like/dislike misaligned; replies not rateable until reload
- #2582 uploads reach the Files tab only after the agent replies; own uploads not downloadable; image download opens inline
- #2583 every block layout an agent can produce renders unbroken in the workspace column — gallery test + fixes
- #2585 backend-unit-nightly splices PR-derived diff text into a bot PR comment with no fence
- #2597 Workspace: the rail's Info body renders a failed agent-page fetch as an empty agent
- #2598 Escape during a voice call ends the call even when an overlay already claimed it
- #2605 the raw-colour ratchet is documented as enforced but nothing runs it, and the tree has drifted past its baseline
- #2610 every multi-agent room goes dead after ~6h — room participants are missing from the session-JSONL reaper keep-set
- #2616 tables, headings and lists in agent responses render unstyled — the transcript is the one markdown surface with no typography
- #2617 the rail stops at 560px — the canvas column cannot be dragged past ~20% of a wide screen
- #2618 the sharing heartbeat's 24h timer restarts with the backend, so an install that restarts daily shares once and never again
- #2620 Room budget defaults panel is hidden on every install — still gated on the entitlement ent#443 removed
- #2624 new messages yank the transcript to the bottom while you are reading — agent chat and rooms
- #2625 Deploy to Dev is failing on dev — deploy-dev.yml's ssh script exceeds GitHub's 21000-char expression cap after #2578
- #2638 a Workspace message on a rate-limited subscription fails instead of switching and completing — close the SUB-003 gaps on the turn path
- #2640 starting a voice call jumps the column layout, and the orb renders squashed because its canvas never resizes with its box
- #2641 sidebar dates are not flush right — an always-reserved availability slot sits after them and takes width from the agent name
- #2643 a pull-dispatched terminal never triggers SUB-003 — the switch hook is missing on
apply_task_result - #2661 the sync /task route has no queued_timeout receipt — the MCP gateway kills the held fetch and the caller sees 'fetch failed' while the target keeps running (#914, second route)
- #2662 the model dropdown is a settings-form field parked above the composer — wrong primitive, wrong container, wrong weight
- #2666 Files tab preview clips every line off-screen with no way to scroll — one unbreakable token blows the pane past the panel's overflow-hidden edge
- #2670 fan_out has no gateway-timeout receipt — the third route of the #914 class, and the one that runs longest
- #2676 The Workspace rail column steps discretely when a voice call ends (#2640 follow-up)
- #2689 /auth/exchange 500s for every caller — settings_service is used and never imported (ent#163 seam is dead)
- #2691 "Add a domain" doesn't say why, and it's unclear what the public-URL setting actually changes
- #2693 seeded default agents have no images on a fresh install — avatar generation needs a Gemini key nobody has yet
- #2694 a voice call sits at the top of the thread instead of where it happened, and the agent's next typed turn does not know what was said
- #2695 the mic renders on ElevenLabs key presence, not STT capability — a key without speech_to_text gives a control that fails every time
- #2696 the /stt 422 collapses every provider failure into "Could not transcribe the audio" while the cause sits in a backend log
- #2700 Workspace voice: an orphaned live-call marker 409s the thread for ~32 min when the socket never opens
- #2703 a library skill assigned to an agent is missing from the Workspace and every playbook list until a manual Sync or restart — and the lists never refresh on assign/unassign
- #2705 frontend-e2e nightly @smoke suite is red on dev
- #2718 the raw-colour ratchet scanner counts issue references in copy (
#190,(ent#184)) as hardcoded colours - #2726 selectable model catalog is stale — Claude Fable 5.1 (claude-fable-5-1) not selectable anywhere; tier labels + alias help text behind the current lineup
- #2730 null-session turn can render Main's previous reply
- #2733 portal file preview blocked by CSP connect-src when portal base URL is a different origin
- #2734 "Updated just now" and "may be out of date" shown together — the run that wrote the canvas marks its own output stale
- #2742 the 60s poller takes .git/index.lock ~2×/min in every agent workspace and orphans a 0-byte lock on churn — silent commit failures fleet-wide
- #2744 legacy skills-library adoption refusal files a new high-priority operator-queue alert on every sync — unbounded, never expires, unclearable by the operator
- #2759 schedule validation config is readable but not writable — create/update_agent_schedule omit validation_enabled/prompt/timeout
- #2763 legacy skills-library adoption compares a raw URL to a normalized one, so the same repo never matches and every sync alerts
- #2766 Workspace thread titles use the instance Anthropic API key over the agent's own subscription
- #2767 issue-status-on-merge cannot relabel issues when the merged PR came from a fork
- #2789 SUB-003 post-switch auto-retry is capped at 300s regardless of the agent's execution timeout — long turns die mid tool-use
- #2792 Workspace room inlines unrelated live executions of a working agent as room work cards
- #2794 attachments are dropped when a 1:1 chat is escalated into a room via @mention
- #2795 running executions in a room cannot be stopped — no Stop on room tiles or the Work tab
- #2800 agent_sync_state.git_dir_bytes is a 32-bit INTEGER on PostgreSQL — .git over 2 GiB breaks the sync-state upsert
- #2802 stale tests in the live-backend, e2e, and Postgres tiers drifted from August/September code changes
- #2812 the journey tier's model gate reads the pytest host's environment, so keyed journeys skip invisibly on subscription-authenticated stacks
- #2814 issue promotion has not run since #2769 — the pull_request_target trigger is inert until it reaches main
- #2815 an unaddressed /review finding is invisible to the PR queue, so ejected PRs get re-validated from scratch on the next train
- #2822 issue-status-on-merge has not run since its trigger moved to pull_request_target — every merge since 2026-09-14 needed a manual status-in-dev bump
- #2827 seven more agent_sync_state columns accept a 63-bit agent value into an int4 column on PostgreSQL
- #2828 an Alembic version-line fork passes every required check, and the backstop for it is defeated by a learnings.md conflict
- #2829 tests that assert source TEXT instead of executing the path — three green-CI ejections in one train, third run running
- #2850 Playbooks show no description when allowed-tools uses Claude Code's comma-separated form — Pydantic rejects the string and the fallback nulls every field
- #2859 test isolation: dev push unit suite red since #2487, 13 test_ent615_token_free_remotes failures from tests that reset services.git_service without its submodules
Private tracker (trinity-enterprise):
- ent#338 loop
timeout_per_runis never clamped to the agent'sexecution_timeout_secondscap - ent#461 Shared file links (share_file / /api/files) unusable on mobile: no Range support, forced attachment, CORP same-origin
Security
- #2261 a client session that EXPIRES on a browser holding a platform login falls back to the platform identity
- #2322 /token returns HTTP 200 with an unusable access_token while a 2FA challenge is pending — silent break for password-grant machine clients
- #2323 machine identities for admin/ops APIs — service credentials that survive enforced 2FA
- #2381 fresh install leaves setup_completed=false with a real admin — unauthenticated /api/setup/admin-password overwrites the admin password
- #2411 the SSH access toggle reads the wrong payload shape — it always renders OFF and the first click inverts the operator's intent
- #2692 step-by-step hardening for a marketplace install — Cloudflare Tunnel and Tailscale VPN
- #2791 main app and Workspace disagree about the platform session — two credential sources, no cross-tab sync, three 401 logout paths; a stale Workspace tab logs a fresh re-login out
- #2807 a denied chat_with_agent / fan_out call is audited as a successful tool call
Private tracker (trinity-enterprise):
- ent#345 guardrail hook registration lives in agent-writable, git-synced ~/.claude/settings.json — an agent can disable its own guardrails
- ent#363 Workspace: tell an agent when a room is user-facing
- ent#435 live credentials stored in cleartext in system_settings (anthropic_api_key, github_pat, slack secrets) — CWE-312
- ent#467
/wsbroadcasts fleet-wide agent_activity (execution ids, agent names) to any authenticated user — scope by accessible_agents - ent#580 first-run admin claim on marketplace installs — the operator sets the admin in the browser, not the droplet console
- ent#614 actor attribution on chat/task/fan-out trusts the raw X-Source-Agent header from human principals — a permitted user can attribute their action to an agent in the SEC-001 audit log
- ent#615 the fleet PAT is readable inside every agent container — embedded in remote.origin.url and exposed in git child argv on every sync-health fetch
- ent#628 run_agent_loop skips checkAgentAccess — an agent-scoped key can start a loop on any same-owner agent without a permission edge
Refactors
- #1028 split oversized backend routers & services (settings, public, agent crud, git, agent_client)
- #1921 replace bespoke spinners with skeleton placeholders on non-chart surfaces (scanline stays on charts only — design-system p12 as amended 2026-09-06)
- #2085 Seed retention rows on existing installs, not just fresh ones — the remaining half of #1638
- #2163 the roster's latency floor is its slowest agent — defer briefing hydration off the critical path
- #2314 decompose task_execution_service.py — uncovered top-3 code-health hotspot (dispatch hot path)
- #2337 extend the orchestration invariant catalog to journey-level invariants
- #2361 The next dev→main release PR needs an
alembic mergerevision — 0044 forked the version line at 0038 - #2461 one pytest shard in ~40% of runs is killed by the 45-minute cap — parallelise with xdist instead of buying minutes
- #2492 delete 11 unreferenced Vue components and views (~2,800 lines with zero importers)
- #2493 remove dead modules — utils/errors.py, the two OSS-move schema shims, scripts/poc, and 14 vulture hits
- #2540 the scanline reveal is for chart loading only — take it off the Workspace stage, thread and briefing; pages and lists load with skeleton placeholders
- #2545 bump the bundled community-catalog pin to trinity-skills v0.2.0 (lockstep with the library release)
- #2559 retire the chat-panel voice overlay — the Talk button opens voice in the Workspace
- #2669 No OSS guard stops a fourth get_or_create_installation_id call from a read path — the guard lives in the private repo, the accessor lives in OSS
Private tracker (trinity-enterprise):
- ent#443 Move multi-agent rooms (shared_sessions) into OSS core — ent#356 shape, no data migration
Documentation
- #2306 split architecture.md into a lean always-loaded core + per-area reference files
- #2339 consolidate docs/testing — 17 files to STRATEGY.md plus pointers
- #2593 install-provenance flow still describes the hardening card as single-stage (superseded by #2564)
- #2642 architecture area files are read deliberately — drop the unwired PreToolUse hook, state the rule in the core
- #2869 user docs synced with the release payload, a new Deploy on DigitalOcean guide, the managed-hosting option removed (Trinity is self-hosted), FAQ grown to 499 questions, and this release's What's New page (PR, no tracker issue)
Other fixes
- #2577 Canvas published with audience: operator is silently invisible to roster/public-link viewers
- #2796 Interactive chat sends the caller's role as the model — agent runs fail with unrecognized_model: "admin"
Delivered inside the enterprise module
7 further private-tracker items shipped inside the private enterprise submodule (pin 65182c1 → 08cd4dd). Per the open-core docs rule (trinity-enterprise#45), they are not enumerated here.
Other changes
- 19 dependency bumps (dependabot)
Abilities Marketplace (ecosystem)
Updates to the abilities plugin
marketplace during this release window (2026-08-17 → 2026-09-17). No PRs merged
and no marketplace releases were cut this cycle; all six items landed as direct
commits and are referenced by short SHA.
- create-agent: create-agent 2.0.0 retires eight domain wizards
(chief-of-staff, doctor, ghostwriter, kb-agent, prospector, receptionist, recon,
webmaster) and keeps custom and website plus the create router, review, adjust
and clone. The router menu shrinks to match (create 3.0). Also: operator-queue
file key corrected (custom 1.12) and report-guard checks (review 1.7)
(f84bbce). - trinity: trinity 2.9.0 is a platform-truth sync to 0.9.5. It covers the
pre-installed plugin (ent#411), the platform-denied tools (#2468),
turn integrity (#2467),fan_out_timeout/get_fan_out_result(#2670), loop
caps (ent#338/#2523), the first-run 403 (#2381), nginx/mcp,--hosted
images and a refreshed deploy-new-instance (f84bbce). Separately,
create-dashboard 1.2 drops the fictionalchartwidget type and teaches
id-keyed sparklines and the markdown widget (#2110) (b19ccc8). - agent-dev: runtime skills are authored once. The
project-*skills
(project-init, project-task, project-steward, project-reconcile,
project-intake) became standalone skills that installers copy, so
add-project-management 2.0 and add-backlog 2.1 stop embedding drifted copies
(e5db6dd). Also: commit checkpoint mode stages the agent-state set and never
credentials (7090c8b), strict-YAML-safe changelog quoting (7ff567a), and
agent-dev 1.16.1 platform-truth notes: rooms in OSS,fan_outsemantics,
thedeploy_localmanifest (#2060), managed settings (ent#345) (f84bbce). - Marketplace-wide: the v0.9.0 platform-truth refresh of the
trinity-knowledge pack covers the headless fork wait, the.mcp.json
public-URL rule, the agent-scoped report guard and the autonomy banner
(4e3d050).
⚠️ Behavior changes / upgrade notes
Rebuild the platform images, or pull them
Build-from-source installs: the backend image now copies the OSS
shared_sessions package (ent#443), and both frontend Dockerfiles changed.
start.sh does not rebuild images, so build them first:
git checkout v0.9.5
docker compose build
./scripts/deploy/start.shNew: hosted installs can skip the build entirely. ./scripts/deploy/start.sh --hosted pulls the published GHCR images (#2280). Pin TRINITY_IMAGE_TAG
(v0.9.5 or 0.9.5) on any instance you keep: latest moves with every
release, so an unpinned start.sh --hosted is an unscheduled upgrade.
Rebuild the agent base image, then restart agents
27 files under docker/base-image/ changed. Among them: the git credential
helper (ent#615), managed guardrail settings (ent#345), the event-loop and
reader-deadlock fixes (#2398/#2455), the removal of wake-up tools that never fire
in headless runs (#2468), the comma-separated allowed-tools parse (#2850), and
Codex API-key auth (#2208).
Operator action: run ./scripts/deploy/build-base-image.sh, then stop and
start each agent (or use Operating Room → Restart All). A cold stop/start
recreates onto the rebuilt image.
Existing agent containers need a restart policy (#2541)
New and recreated agents are created unless-stopped. Containers created
before this release are still on Docker's default no, and will stay down after
a host reboot until they are recreated. The census and one-shot
docker update --restart unless-stopped fix are in
docs/migrations/AGENT_RESTART_POLICY_2026-09.md.
Credential settings are encrypted at rest. Rotate them (ent#435)
The Anthropic, GitHub, Google and Slack credential rows in system_settings
are migrated to AES-256-GCM envelopes on upgrade, and the cleartext rows are
deleted. If CREDENTIAL_ENCRYPTION_KEY is unset and there are rows to
encrypt, the backend refuses to start. Set the key before upgrading. Historical backups still hold the cleartext values, so
rotate those credentials. Runbook:
docs/migrations/SECRET_SETTINGS_ENCRYPTION_2026-08.md.
Git remotes no longer carry a token (ent#615)
Agent remotes are rewritten credential-less on upgrade, and git asks a
credential helper instead. A boot-time sweep, the start hook and startup.sh
converge the fleet, including agents on an older base image. No action is
needed to adopt it. Afterwards, decide
whether to rotate the platform token, since it was previously readable in
.git/config and in process listings, and backups and logs from before the
upgrade can still contain it. Agents can still read their own token from their
environment. Runbook:
docs/migrations/GIT_REMOTE_TOKEN_SCRUB_2026-09.md.
Answered asks wake an agent only when its owner opts in
An agent's owner must turn on Wake this agent when an operator answers,
per agent, in the Reliability panel before an answered ask re-triggers it. It is off by default
because each wake-up is a paid turn, and the toggle is human-only: an agent
key cannot switch it on.
Configuration
WORKSPACE_ENABLEDis retired and does nothing. You can delete it from.env.- The bundled community skill source now pins
v0.2.0for new installs
only (#2545). Existing installs stay onv0.1.0until an admin re-points the
source. - New opt-in outbound calls stay off until an admin consents: operator intake
contact, and Tier-2 telemetry sharing. - Images from
docker-compose.hosted.ymlhave the in-app bug-report widget
built in (VITE_BUG_REPORTING_ENABLEDis a build argument). - Marketplace images set
ADMIN_PASSWORD_SOURCE=browser. No admin exists until
the first person to open the instance creates one at/setup(ent#580). Leave
it unset on every other install. - New environment variables (all optional):
TRINITY_IMAGE_TAG·
TRINITY_INSTALL_SOURCE·ADMIN_PASSWORD_SOURCE·
WORKSPACE_VOICE_MAX_DURATION·CANVAS_MAX_PER_AGENT·
PORTAL_FILE_BURST_LIMIT/_HOURLY_LIMIT/_DELETE_BURST_LIMIT·
OPERATOR_QUEUE_EMAIL_MAX·SUBSCRIPTION_SWEEP_CONCURRENCY·
SYNC_HEALTH_POLL_INTERVAL_SECONDS·BACKEND_AGENT_CALL_LIMIT/
_QUEUE_TIMEOUT_S·MCP_CHAT_TIMEOUT_MS·MCP_RECOVERY_TIMEOUT_MS·
PRIVATE_NETWORK_CIDRS. See.env.example.
Database migrations
The PostgreSQL Alembic revisions run from 0039 to 0063, with their SQLite
twins, on a single head. They apply automatically at boot, after the
pre-migration backup. Revision 0063 widens agent_sync_state.git_dir_bytes to
BIGINT (#2240/#2800).
Enterprise instances
Bump the src/backend/enterprise pin to 08cd4dd (the enterprise-main tip).
Sessions, MCP clients and SQLite
Re-login after upgrading, since sessions rotate on backend restart, and
reconnect MCP clients. SQLite passed its announced end-of-support date
(September 1, 2026). It still runs in this release, but PostgreSQL is the
supported forward path; the guide is docs/migrations/SQLITE_TO_POSTGRES.md.
Known limitations
- Pull dispatch remains opt-in and experimental. Push dispatch is the
default; pull-by-default waits on a production soak (#1766) and the hardening
in #2842–#2846. - DigitalOcean Marketplace listing: the guided DigitalOcean install works
today, and the Marketplace image ships in this release. The Marketplace listing
itself goes live after vendor review (#2281). - Subscription headroom history is recorded but not yet charted. The admin
read is API-only. - MCP keyless email sign-in (#848) still ships default-off
(MCP_INLINE_AUTH_ENABLED). - Workspace rail tabs refresh by polling. Live-on-write updates follow.
Resolved from v0.9.0's list: deploy_local_agent archive integrity
(#2060) and Codex API-key auth (#2208).
Contributors: @dolho · @vybe · @obasilakis · @AndriiPasternak31 ·
@webmixgamer · @oleksandr-korin, with community contributions from @L4XB ·
@alex-furman · @louisss1016 · @Anai-Guo.
Commit-reconciled addendum (post-release)
This section reconciles the release PR's commit payload (#2268 head bcf6711
→ #2872 head b422f26, 405 commits) against the label-driven notes above.
Every issue outside the labels was already listed. No shipped issue was left
open.
Shipped after the notes were drafted (no tracker issue):
- #2876: the DigitalOcean installer defaults to
v0.9.5. The release-pin
guard (test_2380_installer_release_pin) failed on the VERSION bump, as it
was designed to, becausescripts/deploy/trinity-do-create.shstill
installedv0.9.5-rc5.
Shipped in part; these issues stay open:
- #2281: the DigitalOcean Marketplace Packer bundle, the build standard and the
catalog copy (#2471/#2522/#2680). The listing waits on vendor review. - #2238: every router declares its MCP surface, and the architecture counts
were refreshed (#2482). The remaining drift findings are still open.
Hotfix promoted to main between tags: #2406 (the sanitizer ReDoS fix for
#2398, 2026-08-26). It is already listed under #2398.
Corrections:
- The headline commit count was 877, which also counted pre-v0.9.0
dev
history that earlier releases had squashed. The exact payload is 405
commits. - Dependency bumps: 38 → 19.
- The contributors line is trimmed to this range.
- File and issue counts are unchanged: they came from a tree diff and from
the label sets.