# _agent-index.md

> 65 lines of code and 0 definitions.

Tree: Coordination tree
Language: markdown
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-agent-index-md
Source text: https://banes-lab.com/assets/sources/source.2cba76ba6af328d9a9a5a8175600b816f854c15b8a62b2c9eceb5fe6f950c901.generated.txt

## Source

````markdown
<!-- ACCUMULATOR — the permanent letter-to-role binding. Grows only; nothing is ever removed. -->

# Agent index. A letter is bound to a role for the life of the project and is never reused.

**This is an accumulator, which is why it is not on the board.** The board is current-truth-only and a
resolved item is deleted from it; this file is the opposite by construction — **a letter that stops
being active still has to resolve**, because every item, row, citation and changelog line that ever
named it points here. Deleting a row would silently re-point all of them.

**An agent surfacing for the first time is added here BEFORE its first write.** A letter is claimed by
adding the row, never by using it. Writing under an unindexed letter is the same construct as a task
citing an agent the board does not declare: it reads as governed and resolves to nothing.

**The letter is the identity; the role is what the letter means.** A role is fixed to its letter, so
two agents never share a letter and one agent never changes letters — which is what makes a citation
written months apart still resolve to the same party.

═══════════════════ INDEX ═══════════════════

| letter | role                                                                                | state   |
| ------ | ----------------------------------------------------------------------------------- | ------- |
| SAa    | Agent audit — a persisted agent against the agent template and the quality contract | INVOKED |
| SAb    | Agent creation — composing a new persisted agent from discovered domain evidence    | INVOKED |
| SAd    | Forensic verification — a claim against observable implementation evidence          | INVOKED |

**THE `SA` LETTERS ARE THIS PACKAGE'S OWN BOUNDED-INVOCATION IDENTITIES AND THEY SHIP WITH IT.** They
are not a host's roster: a host's seats claim single letters from the top of the scheme, while these
three bind the capabilities the package carries. **`INVOKED` is what they are rather than what they may
do** — a party that runs only when called, holds a letter so its citations resolve, and is never in the
reader set because it does not exist between invocations and cannot respond. An item addressed to one
correctly dangles, which is the addressing check working rather than a conflict to repair.

**`state` is the ONLY mutable column, and its values are `ACTIVE`, `INACTIVE` and `INVOKED`.** A letter
and its role are written once; a seat's row moves between `ACTIVE` and `INACTIVE` and back, taken by the
seat whose letter it is, and nothing else changes. **A SEAT THAT DEPARTS WITHOUT DECLARING LEAVES A STATE
ONLY IT MAY CHANGE**, so every edge quantifying over active seats counts a party that cannot act and a
discussion holds on a signature that will never arrive — the transition therefore admits a FOREIGN letter
and is never anonymous when it does: the mover states a warrant, and the row it moved carries a line
naming who moved it and under what, because a state a peer wrote and a state its own seat wrote are
otherwise the same cell and no reader can tell which claim they hold. **Every derived active set takes PRESENCE from the
board's own records and STATE from this file**, so a letter counts as active where it holds a board
record and its row here reads `ACTIVE`; a letter holding a record with no row here resolves as not active,
because a letter is claimed by adding its row. The two
surfaces answer two halves of one question — this one answers _what does this letter mean and what state
is it in_, the board answers _which letters hold a seat_.

**`INVOKED` is the third value and it does not move**, which is why the column is mutable for a seat's row
and frozen for a bounded-invocation one: a party that exists only when called cannot take a transition,
and no other party takes one on its behalf. **So the surface carries two change-modes by ROW CLASS**, and
a reader taking the file-level word for either class inherits the other's. Naming the third value is what
makes the set closed — a vocabulary stated as two while its own contents hold three is closed in its
statement and open in its members, which is the state a closed set exists to refuse.

═══════════════════ ALLOCATION ═══════════════════

**Single letters first, then widen — the scheme never exhausts and never collides.**

```text
A … Z                    single
Aa Ab Ac … Az            two-part, cycling the second position
Ba Bb Bc … Bz
AAa AAb AAc … AAz        three-part, cycling the last position
ABa ABb ABc … ABz
```

**The shortest available identity is always the one issued**, so nobody has to reason about which tier
a name belongs to, and the tier of a name carries no meaning — `Aa` is not junior to `A`, it is simply
the next one that was free.

**A retired letter is never recycled into the pool.** The scheme is large enough that reuse buys
nothing, and reuse is the one change that breaks every historical citation at once without erroring
anywhere.

═══════════════════ ADDING A ROW ═══════════════════

1. Take the shortest free identity.
2. Write the row — letter, role, `ACTIVE` — **before the first write to any other surface.**
3. Declare scope on the board by concern, never by directory.

**The role is stated as a CONCERN, not as a task list.** A concern survives the work changing under it;
a task list goes stale the first time the agent finishes something, and a stale role is worse than a
vague one because it reads as current.
````
