Files
erp/fleet
arcodangeandClaude Opus 5 a11ec634ea feat(erp): manifeste d'exercice — décrire les faits pour pouvoir les rejouer
Un exercice OUVERT n'a d'engagement envers personne : aucun compte déposé,
aucune liasse, aucun FEC remis. Tant qu'il en va ainsi, une erreur de
MODÉLISATION se corrige mieux en rejouant depuis les pièces qu'en la
contournant — la piste d'audit fiable demande que l'écriture reflète sa pièce,
et rejouer resserre ce lien là où une rustine le distend.

extractExercise.ts ne fait que LIRE. Il produit la description ordonnée des
faits : tiers, factures client et fournisseur avec leurs lignes et règlements,
et l'intégralité des mouvements bancaires.

Les mouvements bancaires sont le RÉFÉRENT : Qonto et Wise sont hors de
Dolibarr, on ne peut pas les réécrire. Le test d'acceptation d'un rejeu est
donc qu'ils soient retrouvés au centime et à la date.

La ligne de partage entre ce qui se rejoue et ce qui est figé n'est pas
technique mais juridique : est figé tout ce qu'un tiers détient — facture
client ENVOYÉE, dépôt au greffe, déclaration transmise — et tout exercice clos.
Les factures client sont donc extraites avec delivered:true : un rejeu les
reproduit à l'identique, il ne les recalcule pas.

Les exclusions sont DÉCLARATIVES ET MOTIVÉES, jamais codées en dur : un
auditeur doit lire pourquoi une référence manque sans avoir à le deviner. Deux
pièces sont écartées — FAC001-CL00001, dont la référence était malformée par un
défaut de masque, et l'avoir qui l'annulait. L'opérateur a établi qu'elle n'a
jamais quitté la société : KissMetrics a été facturé via Wise en février, et le
document qu'il détient référence FAC001-CL0001001. L'avoir ne documentait donc
qu'un faux pas interne. La séquence FAC reste continue (FAC001 à FAC008), la
réémission portant elle aussi FAC001 — rien à renuméroter.

Deux constats que l'extraction met au jour :

- 20 des 37 mouvements bancaires portent un libellé Dolibarr générique
  (« SupplierInvoicePayment », « CustomerInvoicePayment ») qui traverse le grand
  livre tel quel et y est illisible pour un repreneur comme pour un inspecteur ;
- FAF2025001 (OVH, 7,30 EUR) est datée du 24/10/2025, trois mois avant
  l'immatriculation, et NE FIGURE PAS à l'annexe 1 des statuts qui recense les
  actes accomplis pour le compte de la société en formation. Une dépense
  antérieure à l'existence de la société ne peut être supportée par elle que si
  elle est reprise par cet état ou ratifiée ensuite.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-14 17:55:30 +02:00
..

fleet/ — the atom registry

The fleet is Arcodange's AI back-office: narrow agents ("atoms") that operate the Dolibarr ERP's daily admin & accounting under the AI back-office PRD. This directory is the registry — the versioned source of truth for what the fleet may do. An atom absent from the registry does not run. Contract semantics come from the PRD atom contract; file syntax from the PRD document surface.

What an atom is

One narrow capability (classify, extract, validate, record, reconcile, report, remind) with a strict I/O contract and deterministic validators around it. The LLM proposes, code disposes: formats, arithmetic, checksums, dedupe and referential integrity are enforced by validators, and a model output that fails validation is quarantined, never auto-corrected. Workflows are compositions of atoms with explicit gates — never one prompt that "does the accounting".

Each atom lives in fleet/atoms/<atom>/:

File Role
atom.yaml the registry entry — the contract (schema below)
prompt.md thin runtime prompt, ≤ ~40 lines, extends exactly one class skeleton; no business rules (rules live in fleet/profile/ and in validators)
scripts/ the deterministic implementation: runners, validators, scoring hooks

Folder name = atom name = registry name — the house <app> join-key discipline applied to atoms.

Layout

fleet/
├── README.md                  # this file: registry doc + atom.yaml schema
├── classes/                   # the 7 prompt skeletons (PRD agent catalog)
│   ├── sentinel.md
│   ├── extractor.md
│   ├── erp-scribe.md
│   ├── deterministic-controller.md   # no-LLM by design
│   ├── analyst-writer.md
│   ├── researcher.md
│   └── knowledge-archivist.md
├── atoms/
│   └── invoice-extract/       # T02 — the worked example (contract only; implementation = erp#40)
│       ├── atom.yaml
│       ├── prompt.md
│       └── scripts/
├── golden/                    # per-atom golden sets — land with erp#39
├── profile/                   # fiscal.yaml + calendar.yaml + ADC register + validator (profile/README.md)
└── harness/                   # multi-runtime harness layer: verifier tests + builder bench (harness/README.md)

atom.yaml — the contract, field by field

Per the PRD atom contract:

Field Meaning
name, version Identity. Folder name = name. version bumps on any behavioral change (prompt, model, validator) — a bump re-triggers the atom's golden-set evals.
input_schema / output_schema JSON Schema for the atom's I/O; enforced at runtime (constrained decoding where the model tier supports it).
invariants Deterministic post-conditions checked by code after every run (e.g. HT + TVA == TTC ± 0.01). A failed invariant quarantines the output — refuse, never repair.
side_effect_class read · draft · write-sandbox · write-prod · outbound — drives which gates and credentials apply, per the PRD environment posture table.
idempotency_key How a replay is recognized (e.g. supplier + ref_supplier + TTC) — a second run with the same key must be a no-op.
autonomy The earned level (A0A3 on the autonomy ladder) + a pointer to the eval evidence that justifies it.
model_policy Preferred tier, fallbacks, escalation rule, per the PRD model fleet; closed per-atom by routing-bench evidence (erp#45 for the first atoms).
eval_ref Where the golden set + scoring script live (fleet/golden/<atom>/).

Two registry conveniences beyond the PRD contract fields bind the entry to the rest of the surface: class (which fleet/classes/<class>.md skeleton the prompt extends) and task (the PRD task-inventory id the atom serves).

The worked example is atoms/invoice-extract/atom.yaml (T02) — contract only; its implementation is erp#40.

How an atom graduates

Autonomy is earned per atom, never assumed. The levels (A0 manual → A1 prepare → A2 rehearse + gate → A3 autonomous + audit) are defined on the PRD autonomy ladder; promotion and demotion are mechanical, per the PRD autonomy promotion gates (golden-set evals, unedited-approval streaks, incident demotion — the bars live there, not here). The earned level and its evidence are recorded in the atom's autonomy field: a promotion is a PR that changes that field with the evidence linked, verified per the QA strategy's independent-verification rule.

Conventions

  • English for all agent-facing files (house language policy).
  • Same-change freshness: a change to an atom that leaves its atom.yaml / prompt.md stale is an incomplete change.
  • One capability per file; YAML/frontmatter over prose for anything a machine parses.
  • Environment rules (trunk hygiene, read-only prod, sandbox-first writes, promote gate) are the repo-wide ones: AGENTS.md operating rules + dolibarr-sandbox-write SKILL.md.