Files
erp/fleet/harness
arcodangeandClaude Opus 5 5607e2af86 feat(erp): cycle M4 KissMetrics, comblement des écarts bancaires, clause de pénalités rétablie
Deux passages gated en production, et l'outil qui manquait pour clore le dossier
client.

CYCLE M4 (2026-08-24-m4-et-ecarts). Cinq opérations : le tiers Anthropic PBC —
entité américaine, distincte d'Anthropic Ireland Limited — et sa facture de
90 EUR réglée le 19/07 ; le règlement Darnis de 262,20 EUR ; les deux factures
du cycle M4 (part fixe 2 500 USD → 2 140,45 EUR échéance 22/09, part différée
3 000 USD → 2 568,54 EUR échéance 23/11). Les trois écarts bancaires relevés
sont comblés ; Qonto tombe à 3 806,08 EUR.

Le juge pré-gate a bloqué : le règlement Darnis du 14/08 précède la facture
datée du 31/08. C'est un fait bancaire, pas une erreur de saisie — Darnis
facture en fin de mois — et adc-008 avait EXPRESSÉMENT prévu ce blocage et
autorisé le passage outre tracé. L'art. 289 du CGI qu'invoque le juge régit la
numérotation des factures ÉMISES, non l'ordre entre un paiement et sa facture ;
c'est la troisième fois de la session qu'il l'étend hors de son champ.

CLAUSE DE PÉNALITÉS (2026-08-24-clause-bilingue). Les factures M4 sont sorties
avec une clause AMPUTÉE : sans la traduction anglaise, sans la mention « Ces
stipulations sont des minima légaux d'ordre public auxquels il ne peut être
renoncé ». Détecté par le contrôle des mentions obligatoires sur les PDF —
avant tout envoi. La note publique est rétablie dans sa rédaction de référence,
à droit constant : aucun montant, aucune date, aucune ligne touchés.

Deux raisons de corriger plutôt que de laisser courir. La permanence des
méthodes (PCG art. 121-5, adc-011) : une clause légale identique doit être
rédigée identiquement, sans quoi la variation se lit comme une intention. Et le
fond : le destinataire est américain, c'est la version anglaise qui lui rend la
clause opposable en fait — et c'est sur elle que s'appuie la relance.

Le juge a bloqué là aussi, en supposant que la référence portait « ce montant ».
Il ne l'avait pas vérifié, et son propre residual risk demandait de le faire.
Vérification faite et consignée (02b-preuve-reference.txt) : FAC005 à FAC008
portent toutes « ce forfait », et la clause proposée leur est identique au
caractère près — 1283 car. Le finding était inversé.

test/buildInvoicePdf.ts. Valider une facture par l'API ne produit AUCUN PDF : le
fichier n'existe que si quelqu'un l'a demandé. `PUT /documents/builddoc` le
ferait mais répond 403 — ce droit n'est accordé à aucun scope agent. Le script
emprunte donc l'interface, puis relit le fichier par l'API : on ne croit pas la
page de retour, on vérifie que le PDF est déposé et lisible par un tiers.

Les deux juges post-gate passent sans dérive.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-24 13:12:34 +02:00
..

fleet/harness/ — the multi-runtime harness layer

The harness is the orchestration layer around the atoms: builder sessions that execute backlog issues, cold verifiers that check them (locate-tests, backlog audits, refutation passes), and the evidence flow into Gitea. Per the PRD model-fleet harness portability (operator direction 2026-07-15), this layer must not have Anthropic as a hard dependency: the same loop runs on Mistral (vibe -p, mistral-medium-3.5) or on hermes-served local models (Ornith / MLX, 127.0.0.1:18080). Claude is an escalation tier, not a prerequisite. Admission of a runtime to a role is evidence-gated (erp#63): verifier roles first, scoped builders benched second, and no acceptance gate is ever relaxed for a cheaper runtime.

Layout

Path Role
verifier/locate-test.md canonical locate-test: prompt, inputs, ground truth, pass rule
verifier/backlog-audit.md canonical cold-reader backlog audit: prompt, inputs, rubric
bin/run-verifier.sh run a verifier test against a runtime; emits a JSON transcript
bin/vibe-builder.sh run a scoped builder bench (vibe -p) inside a worktree, with caps + journal
runs/<date>/ committed evidence transcripts, when they back an issue comment

Runtimes

Runtime How the harness reaches it Typical role
claude a context-free subagent in a Claude Code session, given the exact assembled prompt (run-verifier.sh <test> --print-prompt) and nothing else baseline verifier; multi-file builder (default per the PRD complexity ceiling)
ornith hermes MLX server, OpenAI-style POST /v1/chat/completions on 127.0.0.1:18080, model leonsarmiento/Ornith-1.0-35B-5bit-mlx verifier (candidate)
mlx --model <id> same endpoint, any model the server lists under /v1/models verifier (candidate)
mistral vibe -p programmatic mode, tools disabled, model = the vibe active_model (today mistral-medium-3.5) verifier (candidate); scoped builder via vibe-builder.sh

Verifier protocol — no self-grading

  1. Assemble the prompt from the canonical test file + the pinned input documents (run-verifier.sh embeds file contents verbatim and records their sha256).
  2. Run every candidate runtime on the same assembled prompt, temperature 0.
  3. An independent, context-free judge (never the session that built the thing, per the PRD qa-strategy) scores each transcript against the test's ground truth and emits the parity table. A runtime is admitted to verifier duty when it reaches verdict parity with the Claude baseline on both tests.
  4. Once a non-Claude verifier is admitted, prefer cross-family verification: the verifier SHOULD be a different model family than the builder — a foreign family refuting the builder is stronger evidence than the builder's own family agreeing with itself.

Builder bench protocol

vibe-builder.sh runs one tightly-footered backlog issue end-to-end under a non-Claude runtime, against the unchanged Execution footer and acceptance gates. It measures completion, intervention count and wall-clock; a failed bench is a valid result — it sets the complexity ceiling honestly. Safety bounds:

  • refuses to run anywhere that is not a linked worktree (never the trunk — same structural-guard pattern as dol-write.sh);
  • hard caps: --max-turns and --max-price are always set;
  • --auto-approve is acceptable only because the blast radius is bounded: a disposable worktree, read-only API credentials, and the caps above;
  • the full vibe JSON journal is kept per run.

Recurring tasks on the Mistral tier

A recurring task (T11 reminders, T13 drift checks, T14 backup freshness) is a scoped builder with a standing prompt: cron (hermes cron or the operator's scheduler) calls vibe-builder.sh <worktree> <task-prompt.md> and routes the journal into the digest. The task prompt lives with the atom (fleet/atoms/<atom>/prompt.md + its class skeleton); the harness only supplies the bounded execution shell. No recurring task writes outside its worktree, and anything ERP-write-shaped still goes through the sandbox + promote gate — runtime choice never changes the gates.