[DTP-Worker] Sprint 8 · buffer · Frontend Console/AGENT.md : gate d'IDENTITÉ des configs runtime Chat OTOIA (persona · langues · endpoint:null #6/#8) ancré sur chat_mount.json ⨯ MANIFEST.json
Bloc anti-dérive #6 dans ci/check_readme_claims.sh : la cellule « Métrique vérifiée » de 03_agents/frontend_console/AGENT.md:29 restituait 3 attributs data-derived du montage OTOIA (persona Amélie · langues FR/EN/ES · `endpoint: null`) ; le bloc chat_otoia amont ne gate que le COMPTE blocks/mounts/portails, et le gate persona/capabilities ancré sur CLAUDE.md vise spec/mounts/MANIFEST/README/oracle, jamais cette fiche. Le nouveau bloc recompute les 3 depuis out/chat_mount.json (5 configs) + out/MANIFEST.json byte-gatés : persona==MANIFEST.persona.nom, langues==MANIFEST.langues majuscule, endpoint:null == affirmation d'honnêteté exigeant all(mount.endpoint is None) — un endpoint fabriqué mord. Cohérences croisées MANIFEST⇔chaque mount + endpoint_statut=='a_confirmer'⇔endpoints tous null. 6 morsures vérifiées · 7 gates verts · aucune écriture out/ (0 dérive artefact). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1106,3 +1106,63 @@ interdit absolu) · **7 gates re-verts** (`check_readme_claims`/`check_ci_integr
|
|||||||
aucune écriture dans un `out/` ⇒ 0 dérive d'artefact ; l'application `bench` réelle
|
aucune écriture dans un `out/` ⇒ 0 dérive d'artefact ; l'application `bench` réelle
|
||||||
reste côté agent ERPNext Backend / VPS).
|
reste côté agent ERPNext Backend / VPS).
|
||||||
- **Auto-score 4Big** : 96/100.
|
- **Auto-score 4Big** : 96/100.
|
||||||
|
|
||||||
|
## Session `20260801_103304` · Buffer S8 · Chat OTOIA — IDENTITÉ des configs runtime (persona · langues · endpoint) dans la fiche Frontend Console
|
||||||
|
|
||||||
|
**Contexte** : Sprint 8 · buffer (roadmap fonctionnellement close ; poursuite de la
|
||||||
|
série anti-dérive CLAUDE.md #6, classe « fiche agent qui restitue des attributs
|
||||||
|
data-derived, gatée uniquement sur des COMPTES agrégés » — mémoire
|
||||||
|
[[agent-fiche-role-attrs-ungated]]).
|
||||||
|
|
||||||
|
**Dérive silencieuse fermée** :
|
||||||
|
- `03_agents/frontend_console/AGENT.md:29` — la cellule « Métrique vérifiée » du
|
||||||
|
livrable `chat_otoia` restitue TROIS attributs data-derived du montage OTOIA :
|
||||||
|
« persona **Amélie** … · langues **FR/EN/ES** · `` `endpoint: null` `` ». Le bloc
|
||||||
|
chat_otoia amont (`ci/check_readme_claims.sh`) ne recompute que le **COMPTE**
|
||||||
|
blocks/mounts/portails (tous = 5) — AVEUGLE à CE QUE dit chaque config runtime.
|
||||||
|
- Le gate persona/capabilities « ancré sur CLAUDE.md §Architecture cible » vise le
|
||||||
|
spec, les 5 mounts, le MANIFEST, le README et l'oracle du test — **JAMAIS** cette
|
||||||
|
cellule de fiche, et il ignore langues comme endpoint. La cellule était donc une
|
||||||
|
surface data-derived ungated de plus.
|
||||||
|
- Sources faisant autorité (byte-gatées par `check_artifacts`) :
|
||||||
|
`frontend/chat_otoia/out/chat_mount.json` (une config par portail · 5) +
|
||||||
|
`out/MANIFEST.json` (persona/langues/endpoint_statut consolidés).
|
||||||
|
- **`endpoint: null` = AFFIRMATION D'HONNÊTETÉ #6/#8** : l'endpoint OTOIA n'est PAS
|
||||||
|
fabriqué (renseigné côté VPS · agent Frontend). Qu'une config gagne un endpoint réel
|
||||||
|
dans l'artefact et la fiche « endpoint: null » devient un MENSONGE en silence.
|
||||||
|
- **État courant** : aucun attribut périmé — persona `Amélie` · langues `fr/en/es` ·
|
||||||
|
`endpoint == null` sur les 5 mounts ET le MANIFEST (anti-invention #6, rien à
|
||||||
|
réécrire). Le défaut est la **surface ungated**.
|
||||||
|
|
||||||
|
**Gate ajouté** (`ci/check_readme_claims.sh`, bloc « Chat OTOIA · IDENTITÉ des configs
|
||||||
|
runtime (persona · langues · endpoint) » après le bloc de COMPTE chat_otoia) : charge
|
||||||
|
`MANIFEST.json` + `chat_mount.json` (5 configs) et exige, sur la cellule de la fiche
|
||||||
|
(regex `persona (\S+) QC · langues ([A-Z/]+) · \`endpoint: ([^\`]+)\``, ne matche QUE
|
||||||
|
la ligne :29, pas la prose Scope :12) : (a) persona == `MANIFEST.persona.nom` (le
|
||||||
|
« QC » est le qualificatif de marque `Voix Amélie QC` de CLAUDE.md, gardé en littéral
|
||||||
|
NON gaté) ; (b) langues `FR/EN/ES` == `MANIFEST.langues` en majuscule ; (c) `endpoint:
|
||||||
|
null` avec `all(m.endpoint is None)` sur les 5 mounts (sinon `exp_endpoint` devient
|
||||||
|
`NON-null(...)` ⇒ morsure d'honnêteté). Cohérences croisées : `MANIFEST.persona.nom`
|
||||||
|
et `MANIFEST.langues` == CHAQUE mount (montage désynchronisé mordu) ·
|
||||||
|
`endpoint_statut == 'a_confirmer'` ⇔ endpoints TOUS null (incohérence interne
|
||||||
|
artefact sinon). Un claim absent échoue AUSSI (INTROUVABLE = régression #6). Aucune
|
||||||
|
suite `tests/` (FONCTIONS du builder, jamais la prose de la fiche) n'attrape ce
|
||||||
|
« vert trompeur ».
|
||||||
|
|
||||||
|
**6 morsures vérifiées** (restauré vert après chacune) : fiche persona `Amélie→Amelia`
|
||||||
|
(mismatch) · fiche langues `FR/EN/ES→FR/EN` · fiche `endpoint: null→endpoint: fixé` ·
|
||||||
|
**artefact** un mount `endpoint null→URL réelle` (bascule d'honnêteté ET incohérence
|
||||||
|
`endpoint_statut='a_confirmer'` — le vrai *silent green* : l'endpoint fabriqué pendant
|
||||||
|
que la fiche promet `null`) · fiche retire le bloc attributs (claim absent =
|
||||||
|
INTROUVABLE) · **artefact** un mount `persona Amélie→Nadia` (montage désynchronisé du
|
||||||
|
MANIFEST). Working tree byte-restauré (`git checkout --`, **JAMAIS** `git clean`,
|
||||||
|
interdit absolu) · **7 gates re-verts** (`check_readme_claims`/`check_artifacts`/
|
||||||
|
`check_docs`/`guard_constraints`/`check_regression`/`check_ci_integrity`/`validate_json`).
|
||||||
|
|
||||||
|
- `ci/README.md` (clause de la table récap du pipeline + paragraphe détaillé sous le
|
||||||
|
bloc de COMPTE chat_otoia, avec renvoi au gate persona/capabilities distinct) mis à
|
||||||
|
jour.
|
||||||
|
- **Hors périmètre worker (VPS · #8)** : néant (gate bash/python3 stdlib en-repo ;
|
||||||
|
aucune écriture dans un `out/` ⇒ 0 dérive d'artefact ; le câblage réel de l'endpoint
|
||||||
|
OTOIA + web-component reste côté agent Frontend / VPS).
|
||||||
|
- **Auto-score 4Big** : 96/100.
|
||||||
|
|||||||
+24
-1
File diff suppressed because one or more lines are too long
@@ -2234,6 +2234,79 @@ if co_cb is not None:
|
|||||||
bad(f"Chat OTOIA · {CO_RD} — dit {m.group(1)} configs runtime MAIS artefact "
|
bad(f"Chat OTOIA · {CO_RD} — dit {m.group(1)} configs runtime MAIS artefact "
|
||||||
f"dit {co_mo} → régénérer le README")
|
f"dit {co_mo} → régénérer le README")
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Chat OTOIA · IDENTITÉ des configs runtime (persona · langues · endpoint) —
|
||||||
|
# ATTRIBUTS transcrits À LA MAIN dans la cellule « Métrique vérifiée » de la
|
||||||
|
# fiche agent, AVEUGLES au gate de COMPTE ci-dessus.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Le bloc précédent gate le NOMBRE de blocks/mounts/portails ; il est indifférent
|
||||||
|
# à CE QUE chaque config runtime dit. Or la même cellule (03_agents/
|
||||||
|
# frontend_console/AGENT.md:29) restitue TROIS attributs data-derived du montage :
|
||||||
|
# « persona Amélie … · langues FR/EN/ES · `endpoint: null` ». Ils sortent des
|
||||||
|
# artefacts byte-gatés out/chat_mount.json (une config par portail) + out/
|
||||||
|
# MANIFEST.json (persona/langues/endpoint_statut consolidés) — jamais de la spec.
|
||||||
|
# • persona.nom : le prénom de l'assistant (le « QC » est le qualificatif de
|
||||||
|
# marque CLAUDE.md « Voix Amélie QC », gardé en littéral — non gaté ici).
|
||||||
|
# • langues : la surface trilingue FR/EN/ES lue par le générateur dans
|
||||||
|
# seo_spec.json (source unique des langues).
|
||||||
|
# • endpoint : `null` est une AFFIRMATION D'HONNÊTETÉ #6/#8 — l'endpoint OTOIA
|
||||||
|
# n'est PAS fabriqué (renseigné côté VPS). Si une config gagnait un endpoint
|
||||||
|
# réel, la fiche « endpoint: null » deviendrait un MENSONGE en silence.
|
||||||
|
# Cohérence croisée (bijection du générateur) : MANIFEST.persona.nom ET
|
||||||
|
# MANIFEST.langues doivent valoir EXACTEMENT ce que porte CHAQUE mount (un mount
|
||||||
|
# désynchronisé de son propre manifeste mord ici) ; endpoint_statut « a_confirmer »
|
||||||
|
# doit correspondre à des endpoints TOUS `null` (sinon incohérence interne de
|
||||||
|
# l'artefact). Un claim absent échoue AUSSI (INTROUVABLE = régression #6). Aucune
|
||||||
|
# suite tests/ (FONCTIONS du builder, jamais la prose de la fiche) n'attrape ce
|
||||||
|
# « vert trompeur ».
|
||||||
|
# ============================================================================
|
||||||
|
try:
|
||||||
|
ci_man = load("frontend/chat_otoia/out/MANIFEST.json")
|
||||||
|
ci_mounts = load("frontend/chat_otoia/out/chat_mount.json")
|
||||||
|
ci_persona = ci_man["persona"]["nom"]
|
||||||
|
ci_langs = list(ci_man["langues"])
|
||||||
|
ci_statut = ci_man["endpoint_statut"]
|
||||||
|
if not ci_mounts:
|
||||||
|
bad("Chat OTOIA identité · out/chat_mount.json vide"); ci_persona = None
|
||||||
|
except (OSError, KeyError, ValueError, TypeError) as e:
|
||||||
|
bad(f"Chat OTOIA identité · artefact illisible/inattendu : {e}"); ci_persona = None
|
||||||
|
if ci_persona is not None:
|
||||||
|
# Cohérence croisée MANIFEST ⇔ chaque config runtime (bijection du générateur)
|
||||||
|
bad_persona = sorted({m["persona"]["nom"] for m in ci_mounts if m["persona"]["nom"] != ci_persona})
|
||||||
|
bad_langs = sorted({"/".join(m["langues"]) for m in ci_mounts if list(m["langues"]) != ci_langs})
|
||||||
|
all_null = all(m["endpoint"] is None for m in ci_mounts)
|
||||||
|
if bad_persona:
|
||||||
|
bad(f"Chat OTOIA identité · persona MANIFEST={ci_persona!r} MAIS mounts portent "
|
||||||
|
f"aussi {bad_persona} (montage désynchronisé)")
|
||||||
|
if bad_langs:
|
||||||
|
bad(f"Chat OTOIA identité · langues MANIFEST={ci_langs} MAIS mounts portent "
|
||||||
|
f"aussi {bad_langs} (montage désynchronisé)")
|
||||||
|
if all_null and ci_statut != "a_confirmer":
|
||||||
|
bad(f"Chat OTOIA identité · endpoints TOUS null MAIS endpoint_statut={ci_statut!r} "
|
||||||
|
f"(attendu 'a_confirmer' — incohérence interne artefact)")
|
||||||
|
if (not all_null) and ci_statut == "a_confirmer":
|
||||||
|
bad("Chat OTOIA identité · endpoint_statut='a_confirmer' MAIS ≥1 endpoint fabriqué "
|
||||||
|
"(incohérence interne artefact)")
|
||||||
|
exp_langs = "/".join(l.upper() for l in ci_langs)
|
||||||
|
exp_endpoint = "null" if all_null else "NON-null(" + ",".join(
|
||||||
|
sorted({str(m["endpoint"]) for m in ci_mounts if m["endpoint"] is not None})) + ")"
|
||||||
|
co_fi2 = read_norm(CO_FI)
|
||||||
|
if co_fi2 is not None:
|
||||||
|
m = re.search(r"persona (\S+) QC · langues ([A-Z/]+) · `endpoint: ([^`]+)`", co_fi2)
|
||||||
|
if m is None:
|
||||||
|
bad(f"Chat OTOIA identité · {CO_FI} — claim « persona <nom> QC · langues "
|
||||||
|
f"<L> · `endpoint: <e>` » INTROUVABLE (attendu {ci_persona}/{exp_langs}/{exp_endpoint})")
|
||||||
|
else:
|
||||||
|
got = m.groups()
|
||||||
|
want = (ci_persona, exp_langs, exp_endpoint)
|
||||||
|
if got == want:
|
||||||
|
good(f"Chat OTOIA identité · {CO_FI} — persona {got[0]} · langues {got[1]} · "
|
||||||
|
f"endpoint {got[2]} == artefact (chat_mount ×{len(ci_mounts)} ⇔ MANIFEST)")
|
||||||
|
else:
|
||||||
|
bad(f"Chat OTOIA identité · {CO_FI} — dit persona {got[0]}/langues {got[1]}/"
|
||||||
|
f"endpoint {got[2]} MAIS artefact dit {want[0]}/{want[1]}/{want[2]} "
|
||||||
|
f"→ régénérer la fiche")
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Recette (module) · couple « N livrables de sprint + M métriques succès MVP »
|
# Recette (module) · couple « N livrables de sprint + M métriques succès MVP »
|
||||||
# transcrit À LA MAIN dans DEUX docs — même classe de « vert trompeur ».
|
# transcrit À LA MAIN dans DEUX docs — même classe de « vert trompeur ».
|
||||||
|
|||||||
Reference in New Issue
Block a user