Changelog¶
All notable changes to this project will be documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]¶
[1.0.0] - 2026-10-18¶
release notes¶
agentteams 1.0 generates a coordinated agent team (orchestrator, governance, domain and workstream-expert agents)
from one project brief, for Claude, Copilot (VS Code and CLI), Goose, Codex, AGENTS.md and Grok. This release
collapses fourteen release candidates (rc.1 to rc.14) and everything since 0.1.0. The largest changes are a
signed, hash-chained security decision log that the constitutional gate hook enforces, and an opt-in
write_policy: "orchestrator-only" mode. In that mode only the orchestrator writes, and other agents write and
run commands through an out-of-session, OS-confined runner. Claude and Copilot (VS Code and CLI) are Stable;
Goose, Codex, AGENTS.md and Grok are Beta and outside SemVer (see STABILITY.md). If you are upgrading from 0.1.0
or from any release candidate, read "Breaking changes and migration" first.
- Install: run from a verified, detached checkout of the signed
v1.0.0tag. Pin the tag's commit, nevermain. The migration guide's "Moving to a release checkout" section has the steps. - Upgrade order:
--verify-integrityand review its HALT report; then--migrate-decision-log; then re-render; then--check-wiring. - Signing key: tags are SSH-signed by the operator. The key fingerprint begins
SHA256:IPdnLwlF; the full value is inSECURITY.md, under "Release signers".
Security and governance¶
The constitutional rules cited below are: C-2, a @security HALT is final; C-3, an agent's declared tools are a
limit; C-4, content an agent reads is data, not instructions; C-5, clearance before destructive actions.
The constitutional gate hook¶
- The gate runs under an interpreter that can import agentteams. Each Claude render, and each confined Grok
render, writes a gitignored
<hooks>/agentteams-pythonpin that names the rendering interpreter. Whenpython3can't import agentteams, the gate re-runs under the pin with a scrubbed environment. (rc.10, rc.11) #226 - No silent allow when the gate can't run. Before, a gate that couldn't import agentteams denied everything
under a confined profile and allowed everything under the default cooperative profile. Now, with no working
interpreter, a content-bearing Write or Edit gets
ask(cooperative) ordeny(fail-closed), and the reason namesagentteams --check-wiring. (rc.7, rc.10) #226 - The pin is not written without its ignore rule. When the hooks
.gitignoreis operator-owned or a symlink, agentteams leaves it alone, writes no pin and prints a notice. #226 - The gate never imports agentteams from the project tree. The repository-root fallback is removed, and the
hook drops its own directory from
sys.pathbefore any import (except under-I). The gate and the Grok shim no longer usefrom __future__ import annotations. A plantedagentteams/,json.pyor__future__.pycan no longer choose the verdict. (rc.7, rc.11) - Confined and exclusive teams get a fail-closed gate. The hook is emitted with
_FAIL_CLOSED_ON_ERROR = True, so a crash denies.--allow-fallback-fail-openrestores fail-open. The gate flips only on an explicitly set profile, not a defaulted one. Cooperative teams are unchanged. (rc.7, rc.8) - PR merges prompt the operator whatever client sends them. The gate asks on
gh [flags] pr [flags] merge, the RESTpulls/<n>/mergeendpoint and themergePullRequest/enablePullRequestAutoMergemutations, fromgh,curl,wget, httpie or an interpreter, including backslash-newline splits. "merge" in a PR body or a latergit mergeno longer prompts. (rc.9) #150, #173 - Branch deletions ask. The gate asks before
agentteams --branch-cleanupor--branch-post-merge … --apply(see "Branch lifecycle"). - Outbound sends ask. Uploads, requests built from command output or naming credentials, raw sockets, remote
copies, gists, new or repointed git remotes, pushes to a URL, DNS lookups built from output and interpreter POSTs
get
ask. Decoding is not gated. #211 - Git config writes ask. A write to any git config file is
ask, after the content scan, so a credential in it is still denied. #211 - A timed-out scan no longer allows the command. Superlinear patterns are rewritten. Commands over 32,768 characters, or with lines over 8,192, go to the operator unscanned. #211
- Opt-in per-case gate decision log. With
AGENTTEAMS_GATE_LOGset to an absolute path outside the project and any work tree, the hook appends one hash-chained JSON line per call.AGENTTEAMS_GATE_LOG_KEYadds an input HMAC. Unset, the hook behaves as before. #217 - The gate decision log holds no content. It records the decision, reason id, scanner categories, what was checked and the hook's sha256, never written content, reason text or exception text. Relative, in-project, symlinked or non-regular log paths are refused, and a failed log write never changes the decision. #217
The decision log, clearances and HALTs¶
- Decision signing is on by default. The
enforce_decision_signingbrief field (defaulttrue), emitted inreferences/agent-privilege.json, makes the gate refuse unsigned authorizing rows (PASS, CONDITIONAL, HALT-RETRACTED). It turns on at--updatewith a notice naming the opt-out. An absent file counts as off; an unreadable one fails closed. (rc.7) - The signing switch follows the brief. Every render and projection rewrites an owned switch file to match
the brief. It never relaxes a signing-governed team, and prints
SIGNING SWITCH RELAXEDorKEPT. (rc.10) #208 - A signature covers the whole decision. Signed payloads cover
scopeand theeffect_*columns, and a new optionaltext_digestcolumn binds theconditionsandevidencetext. A row whose text was edited after signing stops clearing.--sign-decisionbinds the digest before signing, and refuses a constraint-relaxing row in a log with notext_digestcolumn. A|in a signed axis is refused. (rc.9, rc.11) - An Ed25519-signed row is verified as Ed25519 for every authorizing verdict. The gate dispatches on the
row's signed
sig_schemeand verifies againstreferences/authorized-verify-keys/<key_id>.pub.pem, whateverenforce_decision_signingis. A failed check never falls back to HMAC. Operator Ed25519 retractions clear, and no HMAC secret is needed where an agent runs a render. (rc.11) - Signed logs chain.
--sign-decisionfillsprev_digest. Logs left with empty links by the old signer verify through a disclosed legacy prefix.--verify-integrityreports the prefix length and any HALT inside it, and exits 1 on a broken chain. #224 - New signed logs keep the legacy columns first, and the Goose coordination MCP server no longer rewrites the header and refuses a hash-chained log. #224
--migrate-decision-logupgrades a legacy log. It appends the missing signing columns (neverprev_digest) and an emptytext_digest, pads short legacy rows, refuses torn rows, and checks that each signed payload is unchanged. It backs up first, writes atomically, is idempotent and needs--yes. (rc.10, rc.11) #212, #224--migrate-decision-logreports what stops clearing.--dry-runlists the unsigned PASS and retraction rows that will stop clearing. The report names each revoked retraction whose HALT blocks again ("reactivates_halt": truein--json). (rc.10, rc.11)- A HALT blocks every action named in its id. A HALT matches when an action id appears as a whole token in
its id, so
m6-overwrite-render-1a2fad6blocksoverwrite. Only an exact-idHALT-RETRACTEDrow clears a token-matched HALT. Clearing-side matching stays strict. #225 - An unauthenticated retraction no longer wedges the HALT scan. A
HALT-RETRACTEDrow that fails authentication or has no evidence retracts nothing and is skipped. The HALT stays open until a valid retraction, and the error names each skipped row and why. (rc.12) - Constraint-relaxing exceptions are derived, elevated and bounded. Whether a decision relaxes a constraint
is derived from its effect, never self-declared. The HALT scan follows lineage. Relaxing exceptions need the
operator's Ed25519 signature, trust-root targets are refused even when signed, and an exception registry
enforces an aggregate cap and sunset. New: the
signingextra,--sign-decision,--audit-exceptionsand--list-exceptions. (rc.8) #46 - A superseded clearance can't be replayed. The newest matching decision row decides; if it is consumed, the gate refuses. A pre-recorded clearance yields one use. (rc.9)
- Signing needs explicit confirmation.
--sign-decisionand--sign-grantshow the payload and a review sha256, then need[y/N]on a TTY or--confirm-review-sha256 <digest>without one, before the key is read.--yesnever applies. Control, bidi and zero-width characters are refused. (rc.8) #9 - Signing is refused from an untrusted install. It refuses when the package,
sys.prefixorsys.executableis inside the cwd, a git work tree or an allowWrite root.--allow-checkout-signingoverrides, warns every time and is recorded in the signed row. The signing code lives in the pinnedcli/operator_signing.py, and its closure is checked against the integrity manifest before the key is read. (rc.8) #10 --sign-decisionchecks its target. It refuses an--outputthat is not a team directory and verifies each signature against the team's public key before appending. The key-provisioning helper needs--team-dir. (rc.8)- Governance logs are validated.
--verify-integritydetects malformed append-only CSV logs (field count, unclosed quote, swallowed rows) and exits non-zero. Appends are one locked, validated write. Security-gate and red-team ledger rewrites are atomic. (rc.7, rc.9) #159 - Plain
--updatedoesn't need a clearance;--overwritedoes. The destructive-overwrite gate fires only on--overwrite, which needs anoverwriteclearance.--revert-migrationneeds none, so a failed--migratecan always be undone.--from-migrate, which let the command line skip the gate, is no longer a CLI flag. (rc.1) - Gate refusal codes name the gate. Failures carry
[SEC-GATE/DESTRUCTIVE:<action>]or[SEC-GATE/INTEL-FRESHNESS]. The stale-intel refusal states how many intel-bearing placeholders it affects. (rc.7) - Threat intel is never falsely fresh. A vulnerability cache that is unreadable, not a JSON object,
schema-invalid or missing
generated_atreadsstale(freshness.cache_corrupt).--security-offlineand a failed fetch no longer blank cached CVEs, and invalid cache reads are rejected. (rc.7, rc.10) #224
Keys and grants¶
- HMAC signing keys must be strong. Signing and verifying refuse a key under 32 bytes, a known placeholder
(
...,changeme,secret,password, …) or one repeated character. This covers decision rows, waivers, grants, management directives and the runner's proposal-ledger key (file or environment). A weak key fails closed, with no bypass. (rc.12) - The signing key is unreadable in every sandbox. Keys live in
~/.config/agentteams/keys/(mode 700). Every sandbox read-denies it,permissions.denyemitsReadrules forkeys/**and*.pem(Claude's built-in tools ignore the sandbox), and the launcher masks--excludefiles. Write roots insidekeys/are refused. The provisioning script refuses symlinked or loose key directories. Legacy~/.config/agentteams/*.pemis denied. (rc.8) - Only Ed25519 grants widen a sandbox.
--sign-grant SPEC.jsonissues domain-tagged Ed25519 grants. HMAC write grants are refused; HMAC remains for grants that don't widen. The approver roster is read only from the team directory. (rc.7, rc.8) - Cross-workspace capability grants.
--issue-grantand--verify-grantsmanage signed grants with an optionalteam_id. A grant never overrides a HALT. Grants fail closed without a non-emptyreferences/security-approvers.txt. (rc.7) - Grant hardening. The grant ledger is hash-chained, so deletion or reordering fails closed. An optional
signed
issuer_rootrejects target paths outside it. Issue rejects empty,/, home-rooted or..targets and malformedexpires_at. (rc.7) signed_ledgerwarns once whencryptographyis below the pinned version, and still signs. (rc.8) #20
Management directives¶
- Management repositories. A brief can set
is_management_repoandauthorized_managers. An HMAC-signed directive verified withAGENTTEAMS_MANAGEMENT_SIGNING_KEYauthorizes only the exact non-destructive scope it names. New:--issue-directiveand--verify-directives. Off by default. (rc.7) - A directive is an authenticated operator artifact, not a tier. It can never clear C-5, pierce C-2, widen C-3 or change governance. It fails closed on an empty roster, a missing key or an invalid or expired directive. (rc.7)
- The scope denylist matches word stems, so inflections such as
deletesoroverwritingare refused, andwipe,truncat,revertanddestructare added. (rc.7) - A directive that can't be relayed goes to the operator. If it fails to verify or hits a refused scope,
HALT, constitution change or C-5 destruction, the agent asks the operator once and logs the answer to
orchestrator-escalation.log.csv. (rc.7) - Progress check-ins. At every stop, a management-relay orchestrator prints an agent-by-task progress table.
Cross-repo handoffs get one row each and escalate after
CROSS_REPO_REPORT_STALE_HOURS(default 48). (rc.7)
Content, scanning and secrets¶
- Derived content stays data (C-4). Text an agent derives from read content (decoded, translated, summarized, OCR'd, or returned by a tool or subagent) keeps the no-authority status of read content. A request to transform and follow is itself a finding. Text in the project's own records has authority only when its write traces to an operator instruction. #211
- Untrusted results are labelled. The OCR proxy fences image text with a nonce, and memory- and code-index results are labelled untrusted. #211
- The security template gates data leaving the machine, including one-off sends and rendered markdown URLs.
Pre-configured remotes and the project's own
ghrepository are exempt. #211 python -m agentteams.scan <path>scans a file or directory and returns one verdict (HALT, CONDITIONAL_PASS or PASS; exit 1 only on HALT). It opens regular files without following links, and a skipped file raises ascanner-evasionfinding. (rc.7, rc.8)- Scan patterns. The scanner adds GitHub, Slack, Stripe and JWT credential patterns and literal instruction-override strings. File paths no longer trip the credential check, and Goose and Codex references no longer raise false positives. (rc.1, rc.7)
.envfiles stay out of git.python -m agentteams.env_hygiene REPO [--fix [--execute]]reports tracked or unignored env files and Dockerfiles that copy them.--install-git-hooksinstalls a blockingenv-file-guardpre-commit hook. (rc.9)--scan-securitychecks for PII, credentials and placeholders, with live CVE, CISA-KEV and EPSS lookups. (rc.1)- No absolute home paths in generated artifacts. The delivery receipt, bridge stubs and reports, the
memory-index snippets and
build-log.jsonrecord relative paths only. (rc.7, rc.9)
Integrity, trust roots and the control plane¶
--verify-integritychecks the enforcement manifest and exits 1 on drift. A missing manifest is a finding where the repository tracks one, and the confined gate then answersask. A re-record keeps absent installed-hook pins. The grant and rank emitters and the gate hooks are pinned. (rc.7, rc.8, rc.10) #221- In the agentteams tree,
--checkfails on enforcement drift, and--write-integrity-manifestexists. (rc.7) --pin-templatesrecords template digests in.agentteams/template-pins.json(trust on first use). A mismatch is reported, not blocked, and an ambiguous pin location is refused. (rc.7)- The control plane is write-protected. Claude
denyWritecovers all of.claude(a read-only mount, so a rename fails) and.codex,.github/agentsand.goosewhen those teams exist. (rc.7, rc.8) permissions.denycovers trust roots:.claude/settings*.json,.claude/hooks/**, the signing switch, the verify-key store, operator rosters andmanagement-authority.json. Copilot and Codex teams get roster stubs. (rc.7, rc.8)- Stale protections are named. Advisories name
denyWriteentries that no longer exist and sibling teams the live settings miss. (rc.8) - Opt-in prompt-root protection.
protect_prompt_roots: trueaddsEditdeny rules for the prompt roots (instruction files, agent directories,AGENTS.md,CLAUDE.md,.mcp.jsonand others).AGENTS.override.mdis a prompt root. (rc.8, rc.9) #8 - Prompt-root changes are detected. Every render records
prompt_root_hashes.--updateand--checkwarnPROMPT-ROOT CHANGED since last build, and--strict-prompt-rootsmakes--checkexit 1. (rc.8) #8 - Planted files are named. The launcher, generation and
--checkwarn about a marker-onlyreferences/build-log.jsonand about a.codex/config.tomlthat sets approval, sandbox, notify or MCP keys. Generation and--checkwarn, and--check-wiringfails, when.claude/settings.jsonusessandbox.excludedCommands. (rc.8, rc.9) - Backups can't be loaded as agents. Backed-up
.md,.yaml,.ymland.tomlfiles and lost-fence sidecars are stored as*.agentteams-bak; older backups are renamed in place. A restore never revives a sidecar. (rc.8, rc.10) #207, #224
Security and governance templates¶
@securityvets dependencies before install. It searches advisory sources and applies a 14-day release cooldown to every install or update in every ecosystem. Distro security channels are exempt. (rc.7)- More
@securitycoverage: package-install and sudo triggers, metered-endpoint disclosure, low-level vulnerability screening, OS hardening references, an infrastructure-layer reference, AI-code insecure defaults and.envrules.@git-operationsnever commits a.envfile. (rc.7, rc.9) - Vulnerability notes in remediation plans.
remediation.plan.mdfinding rows get advisory notes from the cached KEV and OSV threat intel, with no new network call. (rc.7) - Capability keys are never applied silently. A change to
tools,model,agents,hooks,mcpServers,permissionMode,skillsormemoryis reported as a proposal with the exact line to apply. (rc.7, rc.9) - Tool grants are narrower. Claude
allowed-toolsfollowstools:, so read-only agents get no Bash, Write or Edit.conflict-auditoris read and search only.--post-auditwarns when a non-orchestrator agent holds both a write tool and dispatch (AR_WRITER_DISPATCH). (rc.3, rc.7, rc.9) - Orchestrator spawn authority and query funnel. A delegate routes user questions up to its own orchestrator, and an orchestrator can spawn a scoped child orchestrator. (rc.7)
- Bridge-refresh Pre-Flight checks are canonical in
bridge-refresh-safety.mdand bind the orchestrator,@git-operations,@securityand@cleanup. (rc.7) - Red-team audits.
agentteams --redteamruns a standing red-team audit with a self-audit phase.--redteam-freshness-check(operator-only, needsagentteams[research]) searches for new AI-attack techniques and writes candidates toreferences/redteam-freshness-candidates.md. (rc.7)
Orchestrator-only writes and the runner¶
The write_policy switch¶
write_policy: "orchestrator-only"(opt-in). Every non-orchestrator agent is narrowed to read, search and todo and told "Return Proposals, Never Write". The orchestrator keeps its tools and gains an "Applying Proposals" workflow. The team shipsreferences/write-policy.reference.md. With the field absent or"default", output is byte-identical. (rc.9)- Where the switch applies. It needs an explicit
privilege_profileofconfinedorexclusive.write_policy_frameworkslimits it when one brief emits several frameworks. (rc.9) - Frameworks under the switch. Claude is enforced. Codex is allowed on Linux and macOS and holds only when
launched through the launcher (see "Codex under the launcher"). Goose is refused
(
AGENTTEAMS_ALLOW_UNENFORCED_GOOSE_SWITCH=1is for testing only), as are Copilot and agents-md. (rc.9, rc.10) #204 - The top-level session gets the dispatch contract.
CLAUDE.mdgets "Write Policy: You Are the Orchestrator", covering nonces, the staged approval loop and--verify-proposal-ledger. Granted agents are told a write receipt is final. #204 - Existing teams adopt the switch with
--update --mergeand--reconcile-front-matter --reconcile-apply, which narrow markdown agents and add missing capability keys. Only Codex TOML needs a fresh build, or--overwritewith a recorded clearance. (rc.9, rc.10)
Proposals, dispatch nonces and the ledger¶
- Revoking an MCP grant binds live dispatches. Once a grant is removed and the runner restarted, the agent's unexpired nonces are refused on the MCP channel. Nonces issued while it held the grant carry a signed flag, and the orchestrator's queue refuses them too. Nonces issued before rc.14 have no flag and stay usable for up to 24 h; rotating the ledger key at upgrade closes that window. (rc.14) #242
- Proposals instead of writes. Agents return typed change and deletion proposals and command requests. The
orchestrator applies them with
--apply-proposaland--run-request. Identity comes from a signed dispatch nonce (--issue-dispatch --agent SLUG), never from the caller. Nonce uses are counted only just before an action, and attempts are capped. (rc.9) - Policy lives in the brief. New fields:
write_policy,agent_policies(write scopes, commands with exact argv prefixes, cwd, stdin gates),proposal_gates,protected_pathsandconfined_programs. Lint refuses shells, option or parent patterns and scopes that cover the brief or the control plane. Write scopes accept single-segment patterns. (rc.9) - Requests fail closed. A proposal outside its scopes, in the control plane, stale or failing a gate is
refused. Commands get a scrubbed environment; an undeclared write fails the run (exit 3); a timeout kills the
process group. An empty
stdin_gateslist is refused. (rc.9) - A signed proposal ledger.
.agentteams/proposal-ledger.jsonllogs every action and refusal, HMAC-signed and hash-chained with a signed head anchor.--verify-proposal-ledgerchecks it. (rc.9) - Where the ledger key comes from. The runner reads it only from a 0600 file in
~/.config/agentteams/keys, and refuses to start with a ledger key in its environment. Other ledger operations take the key file or the environment (AGENTTEAMS_PROPOSAL_LEDGER_KEY, falling back toAGENTTEAMS_DECISION_SIGNING_KEY). (rc.9, rc.12)
The runner¶
- The runner's own heartbeat never fails a command. A confined command that outlasted a heartbeat tick used to
fail with exit 3, because the runner counted its own
.agentteams/runner.heartbeatwrite as the command's undeclared write. That file is now exempt, but only when an OS sandbox ran. A lock keeps a snapshot from ever seeing a half-written beat. Unconfined runs are unchanged. (rc.14) #242 - An out-of-session runner.
agentteams --serve-requestsruns outside every agent session, alone holds the ledger key, and serves a queue in.agentteams-queue/. Under the switch the proposal commands queue and wait;--wait-resultwaits again. One runner serves a project. Command output is capped and the heartbeat has its own thread. Restart the runner after updating. (rc.9) - The sandboxed orchestrator reaches the runner. The runner publishes its heartbeat and sealed results in the
read-only
.agentteams-status/. Clients without areply_keyare refused. (rc.10) #203 - Staged writes by default. Agent writes are staged under
.agentteams/staged/after every check. The orchestrator uses--list-staged,--show-staged,--apply-staged SID(re-checked against the current file) and--reject-staged. Deletions are always staged. (rc.9) - Direct writes only under an operator grant. The runner applies a write directly only under a verified
operator Ed25519 grant that binds the agent, tools, scopes, gates, server hash, expiry (30 days at most) and a
write cap, with an aggregate cap of 3. New:
--sign-mcp-direct-grant,--list-mcp-direct-grantsand--revoke-mcp-direct-grant. (rc.9) #166 - The
agentteams_runnerMCP server. Agents named in the newmcp_grantsbrief field get exactmcp__agentteams_runner__<tool>names and the server (write_file,delete_file,run_command,read_file_hashed,request_status). It holds no key, serves one agent, launches pinned (python3 -I -S) from.agentteams/bin/, and records no machine path. The runner takes the channel from the queue directory and binds each request to its nonce's agent. (rc.9) - The runner names the reinstall command when the operator's confined file is out of date. (rc.10)
Confinement¶
- Runner commands run in an OS sandbox. Every
--run-requestcommand and pre-write gate runs confined. Leftover processes fail the run. With no usable sandbox the runner refuses unlessallow_unconfined_runsis set, which is logged. Write roots must be real, symlink-free in-project directories. (rc.9) - On macOS the sandbox is Seatbelt: writes only to declared roots and a private
TMPDIR; the control plane, ledger, queue and.gitdenied; the key directory unreadable; only declared programs run. On Linux it is bwrap, with the same write rules and a PID namespace, but no program allowlist. (rc.9) - The confined-programs file is operator-owned. The runner reads
confined_programsfrom~/.config/agentteams/confined/<project>-<hash>.json.--install-confined FILEinstalls it only on a rerun with a matching--confirm-review-sha256. Commands take a per-entry timeout. (rc.9) - Gate programs are bound.
gate_execentries are bound to the gate argv (gate_argv_sha256), and a gate whose programs overlap a write root is refused. (rc.9) - macOS: xcrun launchers reach their real tool. For a
/usr/binprogram that is an xcrun launcher, such as/usr/bin/git, the profile also allows the real tool by literal path, and for git its--exec-pathhelpers. Paths come fromxcrun --findunderxcode-select -p, and only root-owned paths are kept.--check-wiringreports each launcher's expansion and warns on unresolved ones. (rc.13) - Write roots over package stores warn. A root that covers
.lake/packages,node_modules,site-packages,.venv,venv,vendor,.cargo/registry,Podsor.gradlewarns at--install-confinedand each run. A run that also depends on an unresolved launcher is refused unless the entry setsallow_unresolved_launcher_with_package_store: true. (rc.13) - Claude sandbox confinement by profile.
privilege_profiledefaults toconfined, which emits a sandbox block that confines Bash and child writes toworkspace_write_rootsonce merged;"cooperative"opts out.exclusivealso denies reads of a curated set plusprotected_read_paths. The block sets"failIfUnavailable": true. An unknown profile fails the build. (rc.7, rc.8) - Write roots are checked. Generation refuses roots at
/,~,$HOMEor their ancestors, the key directory, credential paths, control-plane directories and paths with shell or glob metacharacters. A new root outside the project needs--accept-write-root PATH, and each added root printsSANDBOX WIDENING. (rc.8) - Confinement fails closed only where the host has no boundary. Claude has its own sandbox, and on Linux and
macOS the other frameworks are confined through the launcher. On native Windows and other platforms, a
confinedorexclusivebuild for a non-Claude framework exits non-zero unless--allow-unenforced-confinementis passed. (rc.7) - Fail-open settings are named.
--update,--dry-runand--checkprint a notice for a merged Claude sandbox withoutfailIfUnavailable, and an advisory for a confined team with no sandbox merged. (rc.8) - The
confine-run.shlauncher binds the control plane read-only, including all of.claude, and self-binds its ancestors. It refuses symlinks and hard-linked protected files, and adds--protect PATH. On macOS its Seatbelt profile matches Linux. (rc.8, rc.9) #8 - Launcher behaviour. It uses a default-deny environment allowlist and runs on bash 3.2. A framework's
control-plane entries are required only when its agents directory holds a build-log marker. New:
--protect-prompt-roots(Linux) and--coord-root PATH. (rc.7, rc.8) #8, #78 - Goose's macOS Seatbelt profile denies all of
.claude, as on Linux. (rc.8) #86 - Goose Linux runner: shell injection fixed (HIGH). Write roots were pasted raw into an operator script. They are now validated and shell-quoted. (rc.8)
- Linux setup.
scripts/install-sandbox-deps.shinstalls bwrap and socat and diagnoses AppArmor user namespaces;test-sandbox-apparmor-userns.shprobes a profile. (rc.8)
Codex under the launcher¶
- Codex runs under agentteams' launcher. This is how Codex holds under the switch (see "Frameworks under the
switch").
confinedandexclusiveon Codex expand tocodex:sandbox. Linux and macOS teams get.codex/confined-run.example.sh, which runs Codex insideconfine-run.sh. (rc.9) #160 - A per-project
CODEX_HOME. The launcher validates it and makes its config, hooks, prompt and plugin files read-only. (rc.9) #160 - The Codex role gate. Under the switch, Codex teams get
.agentteams/bin/codex-role-gate.py, the pinned read-only file server and.codex/hooks.json. Calls from a spawned agent may use onlyagentteams_readfsread tools; every call is denied withoutAGENTTEAMS_CODEX_CONFINED=1. (rc.9) #160, #167 - The runner checks the gate before starting. It refuses unless the gate, server and hooks file match their pinned hashes, and refuses nested Codex config. A self-probe before every confined launch checks that keys are unreadable and the control plane is unwritable. (rc.9) #167
MCP servers and checks¶
- A foundational MCP server catalogue. First-party read-only
recallandgitreadservers are on by default wherever an MCP host feature is set;github-read,github-write(no merge, delete or fork) andfetchare opt-in.agentteams --serve-mcp {recall,gitread}runs them over stdio, confined to the project. Nothing is emitted under the switch. New brief fields:mcp_catalog,mcp_catalog_exclude,pr_management. (rc.9) #150 - The MCP-need protocol. Under the switch, teams decide from runner-ledger evidence whether an agent needs an
MCP server, keep
references/mcp-needs.csv(orchestrator-only), and route every capability-gap plan to the orchestrator.--mcp-need-reportsummarizes the evidence per agent. (rc.9) AR_WRITE_POLICYaudits the switch. Under the switch it errors on any non-orchestrator agent that can write, on capability front-matter keys, on a shell on any non-orchestrator agent in a team with grants, on a granted agent that isn't rendered exactly, and on an orchestrator without "Applying Proposals". Every render warns[WRITE-POLICY]for adopted agents that fail it. (rc.9)--check-wiringcovers the switch. It refuses any config that definesagentteams_runner, checks the required deny rules and that the sandbox is enabled, refuses loadable files in the backup tree, and flags a project-localpython3. (rc.9, rc.10)--check-wiringrefuses unsafe status-channel setups: a Read rule on.agentteams-status/,allowUnsandboxedCommands, and any Linux host for a team under the switch, until the runner's status channel is measured under bwrap. (rc.10) #203
Frameworks¶
Claude¶
- Skills are discoverable. Skills are emitted as
.claude/skills/<name>/SKILL.md, so they run as/namecommands. Old flat files get a notice and are never deleted.recallleads with lexical search. (rc.7) - Bridge features (
bridge:copilot-vscode-to-claude:*): subagent stubs, example hooks, a cache-splitCLAUDE.md,/scheduleroutines and a plan-to-TodoWrite skill. (rc.7) - The team builder launches. Its file has front matter, and under the switch its canonical tools map to Read, Grep and Glob. (rc.7, rc.9)
- Claude Code version tripwire.
--check-wiringnotes when the installedclaude --versionhas no recorded sandbox test pass. (rc.8)
Copilot (VS Code and CLI)¶
- copilot-cli emits
.github/agents/*.agent.md, the VS Code format, instead of.github/copilot/<slug>.md. Old files are left as orphans. Sync refuses copilot-vscode and copilot-cli together;--frameworksnarrows the set. Interop into copilot-cli keeps tools, model and roster. (rc.7) user-invokableis renameduser-invocable; deployed files migrate automatically. (rc.7)- Body size. A body over 30,000 characters warns on native generation and is refused on interop. (rc.7, rc.10) #210
--updatenever blanks an orchestrator'sagents:list, and filtering handles flow and block lists. (rc.1, rc.7)
Goose (Beta)¶
- Goose support.
--framework gooseemits recipes, orchestratorsub_recipes,AGENTS.md,.goosehintsand a team builder. Goose is a convert and bridge target..goosehintsno longer importsAGENTS.md, which Goose reads natively. (rc.7) - Grant-scoped recipes.
goose_tool_scoping: "grant"derives each recipe's extensions from its declared tools (verified on Goose 1.37.0). In rc.9 the switch forced grant mode; the switch itself is now refused on Goose, so setgoose_tool_scopingdirectly. In legacy mode an empty extension list emitsextensions: []. (rc.9, rc.10) agentteams_readfs. Read-only agents read through a read-only stdio file server shipped as package data and launchedpython3 -I -S. (rc.9)- Recipe checks.
--post-auditreportsAR_GOOSE_GRANT_EXCEEDED,AR_GOOSE_MARKER_MISSING,AR_GOOSE_READONLY_WRITEandAR_GOOSE_EXTENSIONS_FAIL_OPEN. An operator MCP server's name never excuses a builtin.--checkcompares the installed Goose version with 1.37.0 (advisory). (rc.9) - Delegation is narrowed. In grant mode the orchestrator recipe lists the exact
extensionsargument for each sub-recipe; unknown targets get onlyagentteams_readfs. This stays cooperative. #206 - Merge keeps recipes intact.
--update --mergereconcilessub_recipesandextensionsfrom the render, keeps enriched bodies and valid YAML, puts new sections insideinstructions: |, and adds a Project-Specific Notes region. It removes hand-addedteam-builderentries fromsub_recipes. (rc.8, rc.9, rc.10) #15, #189 - Goose leaves other owners'
AGENTS.mdalone. It no longer overwrites a rootAGENTS.mdit didn't write, and marks its own. (rc.10) #222 - Runtime helpers.
goose-run-resilient.pyresubmits dead turns; an OpenRouter route proxy and--providerspreflight help with backend routing; a coordination MCP server andcoordination_write_rootssupport cross-repo work. (rc.7, rc.8)
Codex (Beta)¶
- Agents are
.codex/agents/*.toml. Tools and handoffs go into a fencedcodex_translationblock, which is template-authoritative. Tool docs are.agents/skills/<slug>/SKILL.md. Handoffs are pruned to the roster. (rc.8) #25 - Every role gets an explicit
sandbox_mode:workspace-writeonly when it declares edit, otherwiseread-only, which means no edit, execute or retrieval. Read-only agents get a "Reading on Codex" section (the role-gate version under the switch); shell agents get a "Secrets on Codex" section. (rc.9) #132 - Codex bodies update. Agent bodies are fenced, and
--update --merge --yesretrofits legacy files. Every native agent has a Project-Specific Notes region, so--update --overwritecarries notes. Learned blocks sync to and from the TOML. (rc.9, rc.12) - A merge never writes an agent TOML that doesn't parse. Every merged
.tomlis parsed before writing; a failure is refused, the file is left as it was and the run exits non-zero. (rc.11) - MCP.
codex:mcpwrites read-only servers into a managed block of.codex/config.tomlwithdefault_tools_approval_mode = "prompt". (rc.7, rc.8) - Shared
AGENTS.md. A foreign or symlinked rootAGENTS.mdis never written, even with--overwrite, and even before.codex/agentsexists. (rc.8) AGENTS.mdunder the switch. A goose-ownedAGENTS.mdgets only acodex_write_policyfence; a hand-written one gets a paste-in file under.codex/examples/(not when it is a symlink). (rc.11)- Codex is an interop source, with a lossless round trip. (rc.8)
AGENTS.md¶
--framework agents-mdemits a neutral repository-rootAGENTS.mdplus.agents/. It is generate-only, and it still overwrites any owner'sAGENTS.md. (rc.7, rc.10)AGENTS.mdcarries the constitutional rules in a template-sourcedconstitutional_rules_baselinefence, with a heading for project extensions, and a## Code Stylesection fromstyle_rules. (rc.7, rc.8) #16
Grok (Beta)¶
- Grok Build adapter.
--framework grokrenders.grok/agents/<slug>.mdwithout default tools or MCP inheritance, co-ownsAGENTS.mdthrough agrok_runtimefence, and protects.grok/. It works with interop,--absorband fleet; convert and bridge refuse it. (rc.10) #214, #216, #218 - The Grok hook gate is advisory. A pinned shim runs the unmodified gate and fails open. #216
- No widening on Grok. Scoped
tools:entries andMCPToolare dropped, and denies are applied by leaving the tool out. A deny list that leaves no tool is refused.--update --mergenames any.grok/agentsfile that still widens. #227, #228 - Run an agent by path:
grok --agent .grok/agents/<slug>.md. Grok 1.0.52 can't spawn custom subagents. #227
Interop, sync, convert and bridge¶
--interop-fromnever widens a grant. Each projected agent is re-read as its target reads it and checked against its source grant before anything is written. Pinned sync and--convert-fromcheck every agent first. Front-matter values are written on one line and quoted. #210--interop-allow-cooperative SLUG[,SLUG…]. A narrow agent projected to Codex (outside its role gate) or agents-md is refused unless named here. Naming it needs a decision log and records a row. #210- Interop carries the switch into Claude.
--interop-from DIR --framework claude --description BRIEFapplies the brief'swrite_policyandmcp_grants, so adopted bespoke agents get the runner. A non-Goose bridge orchestrator is narrowed, not refused. (rc.9) #174, #178 - Interop into Goose under the switch is refused, because the switch is refused on Goose. Without the switch,
interop into Goose works; a pinned sync to Goose needs the pinned
agentteams_readfsserver. (rc.10) #210 - Convert and bridge refuse a switched team.
--convert-fromand bridge subagent stubs refuse a team under the switch and point to interop. (rc.9) #183 - Interop-projected teams are visible. Codex, Copilot and Goose projections write a team marker, so fleet,
--checkand the launcher see them; the marker authorizes nothing. (rc.9) - Skills.
--interop-skills-onlyimports skills only. Skill paths are contained, descriptions are kept and safely quoted, and slugs are validated. (rc.8) #71 - Pinned sync.
sync_pinkeeps several framework renders in step from one canonical source. Unchanged agents are left byte-identical, instruction files receive only fenced regions, and projections back up first.--sync-initand--synctake their root from--project. (rc.7, rc.8) - Canonical format. The CAI round trip keeps capabilities, tool scopes, names and descriptions. A canonical
directory can be a bridge source,
--framework genericis a bridge-only target, and--package-teamexports a portable zip. (rc.7) - Bridges.
--bridge-mergeleaves project-owned entry files and native agent bodies alone and says so; the banner names the mode; the check report records a source digest. Bridged Goose teams documentagentteams.research. (rc.7, rc.8) - Framework watch. Every team ships
references/framework-watch.reference.md.--agent-checkand--framework-freshnessreport provider drift and stale renders;--stale-checkreportsPIN_UNSYNCABLE. (rc.1, rc.8) - Scoped Bash support is tracked. The framework watch records whether upstream docs show that Claude honours
Bash(...)scopes in subagents. Only a person may mark it supported. (rc.7)
CLI and pipeline¶
Update, merge and fences¶
--updatemerges by default. It preserves content outside fences; a full re-render needs--update --overwrite. Byte-identical files are not rewritten. (rc.1)- Fenced sections. Merges update fenced regions only, and every persona has a Project-Specific Notes region.
Legacy files are wrapped in a
contentfence on--update --merge --yes(--no-add-fence-markersopts out), and a stalecontentfence is migrated to named fences. (rc.1, rc.7, rc.10) #201 - Fence tools.
--add-fence-markersadds fences to a legacy file.--migratetags a snapshot and re-renders with fences;--revert-migrationrestores the snapshot. (rc.1) - Merges keep your edits. Missing sections are inserted in position. Front matter gets a three-way merge (skills included), keeping both-side changes as reported conflicts. Hand-written handoffs are kept. (rc.7, rc.9, rc.10)
- Merges say what they skip. Unfenced drift is reported for unedited files, and
--updatewritesupdate.report.md. (rc.7) - Shrink policies.
--shrink-policytakeswarn,halt,allow,preserve(default) andadditive. Security, constitutional andcodex_translationfences are template-authoritative. A replaced body is saved as a.lostsidecar and reported. (rc.1, rc.2, rc.7, rc.8) --shrink-allow FILE:FENCE@DIGESTliftspreservefor one reviewed section, including files above the agents directory. (rc.9, rc.10)- User regions survive
--overwrite. Project-Specific Notes and Rules are carried into the new render;--discard-user-regionsopts out. (rc.9) - Project Layout region. A USER-EDITABLE Project Layout region in the instruction files overrides the generated layout. (rc.10) #193
- Fence twins. An unfenced copy of a fenced section is dropped only on proof. A row in
references/fence-twin-acks.csvacknowledges a twin kept on purpose; fleet flags new acknowledgements once. (rc.10) #198, #199 - Previews.
--update --dry-runpreviews every action, including front-matter capability changes;--jsonprints pure JSON.--checkuses the same pipeline. (rc.1, rc.7) --reconcile-front-matterreports divergence from template front matter;--reconcile-applyapplies it and prints[CAPABILITY GRANT CHANGED]. (rc.7, rc.10)- Learned agent notes.
--sync-agent-docspropagatesAGENTTEAMS-LEARNEDblocks between framework copies. It reports by default; blocks with findings are quarantined. Regeneration keeps them. (rc.9) - Safer targets. A relative
--outputon a foreign git-tracked directory is refused (--allow-foreign-output)..vscode/tasks.jsonis never written outside the output tree. An in-sandbox--updaterefuses before writing. (rc.7, rc.8) --selfwithout--outputwrites to the chosen framework's agents directory (.claude/agentsfor Claude). It refuses when that directory's signing switch is weaker than.github/agents. (rc.10)--updateon a bridge target needs--materialize-native. (rc.7)
Adoption, fleet and backups¶
- Adopting bespoke agents.
--adopt-orphansadds agent files to the roster. With--updateit is append-only and needs a once-only operator Ed25519 decision (adopt-orphans-merge). (rc.7, rc.9) --adopt-only SLUG[,SLUG…]adopts a named subset and touches only the orchestrator. Adopted agents are routed in every orchestrator. (rc.9, rc.10) #209--overwritekeeps adopted routing rows. It refuses with[ADOPTED-ROWS] blockedrather than drop a row whose agent file still exists. (rc.9)--fleet DIRupdates many workspaces in process (dry run by default). It skips its own output, worktrees and submodules, refreshes bridges from their recorded source, detects USER-EDITABLE regions correctly, and reports shrink grants and tracked volatile churn. (rc.7, rc.9, rc.10) #181- Backups. Writes are atomic and backed up to
.agentteams-backups/with a hash manifest. New:--list-backups,--restore-backup,--verify-backup,--prune-backups,--backup-mirrorand--no-backup. (rc.1, rc.7)
Retrieval, research and indexes¶
- Memory index.
references/memory-index.jsonis a BM25 index the navigator queries first. Results carry a confidence label. Paths are relative and local paths are redacted. (rc.1, rc.7) - Memory-index shards. The index is written compactly, and above 20 MiB it is sharded into sha256-pinned parts. (rc.10) #219
- Code index.
--refresh-code-indexand--query-codesearch code and APIs from a gitignored cache that is never executed. A partition path can't leave the cache. (rc.7, rc.9) agentteams[research]. Search with a backend fallback chain, scholarly search (OpenAlex, Crossref, arXiv), a TTL cache and page fetch (400 KB cap). Theretrievaltool token grants it to two agents. (rc.7)- Browser rendering.
python -m agentteams.research browser URLrenders a page with Playwright (agentteams[browser]plusplaywright install chromium). (rc.7, rc.10) - News as perspective.
agentteams.research.newstags news sources and attributes their claims as perspective, with published dates. (rc.7) - Source allowlist presets.
SOFTWARE_CONFIG,RESEARCH_CONFIG,DATA_CONFIGandconfig_for_project_type()give per-archetype source allowlists.DEFAULT_CONFIGis unchanged. (rc.7) - Research-capability advisory. The manifest advises, and does not enable,
research_verificationwhen a team could use it. (rc.7) - Every team ships an external-retrieval quality gate: externally sourced summaries are reviewed before use. (rc.7)
Branch lifecycle¶
--branch-inventory,--branch-cleanupand--branch-post-merge. Inventory classifies branches and writes a deletion plan. Cleanup needs a once-only@securityPASS bound to the plan's hash; post-merge deletion needs an operator Ed25519 grant. Deletions are logged to a hash-chained ledger, and the gate asks before either one applies (see "The constitutional gate hook"). (rc.9) #102
Checks, audits and records¶
--verify-integritypasses on a clean checkout of a Claude team. The gate's machine-local interpreter pin is gitignored, so it is reported asLOCALwhen absent, notMISSING. Every other absence is stillMISSING, and--check-wiringstill checks the interpreter. (rc.14, found in baseAgent) #242- New checks:
--check-budget,--check-rankand--check-rank-strict,--check-wiring,--stale-checkand--stale-remediate,--capture-baselineand--check-baseline, a living-document check and a dual descriptor advisory.--post-auditand the orphan advisory work for every framework. (rc.1, rc.3, rc.7, rc.9) - The build log records which code ran.
build-log.jsonrecordsagentteams_source, and--versionprints it. (rc.8, rc.9) #40, #106 - Behavioural drift detection.
behavioral_drift.detect_behavioral_driftcompares a run's trajectory with the team's eval suite and reports divergence. (rc.1) python -m agentteams.session_scancollects known issues, pending or blocked plan steps and git status anomalies. (rc.7)- A man page,
agentteams.1, is generated from the CLI. (rc.1)
Generation and templates¶
- Tools are documents, not agents. A tool emits a reference document (Copilot) or a skill (Claude) and is no longer on the roster. (rc.7)
- The default model is Claude Opus 4.8 for every generated agent.
--cost-routingtiers are unchanged. (rc.7) - Generated references and records: an eval suite, a delivery receipt, a team graph and a model-routing
contract (
--cost-routing, off by default). (rc.1) - Eval adapters.
agentteams/eval_adapters/turns the eval suite into Inspect AI task source or an OpenAI Evals definition, without importing either framework. (rc.1) - Templates use the update features. The orchestrator gains a behavioural-verification workflow that reads the eval suite. The conflict auditor checks typed handoffs. The adversarial and work-summarizer agents query the memory index first. The agent updater documents dry-run JSON, cost routing, receipts and backups. (rc.1)
- Workflow templates: governance workflow updates, work-summary capture and backfill, the Post-Deliverable Retrospective, a post-merge CI check and parallel plan waves. (rc.1, rc.7)
- Code-hygiene and review rules: new code-hygiene rules on exception handling, AI bad habits, script-first output and dispatch tables; technical-validator rules get their own numbering; quality and adversarial checks cover claims that depend on an unstated time, place or text version; read-only roles default to terse output. (rc.3, rc.7, rc.9) #180
- A Unix-philosophy reference maps the code-hygiene rules to Unix principles. (rc.1)
- Post-production auditor template and closure-gate schemas. (rc.1)
- Opt-in agents:
@pr-manager,@pr-notifierand@pr-reminder(never merge), andagentteams-updater(proposal-only). (rc.7, rc.9) --enrichand--auto-correct.--enrichfills default template elements from project context and exportsdefaults-audit.csv.--auto-correctruns thecopilotCLI to fix audit findings, then re-audits. (rc.1)--target-host-featurestakes<namespace>:<feature>tokens that turn on opt-in emission paths. Default output is unchanged. (rc.7)- MCP server auto-detection is added but inert: default emission is unchanged. (rc.7)
- Brief handling:
{MANUAL:*}tokens become N/A outside--self; archetype matching uses word boundaries; the module-doc pair needs packaging or docs-site signals; tool docs can follow a pinned version; scripts and destructive commands are never a default task; schema fixes. (rc.1, rc.7, rc.9, rc.10) #208 - Ingest fallbacks. A Markdown brief's
project_goalcomes from an overview heading or the first paragraph. Withdoc_site_config_filedeclared, reference and style paths are inferred fromdocs/ordocs_src/. (rc.1, rc.7) devDependenciesno longer get a reference document each; they are categorisedother. (rc.7)- The
build-teamcommand is deprecated. It still works through 1.x with a warning; useagentteams. (rc.1)
Release and installation¶
- Releases.
v1.0.0is a signed tag onrelease/1.0;SECURITY.mdlists the release signing keys by tag. (rc.9, rc.10) - Install hints pin a real tag. A release or pre-release maps to its own tag. Dev and local builds pin
LAST_RELEASE_TAG, which a release PR updates withpyproject.toml. (rc.8, rc.9, rc.11) - agentteams itself is never installed from PyPI. Every emitted install command uses the git source,
pip install "agentteams[<extra>] @ git+https://github.com/jlcatonjr/agentteams.git". Commands generated at runtime pin the installed tag (…agentteams.git@<tag>). (rc.8) - Dependencies. The one runtime dependency is
jsonschema>=4.20, installed from PyPI. Optional extras:research,signing(cryptography==50.0.0),browserandtest. (rc.1, rc.2, rc.7, rc.8) - Packaging. The wheel ships the JSON schemas, the Goose helper scripts and the read-only file server, and
leaves out scratch directories.
__version__comes from package metadata. (rc.1, rc.7, rc.9, rc.10) - The
signingextra pinscryptography==50.0.0(CVE-2026-69247). (rc.8) - Environment scripts:
scripts/verify-env.py(Python 3.11 or later, git 2.23 or later) andscripts/install-agent-doc-sync.sh(systemd units for learned-note sync). (rc.1, rc.9)
Docs¶
STABILITY.mdlists the SemVer surface, a status table for all seven frameworks and the per-framework 1.0 status ofwrite_policy.SECURITY.mdgives disclosure, the threat model and the signing keys. (rc.1, rc.11)- New:
docs_src/known-limitations.md; "Upgrading to 1.0" indocs_src/migration-guide.md; Grok privileges; the confinement andproposal_runAPI pages; runtime-governance guides. (rc.7, rc.9, rc.10, rc.11) #179 - Corrected: the claim that interop into Goose is unsupported (it is supported without the switch); the Goose privileges profile; the threat-model disclosure of laundering; the waiver example's placeholder key. The CLI reference lists every flag. (rc.7, rc.9, rc.10, rc.11, rc.12)
- Release checkouts and signing. The migration guide notes that a release checkout records its pin only when
pip-installed: a source-path install (
.pthorPYTHONPATH) reports0.0.0+localand records no pin.SECURITY.mdexplains why a signer installed under$HOMEcan be refused when a repository has no.claude/settings.json: install it outside$HOME, for example under/opt. (rc.14) #237 - Architecture graph (
references/architecture-graph.mdand its SVG) regenerated for the 1.0 module layout. (rc.14) #236
Breaking changes and migration¶
This section is for anyone upgrading from 0.1.0 or from any release candidate. The steps, with commands, are in
docs_src/migration-guide.md, "Upgrading to 1.0". Run them from the 1.0 install, before re-rendering.
- Check HALTs and the chain first. Run
agentteams --verify-integrity. Its report lists each unretracted HALT that the token rule now makes blocking, with the id to retract it by. Retract what no longer applies. (Step 1) #224, #225 - Migrate the decision log. Run
--migrate-decision-log --yesfor the signing columns, row padding andtext_digest. Re-issue any revoked retraction as a signed row. (Step 2) - Re-sign rows signed before rc.9 that have a non-empty
scopeoreffect_*value, and every later row in a chained log. Don't clear the cells instead. (rc.9) - Replace weak HMAC keys. Generate a 32-byte secret (
python -c 'import secrets; print(secrets.token_hex(32))'), re-sign outstanding decisions, waivers, directives and grants, and write a new ledger key (mode 0600) before issuing new nonces. (rc.12) - Re-render, then check the gate. Re-render, or copy the template hook into
.claude/hooks/and.github/hooks/, then run--check-wiring. (Steps 3 and 4) research browser --screenshotis removed. Use thebrowser_screenshot()library call instead. (Step 5) #224- Scripted signing needs
--confirm-review-sha256 <digest>. Signing from a checkout is refused; sign from a trusted install, or pass--allow-checkout-signing. The key-provisioning helper needs--team-dir. (rc.8) - Move the signing key. The operator runs
provision-operator-signing-key.sh --migrateto move it to~/.config/agentteams/keys/, updates any exported keyfile path, and re-merges the sandbox block. (rc.8) - Grants. HMAC write grants no longer widen a sandbox; re-issue them with
--sign-grant. Createreferences/security-approvers.txtbefore issuing or verifying grants. (rc.7, rc.8) privilege_profiledefaults toconfined. To opt out, set"privilege_profile": "cooperative". (rc.8)- Decision signing is on. To opt out, set
enforce_decision_signing: falsein the brief. (rc.7) --updatemerges. Scripts that relied on a full re-render must pass--update --overwrite, which needs anoverwriteclearance. (rc.1)- Merges wrap legacy files in fences. To opt out, pass
--no-add-fence-markers. (rc.7) - The default model is Opus 4.8. A
model:value you set by hand is kept: a merge reports template model changes but doesn't apply them. (rc.7) - Sandboxes. Re-merge the Claude
sandboxandpermissionsblocks (includingfailIfUnavailable) after updating. Dangerous write roots are refused; add a new external root with--accept-write-root PATH. (rc.8) - Profiles and hosts. An unknown
privilege_profilefails the build; fix the spelling. On native Windows and other platforms without a launcher, a confined non-Claude build exits non-zero; pass--allow-unenforced-confinementor use"cooperative". (rc.7) - macOS launcher. It refuses a team that is missing a control-plane entry; run
agentteams --update. (rc.9) - The switch. It needs an explicit
confinedorexclusiveprofile, and is refused on Goose, Copilot and agents-md. Interop under the switch targets Claude only. (rc.9, rc.10) - The confined-programs file. Reinstall it once with
--install-confinedand--confirm-review-sha256, so it recordsgate_argv_sha256. (rc.9) - The runner. Clients without a
reply_keyare refused: upgrade every agentteams install that talks to the runner to 1.0, then restart--serve-requests. (rc.10) - Interop with existing agents under the switch needs
--overwrite. (rc.9) - Framework output moved. Codex agents are
.codex/agents/*.toml; copilot-cli agents are.github/agents/*.agent.md; Claude skills are<name>/SKILL.md; tools are documents. Remove the old files by hand. (rc.7, rc.8) - Codex roles. Command roles that don't declare edit are now
read-only. Declare edit for a role that must write. (rc.9) - Goose and
AGENTS.md. Goose no longer overwrites anAGENTS.mdit didn't write. To hand the file to Goose, delete it and re-render. (rc.10) - Goose and
.goosehints..goosehintsno longer importsAGENTS.md; Goose reads it natively, so no action is needed. (rc.7) - Grok scoped entries are dropped. Run
--reconcile-front-matter --reconcile-apply, or fix the files that--update --mergenames. (rc.10) - Widening interop is refused. Name each agent whose cooperative grant you accept in
--interop-allow-cooperative. Interop also refuses a Copilot body over 30,000 characters; shorten the body first. (rc.10) --from-migrateis removed. Use--migrate, which sets its gate exemption internally. (rc.1)--selfwrites elsewhere. Without--output, it writes to the chosen framework's agents directory (.claude/agents,.goose/recipes,.codex/agents,.agents). Copilot (the default) still uses.github/agents. The old location was a bug that put non-Copilot agents in the Copilot directory in the wrong format, so do not recreate it with--output; remove any such stray files from.github/agents. (rc.10)- CLI.
--updateon a bridge needs--materialize-native;--sync-initand--syncrefuse--output(pass--project). Hand edits insidecodex_translationare overwritten; move them to Project-Specific Notes. (rc.7, rc.8) scripts/resolve_fence_collisions.py --trust-provenanceexits 2. Useagentteams --update --merge, which drops a fence twin only on proof. (rc.10)- Memory index. Once one writer produces a sharded index, keep every writer on 1.0. (rc.10) #219
- Rolling back: see "Rollback A: turning
write_policyoff" and "Rollback B: reverting to rc.9" in the migration guide.
Known limitations¶
These ship with 1.0. Those from rc.10 onward are described, with workarounds, in docs_src/known-limitations.md;
the rest are stated here.
- Clearances bind by id prefix; name them
<action>-<instance>and use thescopecolumn. A CONDITIONAL PASS needsconditions_verifiedto be exactlyverified. A family retraction clears every prefix-matched HALT. (rc.10) - Logs signed before 1.0 may verify through a legacy prefix; deletions inside it, and rows cut from the tail, are not detected. (rc.10)
- Grants are cooperative, not enforced, on Goose delegation, Codex outside its role gate, agents-md and Grok. (rc.10)
- Claude under the switch is refused on Linux. (rc.10)
- Claude Code's built-in general-purpose subagent holds Bash. (rc.10)
- The research cache still writes under
references/research-cache. (rc.10) - Codex: a merge doesn't narrow
sandbox_mode; a project's own.codex/hooks.jsonkeeps the role gate out; new teams start a legacy six-column decision log; the role gate has no codex-cli version pin. (rc.11, rc.12) - A signed
overwriterow can't cover a render'sCLAUDE.mdwrite. (rc.11) - In an unconfined session, anything that can write the verify-key store can plant a key. (rc.11)
- Copilot: the orchestrator and security agents exceed GitHub's custom-agent body size. (rc.12)
- Repository scanning with
--projectcan change the roster. (rc.12) - macOS: only git gets a helper directory for an xcrun launcher, and an unresolved launcher alone warns but is not refused. (rc.13)
- Adopted agents can't be put under orchestrator-only on Codex, so a team with adopted agents keeps its Codex surface frozen for 1.0. (rc.14) #237
AGENTS.mdis not classed as a governance trust root: a clearance targeting it is classed by its other effects. Review such rows as you would aCLAUDE.mdone. (rc.14) #237- Revocation: proposals an agent staged before its MCP grant was revoked can still be applied with the orchestrator's approval. Reject them by hand. (rc.14)
- The prompt-injection evaluation (Experiment 1) runs after 1.0, under its approved test plan; it is not yet
evidence for this release. Its findings ship as
v1.0.Nfixes or 1.1 changes. (1.0.0, release notes only) .agentteams-backups/is not added to.gitignorefor you. Add it, andgit rm --cached -rit if it was already committed. (rc.1)--migrateregenerates every agent file, so content added after generation is lost; recover it from thepre-fencing-snapshottag. Use--update --mergefor routine updates. (rc.1)jsonschemais a required runtime dependency, the one exception to the base install being stdlib-only. (rc.2)- On
--update --mergeunder the default--shrink-policy preserve, a fenced section whose enriched body would shrink keeps its old body, so a brief change may not reach it; check the shrink notices. (rc.7) - The Tone and Style section names a fixed set of agents, some of which your team may not have. (rc.7)
- A confined command can be reported as failed (
undeclared_writes) when the generated Claude hook writes.claude/hook-notices/<date>.logwhile the command runs. It is a false failure, never a false pass; re-run the command. Fixed in 1.0.1. (1.0.0, release notes only; M6-F7)
[0.1.0] - 2026-04-15¶
Added¶
-
Reference: Unix Philosophy Mapping for Code Hygiene Rules — added
agentteams/templates/domain/unix-philosophy-mapping.template.mdand integrated into build pipeline. Each generated team includesreferences/unix-philosophy-mapping.reference.mdmapping rules (CH-01 through CH-23) to Unix design principles. Three-tier classification: Tier 1 (foundational), Tier 2 (aligned), Tier 3 (project-specific). See audit reporttmp/by-week/2026-W20/unix-philosophy-mapping-audit-revisions.md. -
ingestmodule: load project descriptions from.jsonor.mdbriefs; scan existing project directories to supplement missing fields analyzemodule: classify project type, select agent archetypes, detect tool agents, build team manifestrendermodule: resolve auto and manual placeholders in agent templates; compute template hashes for drift detectionemitmodule: write rendered agent files to disk with dry-run and overwrite-protection supportdriftmodule: detect content drift (template hash comparison) and structural drift (team composition changes) against build-logscanmodule: proactive security scan for PII paths, credentials, and unresolved placeholdersauditmodule: post-generation static audit plus optional AI-powered review viacopilotCLIremediatemodule: auto-correction support via standalone Copilot CLI after audit findingsgraphmodule: directed graph inference for agent team topology; outputs Mermaid, DOT, JSON, and Markdownframeworkspackage:copilot-vscode,copilot-cli, andclaudeframework adaptersbuild_team.pyCLI: 16-flag command-line interface wiring all pipeline stages- Template library at the 0.1.0 release: 9 universal governance templates, 9+ domain archetype templates, 3 builder templates, 6 workstream expert-pattern templates
- JSON schemas:
project-description.schema.jsonandteam-manifest.schema.json - Example project briefs: research, software, and data-pipeline projects
--selfmode: self-maintenance of the module's own agent team--post-auditmode: static + AI-powered conflict and presupposition review--update/--prunemode: incremental re-rendering with manual value preservation