# Recipe: relaying cross-repo feedback (draining the outbox)

> **Audience:** the federation **supervisor** — the maintainer (or an explicitly
> delegated relay agent) who is the *sole* sanctioned cross-repo writer — plus
> the `mgf-fed feedback` tool that automates this (spec in §The tool).
> **What this is:** the deterministic procedure that moves a paper from a
> sibling's `pending-feedback/<target>.md` **outbox** into the target repo's
> `FEEDBACK.md` **inbox** — tracked, idempotent, no-loss. It closes the one
> manual seam in the otherwise tool-backed feedback flow. Defines **FB-05**.

## Why this exists

The [federation-sync prompt](federation-sync-prompt.md) makes every sibling
**read-only on every other repo**: a finding about `mgf-common`, a sibling, or
the standard is written to THIS repo's `pending-feedback/<target>.md` outbox,
never edited into the target. That keeps the boundary clean — but it leaves a
gap: *someone* has to carry the outbox paper across the boundary into the
target's `FEEDBACK.md`. "Someone, somehow" is where the value leaks — different
engineers (and agents) do it differently, or not at all, and a paper rots in an
outbox unnoticed. This recipe makes that step **one defined command run by one
defined role**, identical for everyone, with a gate that makes a forgotten relay
impossible to miss.

## The two halves (FB-05)

| | Outbox (source repo) | Inbox (target repo) |
|---|---|---|
| File | `pending-feedback/<target>.md` | `FEEDBACK.md` |
| Writer | any sync session (read-only on the target) | the supervisor only |
| Numbering | none (draft) | target-local `PAPER-NN` (FB-01) |
| Lifecycle | drafted → relayed → moved to `relayed/` | appended as `OPEN` |

## Outbox schema (what a sync session writes)

`pending-feedback/<target>.md` — **one file per target repo**. A header declares
the outbox; each paper is a `### PAPER (→ <target>) — <title>` block carrying:

- **Severity:** 🟢 / 🟡 / 🔴
- **Origin:** `<source-repo>` · `<ISO-date>` · `<friction commit URL>`
- **What hurts** / **Why it matters** / **Evidence** (file:line + version) /
  **Suggested shape** — the [feedback-md-template](feedback-md-template.md) fields.

The `Origin:` line is the one addition over a normal FEEDBACK.md paper: it is
what lets the relay stamp the FB-01 `Federation paper:` cross-reference in the
destination, so provenance survives the crossing.

## The relay procedure (the supervisor / the tool)

1. **Discover** — scan every repo for `pending-feedback/*.md`, fleet-wide:
   `mgf-fed feedback --check` lists every un-relayed paper (source → target →
   age). By hand: `find . -path '*/pending-feedback/*.md' -not -path '*/relayed/*'`.
2. **For each paper, into its `<target>`:**
   1. read the target's `FEEDBACK.md`; the new number is `PAPER-(highest+1)`
      (FB-01 — never reuse, never renumber);
   2. append the paper in the target's canonical format — FB-02 metadata table
      (`Status: OPEN`, `Submitter` = the Origin repo + commit, `Submitted` = the
      Origin date, `Severity`) **plus a `Federation paper:` row** back-referencing
      the source repo + outbox entry (FB-01);
   3. land it as a **PR** on the target — cross-repo edits follow the PR flow
      ([codeberg-pr.md](codeberg-pr.md)); the supervisor reviews + merges.
3. **Mark relayed (idempotency)** — move the source paper to
   `<source>/pending-feedback/relayed/<target>-PAPER-NN.md` (or stamp it
   `Relayed: <target>#PAPER-NN <date>`). A relayed paper is **never** re-relayed.
4. **Verify drained** — `mgf-fed feedback --check` reports zero un-relayed for
   the targets you processed.

## Idempotency & tracking

The pair **(target `PAPER-NN` cross-ref ⇄ source `relayed/` record)** is the
durable proof a paper crossed the boundary *exactly once*. The outbox is the
queue; `relayed/` is the receipt. Re-running the relay neither double-files nor
drops — it is a no-op on anything already in `relayed/`.

## The gate (no silent rot)

Un-relayed outbox papers are federation debt. `mgf-fed status` carries an
**un-relayed-feedback** column, and the cohort-release pre-flight refuses to ship
with undrained outboxes for the cohort's repos — the same "surface drift loudly"
discipline as REL-13 registry currency. A paper written to an outbox stays
visible until it lands in its target.

## The tool (`mgf-fed feedback`) — spec for the second pass

- `mgf-fed feedback --check` — fleet-wide scan; **exit non-zero** if any
  un-relayed paper exists (the gate). Output: source → target → title → age.
- `mgf-fed feedback relay [--target <repo>] [--dry-run]` — execute steps 2–3 for
  each outbox paper: assign the target `PAPER-NN`, render the inbox entry, open
  the target PR, move the source to `relayed/`. `--dry-run` prints the plan
  without writing. Idempotent.
- Fold the un-relayed count into `mgf-fed status`.

Until it ships, the procedure above is run by hand by the supervisor — which is
why **FB-05 is staged as a SHOULD**; it promotes to MUST when the command lands
and the fleet's outboxes are schema-conformant.

## The supervisor role

"The supervisor" is the **federation maintainer** (or an agent explicitly
delegated the relay) — the single party permitted to write another repo's
`FEEDBACK.md`. Every other agent is read-only on the federation and reaches a
target only through the outbox. This is what makes *"read-only on the
federation, except the supervisor"* **enforceable**: the relay is the one
sanctioned crossing, and it is tracked + gated.

## Related

- [FB-01..FB-05 + DOC-13 in DOCUMENTATION.md](../standards/DOCUMENTATION.md) — the feedback discipline.
- [`federation-sync-prompt.md`](federation-sync-prompt.md) — the FEEDBACK-OUT step that *writes* the outbox.
- [`feedback-md-template.md`](feedback-md-template.md) — the paper fields.
- [`codeberg-pr.md`](codeberg-pr.md) — how the relay PR is opened.
- [`lesson-learned-md-template.md`](lesson-learned-md-template.md) — `LESSON_LEARNED.md`, the local-memory companion (DOC-19); a generalizing lesson ALSO routes to an outbox.
