Skip to content

TASK-1621 — le plugin devient Pour / Contre : deux assistants sans RAG, message humain publié avant génération - #622

Merged
cslucki merged 10 commits into
developfrom
TASK-1621-le-plugin-devient-pour-contre-deux-assistants-sans-rag-et-message-humain-publie-avant-generation
Sep 22, 2026
Merged

cslucki merged 10 commits into
developfrom
TASK-1621-le-plugin-devient-pour-contre-deux-assistants-sans-rag-et-message-humain-publie-avant-generation

Conversation

@cslucki

@cslucki cslucki commented Sep 22, 2026

Copy link
Copy Markdown
Owner

TASK-1621

Le module « 3 assistants IA » devient « Pour / Contre » : deux rôles
(aperio = POUR, traverse = CONTRE, limen dormant sans migration), ni
synthèse ni follow-ups, connaissances générales du modèle d'abord et
conversation de la Boucle en contexte borné — les Dossiers restent hors
champ. Le message humain est publié AVANT la génération, et le submit est le
seul déclencheur (file différée wire:init, un rôle par requête).

Points saillants

  • Carte de débat progressive, Desktop seul (hidden md:block) : carte
    dès le submit (mire POUR + « En attente… » CONTRE), POUR lisible pendant
    la génération de CONTRE, wire:key stable — mesuré en réel :
    T_CARD − T0 = 0 ms, aucun flash, aucun overflow. Sur smartphone : bulles
    classiques empilées, pas de tableau.
  • Deux gestes uniques au niveau carte : « Ajouter au Dossier » (brouillon
    POUR puis CONTRE, garde anti demi-débat, camp écourté annoncé) et
    « Copier » ; « Répondre » retiré.
  • Plus aucune coupe silencieuse : finishReason=Length → PARTIAL
    publié + badge « Réponse écourtée » ; budget 900 → 2400 ; le plafond
    maison marque la coupe lui aussi ; raison d'arrêt ABSENTE → aucune coupe
    déduite.
  • NOT_APPLICABLE : une question sans camps ne fait qu'UN appel, notice
    neutre unique, aucune carte.
  • Réponses raccourcies par les CONSIGNES (497-672 car., 3 puces), et rendu
    des listes réparé (bp-bulle-markdown : puces compactes, plus de
    paragraphes espacés sans marqueurs).

Tests

  • TASK1621PourContreEngineTest 68 verts · TASK1621PourContreFlowTest
    36 verts · gate Playwright responsive 5/5 (390/1440) · voisins par
    contrat verts (1 rouge PRÉ-EXISTANT documenté : LoopChatTest > workspace cards shell closed by default, mesuré sur branche nue).
  • 12 sabotages → rouges (8 moteur/UX + 4 addendum), restaurations vérifiées.
  • Recette humaine Cyril VALIDÉE le 22/09/2026 (GO CLÔTURE MASTER).

Hors périmètre : choix définitif FREE/PAYANT du modèle (TASK dédiée),
hotfix upload images PROD.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3

Cyril and others added 9 commits September 22, 2026 13:38
…ups (TASK-1621)

Les bancs TASK-1619 et TASK-1620 sont RETIRES : ils pilotaient des actions et
une Evidence qui n'existent plus. Leurs garanties encore valides sont reprises
par TASK1621PourContreEngineTest (moteur) et le banc de flux a venir.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
…ent de preuve (TASK-1621)

Le message humain est publie et RENDU avant toute generation : le submit
remplit une file, une requete differee (wire:init, precedent du depot) lance
un role a la fois. POUR s'affiche sans attendre CONTRE.

Deux retours de recette de Cyril, corriges et testes :

- une pastille de mode VIDE doublait le badge. Le composeur ne connait pas le
  mode `multi_ai` et rendait une puce sans libelle, reduite a son bouton de
  fermeture. Un seul badge desormais, celui du panneau d'etat ;
- le badge d'attente portait un sablier sans identite : il porte l'icone du
  selecteur a gauche, et dit « Preparation des arguments "pour" ».

Admin : « Actualiser les modeles » renouvelle enfin les preuves, mais SEULEMENT
si le releve qui vient d'avoir lieu montre le slug encore present et encore
verifie gratuit. Disparu, redevenu payant ou releve en erreur : aucune
fraicheur fabriquee.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
…pe silencieuse (TASK-1621)

Deux corrections mesurees, et l'UX qui les accompagne.

1. La connaissance du modele d'abord, la Boucle ensuite

Le module ne lisait plus rien, et le modele repondait « the provided Loop
material says nothing about... » : il commentait l'absence d'une matiere
qu'on ne lui avait jamais promise. La conversation revient en CONTEXTE —
dix derniers messages, bornes au declencheur — jamais en source.

ContextBuilder est INCHANGE : les deux bornes voyagent par ContexteIa, le
DTO qui porte deja les donnees par operation. Les sept autres capabilities
declarant loop.messages rendent la requete d'avant, a la virgule pres.

La borne est haute et EXCLUSIVE, pas une exclusion par identifiant : POUR
et CONTRE tournent dans deux requetes differees, et une exclusion n'aurait
ferme que le premier des deux. Ordre total sur (created_at, id) : created_at
est a la seconde.

2. Une reponse coupee ne se publie plus en silence

A 900 jetons, 13 des 14 tours « vides » s'arretaient EXACTEMENT au plafond,
et 12 reponses publiees comme completes l'atteignaient aussi. Le modele
n'etait pas muet : il brulait son budget en raisonnement.

- max_tokens 900 -> 2400 ;
- finishReason est lu, et ABSENT n'est pas Length : sans mesure, le
  comportement d'avant tient ;
- Length + texte -> PARTIAL, publie et marque, jamais un SUCCESS ;
- Length + vide -> OUTPUT_BUDGET_EXHAUSTED, plus EMPTY_MODEL_ANSWER ;
- notre propre plafond de caracteres marque la coupe lui aussi.

3. L'ecran

Modale supprimee, le bouton EST l'interrupteur. Bulles vert (POUR) et rouge
(CONTRE), modele affiche discretement. Rangee des modes visible sur mobile,
a defilement horizontal ; contraste du bouton + corrige. Le panneau
« Pourquoi cette reponse ? » ne dit plus « MULTI_AI ».

Defaut trouve en chemin : aiModeOf() ne connaissait pas multi_ai et
retombait sur llm — tout ce qui en dependait restait eteint a l'ecran alors
que le code etait la.

Tests : 1293 verts sur la salve des voisins, 3 sabotages qui mordent, gate
responsive REEL a 390 px. Le seul rouge est pre-existant, mesure sur la
branche nue.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
« Windows ou Linux que choisir ? » rendait DEUX reponses en faveur de Linux.
Les deux modeles avaient obei : la consigne disait « defends LA proposition
exprimee par la question », et une question « A ou B ? » n'en exprime aucune.
La clause de repli des personas laissait alors chaque role choisir son sujet,
et les deux roles tournent dans deux appels separes : rien ne pouvait les
recoordonner.

Le referent est fixe dans le socle administrable (v3), au seul rang partage et
identique pour les deux appels. Aucun parser PHP : ce n'est pas une analyse
syntaxique, c'est une convention de lecture.

Et tout se dit en termes POSITIFS de camp DEFENDU. Un premier jet fixait le
referent mais laissait au rang du dessous un verbe — « conteste », « 3 a 5
objections » — qui permettait de le contourner : en recette, CONTRE attaquait
son propre camp, donc renforcait celui de POUR. Interdire une forme ne ferme
pas le comportement.

- socle : « TON CAMP EST UNE POSITION QUE TU DEFENDS, jamais une cible que tu
  attaques », et le piege nomme : « tu ne dois PAS attaquer B, B est TON camp » ;
- questions ouvertes : la regle prime sur toute consigne de nombre d'arguments,
  aucun camp n'est invente, les deux roles repondent la meme chose ;
- personas FR + EN reformulees, plus aucune formulation negative.

Ni Constitution ni doctrine touchees.

Recette reelle, MEME modele pour les deux roles afin d'isoler la semantique :
5 cas sur 5 conformes, 0 echec provider. L'inversion de l'ordre inverse bien
les camps.

Tests : 63 verts sur le banc moteur, 1298 sur la salve des voisins. Trois
sabotages mordent. Le seul rouge est pre-existant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
…et les reponses sont deux fois plus courtes (TASK-1621)

1. NOT_APPLICABLE

« Quel CMS choisir ? » publiait DEUX bulles disant la meme chose : deux appels
payes pour un seul message utile. Le modele annonce desormais le verdict par un
marqueur exact, cherche dans le texte BRUT (le sanitiseur pourrait manger les
crochets). Aucun parser : une reponse qui PARLE de reformulation sans le
marqueur reste une reponse ordinaire, et un test le pin.

Quatrieme etat, ni success ni error ni refused — les trois lectures sont
fausses. Au ledger, `completed` sans `failure_reason` : l'appel a abouti, le
compter comme panne fausserait les sommes de fiabilite. La file s'annule des
que le premier role s'abstient. La notice est neutre, sans nom d'assistant et
sans « Reessayer » : ce n'est pas un role qui a echoue.

2. Des reponses deux fois plus courtes

Mesure : 833-1221 caracteres, 5 puces dans 10 cas sur 12. « 3 a 5 arguments »
-> le modele prend toujours le maximum. Et un sous-titre en gras par puce, qui
contredisait la regle « une seule phrase en gras » deja presente.

Raccourci par la CONSIGNE, jamais par les plafonds : depuis le correctif de
troncature, toute coupe par plafond affiche « Reponse ecourtee ». Baisser
max_tokens aurait signale comme incompletes des reponses qui ne le sont pas.

Resultat mesure en recette reelle : 497-672 caracteres, 3 puces partout, zero
gras dans les puces, finishReason Stop partout, aucun badge.

3. Les ecrans

Limen retire des deux ecrans de reglage — `catalogueVivant()`, distinct du
catalogue complet que `label()` et les bulles anciennes ont encore besoin de
lire. On retire un role des ecrans, pas des donnees. Le plugin s'appelle
« Pour / Contre » partout ou un humain le lit. La mire d'attente nomme le
modele qui prepare.

Tests : 90 verts sur les deux bancs, 1394 sur la salve des voisins. Cinq
sabotages mordent. Le seul rouge est pre-existant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
…progressive (TASK-1621)

Point de retour demande par Cyril avant la passe d'affichage progressif :
carte 2 colonnes groupee par reply_to_id, mire par role, En attente…,
bulle a largeur de colonne. Non recette — la passe suivante corrige le
cycle d'affichage, le mobile sans tableau et la barre d'actions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
…, deux gestes uniques (TASK-1621)

ROOT_CAUSE du constat Cockpit : observation anterieure a la logique
$debatEnCours — l'enchainement progressif marchait deja (capture Cyril).
Cette passe : carte hidden md:block / bulles md:hidden (pas de tableau
sur smartphone, decision Cyril) ; mire et echecs du bandeau en md:hidden
(une surface par viewport) ; Repondre retire ; Ajouter au Dossier unique
capitalisant le debat entier sous garde anti demi-debat, camp ecourte
annonce ; Copier unique repare (x-data remonte a la racine) ;
:show-copy-button lie. 36 verts flow + 138 voisins + 4 sabotages rouges.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
…ve etendu, recette mesuree (TASK-1621)

Le format demande (titre gras + 3 puces) sortait DEJA du modele : le rendu
le perdait — whitespace-pre-wrap transformait les sauts de ligne inter-<li>
en lignes vides et le preflight retirait list-style. bp-bulle-markdown +
regles app.css. Recette Claude for Chrome : T_CARD-T0 = 0 ms (meme
mutation), POUR lisible pendant la mire CONTRE, cardGone=0, brouillon de
debat verifie, NOT_APPLICABLE sans carte ni bulle. Gate Playwright 5/5
(390/1440). Nettoyage recette : 4 supprimes, 0 restant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
@cslucki cslucki added the validation:sensitive TASK-1150 : charge CI complete obligatoire (auth/tenant/migration/securite) label Sep 22, 2026
…SK-1621)

Le helper posait owner_id ET loop_id ; la contrainte CHECK n'existe que
sous PostgreSQL — verts SQLite, 3 rouges au shard 4/6. Un Dossier de
Boucle n'a pas de proprietaire personnel : owner_id null. Rejoue en PG
(36/36, 144 assertions) et en SQLite (36/36).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
@cslucki
cslucki merged commit e0a940f into develop Sep 22, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

validation:sensitive TASK-1150 : charge CI complete obligatoire (auth/tenant/migration/securite)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant