`.claude/agents/` was the source of truth, which made every role Claude-Code
shaped. Adding a second client meant rewriting each role in that client's syntax
and maintaining both copies — the drift this scaffold exists to prevent, one layer
up.
Roles and skills now live under `.agents/` and render into each registered
client. `.claude/agents/`, `.claude/skills/` and `.codex/agents/` are generated;
`scripts/sync-agent-integrations.py --check` fails on drift and belongs in CI.
The role metadata is portable rather than vendor-named: `reasoning_tier`
(deep/balanced/fast/vision), `capabilities`, `mutation`, `invocation`, and an
optional `preload_skills`. A client manifest maps those to native syntax and must
declare what it cannot express — `codex.yaml` declares `tier_policy: unsupported`
and its adapters say so in the file, rather than the tier silently evaporating and
leaving the repository to believe it was enforced.
The port is behaviour-preserving where it should be and a fix where it should not.
Every instruction body is byte-identical — the whole diff to `.claude/agents/` is
18 added lines and zero deletions. What changed is frontmatter that was missing:
- four agents (`code-reviewer`, `tdd-guardian`, `dependency-audit`, `pr-creator`)
declared no `tools:` and therefore inherited the ENTIRE tool pool, so three
review-only agents could edit and write the code they were reviewing. All eight
now declare capabilities explicitly.
- the six read-only roles gain a non-editing permission mode, so the constraint is
enforced by the client rather than by the prompt asking nicely.
- `mutation` is now explicit, which records the two roles that genuinely need to
write: `pr-creator` (external-write — it pushes a branch and opens a PR) and
`dependency-audit` (workspace-write — package managers rewrite lockfiles).
`pr-creator` keeps `shell` because opening a PR needs it, but it is now the only
agent here with a write mutation and a declared reason for it, instead of one of
four with unlimited access by omission.
Adds a mandatory "No Pre-Existing Issue Exceptions" policy to prevent
Claude from dismissing errors, warnings, or linting failures it didn't
write. Also extends the code-reviewer agent with an Issue Ownership
Policy requiring concrete fixes rather than passive reporting.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>