Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
…tants se reglent (TASK-1616)
SLICE B de la Product Spec V0 « ChatLoop — 3 assistants IA ». Les deux
maillons suivants de la chaine posee par SLICE A :
catalogue plateforme -> disponibilite Organization
-> ACTIVATION BOUCLE -> CONFIGURATION DES 3 ASSISTANTS
LE PLUGIN N'EST PAS UNE LOOPCARD, et c'est la decision centrale.
Le bloc « Actions de ChatLoop » est pilote par les Cards de placement
chat_action (« Resume IA »). Modeliser le plugin ainsi aurait semble naturel
et aurait ete faux : LoopPresetConfigurator::canConfigure() est
proprietaire-only — « un animateur anime, il ne recompose pas » — et la
matrice mesuree donne loops.manage_cards = NON pour owner, facilitator ET
member, TASK-1083 l'ayant retiree au motif qu'elle annoncait un droit que
l'interface ne donnait pas.
Passer par la Card imposait donc de choisir entre exclure le facilitator
(contre le CDC §5) et percer une doctrine posee expres. Le plugin garde son
PROPRE etat, rendu A COTE de « Resume IA », et son PROPRE droit :
loop_plugins.configure — owner + facilitator, membre refuse, SuperAdmin et
Admin d'Organization par les etapes 3 et 4 du resolveur.
LE HARD GATE VIT DANS LE SERVICE, pas dans l'ecran. Cacher un bouton n'a
jamais empeche un POST : chaque lecture et chaque ecriture reconfronte la
disponibilite de l'Organization de la BOUCLE. Retirer l'autorisation eteint
toutes ses Boucles sans reecrire une ligne.
ECART, PAS COPIE. Une posture identique au defaut n'est pas stockee, et vider
un champ SUPPRIME l'ecart — sinon la Boucle figerait le texte du jour. Les
postures SURVIVENT a l'extinction, dans la Boucle comme dans l'Organization.
ZERO APPEL PROVIDER : ni capability, ni AiEconomicGuard, ni ai_pricing, ni
OpenRouter, ni AiTurnLock, ni Evidence Build, ni follow-up.
MESURES
27/27 verts. Sabotage 1 (gate Organization neutralise) -> 6 rouges ;
sabotage 2 (droit retire au facilitator) -> 3 rouges. Voisins : 238 verts.
Recette navigateur : les deux surfaces, l'ecran des trois postures, la
persistance relue, et 403 en URL directe sur une Organization non autorisee.
UX_DEBT_SLICE_E : le facilitator detient le droit mais n'atteint pas /outils,
garde par canConfigure() des Cards, anterieur a cette TASK. Arbitrage de
Cyril : ne pas ouvrir cette page, reporter la decouvrabilite a la SLICE E sur
une surface accessible depuis ChatLoop. Consigne comme dette, pas comme bug.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SLICE B — le plugin s'active dans une Boucle, et ses trois assistants se règlent
Les deux maillons suivants de la chaîne posée par SLICE A (TASK-1614) :
Zéro appel provider.
La décision centrale : le plugin n'est PAS une LoopCard
Le bloc « Actions de ChatLoop » est piloté par les Cards de placement
chat_action— « Résumé IA » estcore.ai_summary. Modéliser le plugin ainsiaurait semblé naturel, et aurait été faux.
LoopPresetConfigurator::canConfigure()est propriétaire-only, avec lecommentaire explicite « un animateur anime, il ne recompose pas ». Et la
matrice mesurée, pas lue dans la doc :
loops.manage_cardsa été retirée de l'owner par TASK-1083, au motif écrit que« la matrice annonçait un droit que l'interface ne donnait pas ».
Passer par la Card imposait donc de choisir entre exclure le facilitator
(contre le CDC §5) et percer une doctrine posée exprès. Le plugin garde son
propre état, rendu à côté de « Résumé IA », et son propre droit.
loop_plugins.configure— nécessaire, pas inventéAbsent du dépôt ; le CDC §5 le nommait déjà. Déclaré dans
config/loop_permissions.php, accordé àowner+facilitatordansrole_defaults. SuperAdmin et Admin d'Organization l'obtiennent par les étapes3 et 4 du résolveur, jamais par ce socle. Le membre tombe en refus à l'étape 11.
Aucun droit Cards n'est élargi — un test le verrouille explicitement.
Le hard gate vit dans le service, pas dans l'écran
Cacher un bouton n'a jamais empêché un POST. Chaque lecture et chaque écriture
reconfronte la disponibilité de l'Organization de la Boucle — jamais celle
de l'utilisateur, puisqu'un SuperAdmin agit depuis
/admin, hors du tenant.Retirer l'autorisation éteint toutes les Boucles de l'Organization d'un coup,
sans réécrire une seule ligne.
Et « pas autorisé » n'est pas « éteint » : l'écran rend alors un tableau vide,
le plugin en est absent. Un plugin visible suggère un geste possible.
Écart, pas copie
Une ligne
loop_ai_assistantsexiste seulement là où la Boucle s'est écartéedu catalogue. Une posture identique au défaut n'est pas stockée, et vider un
champ supprime l'écart au lieu de recopier le défaut — sinon la Boucle
figerait le texte du jour et cesserait de suivre le produit. Convention de
loop_type_settings.Les postures survivent à l'extinction, dans la Boucle comme dans
l'Organization : rallumer rend ses réglages, il ne les redemande pas.
Tests — 27/27, et les deux gardes sont mesurées
Sabotage 1 —
isAvailableFor()ne consulte plus la disponibilité :Sabotage 2 —
loop_plugins.configureretiré du soclefacilitator:Arbre commité avant chaque salve,
git diffvide après restauration.Voisins — 238 verts (2443 assertions), grepés sur les contrats touchés :
T1079 Matrix + Resolver, T1090, T1118, T1123, T1124, T1125, T1127,
T1313 FacilitatorAuthority, T1331, UserDataLifecycleRegistry, T1614.
Recette navigateur — jouée sur
https://test.laravel/admin/loops/{loop}/configure/org/main/loops/{loop}/outilsNon vérifié — responsive : même limite qu'à TASK-1614, le viewport rendu ne
suit pas le redimensionnement de la fenêtre pilotée.
UX_DEBT_SLICE_E
Le facilitator détient
loop_plugins.configure— service, routes et testsle lui reconnaissent, et le sabotage 2 le prouve. Ce qu'il n'a pas, c'est le
chemin :
/outilsest gardé parcanConfigure()des Cards, antérieur àcette TASK.
Arbitrage : ne pas ouvrir cette page, ne pas toucher à
canConfigure(), ne pasélargir les droits Cards. Ouvrir
/outilsau facilitator lui montrerait lagrille de composition et ses boutons, que le serveur refuserait ensuite un par
un — exactement le défaut que TASK-1083 a corrigé.
La découvrabilité passe en SLICE E, sur une surface réellement accessible
depuis ChatLoop. Consigné comme dette, pas comme bug de TASK-1616.
Hors scope préservé
Ni
CapabilityRegistry, niAiEconomicGuard, niai_pricing, ni OpenRouter,ni
ProviderResolver, niAiTurnLock, niPromptRepository, ni EvidenceBuild, ni follow-up, ni bouton « Demander aux 3 », ni génération. Le mot
« provider » n'apparaît que dans un commentaire qui dit que l'écran n'en
choisit pas.
Aucune logique
Community.LoopPresetConfiguratoret la doctrine Cardsintacts.
VERSION 1.616.
🤖 Generated with Claude Code
https://claude.ai/code/session_01JqwjarKwhSbpzdPxLAmNh3