# ERRATA — EMAILFIND-001

Journal des corrections publiées. Une entrée par erratum, jamais réécrite: une
correction ultérieure ajoute une entrée, elle ne modifie pas les précédentes. Les octets
d'avant correction restent dans l'historique git aux commits cités.

Procédure: `docs/decisions/L0-002-procedure-erratum.md` (adoptée le 2026-09-03), sept
étapes. Deuxième cas d'application dans le dépôt, premier sur ce run.

---

## ERR-001 — `conflicts` servi vide alors que devlo est client des deux bras (2026-09-04)

| | |
|---|---|
| **Date (UTC)** | 2026-09-04T09:40:00Z |
| **Champs fautifs** | `conflicts` (servi `[]`) et `runner` (« devlo (GLADIATOR lane L3, agent-operated) ») de `runs/EMAILFIND-001/result.json`, source `contest.yaml` |
| **Constaté par** | lane OPS-001 (inventaire des détails, ligne OPS-109; jargon interne: ligne OPS-021), revue croisée Grok du 2026-09-04 |
| **Décision de référence** | `docs/ops/DETAILS-INVENTORY.md` OPS-109; procédure `docs/decisions/L0-002-procedure-erratum.md` |
| **Corrigé par** | lane OPS-002 |

**Sévérité: bloquante.** La surface publique disait « aucun conflit » pour un run dont les
deux bras mesurés sont des outils dont devlo est client, et dont le coût a été payé sur les
crédits prépayés devlo de ces deux comptes. Un lecteur qui juge l'indépendance de la mesure
lisait un fait faux, sur toutes les surfaces (bundle, `results/emailfind/latest.json`,
rapport, site, MCP `explain_limits`).

### Ce qui était publié

`conflicts`: `[]`. `runner`: « devlo (GLADIATOR lane L3, agent-operated) ».

### Ce qui est vrai

`CONFLICT_REGISTER.json` déclare Lusha `USER_OF_TOOLS` depuis le 2026-09-02 (devlo est
client, provider registré de sa cascade de recherche d'emails). `SPEND_LEDGER.json` montre
que le run a consommé 106 crédits prépayés Dropcontact et 26 crédits prépayés Lusha du
compte devlo existant. Dropcontact n'avait pas d'entrée au registre: elle est ajoutée par cet
erratum (`USER_OF_TOOLS`, même relation). Le nom interne de lane (« GLADIATOR lane L3 »)
n'est pas une information pour le lecteur: le run a été opéré par un agent pour devlo.

### Origine

`conflicts` et `runner` étaient **codés en dur** dans les deux producteurs de la catégorie
(`categories/emailfind/scorer.py` et `categories/emailfind/convert_bundle.py`), sans lecture
du registre. La propagation: producteur → `contest.yaml` → `result.json` →
`results/emailfind/latest.json` → `reports/EMAILFIND-001.*` → site, MCP.

### Correction appliquée

`conflicts` après correction (une ligne par participant présent au registre, grammaire
fermée en anglais, projetée de `CONFLICT_REGISTER.json` par
`categories/emailfind/conflicts.py`):

> « dropcontact: devlo is a customer of Dropcontact and this run was paid from devlo's
> existing prepaid credits; devlo is a user of the tool, not a vendor; same conditions and
> credits for every arm, journaled (CONFLICT_REGISTER.json: USER_OF_TOOLS) »
>
> « lusha: devlo is a customer of Lusha and this run was paid from devlo's existing prepaid
> credits; devlo is a user of the tool, not a vendor; same conditions and credits for every
> arm, journaled (CONFLICT_REGISTER.json: USER_OF_TOOLS) »

`runner` après correction: « devlo (agent-operated) ».

Corrigés à la source, dans cet ordre:

1. `CONFLICT_REGISTER.json` — entrée Dropcontact ajoutée (`USER_OF_TOOLS`, source
   `SPEND_LEDGER.json`).
2. `categories/emailfind/conflicts.py` (nouveau), `categories/emailfind/scorer.py`,
   `categories/emailfind/convert_bundle.py` — les producteurs projettent `conflicts` du
   registre et portent le `runner` sans jargon. Sans cela, tout rescore réintroduirait la
   faute (règle « réparer l'artefact ET le producteur »).
3. `tools/check_conflicts_projection.py` et `tests/test_conflicts_projection.py` — le gate
   qui refuse `conflicts: []` pour un participant présent au registre, avec sa fixture
   négative (la faute reproduite) et son contrôle positif.
4. `runs/EMAILFIND-001/contest.yaml` — source canonique des deux champs. Ce fichier est
   **gelé dans `PROTOCOL.lock`**: sa correction est traitée en **amendement A6**, décrit dans
   `PROTOCOL_AMENDMENTS.md` (réécriture du lock à `locked_at` inchangé + re-chaînage du
   journal, dont la genèse est le hash du lock; outil
   `categories/emailfind/tools/amend_conflicts.py`, calque de l'amendement A2 de
   TRANSCRIPTION-001).

   **Antériorité: le nouveau lock n'en prouve aucune pour le texte corrigé** (L0-002 étape 2,
   « le dire »). Les lignes `conflicts` ont été écrites le 2026-09-04, après le run. Ce qui
   est antérieur et vérifiable, c'est le fait qu'elles décrivent: l'entrée Lusha du registre
   (2026-09-02) et les lignes de crédits du ledger (2026-09-02), toutes deux antérieures au
   premier événement du journal. `ANALYSIS_PLAN.md` et `PROTOCOL.md`, gelés, sont inchangés
   par l'erratum (leurs empreintes sont identiques dans les deux versions du lock).
5. `runs/EMAILFIND-001/result.json` — rescoré par `gladiator` (`score_run`), remis en ordre
   servi (`tools/apply_served_order.py`).
6. `results/emailfind/latest.json`, `reports/EMAILFIND-001.md` et
   `reports/EMAILFIND-001.report.json` — régénérés.

### Ce qui ne change pas

Aucune observation, aucun appel API (zéro dépense), aucune estimation, aucun intervalle,
aucun statut (INDETERMINATE, servi INSUFFICIENT_EVIDENCE). Les payloads des 222 événements
sont inchangés octet pour octet; seul leur champ `prev` (chaînage) est recalculé, la genèse
de la chaîne étant le hash du lock.

### Empreintes

| Artefact | Avant (servi) | Après |
|---|---|---|
| `result.json` (`result_sha256`) | `08fdd2ce0aea687689a8fe1d475e55dd183791d517c7c87b2224f0340565e270` | `6c8421045524f5ab173f3a55f49db316df683f03ebf6072b19b609ef5d762020` |
| `PROTOCOL.lock` (`protocol_lock_sha256`) | `f8ef0feb20ae5c4a4c573989692db3503ee8e32cded0dbcc770ad625c1590fff` | `bebf1fdd6fd10c64db7a234e86ea67fe11e2dff25771390566c013364674f047` |
| `contest.yaml` | `ad8084cb7da44475e3e936d216a53385e905dda48d7aa3d40568e93406ef8343` | `b540fad427dc83e5b45cd73cc91aec6a5dc5ea1d642c6698214556582c3e81f4` |
| `events.ndjson` (`raw_data_sha256`) | `2cf35f1c3257ac0d0a9cb5928af29afc837d5424891f4d3ff38727c8c6555f87` | `6863882b60b1ee02572a453d830a94f6e90c1f1fb7da23c2daa321eacbbbf813` |

Diff du résultat, champ par champ: `conflicts`, `runner`, et les trois empreintes dérivées
(`protocol_lock_sha256`, `raw_data_sha256`, `result_sha256`); rien d'autre.

### Chaînage et visibilité

Ligne de chaînage dans `SERVED_SHA_LOG.ndjson` (racine): `served_sha256_before` =
`08fdd2ce…`, `served_sha256_after` = `6c842104…`, `errata_ref` =
`runs/EMAILFIND-001/ERRATA.md#ERR-001`. La page `/runs/EMAILFIND-001` et l'outil MCP
`explain_limits` affichent cet erratum (OPS-030); ce fichier est servi octet pour octet sous
`/runs/EMAILFIND-001/ERRATA.md`. Le SHA « avant » reste retrouvable dans l'historique git et
dans le journal des sha servis.
