v0.4.0 — "Proof of Presence"
Identity resolution can no longer silently misattribute a signed action to
the wrong actor — closing a real incident end to end — plus self-service
role switching with freeform custom labels, ConPTY-backed interactive-serve
on Windows, cosign-free release verification, and a deep TUI interaction
audit (the command palette, a dead keybinding, and a missing focus
indicator).
Security
- Breaking: a governed write resolved through the legacy, machine-wide
default-actor fallback is now refused outright whenever a project has
two or more locally-registered identities to choose between, instead of
silently signing under whichever one happens to be active — the exact
mechanism behind a real, confirmed incident where one agent's action was
signed under a different agent's identity. Session-scoped actor
resolution (below) already made this safe for any Claude Code/Codex
session; this closes the one remaining gap, for CLI/MCP/worker
invocations with no recognized session at all. See RFC 0017. - A provider session (Claude Code, Codex) now resolves its own isolated
default actor, instead of inheriting the one shared, machine-wide
default every concurrent session and script on the account used to read
and write. See RFC 0016. - Self-registering from a session-less caller (an opencode-based agent, a
script) no longer claims the shared legacy default-actor slot for every
other session-less process on the account — closing a second path into
the same class of misattribution the two items above close. - The project owner's role can no longer be changed through any path at
all, self-service or administrative — mirroring the existing, absolute
protectionagent suspend/agent revokealready give the owner.
Added
- Breaking: self-service role switching (
agent switch-role/
agent_switch_role) — any active principal can relabel its own role at
any time, toORCHESTRATORor any freeform custom label
(Frontend-Architect,Tester, ...), with no owner/orchestrator
elevation required. Never targets another principal, never touches
capabilities/scopes, and can never targetOWNER. Switching to
ORCHESTRATORkeeps the full existing gate: a human principal, a
pre-approved HUMAN-tier approval, and the elevated-key passphrase. The
AGENT/OBSERVERroles are removed —AGENTduplicated
PrincipalType's own value for no added meaning, andOBSERVER's
read-only enforcement covered only two transitions. See RFC 0018. interactive-serveand--takeover-pidnow work on Windows (10 version
1809/October 2018 Update or later), closing a platform gap that
previously errored outright. Built on ConPTY
(github.com/charmbracelet/x/conpty) in place ofcreack/pty, a named
pipe control socket (github.com/Microsoft/go-winio) in place of a unix
domain socket, andTerminateProcessin place of POSIX signals for
process lifecycle. See RFC 0014. Closes #17.install.sh/install.ps1andagent-comms updateno longer require a
separately installedcosignCLI to verify a release at all — a new
companion binary,agent-comms-verify, performs the identicalcosign verify-blob --bundlecheck with no external process. Realcosign
remains a fully supported, independent way to run the same check
manually. See RFC 0015.- The TUI's command palette now has real mouse support (click a match to
run it), matching every other surface in the app. - A new "change role" action in the TUI lets an owner/orchestrator change
an already-active agent's role, not just a pending one's first
activation.
Fixed
- Breaking:
agent activate --roleis now a required flag (it lost
itsAGENTdefault, sinceAGENTno longer exists as a role); and
agent activate --role OWNERnow fails for any target outside the one
special bootstrap event at project creation, where it previously
succeeded silently. - The TUI resolves straight to the project owner, instead of refusing,
when the legacy actor fallback would otherwise be ambiguous — the TUI
can only ever be driven by a human physically present at a real
terminal, unlike the CLI/MCP/worker paths the write-refusal above
correctly still protects. See RFC 0019. - The TUI's command palette leaked keystrokes into row actions if opened
from inside a focused view — a typed character could silently trigger
suspend, revoke, or delete on the selected row instead of composing a
search query. The palette's rendered "top match" could also silently
drift from what Enter actually executed, and the spacebar could never
be typed into it at all (no multi-word command was ever reachable).
Clicking elsewhere while the palette was open silently navigated
underneath it instead of closing it. - A
RowActionkeybinding could silently collide with a global reserved
key (confirmed live for the new "change role" action, bound tor,
which lost every time to the global refresh binding) with no error or
indication — rebound, and the row-action key switch now documents the
full reserved set to stop this recurring. - The TUI now shows a visible focus indicator: the active tab renders
differently depending on whether a row list actually has keyboard
focus, or a key likeris just about to hit the hub-level browsing
shortcut instead. - The TUI's actor-switch form no longer clobbers its own success notice,
no longer shows a blind list of candidate identities with no role/status
shown, and now shows which actor ID is currently active. runtime verify-adapteralso checks an adapter's subcommands' own
--helpoutput, not just the top-level command's.- An unknown CLI flag produced zero output on every platform instead of a
usage error. install.ps1's cosign prerequisite check no longer rejects a real,
correctly installed cosign: it now also recognizes
cosign-windows-amd64.exe, cosign's actual upstream release/winget
asset name, instead of only the barecosignname that no documented
Windows install method for cosign actually produces. Previously this
blocked every Windows install that followed the documented steps
exactly — see #16.
Full technical detail is below and in CHANGELOG.md.
Full Changelog: v0.3.0...v0.4.0