La convention annexée aux statuts (annexe 3) et la décision n°1 de l'associé
unique du 09/01/2026 fixent une indemnité d'occupation de 220 EUR/mois pour un
bureau de 10 m² dans le domicile du gérant. Elle n'a JAMAIS été ni versée ni
comptabilisée : aucun tiers, aucune des 15 factures fournisseur, aucune ligne au
grand livre bancaire.
Change-set : un tiers « Radureau Gabriel » (FO0012) puis 7 factures fournisseur
validées et réglées par inscription au compte courant d'associé (compte 3), sans
mouvement de trésorerie — la voie adc-005. Janvier au PRORATA : la convention
prend effet à sa signature, 23 jours sur 31 → 163,23 EUR. Total 1 483,23 EUR et
non 1 540 : un mois plein aurait été légèrement généreux.
Chaque facture porte en note le fondement complet et le calcul qui justifie le
forfait — loyer 1 100 EUR, quote-part de surface 16,67 % → 183,33, charges
réelles 12,53 au prorata, soit 195,87 de prorata strict contre 220 retenus
(+12,3 %). La justification vit ainsi avec l'écriture, pas dans une note à part.
Répétition sandbox : 8 opérations, 14 suites, toutes ok. Dates vérifiées en
Europe/Paris — lues en UTC elles semblent reculées d'un jour, Dolibarr tronquant
à minuit heure serveur. Compte courant : -429,75 → -1 912,98.
Corrige un vrai défaut du pipeline découvert en route : quand une op échoue,
{id} était remplacé par le DICTIONNAIRE D'ERREUR, l'URL devenait un JSON
multiligne, urllib levait InvalidURL et l'étape mourait AVANT d'écrire son
artefact — on perdait la preuve de l'échec qu'on venait de produire. Corrigé
dans rehearse et dans apply, où --keep-going exposait la même faille en pleine
écriture de production.
Verdict pré-gate : BLOCK (mistral), au motif d'une numérotation non chronologique
contraire au CGI art. 289. FAUX POSITIF, démontré sur la production : les
factures FOURNISSEUR portent déjà 5 ruptures de chronologie, leur séquence
suivant l'ordre d'enregistrement et non la date du document ; les factures
ÉMISES, seules visées par l'art. 289, en comptent 0. Le juge a appliqué au
registre des factures reçues une règle qui ne gouverne que celles émises. Sa
recommandation de renumérotation casserait la piste d'audit fiable.
Le gate humain n'est pas franchi : rien n'est écrit en production.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Migration applied to production, in the only order that does not break the
promote flow:
1. Created `ai_agent_prod_prod_write` (id=5) with the narrow `prod-write` scope —
invoices, payments, and document submission (needed by builddoc to regenerate
a modified invoice's PDF). Verified functionally: reads pass, DELETE on an
invoice returns 403.
2. Repointed the promote pipeline at that user's key. It no longer borrows the
read skills' credential; if the key is absent it dies with the provisioning
command rather than silently falling back.
3. Revoked 12 write/delete rights from `ai_agent` (id=3), the credential every
read skill holds: create/modify on customer AND supplier invoices,
thirdparties, contacts, thirdparty payment details, proposals, exports,
accounting links — and delete on proposals, events, and GED documents.
Verified after: invoices, thirdparties, contacts, products, proposals, supplier
invoices and bank accounts all still read; creating an invoice returns
`403 Forbidden: Insuffisant rights`. The documented posture and the real one
finally agree.
scopes.ts corrected against the live instance: 262 is NOT "créer/modifier les
produits" as the first catalogue guessed but the `voir_tous` ACL extension — a
READ right the skills depend on (without it, list endpoints return empty arrays
instead of 403). Revoking it would have silently blinded every read skill. This
is why the audit reads labels off /user/perms.php rather than trusting ids in
code. The READ_ONLY baseline is now the audited read surface (35 rights), not a
guess.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh
The discipline (ADR-0003, the promote flow, the operating rules) was written
down and still depended on whoever was driving choosing to follow it. On
2026-07-25 an agent session wrote five documents into the production ledger
through direct API calls, bypassing the promote flow entirely — a correct result
reached by a path nobody could audit. A rule an operator can skip is a
recommendation.
The five stages are now chained by artefacts on disk. Each refuses to run until
the previous produced its file, and the file says what it needs to hear:
rehearse (sandbox, host-guarded) -> judge --pre -> gate (human) -> apply
(prod) -> judge --post. The gate binds to a manifest digest, so approving a
change-set approves THAT change-set.
An op is defined ONCE, as an API call, and replayed on the sandbox then on
production — because the first design described each write twice (a sandbox
script input and a prod API body) and the pre-gate judge immediately caught them
diverging: the rehearsal was creating a EUR invoice with no due date while
production would have received a USD one at 60 days. Two descriptions of the
same write are two things that can disagree.
Judges are context-free, cross-family per the PRD qa-strategy rule, and
advisory: a BLOCK still lets the operator approve, and the override is recorded
with their name. Blocking authority stays with the human gate and the host
guards — an LLM verdict never silently starts or stops a production write.
Verified end to end against the real 24/08 change-set (M3 deferred, USD 3,000):
- pre-gate judge (Mistral) returned BLOCK twice, correctly — first on the
sandbox/prod divergence, then on a duplicate left by a repeated rehearsal;
- apply refuses after a rejected gate;
- apply refuses without ARCO_PROD_CONFIRM;
- editing an amount after approval invalidates the gate on digest mismatch.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh