v0.4.0
π Cotal 0.4.0 is out!
This release makes the chat read/write boundary genuinely broker-enforced, hardens the agent control plane top to bottom, and adds self-healing mesh connections.
Grab it: npm i cotal-ai@0.4.0
π Channel read ACLs (broker-enforced)
The agent-file channels / publish fields are split into three explicit concepts β subscribe (active read set), allowSubscribe (read ACL), allowPublish (post ACL, default-deny) β with subscribe β allowSubscribe enforced fail-loud. Chat reads/writes are now contained at the broker like DM/TASK: bind-only live-tail durables (an agent can't widen its own filter), name-scoped history reads, and per-channel read grants pinned to the request subject. A follow-up review closed an ACL token-aliasing hole and tightened DM/TASK metadata grants.
β οΈ Breaking: the loader rejects the oldchannels/publishfield names. Migrate agent files and personas tosubscribe/allowSubscribe/allowPublish.
π‘οΈ Control-plane security hardening
- Three-tier control authz (self-service / privileged / admin), default-deny, fail-closed routing.
spawnis a declared capability; destructive / cross-agent ops (incl.purge) are admin-only.- Loopback bind by default (
127.0.0.1);--openis now an explicit, auth-independent choice. - Spawned-agent environment isolation β only the declared allow-list is passed, never
process.env. - Fork-bomb / churn bounding:
MAX_AGENTSceiling + minimum-lifetime floor + recursive child reaping. attachterminal read/write scoped to own children, or admin.definePersonacontent/policy split with a write-once owner β a peer can't grant itself a capability or seize ownership.
β»οΈ Self-healing mesh connection
The endpoint rebuilds itself on a terminal NATS close (unacked messages redeliver on the rebound durables, so nothing is lost), plus a manual CotalEndpoint.reconnect(), a cotal_reconnect tool (Claude Code + OpenCode), and an OpenCode /reconnect command.
π§° CLI & connectors
cotal personasmanagement + dynamic shell completion; barecotalprints help;cotal setupis explicit; spawn names auto-number against the live mesh.- Opt-in per-connector MCP server sharing for spawned agents.
- Agent transcript mirroring is now opt-in (default off).
- OpenCode:
/newcontext reset keeps operator logins; spawned agents reuse local auth; the busy guard releases on any turn end so channel push survives human turns.
π Fixes
- Wildcard channel subscriptions work (
c+c.>). - Deterministic, fail-loud peer-name resolution.
- Spawn denials name the missing capability instead of blaming the manager.
What's Changed
- feat(core): self-healing mesh connection + manual reconnect by @davidfarah2003 in #48
- feat(security): control-plane hardening β three-tier authz, definePersona policy split, spawn bounding by @davidfarah2003 in #49
- fix(security): control-plane hardening follow-up + docs (re-targeted to main) by @davidfarah2003 in #51
- fix(core): make wildcard channel subscriptions work (
c+c.>) by @davidfarah2003 in #52 - docs: restructure docs and add cross-tool agent entry points by @davidfarah2003 in #53
- docs: fill package.json descriptions and list cmux + hermes in README by @davidfarah2003 in #54
- feat(manager): auto-number spawn names on collision by @davidfarah2003 in #55
- feat(opencode): adopt /new as a context reset and keep operator logins by @davidfarah2003 in #57
- feat(cli): auto-number
cotal spawnnames against the live mesh by @davidfarah2003 in #58 - fix(opencode): reuse local auth for spawned agents by @davidfarah2003 in #59
- fix(opencode): release busy guard on any turn end so channel push survives human turns by @davidfarah2003 in #60
- fix(core): make peer name resolution deterministic and fail-loud by @davidfarah2003 in #61
- feat(connector): opt-in per-connector MCP server sharing for spawned agents by @davidfarah2003 in #62
- fix: operator persona can spawn, and spawn errors name the real cause by @davidfarah2003 in #63
- feat(core): broker-enforced channel read ACLs (subscribe/allowSubscribe/allowPublish) by @davidfarah2003 in #64
- feat(cli): cotal personas management + dynamic shell completion by @davidfarah2003 in #65
- chore: changesets for 0.4.0 release by @davidfarah2003 in #66
Full Changelog: v0.3.2...v0.4.0