# Adding, Replacing, and Retiring Assistants The roster is not fixed. Assistants get added when a domain earns one, replaced when the character isn't working, and retired when they don't justify their overhead. This is the checklist for doing that cleanly. ## The casting rule **Assistants are fictional characters.** This is deliberate: - **Real people have baggage.** A real person's biography, politics, and later life all arrive with the name, whether or not they're wanted, and they can change after the fact. - **Dead people are worse.** Speaking as someone who actually lived, and died, is uncomfortable in a way that a character isn't. - **Fictional characters have canon.** A character has a documented voice, a known set of behaviours, and a fixed body of source material to check the writing against. That makes the bible *verifiable* rather than invented. Historical or public figures who function as archetypes (Marcus Aurelius, Hypatia of Alexandria) sit at the edge of this and survive on the strength of the archetype. Contemporary real people generally do not. ## When to retire an assistant Retire when any of these hold, not just when the character is disliked: - **No distinct capability.** An agent with no dedicated MCP server and no tools the others lack is a prompt, not an agent. Its domain can usually be folded into a neighbour. - **Domain overlap.** Two agents whose owners keep cross-referencing each other on the same task are often one agent. - **Casting failure.** The character doesn't fit the rule above, or the voice never landed. - **Headcount.** Every agent is a prompt to maintain, a roster row in *every other agent's* prompt, a port, and a registry entry. Fewer, better-justified agents beat a long tail. **A merge is legitimate.** One new agent can replace two — Sophia replaced Bourdain and Cousteau, taking all eleven of their node types. If a single plausible character can hold both domains, that's a net win. ## Don't tell an agent who they replaced **The successor's prompt and bible describe who they *are*, not who they came after.** An agent doesn't need its own provenance — that information can only muddy the voice, invite comparison to a character that no longer exists, and waste context. Sophia is not "the agent who replaced Bourdain"; she's Sophia. Provenance is a *human* concern and belongs in exactly three places: 1. The **schema Version History** in [tools/neo4j/unified-schema.md](tools/neo4j/unified-schema.md) — the durable record of node-ownership changes. 2. The **git commit** that made the change. 3. Nowhere else. This is a change of practice as of 2026-07-26; earlier replacements (Watson→Seneca, David→Bowie) had lineage sentences in their prompts, which have since been removed. ## Node ownership transfers for free Neo4j uniqueness constraints are keyed on the **node label**, not on the owning agent. A successor inheriting `Recipe` or `Species` needs **no schema migration and no data migration** — only the documentation changes. `utils/neo4j-schema-init.py` and `utils/neo4j-validate.py` reference agents only in comments; verify this before assuming a migration is needed. **Leave historical `Note` messages alone.** Inter-agent messages carry `from:` / `to:` tags. After a retirement those tags name an agent that no longer exists — that is correct. They are an accurate record of what happened, and rewriting them falsifies history for no benefit. ## Checklist Assume the names appear in **more places than seems reasonable** — every agent prompt embeds a copy of the team roster, so a single retirement touches all three teams. Grep first, and grep across every repo, not just koios. ### koios (the spec) - [ ] `docs/{team}/{name}.md` — new bible; delete the retiree's. - [ ] `prompts/{team}/{name}.md` — new prompt; delete the retiree's. - [ ] `docs/{team}/team.md` — agent blurb, responsibility matrix, collaboration patterns, agent count. - [ ] `docs/{team}/subagents.md` — the lead-agent list. - [ ] **The roster table at the end of every personal prompt** and in `prompts/personal/subagents/research.md`. - [ ] **The cross-team directory table in every work prompt** (`| name | Personal | Domain |`). - [ ] **The one-line Assistant Directory** in every engineering prompt and `docs/tools/neo4j/shared.md`. - [ ] `docs/tools/neo4j/{team}.md` — ownership table and counts. - [ ] `docs/tools/neo4j/unified-schema.md` — Teams & Assistants table, the per-agent domain section, the **Primary Owner** column in Node Type Summary, and a new **Version History** row. - [ ] `docs/tools/*.md` — any "Who Uses X" sections naming the agent. - [ ] `utils/neo4j-*.py` — comments only. - [ ] `README.md` — the team roster table. - [ ] **Agent counts** — "N AI assistants", "all N assistants" appear in several files and drift easily. - [ ] **Prose cross-references** — redirect them to the successor rather than deleting; check pronouns if the successor's gender differs. - [ ] **Worked messaging examples** naming the retiree in an `id` or `to_tag` — rewrite wholesale. ### Runtime repos (iolaus, mentor, kottos) The instruction text is **duplicated inline** in each agent module; koios is the spec, the `.py` is the wiring, and they are kept in sync by hand. - [ ] `agents/{name}.py` — new module; delete the retiree's. - [ ] `agents.yaml` — entry, port, description. - [ ] `fastagent.config.yaml` / `fastagent.secrets.yaml.example` — any new MCP server. - [ ] **Every sibling agent's `Directory:` line**, ownership tables, and messaging examples — in *all three* runtime repos, not just the team that changed. ### Deploy (virgo, ouranos) - [ ] `ansible/{project}/agents.yaml.j2` — **the in-repo `agents.yaml` is replaced at deploy time**, so without this the retired agent still starts. - [ ] `ansible/{project}/fastagent.{config,secrets}.yaml.j2` — new servers and tokens. - [ ] `terraform/oci/secrets.tf` + `group_vars` + `host_vars` — any new credential. - [ ] `docs/{project}.md` — the deployed roster, ASCII topology, port table, and smoke-test commands. ## Verifying ```bash # Should return only the schema Version History row and the git log grep -rn -i "retired-name" --include="*.md" --include="*.py" . # Every personal prompt should carry the same number of roster rows for f in prompts/personal/*.md; do printf "%s %s\n" "$(sed -n '/^## Personal Assistant Team/,/^## /p' "$f" | grep -c '^| \*\*')" "$f" done # No dangling links to a deleted bible grep -rn "retired-name.md" --include="*.md" . ``` Then confirm the runtime actually agrees: the module imports, and the registry Pallas would publish contains the new agent and not the old one.