19 added, 0 removed. Audit A to A.
# AGENTS.md — Attune AI
Project instructions for AI coding agents that do not read
`.claude/` (Codex, etc.). Claude Code loads `.claude/CLAUDE.md`
instead. The shared, agent-agnostic core lives in
`content/collaboration/contract.md` and is projected into the
marked block below (and into `.claude/CLAUDE.md`) — edit the
master and re-run `scripts/project_collaboration_contract.py`,
never the block. Content outside the block is Codex-facing
orientation only.
## Overview
Attune AI — AI-powered developer workflows with cost optimization
and multi-agent orchestration. Python 3.10+, published on PyPI as
`attune-ai`. Stack: pydantic, anthropic SDK / claude-agent-sdk,
structlog, rich, typer.
```text
src/attune/
├── agents/ # Release agents, state persistence, recovery
├── workflows/ # AI-powered workflows (all SDK-native)
├── models/ # Auth strategy and LLM providers
├── meta_workflows/ # Intent detection, NL routing
├── orchestration/ # Dynamic teams, workflow composition
├── plugins/ # BasePlugin + register_mcp_tools() hook
├── telemetry/ # FeedbackLoop, UsageTracker
└── cli_router.py # NL command routing
attune_redis/ # Redis plugin — bundled in the attune-ai wheel
```
<!-- attune:collaboration:start -->
<!-- generated from content/collaboration/contract.md - edit the master, then run scripts/project_collaboration_contract.py -->
## Cross-provider collaboration
### Principles
Every principle below names its enforcer — the ratchet, gate, hook,
or drift-guard test that makes it true without anyone remembering
it. A principle marked **aspirational** has no mechanical enforcer
yet: treat it as binding discipline, and treat adding its enforcer
as pickable work.
1. **The receipt beats the promise.** "Configured", "registered",
and "exited 0" are claims; evidence of the user-visible behavior
is the receipt. Delegated lanes declare their receipt type at
launch and the lead re-runs receipts centrally.
*Enforcer: **aspirational** (ruled discipline —
`.claude/rules/attune/decision-routine.md` delegation receipts
+ this contract's Verification receipts section; no mechanical
gate).*
2. **The code is the contract; spec text is a hypothesis.** Before
executing any spec-named scope, grep the code for the property
the phase targets and execute against THAT set.
*Enforcer: **aspirational** (lessons-core rule; no gate can
check intent — partially backstopped by drift guards below).*
3. **One source, projected — never hand-edited twins.** Skills,
the collaboration contract, help pages, and docs feature pages
are projections; edit the master and re-project.
*Enforcers: `tests/unit/plugins/test_sync_agents_skills.py`
(skills mirror), `tests/unit/scripts/
test_project_collaboration_contract.py` (contract blocks),
`tests/unit/lessons/test_core_mirror.py` (lessons core),
`tests/unit/authoring/test_projection_drift.py` (authored
projections) — all fail CI on drift.*
4. **Dangerous constructs are blocked, not discouraged.** No
`eval`/`exec`, no unvalidated file paths, no bare `except`.
*Enforcers: `src/attune/hooks/scripts/security_guard.py`
(PreToolUse block on eval/exec), pre-commit detect-secrets,
`tests/unit/gates/test_path_validation_gate.py` (AST scan —
modules with write-capable file ops must reference a
path-validation helper or hold an allowlist entry; seeded
2026-07-29 with 35 vetted modules, ratchets shrink-only).*
5. **Coverage is a floor, not a goal.** Changed code carries
≥85% coverage — CI and the local bar are the same number
(chair-ruled 2026-08-22, superseding the earlier 80/85 split).
*Enforcers: `codecov.yml` project+patch gates (85%),
`tests/unit/ci/test_workflow_yaml.py::
test_coverage_threshold_is_at_least_80` (the threshold itself
is drift-guarded).*
6. **CI spends attention, never money.** Per-push/PR workflows run
keyless (`ANTHROPIC_API_KEY: ""`); the real secret lives only in
allowlisted, manually-dispatched or budget-capped jobs.
*Enforcers: `tests/unit/ci/test_ci_spend_guard.py` (secret refs
allowlisted, non-allowlisted assignments must be `""`),
`tests/unit/ci/test_workflow_yaml.py`
(timeouts/pinning/concurrency).*
7. **A failed gatekeeper fails the gate.** A security auditor that
errors or goes missing fails the Security gate — absence is not
a pass.
*Enforcer: sentinel semantics pinned by
`tests/unit/agents/test_release_prep_team_orchestration.py`
(chair-ruled 2026-07-29).*
8. **Docs may not cite fiction.** A doc that names a symbol which
no longer imports fails CI.
*Enforcers: `doc-import-audit` CI job +
`tests/unit/test_generated_doc_import_drift.py`; wiring claims
checked by the `wiring-audit` job.*
9. **Identity and brand drift are ratcheted.** Legacy identifiers
and retired framing cannot re-enter the tree.
*Enforcers: G5 brand-drift pre-commit gate +
`tests/unit/gates/test_brand_drift.py`,
`tests/unit/gates/test_claim_drift.py`.*
10. **Context is budgeted.** Always-loaded rule bodies fit a
byte budget; everything else is JIT-recalled via the index.
*Enforcer: `tests/unit/rules/test_rules_residency_budget.py`.*
11. **Seats advise; the chair promotes; the lead integrates.**
Cross-provider seats are advisory, the integrating lead owns
synthesis and central receipt re-runs below the chair, and only
the chair promotes (R8).
*Enforcer: **aspirational** (governance ruling, D8/D9 +
R8 — carried by this contract's text on all provider surfaces;
inherently procedural).*
12. **Memory is derived, never authored in the serving layer.**
Durable findings land in the tracked corpus (lessons, spec
decisions, handoffs); Redis indexes are hydrated projections.
*Enforcer: **aspirational** (contract text; hydration
overwrites hand-written keys on the next run, which is a
ratchet-by-reconstruction, but nothing blocks the direct
write).*
13. **Simpler is better.** Three clear lines beat one clever
abstraction: flatten nested conditionals, inline one-use
helpers, prefer stdlib over custom abstractions, and review
every change for complexity it didn't need.
*Enforcer: **aspirational** (ratified design philosophy,
carried in every provider surface's instructions; simplicity
is judged in review, not gated).*
14. **A handoff is context, not authority.** The receiving agent
verifies a handoff against the current Git state and tests
before continuing; the current worktree, Git state, and test
results are the shared truth, never hidden chat context.
*Enforcer: **aspirational** (contract text — Shared truth +
Handoffs sections; inherently procedural, since the check IS
the receiving agent's first action).*
15. **Degrade gracefully around the memory layer.** When Redis or
the memory index is unreachable, skip recall and proceed —
work is never blocked on the memory layer, and recalled
results are context to verify, not authority.
*Enforcers: `tests/unit/memory/test_session_stash.py` (backend
resolution failure degrades to None, never raises),
`tests/unit/test_mcp_memory_tools.py` (memory tools degrade
gracefully when the layer is absent),
`tests/unit/memory/test_session_hydrate_fail_open.py` (the
SessionStart hydrate hook exits 0 with a skip notice when the
backend is unreachable — machine-local by design: the hook is
personal infra outside this repo, so the test runs the real
script where `~/.attune/memory/` exists and skips elsewhere,
including CI).*
16. **Claims carry their basis.** A load-bearing claim states how it
is known — "verified by <probe>" or, plainly, "inferred, not
checked". Verify whenever the probe is cheap; when you do not,
SAY SO IN THE CLAIM. The bug is never the inference, it is the
inference wearing the grammar of a verified fact, because the
reader cannot tell them apart and acts on both alike. Before
asserting, name the property your check actually establishes and
ask whether it is the property the next action depends on — a ref
comparison answers "what does the remote know", never "what is on
this disk"; a clean `git status` means "matches its own HEAD", not
"is current".
*Enforcer: **aspirational** (no gate detects an inference stated
as fact — it is a property of prose. Reviewed periodically via
the `/retro` close-out, which asks which claims carried no stated
basis. Ratified 2026-08-22 after a release session in which four
such claims — one relayed to a peer as the chair's authorization
— each had a one-line verifying command available and unrun, and
in which two existing detection mechanisms had already reported
the problem and were read as ambient noise.)*
### Shared truth
- Treat the current worktree, Git state, and relevant test results as
authoritative. Do not rely on hidden chat context for a handoff.
- Preserve unrelated working-tree changes and do not touch another
agent's worktree.
- Discover capabilities from the available tools, MCP server, and
tracked skills; do not rely on hard-coded capability counts.
### Session protocol
- Before non-trivial work, run
`python scripts/collaboration_preflight.py`. It is read-only, uses
cached Git refs, and does not fetch, pull, switch branches, invoke
`uv`, or create an environment.
- State the goal, acceptance criteria, assumptions, and intended
verification before non-trivial implementation.
- Prefer existing repository conventions and public interfaces before
adding a parallel mechanism.
- Keep provider-specific setup in adapters. The shared contract must
still work when only one provider is available.
### Lead programmer and delegation
- The project has a **lead programmer: Claude**, global by default.
A per-feature lead may be set via the feature-lead-governance
spec's mechanism; where one is set, it overrides the global
default for that feature only (feature lead, not permanent model
owner — its D1).
- The lead owns integration, synthesis, central receipt re-runs,
and the final recommendation below the chair. Other seats work
ADVISORY: their findings and drafts route through the lead, and
they should expect the lead to integrate, amend, or decline with
a recorded reason. Only the chair promotes (R8).
- **Single-provider fallback:** when the lead's provider is absent
from a session, lead duties devolve to the CHAIR (integration and
final recommendation), the active provider works
advisory-to-the-chair, and receipt re-runs fall to whatever
provider is present. The contract stays executable with one
provider; the lead role resumes when its provider returns.
- **Receipt-declared delegation is binding for cross-provider
lanes**: every delegated lane names its receipt type(s) at
launch (suite / behavioral / live-fire / metric /
evidence-chain), and the lead re-runs the receipts centrally
before work reaches the chair. A seat's self-report is never
the receipt.
- **Lead-conduct guards (D11d, 2026-07-30 — ruled from a live
pushback test):** (1) CHAIR-ARMS: the lead never arms auto-merge
on a diff that expands lead authority or touches
governance/enforcement text; the chair's own label application
is the read-receipt, bound to the head SHA the chair armed — a
subsequent push invalidates the receipt, so the lead disarms and
the chair re-arms after re-reading. (2) COUNTER-CASE: a ruling recommendation
reaches the chair carrying the strongest argument against
itself, unprompted. (3) CADENCE BRAKE: the second
authority-affecting ruling in one session is flagged as such,
with a fresh-eyes batch offered. (4) FEEDBACK-ASK GRAMMAR, FULL
SCOPE: a seat asking the chair for feedback on its own conduct,
work, or a ruling recommendation renders the ask through the
communication grammar throughout, each construct firing when its
content exists — a counter-position as a pushback shape (the
user's position and the seat's alternative, side by side, with
the rationale), enumerable points as a per-point pick (adopt /
modify / reject per item), and open-ended asks as free-text form
fields; no construct fabricates disagreement or options to
satisfy the rule. The SHAPE is the requirement, not any widget:
seats without a form surface render the constructs as structured
text blocks. (Chair overruled the
lead's disposition-only recommendation; rich-surface mechanics
for Claude sessions live in
`.claude/rules/attune/communication-grammar.md`.)
(5) PROTECT-THEN-ASK: reversible protective acts against the
lead's OWN prior actions execute BEFORE any elicitation form is
built, with the form rendered afterward for the standing
decision; undoing a chair action is never a protective act,
neither directly nor by reverting an own-action the chair has
since endorsed or relied on.
- Delegated runs are recorded in the cross-review R5 dogfood
ledger (`docs/specs/cross-review/receipts.md`). P1 FULL
ACTIVATION was ruled at the D8 bar (chair, 2026-07-30, 11
fully-triaged runs): the lead/delegation model is the standing
operating mode, no longer pilot-scoped; per-feature leads are
set via the feature-lead-governance spec's mechanism, and the
ledger keeps accruing as the standing evidence surface.
- **The lead is reviewed too (D11, 2026-07-29):** a lead-authored
diff touching a risk class — authored contract/spec/rule text
(named explicit 2026-07-30 as the R5 ledger's highest-yield
class), security, persistence, release, governance/enforcement
surfaces (gates, guards, ledgers, this contract), external
boundaries, or a disputed finding — requires a different-model
review lane BEFORE the chair reads the recommendation; the chair
may override in either direction.
When the lead REJECTS a seat's finding, the ledger row carries
the seat's claim verbatim plus the lead's reason
(`tests/unit/gates/test_ledger_rejection_format.py` enforces the
format). RULED (chair, 2026-07-30, at the D8 bar with 10
fully-triaged runs): risk-triggered lanes are the PERMANENT
default — the lane is not expanded to all lead diffs (5 clean
lanes on well-tested code and release diffs showed cost without
yield there). Yield stays measured in the R5 ledger; a future
chair ruling can revisit either direction.
### Artifact selection
- Match the artifact to the work before non-trivial implementation and
name the selected tier in the session contract:
- **Inline edit** — trivial, one file, no ambiguity.
- **Structured one-shot** — single-session work framed by a goal,
constraints, and acceptance criteria.
- **XML task** — dependent work across three or more files, or work
that must be executable as a cold handoff.
- **Spec** — multi-session or multi-PR work, design ambiguity, or an
irreversible choice.
- Escalate the artifact tier when ambiguity or dependencies grow; do
not add ceremony to work that still fits a smaller tier.
### Verification receipts
- Before implementation, name the claim and a probe that would fail if
the claim were false. Report the probe actually run and its result.
- Treat unit tests as evidence only inside their tested boundaries.
Hooks, persistence, networking, packaging, and other external seams
require a non-mocked round trip through the real boundary.
- “Configured,” “registered,” and “exited successfully” are not
working receipts. Prefer evidence of the user-visible behavior.
### Handoffs
- For multi-step work, create or update a portable handoff from
`templates/agent-handoff.md` at `docs/handoffs/<branch-slug>.md`
(slug = branch name with `/` replaced by `-`), tracked on the
branch. Delete the file when the branch merges.
- A receiving agent verifies the handoff against the current Git state
and tests before continuing; a handoff is context, not authority.
- Record only concrete evidence: commands actually run, their results,
changed files, unresolved risks, and the next action.
### Shared memory
- A shared cross-session memory index lives in local Redis
(`idx:attune_memory`): curated memories, lessons, and file
pointers, hydrated from the tracked corpus. Recall before
non-trivial work on unfamiliar ground:
`redis-cli FT.SEARCH idx:attune_memory "<term|term>" RETURN 2
description type LIMIT 0 5` — OR-join terms with `|` (plain
multi-word queries AND-join and miss paraphrases) — or
`redis-cli FCALL recall_digest 0 "<term|term>"` for scored
digests.
- Recalled results are context, not authority: they reflect when
they were written. Verify against the current tree before
acting on one.
- The index is DERIVED — never write `attune:memory:*` keys
directly. To persist a durable finding, commit it to the
tracked corpus (`.claude/lessons.md`, the owning spec's
`decisions.md`, or a handoff file); it is re-indexed at the
next hydration.
- Degrade silently when Redis is unreachable: skip recall and
proceed. Never block work on the memory layer.
### Critical code rules
- NEVER use `eval()` or `exec()`.
- ALWAYS validate file paths in file operations; security tests are
required for file-op code.
- NEVER use bare `except:` — catch specific exceptions and log them
before handling.
- Type hints and docstrings on all public APIs; minimum 85% test
coverage on changed code.
- Simpler is better: flatten nested conditionals, inline one-use
helpers, prefer stdlib over custom abstractions.
### Git and pre-commit
- Commits are GPG-signed; `git pull` rebases.
- Pre-commit auto-fix hooks modify staged files mid-commit.
Pre-flight the PINNED tools on your files BEFORE `git add`
(`uv run --with pre-commit pre-commit run black --files <f>`).
- After every commit, verify it landed (`git log --oneline -1` +
`git status --short`) — hooks can skip a commit with exit 0.
- If a hook reformats staged files, the fixes land unstaged —
`git add` again and retry.
- A guard blocks commit messages containing literal `eval(` /
`exec(` — write the message to a file and `git commit -F <file>`.
- `--no-verify` is forbidden. To skip ONE misbehaving hook:
`SKIP=<hook-id> git commit …`.
- detect-secrets flags placeholder-looking strings; annotate false
positives with `# pragma: allowlist secret`.
### Branch and worktree discipline
- One branch per agent per task. Never commit to a branch another
agent has in flight.
- Before updating `main`, inspect its existing checkout. Pull only when
that checkout is on `main` and clean; otherwise fetch `origin/main`
separately and leave the current task worktree untouched.
- One PR per feature surface: before opening a PR, check for an
existing or parallel PR touching the same files
(`gh pr list`, `git log origin/main -- <files>`).
- Fold in, don't stack: when a same-function PR is already open with
≤1 commit, fold its diff into the new PR and close the old one AT
OPEN TIME — a PR stacked on an open sibling goes DIRTY against its
own merged content (#2200, 2026-08-23). Record the fold in the new
PR body.
- Before every commit: `git branch --show-current` — confirm the
checkout you edited is on the branch you mean to ship.
+ - **More than one branch in flight → one worktree each** (chair,
+ 2026-08-25). Juggling concurrent branches through a single checkout
+ is what produces wrong-branch commits, vacuous pushes, and resets
+ that eat unrelated work; separate worktrees make the whole class
+ impossible because there is no switch to get wrong. Single-branch
+ work stays in one checkout — the policy is deliberately scoped to
+ concurrency, since every worktree costs a ~460 MB venv and the pile
+ is already large.
+ *Enforcer: `src/attune/hooks/scripts/dirty_switch_guard.py` — a
+ PreToolUse hook that refuses a branch switch or `git reset --hard`
+ while the tree is dirty (new-branch creation, path-scoped restores,
+ and explicit `--force` stay allowed).*
+ - **Reap the worktree when its PR merges.** A worktree outlives its
+ branch otherwise; delete it in the same step that confirms the
+ squash, never in a bulk sweep that might delete the session's own
+ worktree or one holding an open PR.
+ - Never suppress stderr on a state-changing git command
+ (`2>/dev/null` on a `checkout`/`commit`/`push` turns a loud refusal
+ into a silent no-op you will then reason from).
- Don't touch other agents' worktrees under `.claude/worktrees/`.
### Single-source projections
- `plugin/skills/*/SKILL.md` and `.claude/skills/*/SKILL.md` are
SOURCES for the tracked `.agents/skills/` mirror — after editing
a skill, run `python scripts/sync_agents_skills.py --write` and commit
both sides (a drift-guard test fails CI otherwise).
- This contract's own projected blocks and
`templates/agent-handoff.md` are owned by
`scripts/project_collaboration_contract.py` — edit the master,
re-run the projector.
- `.help/` and docs feature pages are projector-owned; edit the
source and re-project, never the generated output.
### CI notes
- Per-push/PR workflows run with `ANTHROPIC_API_KEY: ""` (empty,
keyless) by design — never wire the real secret into them. To
reproduce keyless CI locally use the empty string, not unset.
- Windows matrix lanes are slow (~13 min) but real — path,
subprocess, and encoding changes must wait for them.
<!-- attune:collaboration:end -->
## Commands
```bash
uv sync --extra dev --extra developer # environment
uv run pytest tests/unit -q # unit tests (fast lanes)
uv run ruff check src/ tests/ # lint
uv run --with pre-commit pre-commit run black --files <f> # pinned format
attune <command> # CLI (canonical entry)
```
## Where agent-specific state lives
- `.claude/` — Claude Code's rules, lessons corpus, skills,
worktrees. Not loaded by other agents; don't edit ad hoc.
- `.codex/` — Codex local config (gitignored).
- `AGENTS.md` (this file) — tracked, shared rules for non-Claude
agents.