docs(prd): agent catalog — task→(prompt+model+orchestrator) matrix + agent-facing file syntax

New agent-catalog.md leaf answering three operator directions:
(1) the document surface agents read is now specified — AGENTS.md
orientation maps, SKILL.md with trigger-carrying descriptions
(Use-when/SKIP-for), atom.yaml registry contracts, thin prompt.md
files (no business rules in prompts — rules live in profile files
and validators), schema'd fiscal.yaml/calendar.yaml with
effective_from dates, [AGENT]/[HUMAN] runbooks, env-var-indirected
.mcp.json; same-change freshness rule extended to the fleet.
(2) hermes's telegram-gateway confirmed as THE human channel when
available (cluster-served cards, email fallback; D1 operator-endorsed).
(3) the categorization to prove: seven agent classes (incl. the
LLM-free deterministic controller) and a T01-T17 assignment matrix
with per-row proof gates and statuses (proven / to-prove / not-built),
re-scored monthly from run journals (fallback rate >20% = wrong cell).
New D8 (fleet code home, leaning erp fleet/).

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
2026-07-11 15:09:28 +02:00
co-authored by Claude Fable 5
parent 5430e5f3ac
commit 8e4186dbeb
4 changed files with 82 additions and 4 deletions
+73
View File
@@ -0,0 +1,73 @@
[vibe](../../README.md) > [PRD](../README.md) > [AI back-office](README.md) > **Agent catalog**
# Agent catalog — who does what, with which brain, under which conductor
> **Status:** In design (assignments are hypotheses until proven)
> **Last Updated:** 2026-07-11
> **Up:** [AI back-office hub](README.md)
> **Related:** [Task inventory](task-inventory.md) · [Model fleet](model-fleet.md) · [Agent architecture](agent-architecture.md) · [QA strategy](qa-strategy.md)
An "agent" here is the concrete triple **prompt + model + orchestrator** bound to a task. This page names the classes, assigns every task, states how each assignment gets *proven* (éprouvé), and fixes the syntax of the document surface agents read to do the work. Honesty first: several agents are deliberately **LLM-free** — a cron-driven script with validators is the best "agent" for deterministic work, and the prompt column says so.
## Agent classes
Seven prompt skeletons; every atom's prompt extends exactly one. Skeletons live with the fleet code (`fleet/classes/<class>.md` — see [D8](agent-architecture.md#open-decisions)).
| Class | Prompt skeleton (the invariant part) | Model policy | Orchestrator | Serves |
| --- | --- | --- | --- | --- |
| **Sentinel** | closed-set classification, schema-constrained output, refuse below threshold | Pi SLM (GBNF) → M4/Mistral fallback | k3s CronJob → queue | T01, deadline detection |
| **Extractor** | document → JSON Schema, zero tools, dual independent run, never "fix" arithmetic | M4 local ∥ Mistral (agreement), Claude escalation | queue workers (cluster leg + hermes leg) | T02, T16 |
| **ERP scribe** | manifest assembly over the write skills, [ledger grammar](compliance.md#the-ledger-grammar-production) honored, predicted-delta before card | Claude (Agent SDK headless) | gateway handler → gate → promote | T03, T04-create, T05, T08-ambiguous |
| **Deterministic controller** | — (no prompt: scripts + validators + linter) | — | k3s CronJobs | T07, T08-matched, T11, T13, T14 |
| **Analyst-writer** | narrative strictly over verified figures; cite from ERP/journals only; no advice | Claude, or M4 for local prose | crons → digest | T06 drafts, T09, T10 narrative, T15 exceptions |
| **Researcher** | sourced-claims-only (official domains), effective dates mandatory, output = diff proposal | Claude + web | quarterly / event-driven | T12 |
| **Knowledge archivist** | vault conventions: append-only, idempotent frontmatter, PARA filing hints | per vault doctrine (Ornith/Mistral/Claude) | hermes cron + per-run hooks | T17 |
## Assignment matrix
Status legend: ✅ proven in operation · 🧪 built or designed, **to prove** (à éprouver) · ⬜ not built. Where a task splits (deterministic core + LLM edge), both appear.
| Task | Class | Prompt / code | Model | Orchestrator | Proof gate | Status |
| --- | --- | --- | --- | --- | --- | --- |
| [T01](task-inventory.md#t01--mailbox-triage--routing) | Sentinel | `fleet/atoms/mail-classify/` | Pi Qwen3-class 1.74B, GBNF | k3s CronJob (30 min) | [POC-2](poc-plan.md#poc-2--pi-sentinel) ≥ 95 % on 200 labeled mails | 🧪 |
| [T02](task-inventory.md#t02--supplier-invoice-extraction) | Extractor ×2 | `fleet/atoms/invoice-extract/` | M4 structured ∥ Mistral JSON; Claude escalation | queue workers | [POC-1](poc-plan.md#poc-1--supplier-invoice-end-to-end)+[POC-5](poc-plan.md#poc-5--model-routing-bench) ≥ 98 % critical fields | 🧪 |
| [T03](task-inventory.md#t03--supplier-invoice-recording) | ERP scribe | `dolibarr-sandbox-write` + `fleet/atoms/invoice-record/` | Claude headless | gateway → gate → promote | POC-1 10-invoice exit gate | 🧪 (write skills ✅, loop ⬜) |
| [T04](task-inventory.md#t04--thirdparty-creation--completeness) | Controller + scribe | `dolibarr-thirdparty-completeness` (audit, no LLM); creation rides T03 | — / Claude | monthly CronJob / with T03 | audit: live now; creation: POC-1 | ✅ audit · 🧪 creation |
| [T05](task-inventory.md#t05--client-invoice-issuance) | ERP scribe + auditor | `dolibarr-recurring-templates` + `dolibarr-invoice-audit` + fire atom | Claude | monthly cron (1st) + card | first agent-fired invoice == manual twin ([D3](agent-architecture.md#open-decisions)) | ⬜ |
| [T06](task-inventory.md#t06--receivables-watch--dunning) | Analyst-writer | `fleet/atoms/dunning-draft/` (+ T17 retrieval for tone/history) | Claude | weekly cron → card | N consecutive drafts approved unedited | ⬜ |
| [T07](task-inventory.md#t07--bank-reconciliation) | Controller | `arcodange-bank-reco` (`bank-match.sh`) | **— no LLM** | weekly CronJob | fixture-proven; standing zero-delta invariant | ✅ skill · 🧪 standing |
| [T08](task-inventory.md#t08--payment-recording) | Controller + scribe | `payment-record.sh` manifests from matched movements | — matched; Claude ambiguous | queue → gate → promote | [POC-3](poc-plan.md#poc-3--reconciliation--payment-recording) one clean month | 🧪 |
| [T09](task-inventory.md#t09--cash-position--runway) | Analyst-writer | balances workflow + `fleet/atoms/cash-report/` | figures deterministic; M4 prose | monthly CronJob + hermes leg | figures == live bank APIs, every run | 🧪 |
| [T10](task-inventory.md#t10--tva-preparation) | Controller + analyst | `dolibarr-tva-summary` + narrative atom | — figures; Claude narrative | calendar-triggered (T11) | [POC-4](poc-plan.md#poc-4--tva-dry-run) €-parity vs filed | 🧪 (skills ✅) |
| [T11](task-inventory.md#t11--compliance-calendar--reminders) | Controller | calendar file + `fleet/atoms/deadline-remind/` | **— no LLM** (parsing upstream in T01/T12) | daily k3s cron → gateway | synthetic-calendar firing test | ⬜ |
| [T12](task-inventory.md#t12--regulatory-watch) | Researcher | `fleet/atoms/reg-watch/` | Claude + web | quarterly + event | every claim sourced + PR review | 🧪 (method proven authoring this PRD) |
| [T13](task-inventory.md#t13--erp-snapshot--drift-detection) | Controller | `dolibarr-data-snapshot` | **— no LLM** | daily CronJob + around writes | drift alert fires on seeded change | ✅ skill · 🧪 cron+alert |
| [T14](task-inventory.md#t14--backup--restore-verification) | Controller | `ops/backup` + freshness watchdog | **— no LLM** | daily CronJob (live) + monthly drill | restore drill green monthly | ✅ backup/restore · 🧪 watchdog+drill cadence |
| [T15](task-inventory.md#t15--monthly-coherence-audit) | Composer + analyst | skill composition + exception narrative | — checks; Claude narrative | monthly CronJob → digest | first pack matches a manual cohort review | ⬜ |
| [T16](task-inventory.md#t16--document-filing--retention) | Extractor | `fleet/atoms/doc-file/` | M4 local | per-document queue | document golden set | ⬜ |
| [T17](task-inventory.md#t17--knowledge-capture--retrieval-second-brain) | Knowledge archivist | `sb.py` + hermes `second-brain` skill + capture atom | vault doctrine (Ornith/Mistral/Claude) | hermes cron (live) + per-run hooks | deposits idempotent over re-runs; retrieval dated | ✅ vault side · 🧪 fleet side |
## Proving protocol — how a 🧪 becomes a ✅
The matrix is a set of falsifiable hypotheses, not documentation:
1. **Tier choice** is proven by [POC-5](poc-plan.md#poc-5--model-routing-bench)'s bench (accuracy × latency × cost on the golden set) and recorded into the atom's `model_policy` — if the Pi can't hold T01's bar, the matrix cell changes, not the bar.
2. **Loop viability** is proven by the owning POC's exit criterion; autonomy then follows the [promotion gates](qa-strategy.md#autonomy-promotion-gates).
3. **In operation, the matrix is re-scored from run journals**: every escalation and tier fallback is journaled, so the monthly ops review reads which tier *actually* served each task. A cell whose fallback rate exceeds ~20 % is wrong and gets reassigned.
4. A ✅ is revocable: incident → demotion → the cell reverts to 🧪 with the same path back.
## The document surface agents read
What an agent knows about this system, it learns from files. Their syntax is part of the architecture:
| File | Read by | Lives at | Syntax rules |
| --- | --- | --- | --- |
| `AGENTS.md` | every agent, session start | each repo root | Orientation map: what the repo is, operating rules, pointers — the factory `AGENTS.md` is the canon (diagram + tables + hard rules). The **erp repo's must gain a Fleet section**: environment rules, ledger-grammar pointer, registry location. Keep it short; link, don't inline. |
| `SKILL.md` | Claude Code (auto-discovery), hermes (snapshot) | `.claude/skills/<name>/`, `~/.hermes/skills/<domain>/<name>/` | YAML frontmatter `name` + `description`; the description **carries the triggers**: capability summary + explicit *"Use when…"* and *"SKIP for…"* clauses (the proven `dolibarr-*` pattern). Body = numbered workflows; executables under `scripts/`; secrets in mode-600 gitignored `.env`. |
| `atom.yaml` (registry) | orchestrators, humans, CI | `fleet/atoms/<atom>/` | The [contract fields](agent-architecture.md#atom-contract): I/O JSON Schemas, invariants, `side_effect_class`, idempotency key, earned autonomy + eval evidence link, `model_policy`. Folder name = atom name = registry name — the `<app>` join-key discipline applied to atoms. |
| `prompt.md` | the model, at runtime | next to `atom.yaml` | ≤ ~40 lines: role (1 line), task, output = *reference to the schema* (never a prose re-description), refusal/escalation clause. **No business rules in prompts** — rules live in the fiscal profile and validators (code); prompts stay thin, versioned, diff-reviewable. Extends one class skeleton (`fleet/classes/`). |
| `fiscal.yaml` + `calendar.yaml` | fiscal atoms, T11 | `fleet/profile/` | Schema'd YAML; **every rule carries an `effective_from`** (and `effective_until` when known); mutations arrive as PRs (T12 proposes, human merges). |
| Runbooks | humans + agents | factory `vibe/runbooks/` | House rule: every step marked `[AGENT]` (safe, delegable) or `[HUMAN]` (prod-mutating, approval-bound) — the same markers as the [task inventory](task-inventory.md). |
| `.mcp.json` | agents needing MCP tools (vault, ERP) | repo/vault roots | Servers declared with **env-var indirection for keys** (`${OBSIDIAN_API_KEY}` pattern) — never literals. |
Cross-cutting rules: **English** for all agent-facing files (house language policy); **write descriptions for retrieval** — agents discover skills by their description text, so triggers belong there, not in the body; **same-change freshness** — a change to an atom that leaves its `SKILL.md`/`atom.yaml`/`prompt.md` stale is an incomplete change (the guidebook-maintenance rule extended to the fleet); **one capability per file**; frontmatter over prose for anything a machine parses.