# AI-Agent Collaboration

> **Conformance:** L1 (every Magogi-foundation repo)
> **Audience:** AI coding agents working in any federation repo;
> human maintainers reviewing agent-authored PRs; operators who
> set the rules of engagement for agent sessions.
> **Propagation (DOC-18):** when an AG-* rule changes, also update → the `AGENTS_BRIEFING` constant the `mgf-fed agents` CLI prints (AG-02) + the `STARTHERE.md` mirror + README *Index of MUSTs* + (for AG-15) [`principles/agent-empowerment-charter.md`](principles/agent-empowerment-charter.md). See DOCUMENTATION.md §10.4.

> **Scope.** The federation treats AI agents as first-class
> collaborators — not assistive autocomplete. Every consumer
> repo's CLAUDE.md is read by an agent; every commit may carry
> an agent co-author trailer; every FEEDBACK paper may have been
> filed by an agent that hit reusable friction. This standard
> codifies the conventions that make agent collaboration
> reproducible across repos, agents, and sessions. It is the
> federation's actual differentiator — no other foundation
> documents this surface, and the conventions only work if every
> sibling and consumer follows the same shape.

---

## Rules box (read this first)

| ID | Rule |
|---|---|
| <a id="AG-01"></a>**AG-01** | **Every repo MUST ship `AGENTS.md` at the repo root** as a thin pointer to `mgf-fed agents`. The file is identical across the federation — generated by `mgf-fed init-project` and refreshed by `mgf-fed catch-up`. It MUST NOT carry a copy of the briefing (would drift); project-specific agent notes belong in `docs/claude/CLAUDE.md`, not `AGENTS.md`. |
| <a id="AG-02"></a>**AG-02** | **The canonical agent briefing MUST be what `mgf-fed agents` prints** — one message for the whole federation. Every repo's `AGENTS.md` points at this single source; project-specific lookups live in the project's own `docs/claude/CLAUDE.md` auto-block (managed by `mgf-fed catch-up`). |
| <a id="AG-03"></a>**AG-03** | **Agent-authored commits MUST include both signing trailers** — `Signed-off-by: <human> <email>` AND `Co-Authored-By: <model name + context size> <noreply@anthropic.com>` (or vendor-equivalent). The trailers are non-negotiable: they establish review provenance, attribute the work honestly, and let `git log --grep` surface agent-authored history for audit. The canonical identity is `Bassam Alsanie <bassam@magogi.org>` + the drafting agent's `Co-Authored-By:`; one-time git setup is in [`../recipes/commit-signing.md`](../recipes/commit-signing.md). |
| <a id="AG-04"></a>**AG-04** | **Agents MUST file reusable friction as a FEEDBACK paper** (via `mgf-fed feedback-howto`, into the `FEEDBACK.md` of the project that caused it — see **AG-11** for routing). Per-project "scaffolding gotchas" sections in CLAUDE.md are temporary documentation of an open paper — once a paper ships, the consumer-side gotcha section disappears on the next catch-up. (Closes PAPER-59's pattern: every GUI consumer was about to re-author the same gotcha section independently.) |
| <a id="AG-05"></a>**AG-05** | **Agents MUST verify memory claims before recommending action.** Memory records are point-in-time observations; file paths, function names, and flag names may have moved. When an agent recalls "X exists at path Y," it MUST grep/read the current state before recommending a change that depends on the claim. Stale memories MUST be updated or deleted, not silently propagated. |
| <a id="AG-06"></a>**AG-06** | **Risky operations MUST require explicit confirmation** unless durable instructions (e.g., a CLAUDE.md directive, a settings.json permission rule) authorize otherwise. Risky = destructive (rm -rf, branch delete, force push), hard-to-reverse (git reset --hard, dependency removal), or shared-state effects (push to main, PR merge, message send). Authorization stands for the scope specified, not beyond. |
| <a id="AG-07"></a>**AG-07** | **Agents MUST use TaskCreate/TaskUpdate for any work spanning ≥3 steps.** Progress visibility is the operator's primary tool for catching a drifting session. Single-step tasks (one edit, one read) MUST NOT use tasks — that's bureaucracy theatre. |
| <a id="AG-08"></a>**AG-08** | **Memory writes MUST be federation-scoped, not session-scoped.** Use `Plan` / `Task` tools for in-conversation state; use memory only for facts that survive the conversation (user preferences, project state that affects future work, conventions learned through correction or confirmation). Activity logs, conversation summaries, and "what I did this session" are NOT memory material — they're ephemeral. |
| <a id="AG-09"></a>**AG-09** | **When an agent's recommendation depends on a federation sibling's published version, the agent MUST verify against the devpi index**, not against the local `dist/` wheel. Local builds may not be published yet; for `mgf-*` packages the self-hosted devpi index (`magogi/prod` on `195.15.203.250`) is the contract that consumers actually see (see [`PACKAGE_DISTRIBUTION.md`](PACKAGE_DISTRIBUTION.md) PKG-05 / PKG-11). Verify anonymously — `curl -fsS https://195.15.203.250.sslip.io/magogi/prod/+simple/<name>/` and confirm `<version>` is listed (equivalently the devpi JSON API `…/magogi/prod/<name>`); never pypi.org, never Codeberg, never a local `dist/`. (Closes the `[[feedback_pypi_vs_local_dist]]` memory rule that lived informally before this standard; the verification target is now the devpi index under PKG-11.) |
| <a id="AG-10"></a>**AG-10** | **Standards drift caught by an agent MUST be filed as a PAPER, not silently fixed.** If an agent notices that `docs/standards/X.md` claims behaviour the code no longer does, the right move is `mgf-fed feedback-howto` — *not* edit-the-doc-to-match-the-code or edit-the-code-to-match-the-doc. The PAPER triages whether the doc was aspirational, the code regressed, or the standard itself was wrong. |
| <a id="AG-11"></a>**AG-11** | **Cross-project feedback MUST be filed in the TARGET project's `FEEDBACK.md`, not the reporting agent's own repo.** Routing: friction with a specific project → THAT project's `FEEDBACK.md` (its maintainer is who triages + acts); cross-cutting or standards-level issues → `mgf-common`'s `FEEDBACK.md`. Recording it only in your own repo (or silently working around it) is a defect — the maintainer who can fix it never sees it. Every paper MUST carry enough for the target to **triage and act without coming back to the reporter**: **what hurts** (the concrete friction), **why it matters** (impact / who it blocks), **concrete evidence** (a repro, `file:line`, commit SHA, the version hit), and a **suggested shape** for the fix. A paper MAY *optionally* enrich its evidence with an **`evidence_level`** (e.g. `VERIFIED_BY_EXECUTION` / `CODE_READ` / `INFERRED`) and a **`confidence`** (HIGH / MEDIUM / LOW), recorded **independent of severity** — a CRITICAL-but-low-confidence concern needs urgent *verification*, not urgent action (the grammar the review recipes already use — see [`audit-outcomes`](principles/audit-outcomes.md)). This stays optional: FEEDBACK is a deliberately prose channel, not a schema. Refines AG-04's "file a paper" into "file it in the right place, with enough detail." |
| <a id="AG-12"></a>**AG-12** | **Every project MUST expose a project-scoped agent briefing via `mgf-fed agents --project`.** `mgf-fed agents` (no flag) prints the federation-wide briefing; `--project` prints the current project's own agent docs (`docs/claude/CLAUDE.md`, falling back to `AGENTS.md`). Because `mgf-common` is installed wherever it is a dependency, this gives **every** project — including pure libraries and non-Python repos that cannot ship their own CLI — the same `agents` capability scoped to itself, without each repo building a bespoke command. The project-scoped *content* lives in `docs/claude/CLAUDE.md` (AG-01/AG-02 keep `AGENTS.md` a thin pointer); `--project` is the uniform way to read it. |
| <a id="AG-13"></a>**AG-13** | **Only the `mgf-common` supervisor may change a library; other projects MUST NOT — they file a request in the target library's `FEEDBACK.md`.** A consumer or sibling that wants a library changed (a new feature, a pin walk, a fix) does NOT edit that library, open a PR against it, or bump its version — it files a PAPER in **that library's own `FEEDBACK.md`** (per AG-11) describing what it needs, and the mgf-common supervisor decides + makes the change. Rationale: one accountable owner keeps the federation coherent and keeps releases passing the consistency gate (**REL-13**); uncoordinated cross-project edits are exactly what produce pin drift and divergent surfaces. The single source of truth for what exists is [`MGF_LIBRARIES.md`](../../MGF_LIBRARIES.md) at the mgf-common root (generated; every library name links to its `DEPS.md`). When the supervisor releases any library, REL-13 leaves the whole federation consistent + verified. |
| <a id="AG-15"></a>**AG-15** | **Agents are empowered — and MUST read the [Agent Empowerment Charter](principles/agent-empowerment-charter.md) — to push back on, propose alternatives to, refine the scope of, decline (with recorded rationale), or ask a clarifying question about any rule, and to conclude "reviewed; no change needed."** The MUST/SHOULD corpus sets the bar; AG-15 grants explicit standing to exercise judgment *against* it where the evidence warrants — via the existing channels (a FEEDBACK paper per **AG-10**/**AG-11**; an ADR or `🚫` decline per [`non-adoption-is-valid`](principles/non-adoption-is-valid.md); the holistic verdict per [`audit-outcomes`](principles/audit-outcomes.md)). **Exercising judgment with a recorded rationale is conformant; silent non-compliance is not.** The charter also defines the **project-mode handshake** (greenfield / unconstrained-brownfield / production-constrained — right-size the rigor; do *not* apply production guardrails to a greenfield spike) and the **never-block protocol** (record an open question, choose a sensible default, mark dependents `INFERRED`, continue — bounded by a small STOPPERS list and a tool-denial fallback that generalises **REL-12**). The only obligation AG-15 adds: know the charter, and use the channels rather than silently complying or silently skipping. This is the agent-facing capstone to the empowerment seeds that were previously scattered and framed as obligations. |
| <a id="AG-14"></a>**AG-14** | **Agents MUST propagate a change to its coupled surfaces in the same change — never leave a dependent stale.** Before reporting a change complete, the agent MUST walk the **Change-Propagation Matrix** (DOCUMENTATION.md §10.4 / **DOC-18**) for every surface it touched and update each listed dependent: in the same commit for same-repo dependents; for cross-repo dependents (e.g. the `mgf-fed` CLI surfaces in `mgf-common`), in the same change-wave — one commit per repo, cross-referenced in both commit messages, and the wave is not "done" until every repo's commit has landed. E.g. a new public symbol ripples to `PUBLIC_API.{md,json}` + `CHANGELOG`; a new/changed standards rule ripples to the README *Index of MUSTs* + the `mgf-fed standards` / `agents` CLI; a wire-schema change ripples to every parallel copy + its alignment test. Run `mgf-fed app-doctor --standards` as the mechanical backstop. When introducing a *new* coupling, the agent MUST add a matrix row + a Propagation header + a pin (where checkable) in the same change. "I'll update the docs in a follow-up" is the exact habit DOC-18 forbids: the follow-up never comes, and the next agent inherits drift. This is the agent-facing form of DOC-18 (cross-repo wave carve-out v2.26.1); it complements **AG-10** (drift you *find* → a PAPER; drift you *cause* → fix it now). |
| <a id="AG-16"></a>**AG-16** | **Every project MUST keep the standards corpus resolvable to its agents — depend on `mgf-common[standards]`.** The corpus (`mgf-standard` — the rules + contract + design + registry) is an **optional extra** of `mgf-common`, not a core dependency (it resolves only from the private devpi index, never public PyPI; it was demoted to an extra in mgf-common 0.45.1 so the cornerstone stays resolvable). Declare `mgf-common[standards]` where agents/maintainers run the federation CLI (the dev/tooling extra is enough). The CLI — `mgf-fed standards` / the `agents` federation map / `catch-up`'s federation-position / `sync-prompt` / `federation` / `design` — resolves *only* from this extra; a plain `mgf-common` install does NOT carry it and those commands **degrade loudly** (a non-zero exit + an install prompt), never a silent partial answer. Resolve-don't-copy only works if the corpus is installed: an agent that "synced" against a degraded CLI has not synced. Mechanically surfaced by the loud-degrade messages + the `agents` startup checklist. |
| <a id="AG-17"></a>**AG-17** | **Every repo MUST keep in-repo agent memory at `docs/memory/`** — a committed `MEMORY.md` index plus one-fact-per-file topic notes (each with `name` / `description` / `type` frontmatter). Unlike the runtime auto-memory (AG-05/AG-08), which is machine-local and private, this memory **travels with the repo**: it survives a fresh clone, is identical for every agent on every machine, and is reviewable in PRs. It MUST be kept current — stale entries updated or deleted, never silently propagated (AG-05) — and hold durable, federation-scoped facts, not session logs (AG-08). It complements (does not replace) `docs/claude/CLAUDE.md` (DOC-07, the curated dense-lookup briefing) and `LESSON_LEARNED.md` (DOC-19, the append-only lessons log). A seeded `MEMORY.md` is conformant (presence is the bar); scaffolded by `mgf-fed init-project`, refreshed by `catch-up`, checked by `mgf-fed app-doctor`. |
| <a id="AG-18"></a>**AG-18** | **Every repo MUST use the federation's standardized git configuration.** (a) The canonical `.gitignore` (shipped by the cookiecutter) MUST be present and MUST ignore build/test artifacts, IDE dirs (`.idea/`, `.vscode/`), Claude-local settings (`.claude/settings.local.json`), and **`my_stuff/`** — the repo-root directory where local secrets/tokens live (the devpi publish password per PKG-03, plus git-forge tokens, sit under `my_stuff/tokens/`). `my_stuff/` MUST NEVER be committed (a SECURITY boundary, not a preference). (b) The `.gitmessage` template MUST be wired via `git config commit.template .gitmessage` so every commit carries the AG-03 trailers. (c) The committed `.githooks/prepare-commit-msg` hook MUST be present (wired per clone via `git config core.hooksPath .githooks`) — it auto-fills the constant `Signed-off-by` trailer locally — AND `scripts/check_commit_trailers.py` MUST run as the generated `.woodpecker.yml`'s `commit-trailers` CI step: the authoritative server-side gate that fails any branch whose non-merge commits lack either AG-03 trailer, independent of a contributor's local config. `mgf-fed catch-up` audits `.gitignore` against the template + distributes the `prepare-commit-msg` hook and checker (`--apply`); `mgf-fed app-doctor` checks that `my_stuff/` is ignored and that the `prepare-commit-msg` hook is present. |
| <a id="AG-19"></a>**AG-19** | **The runtime auto-memory store MUST be version-controlled and backed off-machine.** The machine-local harness memory (`~/.claude/projects/<slug>/memory/` — the private auto-memory of **AG-05**/**AG-08**, distinct from **AG-17**'s in-repo `docs/memory/`) MUST be a git repo pushed to a **private** Codeberg remote named `<project>-memory` (e.g. `magogi-admin/mgf-standard-memory`), so the notes survive disk loss and stay auditable across machines — the "keep track of everything" discipline applied to the agent's own memory. **SAFETY (non-negotiable):** the git scope MUST be the `memory/` directory itself — **NEVER** its parent, which holds the session `*.jsonl` transcripts that can contain secrets (devpi/Codeberg tokens, etc.). Use an allowlist `.gitignore` (`*`, then `!*.md`, `!.gitignore`) so only memory-note markdown is ever tracked, and keep the remote **private**. Commits carry the **AG-03** trailers. AG-19 protects the *private* store off-machine; it does **not** relax **AG-08** (still durable, federation-scoped facts only — no session logs) or **AG-05** (verify recalled claims before acting). Bootstrap/refresh with `scripts/init_memory_vcs.py`. Complements **AG-17**: AG-17's memory travels *with the code* in PRs; AG-19 protects the private runtime store that does not. |
| <a id="AG-20"></a>**AG-20** | **Owned infrastructure is never an external blocker — exhaust the self-owned path before declaring an action blocked.** Before reporting an action as **blocked, human-gated, or impossible**, an agent MUST (a) consult the infrastructure/access registry [`MGF_INFRA.md`](../../MGF_INFRA.md) to determine whether the dependency is Magogi-owned, and (b) for owned infra, **attempt the self-owned recovery path** (SSH to the host, mint/rotate a credential, restart a service) rather than treating a transient failure — an expired token, a 401, a stopped container — as terminal. An auth/access failure against owned infrastructure is a **solvable sub-problem, not a terminal wall.** Reason from **capabilities/assets** (what we control + how to reach it), not only from stated *state* or a recorded conclusion. When an action genuinely cannot proceed, the agent MUST **state the blocking assumption explicitly** ("treating X as blocked because Y") so a human can catch a wrong assumption cheaply. Recorded "blocked"/"gated" conclusions (memory, trackers) MUST carry their **unblock-path + as-of date** and be **re-derived against current capabilities**, never inherited as settled fact. (MUST since v2.26.) |

---

## 1. Why this standard exists

The Magogi federation is the only one I know of that has
explicit conventions for AI agents as collaborators rather than
as tools used opaquely. The conventions accumulated organically:

- The `mgf-fed agents` CLI emerged because every project's
  CLAUDE.md was repeating the same "here's how to work in this
  federation" preamble, and the preamble drifted per-project
  faster than anyone could maintain it.
- The signing-trailer convention emerged because git history
  with agent-co-authored commits needs to be auditable.
- The FEEDBACK-paper pipeline emerged because agents repeatedly
  hit the same friction across consumer projects, and burying
  the workaround in one consumer's CLAUDE.md left every other
  consumer to re-discover it.
- The AGENTS.md thin-pointer pattern emerged because the
  cross-tool `AGENTS.md` ecosystem convention is more durable
  than vendor-specific files.

Each convention works only if *every* repo follows it. The
ad-hoc per-repo variant is what we already had and what these
rules replace. **The differentiator is the discipline of having
the conventions, not the conventions themselves** — any of the
specific rules below can evolve as long as the federation evolves
them together.

---

## 2. The agent's entry point — `mgf-fed agents`

When an agent lands in any federation repo, the first read is:

```
mgf-fed agents
```

This prints the **canonical briefing** — the single source of
truth for how to work across the federation. The output covers:

- The federation shape (cornerstone + siblings + consumers).
- The "use the library + siblings, don't reinvent" principle.
- The standards location + the conformance levels.
- The catch-up cadence + how to use `mgf-fed catch-up`.
- The FEEDBACK paper lifecycle + when to file one.

The agent then reads the project-specific CLAUDE.md
(`docs/claude/CLAUDE.md`, or `docs/CLAUDE.md` on older layouts)
for the per-project lookup table (what's been built, what's
broken, gotchas).

**There is no per-project agent-briefing.** Repos that need
project-specific agent notes carry them in CLAUDE.md, not in
AGENTS.md, not in a vendor-specific `.claude/CLAUDE.md`.

---

## 3. The signing-trailer convention (AG-03)

Every agent-authored commit ends with two trailers:

```
Signed-off-by: <human name> <human email>
Co-Authored-By: <model name + context-size note> <vendor noreply email>
```

Concrete example (this federation's house style — the canonical identity):

```
Signed-off-by: Bassam Alsanie <bassam@magogi.org>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
```

The human signer is always **`Bassam Alsanie <bassam@magogi.org>`**; the
`Co-Authored-By:` model string tracks whatever agent drafted the change.
For the one-time git setup (identity + the `.gitmessage` commit template)
and the `git commit -m` form, see
[`../recipes/commit-signing.md`](../recipes/commit-signing.md).

The two trailers do different jobs:

- **`Signed-off-by:`** establishes that a human reviewed and
  endorses the change. Without it, the commit is the agent's
  work alone — useful as a research artifact but not as a
  production-quality change.
- **`Co-Authored-By:`** attributes the work to the agent
  honestly. The model name + context-size note matters because
  the same prompt can produce qualitatively different work
  across model versions; pinning the model in history lets
  future archaeology distinguish "agent X drafted this" from
  "agent Y drafted this."

Both trailers are mandatory. A commit with only `Signed-off-by:`
hides the agent's involvement; a commit with only
`Co-Authored-By:` hides the human review. Either failure mode
breaks the audit story.

---

## 4. The FEEDBACK paper lifecycle (AG-04, AG-10)

The federation's correction mechanism for the standards
themselves IS the FEEDBACK paper. The lifecycle:

1. **Friction observed.** An agent (or human) hits something
   that's awkward, missing, brittle, or inconsistent in a
   federation library, standard, or tool.
2. **Workaround applied locally** (if needed to unblock).
3. **Paper filed** via `mgf-fed feedback-howto` — the CLI lists
   the existing papers, the severity guide, and the canonical
   submission template. Paper goes into the *cornerstone's*
   FEEDBACK.md (not the consumer's), with a Codeberg link back
   to the consumer commit that surfaced it.
4. **Triage** (maintainer): accept / reject / defer, with
   rationale recorded in the paper.
5. **Ship**: the fix lands; the paper's Retrospective field
   captures the implementation summary; status moves to
   `✅ SHIPPED`.
6. **Cleanup**: the consumer's local workaround disappears on
   the next `mgf-fed catch-up --apply` once the consumer
   pins to a release containing the fix.

The lifecycle's load-bearing property is **step 1's first
move**. When an agent hits a gap, the temptation is to fix it
silently in the consumer code (`# work around mgf-X bug`). That
fix doesn't propagate; the next consumer re-discovers the same
gap. The paper does propagate — every consumer reading the
cornerstone's FEEDBACK.md sees the gap is known + tracked +
either resolved or rationally deferred.

---

## 5. Memory discipline (AG-05, AG-08, AG-17)

The auto-memory subsystem is powerful and easy to misuse.
The rules above codify what's already documented in the
runtime's auto-memory instructions; this section makes them
federation-binding rather than runtime-default.

**Save:**
- User preferences (terse output, no emojis, etc.).
- Project state that survives the conversation (current chapter
  state, federation-version pointers, open-paper queue).
- Conventions learned through correction or confirmation.
- External-system pointers (where credentials live, which
  Codeberg repo holds what).

**Do not save:**
- Code patterns, file paths, conventions — readable from the
  code; will rot.
- Git history or who-changed-what — `git log` is authoritative.
- Activity logs ("today I shipped X").
- Conversation context that doesn't outlive the session.

**Verify before acting:**
- Memory says "function Y is at path Z" → grep before
  recommending a change to it.
- Memory says "sibling X is at version V" → verify against the
  devpi index before pinning to V (AG-09 / PKG-05 / PKG-11):
  `curl -fsS https://195.15.203.250.sslip.io/magogi/prod/+simple/X/`
  and confirm V is listed (anonymous), not a curl to pypi.org.
- Memory snapshot of "recent activity" is frozen; for *current*
  state, prefer `git log`.

### 5.1 In-repo memory (AG-17)

The discipline above governs the **runtime auto-memory** — the agent's
machine-local, private memory subsystem. It does not survive a fresh
container, a new machine, or a different agent: a fact that lives only
under `~/.claude/` is gone the moment that home directory is. **AG-17 adds
a second, committed tier** — `docs/memory/` in the repo itself:

- **Shape.** A `MEMORY.md` index (one line per fact, each pointing at a
  topic file) plus one-fact-per-file notes, each carrying `name` /
  `description` / `type` (`user` / `feedback` / `project` / `reference`)
  frontmatter. This mirrors the runtime auto-memory's structure, so an
  agent can promote a durable runtime memory into the repo verbatim.
- **Why committed.** It travels with the repo — every agent, on every
  machine, in every fresh clone, reads the same memory; it is reviewable
  in PRs; and it cannot be lost when a container is discarded.
- **What goes in.** The same durable, federation-scoped facts AG-08 allows
  (project state, conventions learned through correction, external-system
  pointers) — never session logs. Keep it current per AG-05: an agent that
  recalls a path or version from `docs/memory/` MUST still verify it
  against the live tree before acting.
- **Relationship to the other docs.** `docs/memory/` is the granular,
  evolving memory store; `docs/claude/CLAUDE.md` (DOC-07) is the curated
  dense-lookup briefing; `LESSON_LEARNED.md` (DOC-19) is the append-only
  lessons log. They complement — not replace — each other.

A seeded `MEMORY.md` (even just the index header) satisfies the rule;
`mgf-fed app-doctor` checks its presence, and the cookiecutter scaffolds it.

---

## 6. Risky-action confirmation (AG-06)

Some actions have asymmetric cost:

| Reversibility | Examples |
|---|---|
| **Trivial** (just retry) | Read a file; edit a non-shared file; run a test. |
| **Recoverable with effort** | Commit on a branch; delete a working-tree file. |
| **Hard to reverse** | Push to main; force push; git reset --hard; amend a published commit; delete a branch with unpushed work. |
| **Public / shared state** | Open a PR; merge a PR; send a Slack/email message; publish to PyPI; modify CI/CD config. |
| **Destructive** | `rm -rf`; drop a database table; revoke a credential. |

Trivial actions: just do them. Recoverable: do them with a
brief "I'm about to X" status update. Hard-to-reverse / public /
destructive: **confirm with the operator first** unless an
existing durable instruction (CLAUDE.md, settings.json
permission rule, explicit prior approval) authorizes the
action.

Authorization scope matters: "push this branch once" doesn't
authorize "push every branch from now on." Match the scope of
the action to the scope of the authorization.

---

## 7. Standards drift (AG-10)

A particularly easy footgun: an agent reads a standards doc
that claims behaviour the code no longer implements. Three
possible responses:

1. **Silently edit the doc to match the code** — wrong; you've
   normalised the regression.
2. **Silently edit the code to match the doc** — wrong; you've
   made a behavioural change the operator didn't approve.
3. **File a PAPER** — right; the paper triages whether the doc
   was aspirational, the code regressed, or the standard
   itself was wrong.

The PAPER doesn't have to be heavyweight. Two paragraphs is
plenty. The point is to surface the inconsistency where the
maintainer can triage it, not to bury it in either direction.

---

## 8. Self-review checklist

Before declaring an agent-authored change ready for merge:

- [ ] Every commit ends with both signing trailers (AG-03).
- [ ] `AGENTS.md` is present at the repo root and unchanged
      from the federation template (AG-01).
- [ ] Project-specific agent notes (if any) live in
      `docs/claude/CLAUDE.md`, not in AGENTS.md (AG-01, AG-02).
- [ ] If the change exists because of recurring friction across
      consumers, a FEEDBACK paper was filed (AG-04).
- [ ] No risky action (push, merge, publish, destructive
      command) ran without explicit operator authorization
      (AG-06).
- [ ] Any TaskCreate tasks created during the session are
      either completed or explicitly closed as deleted/deferred
      (AG-07).
- [ ] Any memory writes record durable facts, not session
      ephemera (AG-08).
- [ ] If the work touched a federation sibling's version,
      verification was against the devpi index (PKG-05 /
      PKG-11), not local `dist/` (AG-09).
- [ ] Wherever a rule was declined or a finding was raised against the
      standard, the rationale was recorded via the proper channel
      (AG-10/AG-11 paper, ADR, or `🚫` decline) — never a silent skip
      (AG-15).

---

## 9. Mechanical enforcement

| Rule | Enforcement |
|---|---|
| AG-01 | `mgf-fed catch-up` audit step verifies `AGENTS.md` exists and matches the template; mismatched copies surface as a finding. |
| AG-02 | Implicit — `mgf-fed agents` is the published surface; no separate check needed beyond it staying installed. |
| AG-03 | Git pre-commit hook (consumer-side, optional but recommended) — `mgf-fed app-doctor` MAY grow a `--check-trailers` flag that greps recent commits for the two-trailer pattern. Not enforced today. |
| AG-04 | Review-only. An agent's PR description that documents friction without a paper link is the trigger for a reviewer prompt. |
| AG-05 | Self-enforcement; runtime memory subsystem already prompts the agent to verify. |
| AG-06 | Runtime / harness enforcement (permission prompts on Bash, MCP tool calls). Not a code rule. |
| AG-07 | Self-enforcement; runtime reminders surface stale task lists. |
| AG-08 | Self-enforcement; runtime auto-memory rules cover this. |
| AG-09 | Review-only. |
| AG-10 | Review-only. A PR that "fixes documentation" without a paper link is the trigger for a reviewer prompt asking "was this a drift report?" |
| AG-15 | Review-only (the charter grants license, not a checkable artifact). `mgf-fed app-doctor --standards` pins the DOC-18 coupling — the charter file exists and the AG-15 ↔ charter cross-link resolves. A PR that silently skips a MUST (no paper / ADR / `🚫`-with-rationale) is the trigger for a reviewer prompt. |
| AG-17 | `mgf-fed app-doctor` checks `docs/memory/MEMORY.md` exists (presence is the bar); `catch-up` seeds it. Content quality is self-/review-enforced via AG-05 (verify before acting) + AG-08 (durable, not ephemeral). |
| AG-18 | `mgf-fed app-doctor` checks `my_stuff/` is git-ignored **and that the `.githooks/prepare-commit-msg` hook is present**; `catch-up` audits `.gitignore` against the cookiecutter template and `--apply` appends missing ignore lines + distributes the hook/checker. The `commit-trailers` step in every generated `.woodpecker.yml` is the authoritative AG-03 gate (`scripts/check_commit_trailers.py`, server-side). `commit.template`/`core.hooksPath` wiring is per-clone setup. |
| AG-19 | Bootstrap script (`scripts/init_memory_vcs.py`) — idempotently inits the `memory/`-scoped git repo, writes the allowlist `.gitignore`, attaches/creates the private `<project>-memory` Codeberg remote, and commits + pushes. Server-side CI cannot gate a machine-local store outside the repo, so enforcement is the script + self-check (run it after a fresh machine / clone); the allowlist `.gitignore` is the secret-leak guard. Not CI-enforceable today by design. |
| AG-20 | Review-enforced behavioural rule (like AG-04/AG-05/AG-15 — agent conduct, not a checkable artifact). The standing aids are the [`MGF_INFRA.md`](../../MGF_INFRA.md) registry (the asset/access inventory + recovery playbook an agent consults before declaring "blocked") and the requirement to state the blocking assumption out loud (so a wrong "blocked" is caught in review, cheaply). A "blocked"/"gated" note in memory or a tracker without an unblock-path + as-of date is the trigger for a reviewer prompt. Origin: the 2026-06-29 miss — treating the self-hosted Woodpecker's expired token as a human-gated wall when it was a one-command server-side mint. |

The mechanical-enforcement gaps (AG-03 trailer check, AG-04
paper-link convention) are reasonable v1.x work; the rules
themselves are L1-binding today and reviewer-enforced.

---

## 10. The Agent Empowerment Charter (AG-15)

The MUST/SHOULD corpus tells an agent **what the bar is**. It says far
less about **how much standing the agent has** when a rule, a task, or
the evidence is not a clean fit — and a corpus written almost entirely
in comply-or-violate grammar can read as if "obey" and "violate" are the
only moves. They are not. The federation treats agents as first-class
collaborators (§1), and that only pays off if the agent is *explicitly*
licensed to bring its judgment to bear.

The licenses already existed but were scattered and framed as
obligations — [AG-10](#AG-10) ("MUST file a paper" for drift you find),
[`non-adoption-is-valid`](principles/non-adoption-is-valid.md) (decline
with rationale), [`audit-outcomes`](principles/audit-outcomes.md) (the
flag vocabulary), and [README "How AI agents should use this
folder"](README.md) point 5 (propose before applying). AG-15 unifies
them into one **front door** — the
[Agent Empowerment Charter](principles/agent-empowerment-charter.md) —
and re-frames them from *duty* to *license*:

- **Six licenses** — push back, propose, refine scope, ask, decline with
  rationale, conclude "no change needed."
- **The mode handshake** — confirm greenfield / unconstrained-brownfield
  / production-constrained (orthogonal to L1/L2/L3) before substantial
  autonomous work, so the agent right-sizes rigor instead of either
  over-building production ceremony on a spike or silently dropping
  guardrails on real production.
- **Concrete cost is the test** — a rule that cites a principle with no
  observed cost *here* may be flagged and the lighter shape proposed
  (the application side of [DESIGN_PRINCIPLES §14](DESIGN_PRINCIPLES.md));
  principle-as-aesthetic is not a finding.
- **The never-block protocol** — record an open question, default, mark
  dependents `INFERRED`, continue; bounded by a small STOPPERS list, the
  [AG-06](#AG-06) risky-action gate, and a tool-denial fallback that
  generalises [REL-12](RELEASING.md).
- **Honest-output discipline** — adversarial-but-honest, no false
  balance, depth over breadth over length, self-correction is healthy.

The charter is a **principle, not new MUSTs**: it adds standing, not
ceremony. The one obligation AG-15 imposes is to *know* it and use the
channels — never silently comply, never silently skip. The full text,
including what the charter explicitly does **not** license, lives in
[`principles/agent-empowerment-charter.md`](principles/agent-empowerment-charter.md).

---

## 11. Standardized git configuration (AG-18)

Every repo is wired the same way, so an agent or human dropping into any
federation checkout finds the same git behaviour. Four pieces, all shipped
by the cookiecutter and audited by `mgf-fed catch-up`:

**1. The canonical `.gitignore`.** Present at repo root; ignores build/test
artifacts, IDE config, Claude-local settings, and — the SECURITY-load-bearing
line — `my_stuff/`:

```gitignore
# Local secrets / tokens — NEVER committed (PKG-03, SECURITY)
my_stuff/
# IDE
.idea/
.vscode/
# Local Claude overrides
.claude/settings.local.json
```

(plus the language block — Python `__pycache__/`, `dist/`, `.venv/`…; Zig
`.zig-cache/`, `zig-out/`…). `my_stuff/` is where local credentials live —
the devpi publish password sits at `my_stuff/tokens/…` (PKG-03). Committing
it would leak a credential, so the ignore is a boundary, not a preference.
`catch-up --apply` appends any missing standard lines to an existing
`.gitignore`; it never reorders or removes a repo's own entries.

**2. The `.gitmessage` commit template**, wired once per clone:

```sh
git config commit.template .gitmessage
```

The template carries the AG-03 trailers as a reminder; the trailers
themselves are mandatory per AG-03.

**3. Identity:**

```sh
git config user.name  "Bassam Alsanie"
git config user.email "bassam@magogi.org"
```

**4. The AG-03 commit-trailer enforcement — a local hook + an authoritative CI
gate.** A committed `.githooks/prepare-commit-msg` hook, wired once per clone:

```sh
git config core.hooksPath .githooks
```

auto-fills the constant `Signed-off-by` trailer so `git commit -m` doesn't drop
it (a developer convenience). The **authoritative** half is server-side: the
generated `.woodpecker.yml` runs `scripts/check_commit_trailers.py` as its
`commit-trailers` step, which **fails the build** if any non-merge commit on the
branch lacks either AG-03 trailer — independent of whether the contributor wired
the hook. Both files ship from the cookiecutter (new repos) and are distributed
to existing repos by `mgf-fed catch-up --apply`; `mgf-fed app-doctor` verifies
the `prepare-commit-msg` hook is present. (The hook is convenience; the CI gate is
the enforcement — see AG-03.)

One-time setup for all four is in
[`../recipes/commit-signing.md`](../recipes/commit-signing.md) and
[`../recipes/standardized-git-config.md`](../recipes/standardized-git-config.md).
`mgf-fed app-doctor` flags a repo whose `.gitignore` does not ignore `my_stuff/`
or whose `prepare-commit-msg` hook is absent.
