Files
decision/docs/dev/blueprint-v2-panel.json
T
YvvandClaude Fable 5 53d8752e40 v2 : conception ultracode + moteur de formules porté en TS
- Blueprint définitif (docs/dev/BLUEPRINT-V2.md + JSON) : panel 4 visions
  + 3 juges, corpus doctrinal (Mon nom est personne, Une économie du don,
  SejeteralO), 4 critiques d'intégration, 3 vérificateurs, réparations
- Corpus d'intention + lectures brutes archivés
- Moteur porté Python→TS pur : threshold (inertie WoT, Smith, ComTech),
  nuancé 6 niveaux, DSL modeParams — 45 tests vitest, parité croisée
  vérifiée (Forgeron W=7224 T=120 ⇒ 94)
- Contrat de domaine v2 (types/domain.ts) + lexique UI (lexicon.ts)
- vitest + idb-keyval en dépendances

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 05:59:33 +02:00

511 lines
94 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"summary": "Cartographier la maquette existante puis panel de visions produit pour la refonte v2",
"agentCount": 12,
"logs": [
"Cartographie terminée — lancement du panel de visions",
"4/4 visions produites — jugement"
],
"result": {
"blueprint": {
"nom_produit": "libreDecision",
"manifeste": "Tout le monde décide, tout le temps. libreDecision attrape chaque décision en une phrase et répond en dix secondes : décide seul et trace-le, décide sous mandat, demande leur avis, ou porte-la au collectif — avec le bon cercle, la bonne modalité, le bon seuil, jamais plus lourd que l'enjeu. Les personnes touchées sont incluses par calcul, chacune voit pourquoi, et n'importe qui peut lever la main « ça me concerne » sans se justifier. Rien n'est définitif : toute décision en vigueur garde sa poignée de révision, avec l'inertie de son poids — révoquer un choix léger est un geste, toucher aux règles du jeu exige la quasi-unanimité. Les règles elles-mêmes sont un texte sous vote permanent, le Pacte : le collectif règle son propre curseur entre informel et constitutionnel, en décidant. Du trio d'amis à la toile Ğ1 et ses 7 224 membres, le même geste, le même objet, la même formule. La ville change, le puits demeure : la démocratie d'exercice quotidien, livrable à toute structure.",
"modele_domaine": "// ─────────────────────────────────────────────────────────────\n// libreDecision v2 — noyau de domaine (frontend/app/types/domain.ts)\n// Local-first, prêt-synchro. Identifiants anglais, UI française.\n// INVARIANT : LA DÉCISION EST L'OBJET PIVOT — mandats, clauses,\n// révocations, ratifications en sont des spécialisations chaînées.\n// L'unification est un fait d'architecture, JAMAIS un vocabulaire d'UI.\n// ─────────────────────────────────────────────────────────────\n\ntype Id = string // UUIDv7 — triable par temps, prêt pour la synchro\ntype ISODate = string // ISO 8601 UTC\ntype Json = string | number | boolean | null | Json[] | { [k: string]: Json }\n\n// Toute entité : scoping collectif + horloge de synchro + soft-delete.\n// Règles prêt-synchro : jamais de suppression physique (archivedAt) ;\n// Vote/Advice/Objection append-only (merge trivial) ; le reste LWW par updatedAt.\ninterface Entity {\n id: Id\n collectiveId: Id\n createdAt: ISODate\n updatedAt: ISODate\n archivedAt?: ISODate\n}\n\n// ── Le tenant ────────────────────────────────────────────────\ntype CollectiveTemplate = 'informal' | 'association' | 'cooperative' | 'commune' | 'free-currency'\n\ninterface Collective {\n id: Id\n slug: string\n name: string\n color: string // hex accent\n icon: string // i-lucide-*\n template: CollectiveTemplate // gabarit d'origine — installe le Pacte pré-rempli\n isTransparent: boolean // décisions visibles par défaut de tous les membres\n pactDocId: Id // le TextDoc role='pact' — les réglages EN document voté\n rootCircleId: Id // cercle « tout le collectif »\n createdAt: ISODate\n updatedAt: ISODate\n}\n\n// ── Les gens ─────────────────────────────────────────────────\ninterface Person extends Entity {\n displayName: string\n isMe: boolean // profil local (v2 mono-poste ; mode démo = « agir en tant que »)\n duniterAddress?: string // SS58 — réservé auth Duniter (hors scope v2)\n wotStatus?: 'member' | 'smith' // critères multi-corps Ğ1\n}\n\ninterface Circle extends Entity {\n name: string\n purpose: string // une phrase\n memberIds: Id[] // v2 : liste nominative = SEULE règle d'appartenance (calculable, auditable)\n parentCircleId?: Id // emboîtement (Ostrom 8) — racine = rootCircle\n domains: string[] // tags de domaine — SUGGESTION/découverte uniquement, jamais un droit de vote\n}\n// Corpus d'une décision = union CALCULABLE : membres des cercles du scope\n// personnes nommées titulaires des mandats dont le domaine intersecte.\n// Chaque inclusion garde sa raison (Concern.reason) — auditable en un tap.\n\n// ── LA DÉCISION (pivot) ──────────────────────────────────────\ntype Reversibility = 'easy' | 'costly' | 'irreversible'\ntype Weight = 'light' | 'binding' | 'structural' // léger / engageant / structurant\n\ntype DecisionRoute =\n | 'solo' // je décide (trace facultative hors mandat)\n | 'mandate' // je décide sous mandat (trace obligatoire + fenêtre d'objection)\n | 'transmit' // le mandat d'un autre couvre → transmission au titulaire\n | 'advice' // avis des touchés, puis je décide (advice process)\n | 'collective' // session collective (modalité du protocole)\n\ntype DecisionStatus =\n | 'draft' // capturée, verdict non validé\n | 'advice' // fenêtre d'avis ouverte\n | 'objection' // fenêtre d'objection ouverte (mandate, conservatoire, allègement dérogatoire)\n | 'framing' // formulation collective : contre-propositions bornées\n | 'voting' // session ouverte (consent | binary | nuanced | election)\n | 'adopted' // en vigueur (couvre la réalisation ; revoyure via review)\n | 'rejected'\n | 'revoked' // révoquée par une décision enfant adoptée\n | 'transmitted' // remise au mandataire (terminal pour l'auteur, chaînable)\n | 'closed' // acte one-shot exécuté et revu — archivé\n\ntype TriageRule = 'R-U' | 'R0a' | 'R0b' | 'R0c' | 'R2' | 'R3' | 'R4' | 'R5' | 'R6'\n\ninterface Decision extends Entity {\n authorId: Id\n title: string // LA phrase de capture — seul champ obligatoire\n body?: string // n'apparaît que si la route l'exige (progressive disclosure)\n tags: string[] // découverte + détection de récurrence — JAMAIS un corpus\n\n // — verdict de triage (pré-rempli par le moteur, ajustable) —\n reversibility: Reversibility\n weight: Weight\n urgent: boolean\n scope: {\n selfOnly: boolean\n circleIds: Id[] // cercles touchés — explicites (suggérés par tags, confirmés par l'auteur)\n personIds: Id[] // personnes nommées en plus\n }\n route: DecisionRoute\n triageRule: TriageRule // la règle qui a tiré — affichée en français sur la fiche\n routeOverridden: boolean // dérogation journalisée\n overrideNote?: string // OBLIGATOIRE si allègement (asymétrie de dérogation)\n\n // — spécialisations chaînées (le pliage génératif) —\n underMandateId?: Id // décidée SOUS ce mandat → observatoire du mandat\n createsMandate?: MandateDraft // adoptée ⇒ crée le Mandate (réclamer un pouvoir)\n amendsClauseId?: Id // adoptée ⇒ applique la ClauseVersion liée (boucle fermée)\n protocolId?: Id // modalité si collective (résolue par le Pacte, ajustable en alourdissant)\n parentDecisionId?: Id // chaînage\n chainKind?: 'ratification' | 'revision' | 'revocation'\n\n // — temps & fenêtres —\n status: DecisionStatus\n windowEndsAt?: ISODate // fin de fenêtre avis/objection\n windowSuspendedAt?: ISODate // objection de frontière → compte à rebours SUSPENDU (visible)\n decidedAt?: ISODate\n review?: Review // obligatoire si irreversible || structural\n sunsetAt?: ISODate // clause de caducité — la réversibilité s'ingénie au lieu d'alourdir\n stewardIds: Id[] // garants de la réalisation (haut du gradient d'engagement)\n\n // — preuve & visibilité —\n visibility: 'private' | 'scope' | 'collective' // anti-flicage : trace maîtrisée hors mandat\n engraving?: Engraving\n}\n\ninterface Review {\n dueAt: ISODate\n verdict?: 'confirmed' | 'revise' | 'revoke' // verdict de réalité — 3 boutons\n note?: string\n decidedAt?: ISODate\n}\n\ninterface Engraving {\n sha256: string // hash canonique du PV JSON de la décision\n engravedAt: ISODate\n proofLevel: 'local' // v2 : UNIQUEMENT 'local' — libellé « empreinte locale — démo »\n ipfsCid?: string // réservé v3 ('ipfs') — jamais affiché tant que non réel\n chainRef?: string // réservé v3 ('chain')\n}\n\n// ── Inclusion ────────────────────────────────────────────────\ninterface Concern extends Entity {\n decisionId: Id\n personId: Id\n origin: 'computed' | 'declared' // calculé | « Ça me concerne »\n reason: string // calculé : « membre du cercle Budget » — affichée au tap\n declaredNote?: string // volontaire : motif optionnel, public\n beforeSnapshot: boolean // déclaré avant snapshot ⇒ vote ; après ⇒ voix consultative\n}\n\ninterface Objection extends Entity {\n decisionId: Id\n personId: Id\n kind: 'content' | 'boundary' // fond | « j'ai été oublié / untel manque » — boundary SUSPEND la fenêtre\n argument: string // toujours motivée\n status: 'open' | 'withdrawn' | 'integrated' | 'escalated'\n resolutionNote?: string\n}\n\ninterface Advice extends Entity { // avis (advice process)\n decisionId: Id\n personId: Id\n position: 'favorable' | 'reserved' | 'unfavorable'\n note?: string\n}\n\n// ── Le pouvoir ───────────────────────────────────────────────\ninterface Mandate extends Entity {\n title: string\n holderId: Id\n originDecisionId: Id // le mandat EST né d'une décision — cliquable\n domain: {\n circleIds: Id[] // couverture CALCULABLE — l'entrée R0b/R0c du triage\n tags: string[] // lisibilité + suggestion (jamais seule base du match)\n }\n startsAt: ISODate\n endsAt: ISODate // toujours borné — pas de mandat perpétuel implicite\n electorCircleId: Id // corpus d'élection = corpus de révocation\n nominationMethod: 'ratified-self' | 'election-no-candidate' | 'nuanced-vote' | 'consent' | 'draw' | 'rotation'\n reports: MandateReport[] // redevabilité\n status: 'proposed' | 'active' | 'expired' | 'revoked'\n}\ninterface MandateReport { dueAt: ISODate; deliveredAt?: ISODate; content?: string }\ninterface MandateDraft {\n title: string\n domainCircleIds: Id[]\n domainTags: string[]\n durationDays: number\n reportEveryDays?: number\n}\n\n// ── Les textes ───────────────────────────────────────────────\ninterface TextDoc extends Entity {\n slug: string\n title: string\n role: 'pact' | 'reference' // pact = réglages du collectif ; reference = engagements, licence…\n description: string\n provenance?: Provenance // ex-genesis_json, normalisé\n}\ninterface Provenance {\n sources: { title: string; url: string; date?: string; version?: string }[]\n voteRecord?: { // ex. Forgeron : 97/23/19, W=7224, D30M50B.1G.2S.1\n url: string; modeParams: string; period: string\n result: { for: number; against: number; invalid?: number; wotSize: number; thresholdRequired: number; status: string }\n }\n contributors?: string[]\n notes?: string // typos des textes votés : SIGNALÉES ici, jamais corrigées sans vote\n}\n\ntype InertiaPreset = 'low' | 'standard' | 'high' | 'max'\n// Câblage RÉEL preset → formule (fini l'inertie décorative) :\n// low={M:50,G:0.1} standard={M:50,G:0.2} high={M:60,G:0.4} max={M:66,G:0.6} (B=0.1, C=0 partout)\n\ninterface Clause extends Entity {\n docId: Id\n section: string // ex. « E. Certification »\n position: number\n code: string // ex. « E9 »\n title: string\n inertia: InertiaPreset // détermine le protocole d'amendement — enfin effectif\n currentVersionId?: Id\n settingKey?: string // clauses du Pacte : clé machine, ex. 'triage.smallGroupMax'\n}\n\ninterface ClauseVersion extends Entity {\n clauseId: Id\n decisionId: Id // TOUTE version naît d'une décision (y compris fondatrice seedée)\n versionLabel: string // '2.0.0-fr'\n content: string // markdown\n settingValue?: Json // valeur machine si clause de Pacte\n status: 'current' | 'proposed' | 'superseded' | 'rejected'\n adoptedAt?: ISODate\n}\n\n// ── Modalités & vote ─────────────────────────────────────────\ntype VoteMethod = 'consent' | 'binary' | 'nuanced' | 'election'\n\ninterface Protocol extends Entity {\n name: string // ex. « Vote WoT standard »\n method: VoteMethod\n description: string\n durationDays: number\n formula: FormulaParams // SOURCE DE VÉRITÉ structurée (FormulaConfig v1 fusionnée)\n modeParams: string // DSL DÉRIVÉ affiché : 'D30M50B.1G.2S.1' — jamais édité à la main\n pactClauseId?: Id // référencé par le Pacte ⇒ méta-gouverné : le modifier = amender le Pacte\n}\ninterface FormulaParams {\n majorityPct: number // M\n baseExponent: number // B (défaut 0.1)\n gradientExponent: number // G — l'inertie\n constantBase: number // C (défaut 0)\n smithExponent?: number // critère additionnel sous-toile : ceil(smithCount^exp)\n techcommExponent?: number\n nuancedMinParticipants?: number\n nuancedThresholdPct?: number\n}\n\ninterface VoteSession extends Entity {\n decisionId: Id\n protocolId: Id\n corpusPersonIds: Id[] // SNAPSHOT à l'ouverture — l'inclusion tardive ne renverse pas un vote\n corpusSize: number // W — plus jamais 0\n opensAt: ISODate\n closesAt: ISODate\n status: 'open' | 'closed'\n outcome?: 'adopted' | 'rejected'\n // INVARIANT : tallies TOUJOURS recalculés depuis Vote[] — jamais stockés dénormalisés\n}\n\ninterface Vote extends Entity {\n sessionId: Id\n voterId: Id\n value: 'for' | 'against' | 0 | 1 | 2 | 3 | 4 | 5 // binaire | nuancé (0=CONTRE … 5=TOUT À FAIT)\n comment?: string // OBLIGATOIRE si négatif (against, 0, 1)\n supersedesVoteId?: Id // re-vote audité — l'historique reste\n}\n\n// ── Réglages résolus du Pacte (fonction pure — PAS une table settings) ──\ninterface CollectiveSettings { // resolveSettings(pactClauses, versions) — lu par triage et écrans\n triage: {\n smallGroupMax: number // défaut 5 — clé 'triage.smallGroupMax'\n collectiveMin: number // défaut 50 — bascule vers la formule inertielle\n consentMax: number // défaut 7 — ≤7 consentement ; 8..collectiveMin nuancé\n objectionWindowHours: number // défaut 48\n adviceWindowHours: number // défaut 72\n framingDays: number // défaut 14 — contre-propositions bornées (structurant)\n concernEscalateRatio: number // défaut 0.5 — signal d'affluence\n recurrenceThreshold: number // défaut 3 — suggestion de mandat\n reviewDelayDays: number // défaut 90\n }\n protocolByRange: { // protocoles nommés, référencés par des clauses du Pacte\n consent: Id; nuanced: Id; inertialBinary: Id; election: Id\n clauseByInertia: Record<InertiaPreset, Id> // protocole d'amendement par preset d'inertie\n }\n}\n\n// ── Moteurs purs (frontend/app/engine/ — implémentation UNIQUE, testée vitest) ──\n// threshold.ts : wotThreshold(W, T, {M,B,G,C}) → int — port exact de backend/app/engine/threshold.py (ceil)\n// + smithThreshold, techcommThreshold, nuancedResult (ports de smith/techcomm/nuanced)\n// SPEC EXÉCUTABLE : cas Forgeron W=7224 T=120 M50 B.1 G.2 ⇒ 94 (test_threshold.py porté)\n// triage.ts : triage(input, ctx, settings) → Verdict — port étendu de engine/qualifier.py (R1-R8)\n// modeParams.ts : parse/format du DSL (consolidation de utils/mode-params.ts)\n// settings.ts : resolveSettings(clauses, versions) → CollectiveSettings (défauts + valeurs adoptées)\n// state.ts : canTransition(decision, to) → boolean — machine à états UNIQUE (fin des copies Decision/Mandate)\n// impact.ts : computeConcerned(scope, circles, mandates) → { personId, reason }[]\n\ninterface TriageInput {\n title: string; tags: string[]\n scope: Decision['scope']\n reversibility: Reversibility\n weight: Weight\n urgent: boolean\n amendsClauseId?: Id\n}\ninterface TriageContext { // assemblé par le store, consommé pur — testable sans I/O\n myActiveMandates: Mandate[]\n otherActiveMandates: Mandate[]\n matchingClauses: Clause[] // index Q0 « déjà décidé ? » — le MÊME index que Cmd+K\n similarRecentCount: number // décisions adoptées partageant ≥2 tags sur 90 j\n computedConcernedIds: Id[]\n}\ninterface Verdict {\n route: DecisionRoute\n rule: TriageRule\n explanation: string // UNE phrase française — affichée telle quelle, jamais reformulée\n protocolId?: Id\n windowHours?: number\n framingDays?: number\n reviewRequired: boolean\n engravingSuggested: boolean\n conservatoryChain?: boolean // urgence : la décision de ratification chaînée est créée automatiquement\n alternatives: { route: DecisionRoute; label: string; cost: string }[] // « Je choisis autrement »\n suggestion?: { kind: 'claim-mandate' | 'create-rule'; prefill: Json } // R6 — jamais bloquant\n}\n\n// ── Persistance locale & synchro future ──────────────────────\ninterface Bundle { // export/import ET seeds — le MÊME chemin de code (marque blanche testée)\n schemaVersion: 2\n exportedAt: ISODate\n collective: Collective\n people: Person[]; circles: Circle[]\n decisions: Decision[]; concerns: Concern[]; objections: Objection[]; advices: Advice[]\n mandates: Mandate[]\n docs: TextDoc[]; clauses: Clause[]; versions: ClauseVersion[]\n protocols: Protocol[]; sessions: VoteSession[]; votes: Vote[]\n}\n// data/persistence.ts : IndexedDB (idb-keyval), clé `ld2:<collectiveId>`, écriture débouncée 500 ms.\n// exportBundle() → fichier JSON téléchargé ; importBundle(file) → validation structurelle + détection de collisions d'ids.\n// Prêt-synchro : UUIDv7, updatedAt (LWW champ à champ côté serveur futur), archivedAt (soft delete),\n// Vote/Advice/Objection append-only. Le futur adaptateur FastAPI implémente le même contrat de stores\n// Pinia (collective, people, decisions, mandates, texts, votes) — AUCUN écran ne change.",
"cycle_de_vie": "ÉMERGENCE — la capture : une phrase dans la barre « Qu'est-ce que tu décides ? » (Fil ou FAB). Crée Decision{status:'draft'}. Dix secondes visées, aucun autre champ obligatoire.\n\nTRIAGE — le verdict : triage() pur recalcule à chaque geste ; valider le verdict fait passer draft → l'état de départ de la route. Le verdict est toujours expliqué (une phrase française) et toujours contournable (alourdir libre 1 tap ; alléger = note obligatoire + fenêtre d'objection imposée — l'asymétrie journalisée).\n\nFORMULATION (route collective, poids binding/structural) : status 'framing' — contre-propositions bornées (framingDays, défaut 14 j) : ClauseVersions ou variantes de body avec diff. Sinon la route collective saute directement au vote. C'est ici que la formulation s'affine — chaque version est éditable, comparée, retirable.\n\nDÉLIBÉRATION — trois formes selon la route :\n- 'solo' selfOnly : AUCUNE délibération — draft → adopted immédiat (2 gestes au total). Trace facultative, visibility choisie ('private' par défaut hors mandat).\n- 'mandate' et solo-avec-tiers-dérogatoire : draft → objection (fenêtre objectionWindowHours=48 h, touchés notifiés dans leur Fil, 2 boutons inline « Ça me va / J'objecte »). Silence vaut accord UNIQUEMENT si reversibility=='easy' — sinon la fenêtre exige au moins un « Ça me va » par cercle touché. À échéance sans objection ouverte → adopted. Objection 'content' maintenue → escalade : framing/voting (consentement du cercle). Objection 'boundary' (« j'ai été oublié ») → windowSuspendedAt posé, compte à rebours SUSPENDU jusqu'à résolution — la frontière prime sur le fond.\n- 'advice' : draft → advice (fenêtre adviceWindowHours=72 h) ; les touchés déposent Advice ; à échéance l'auteur décide → adopted (avis annexés à la fiche). Objection formelle pendant la fenêtre → escalade en collective/consent.\n- 'collective' : framing? → voting : VoteSession créée, corpus SNAPSHOTTÉ (union calculée + déclarés beforeSnapshot), W fixé. Clôture à closesAt ou décision manuelle du garant → outcome par le moteur unique (consent : zéro objection maintenue ; binary : votesFor ≥ wotThreshold ; nuanced : nuancedResult ; election : désignation) → adopted | rejected.\n\nADOPTION : decidedAt posé. Si amendsClauseId → la ClauseVersion liée passe 'current', l'ancienne 'superseded' — application AUTOMATIQUE, boucle vote⇒texte fermée. Si createsMandate → le Mandate est créé 'active'. Si weight structural ou reversibility irreversible → review.dueAt obligatoire (posée AVANT l'exécution) et gravure proposée. sunsetAt optionnel : à échéance, la décision expire d'elle-même (caducité) avec relance dans le Fil.\n\nRÉALISATION / ÉVALUATION : la décision vit en 'adopted', visible au registre ; stewardIds (garants) portent l'exécution ; les rapports de mandat et revoyures dues remontent dans le Fil. À review.dueAt : verdict de réalité en 3 boutons — 'confirmed' (review close ; un acte one-shot passe 'closed'), 'revise' (spawn décision enfant chainKind 'revision', pré-remplie, sous le protocole/l'inertie d'origine), 'revoke' (spawn chainKind 'revocation').\n\nRÉVISION / RÉVOCATION : toute décision adoptée porte la poignée « Remettre en question » — ouvre /decider pré-rempli (parentDecisionId, chainKind), protocole et inertie D'ORIGINE affichés : révoquer suit toujours le chemin qui a adopté, jamais improvisé, jamais plus coûteux. Si la décision enfant 'revocation' est adoptée → le parent passe 'revoked' (cimetière de la Mémoire).\n\nURGENCE (transversale) : toggle « décision conservatoire » — si reversibility != 'irreversible', la voie la plus légère s'exécute MAINTENANT (adopted conservatoire + fenêtre d'objection élargie) et la décision de ratification chaînée (chainKind 'ratification', route normale calculée) est créée et programmée automatiquement. Si irréversible : le raccourci est REFUSÉ avec explication. L'urgence diffère l'inclusion, ne la supprime jamais.\n\nTRANSMISSION : route 'transmit' → status 'transmitted' (terminal pour l'auteur) ; la tension apparaît dans le Fil du mandataire qui peut la reprendre (décision chaînée) ; alternative offerte : contester le mandat (revocation sur le mandat).\n\nMACHINE À ÉTATS UNIQUE : engine/state.ts est la seule table de transitions (draft→{advice,objection,framing,voting,adopted,transmitted} ; advice→{adopted,voting} ; objection→{adopted,framing,voting} ; framing→voting ; voting→{adopted,rejected} ; adopted→{revoked,closed} ; + garde windowSuspendedAt). Toute mutation de status passe par canTransition() — fin des machines copiées-collées Decision/Mandate de la v1.",
"triage_algorithme": "MOTEUR : engine/triage.ts — fonction PURE triage(input, ctx, settings) → Verdict. Port étendu de backend/app/engine/qualifier.py (tests test_qualifier.py portés en vitest comme spec exécutable). Tous les seuils viennent de CollectiveSettings, résolus depuis les clauses du Pacte — le triage est gouverné par ceux qu'il gouverne, les changer = amender le Pacte sous l'inertie de la clause.\n\nENTRÉES EXPLICITES (3 chips maximum, récoltées pendant la saisie — jamais un formulaire) :\n1. Touchés → scope : pré-calculé par croisement tags de la phrase × domains des cercles/mandats, corrigeable en un tap (moi seul / cercles cochés / personnes nommées). Plancher : l'auteur peut élargir, JAMAIS restreindre sous le calcul.\n2. Réversible ? → reversibility : facilement ('easy') / coûteux à défaire ('costly') / irréversible ('irreversible').\n3. Ça engage quoi ? → weight : rien ('light') / du temps ou des ressources ('binding') / la structure, les règles, du long terme ('structural').\nENTRÉES INFÉRÉES (zéro saisie) : mes mandats actifs couvrants, mandats des autres couvrants, clauses en vigueur qui matchent (index Q0 = le même index que Cmd+K — chercher et décider sont le même geste), récurrence (similarRecentCount : décisions adoptées partageant ≥2 tags sur 90 j), toggle urgence, clause visée (pré-lien depuis un texte).\n\nRÈGLES, DANS L'ORDRE — première qui matche (chaque règle a sa phrase française affichée telle quelle) :\n- R-U URGENCE (overlay) : urgent && reversibility != 'irreversible' ⇒ voie la plus légère légitime MAINTENANT (conservatoire : adopted + fenêtre d'objection élargie ×2) + décision de ratification chaînée créée automatiquement avec la route normale. urgent && irreversible ⇒ raccourci REFUSÉ : « Irréversible : l'urgence ne peut pas contourner le collectif » — route normale avec fenêtres minimales.\n- R0a DÉJÀ DÉCIDÉ : une clause en vigueur couvre ⇒ « C'est déjà décidé (E9, Acte Forgeron) — agis » avec lien, OU « Conteste la règle » ⇒ bascule en R3 avec l'inertie de la clause.\n- R0b MON MANDAT : scope.circleIds ⊆ domain.circleIds d'un de mes mandats actifs ⇒ route 'mandate' : « Ton mandat Modération couvre — décide, c'est tracé » ; trace obligatoire à l'observatoire + fenêtre d'objection 48 h aux touchés.\n- R0c MANDAT D'UN AUTRE : ⇒ route 'transmit' : « Le mandat de Cgeek couvre — transmets-lui » (un tap) ; alternative : « Conteste ce mandat » (révocation chaînée, protocole d'élection d'origine).\n- R2 MOI SEUL : scope.selfOnly ⇒ route 'solo' : « Personne d'autre n'est touché — décide » ; trace facultative, visibility 'private' par défaut, zéro fenêtre ; si irreversible : revoyure proposée pré-cochée (retirable — sur soi-même l'outil ne s'interpose pas).\n- R3 CLAUSE VISÉE : amendsClauseId ⇒ route 'collective', protocole = settings.protocolByRange.clauseByInertia[clause.inertia] : « Tu proposes une version de E9 — inertie haute, vote du corpus » ; framing selon weight.\n- R4 PETIT CERCLE RÉVERSIBLE : reversibility=='easy' && |concernés calculés| ≤ smallGroupMax(5) ⇒ route 'advice' : « Réversible et 3 personnes touchées — demande leur avis puis décide » ; fenêtre 72 h ; toute objection formelle escalade en R5/consent.\n- R5 COLLECTIF (défaut de l'escalade) : sinon ⇒ route 'collective', modalité par taille du corpus calculé : ≤ consentMax(7) → consentement (tour d'objections, zéro vote) ; ≤ collectiveMin(50) → vote nuancé 6 niveaux ; > 50 → vote binaire à formule inertielle (Seuil = C + B^W + (M + (1M)(1(T/W)^G))·max(0,TC)) ; weight 'structural' ⇒ + framing 14 j + revoyure obligatoire + gravure suggérée + inertie haute ; reversibility 'irreversible' ⇒ revoyure obligatoire.\n- R6 RÉCURRENCE (overlay, jamais bloquant) : similarRecentCount ≥ recurrenceThreshold(3) ⇒ suggestion sous le verdict : « 3e fois — réclame un mandat » (createsMandate pré-rempli, wizard) ou « crée une règle » (nouvelle clause) — Ockham dans le temps : une décision collective en engendre mille individuelles.\n\nDÉROGATION ASYMÉTRIQUE (contrat du rasoir) : ALOURDIR est toujours libre — un tap dans « Je choisis autrement », journalisé (routeOverridden). ALLÉGER exige overrideNote obligatoire ET impose une fenêtre d'objection 48 h aux touchés (le consentement du cercle EST la fenêtre — pas de machinerie en plus) ; l'allègement est affiché en évidence sur la fiche. Le verdict n'est jamais un juge : il recommande, explique, et laisse faire.\n\nINCARNATION UX (/decider, accessible partout — FAB mobile, bouton header, pré-rempli par query : ?clause=, ?parent=&chain=, ?mandat=) : la phrase en haut ; les résultats Q0 « déjà décidé » apparaissent inline DÈS LA FRAPPE ; 3 chips en colonne (une seule visible à la fois sur mobile) ; toggle urgence discret. La carte VERDICT se recalcule à chaque geste : grande icône de route, la règle en français, la frise du processus (qui est convoqué — avatars, combien de temps — fenêtres, quel seuil — jauge miniature), UN bouton principal (« Décide », « Demande leur avis », « Ouvre le vote »…). En dessous, toujours visible : « Je choisis autrement » (alternatives dépliées avec leur coût). MÉTRIQUE PRODUIT : chemin nominal solo = phrase + Entrée + bouton = 2 gestes, < 10 secondes ; le tunnel n'affiche JAMAIS un champ qui ne change pas le verdict.",
"cercles_inclusion": "DEUX PORTES, UNE LISTE, CHAQUE ENTRÉE SOURCÉE (table Concern, horodatée).\n\nPORTE AUTOMATIQUE — les impactés calculés : à la validation du verdict, engine/impact.ts calcule l'union CALCULABLE : membres des cercles du scope personnes nommées titulaires des mandats dont le domaine intersecte le scope. Chaque inclusion crée Concern{origin:'computed', reason} avec sa raison en clair : « membre du cercle Forgerons », « titulaire du mandat Modération », « nommé par l'auteur ». AUDITABLE : un tap sur un avatar affiche la chaîne d'inclusion — jamais un « vous êtes invité » opaque. Les tags ne donnent JAMAIS un droit de vote : ils suggèrent des cercles, l'inclusion repose sur les listes nominatives des cercles (v2) — règle d'appartenance auditable, extensible plus tard (WoT, géo) sans changer le modèle. PLANCHER ANTI-EXCLUSION : l'auteur peut élargir la liste, jamais la restreindre sous le calcul. Les inclus voient la décision dans leur Fil avec le verdict et la fenêtre — une ligne dans l'écran qu'ils ouvrent déjà, pas un canal de plus.\n\nPORTE VOLONTAIRE — « Ça me concerne » : bouton présent sur toute décision visible (selon Decision.visibility et Collective.isTransparent), SANS justification requise — c'est un droit, pas une demande ; champ « pourquoi » optionnel et public. Crée Concern{origin:'declared', beforeSnapshot}. Droits : déclaré AVANT le snapshot de session ⇒ entre au corpus de vote ; APRÈS ⇒ voix consultative (ses avis et objections comptent et sont notifiés, pas de vote) — règle simple, affichée en compte à rebours sur la fiche. Les déclarations sont publiques : la transparence dissuade le noyautage.\n\nOBJECTION DE FRONTIÈRE (suspensive — Ostrom, la contestation des frontières prime sur le fond) : « J'ai été oublié » / « Untel manque » = Objection{kind:'boundary'} ⇒ windowSuspendedAt posé, le compte à rebours de la décision est SUSPENDU (pastille pause visible) jusqu'à résolution (intégration au périmètre ou réponse motivée) ; priorité maximale dans le Fil de l'auteur.\n\nSIGNAL D'AFFLUENCE (la subsidiarité auto-corrective) : si |déclarés| ≥ concernEscalateRatio(0.5) × |calculés|, bannière sur la fiche et dans le Fil de l'auteur : « Le périmètre déborde — élargis d'un cran » (ajout du cercle parent ou du collectif entier, un tap, re-triage, journalisé). L'impact réel corrige le périmètre déclaré ; un afflux massif déclenche une revue de périmètre, jamais un comptage brut.\n\nGRADIENT D'ENGAGEMENT (quatre niveaux, affichés sur la fiche) : observateur (lecture) < concerné (avis, objection — computed hors corpus ou declared tardif) < lié (vote — dans le corpus snapshotté) < garant (stewardIds — exécution et rapport).\n\nANTI-BRIGADING PAR CONSTRUCTION : déclarations publiques + snapshot qui ferme le corpus + entrée tardive consultative + escalade de périmètre — et la formule inertielle absorbe naturellement l'afflux : gonfler W sans que T suive fait MONTER le seuil vers la quasi-unanimité. ANTI-FLICAGE (ligne rouge produit) : hors mandat, la trace est facultative et visibility choisie ('private' par défaut pour le solo personnel) ; sous mandat, trace obligatoire visible du cercle électeur — la redevabilité s'applique au pouvoir, pas aux personnes.",
"navigation": "SHELL : layouts/default.vue (le shell sort enfin de app.vue). Header : logo-stamp (icône puits + rotation -10°) + « libreDecision » ; WorkspaceSelector (collectifs locaux + « Créer un collectif ») ; recherche globale Cmd+K (index unique : clauses en vigueur + décisions + mandats — le MÊME index que Q0 du triage) ; MoodSwitcher ; bouton « Décider » (desktop). FAB « Décider » 56 px en mobile, au-dessus du sceau. Sceau hexagramme #48 Tsing 井 fixe bas-droite (géométrie SVG canonique des consignes). layouts/bare.vue pour /creer.\n\nSIDEBAR — 4 ENTRÉES, pas une de plus (le rasoir appliqué à la nav) :\n1. Aujourd'hui (/) — le Fil + la capture. L'écran qu'on ouvre chaque jour ; à 3 personnes, c'est tout l'outil.\n2. Décisions (/decisions) — le registre + la Mémoire.\n3. Textes (/textes) — les documents sous vote permanent, Pacte épinglé en tête.\n4. Mandats (/mandats) — les pouvoirs délégués.\n\nDISSOLUTIONS VOLONTAIRES : les protocoles vivent dans le Pacte (/textes/pacte, clauses F) et dans l'étape modalité du verdict — pas de section. L'Atelier des formules = /textes/formules, lié depuis CHAQUE seuil affiché dans l'app. Le Sanctuaire = badge 井 + fiche de preuve sur les objets gravés + filtre ?filtre=gravees du registre — pas de section. La boîte à outils v1 disparaît : ContextMapper devient le « pourquoi ? » dépliable du verdict, SocioElection devient la modalité 'election' en session, WorkflowMilestones nourrit les gabarits. Pas de page réglages : les réglages SONT le Pacte ; les préférences locales (mood, export/import, identité, mode démo) = /donnees, accessible du menu du WorkspaceSelector.\n\nROUTES :\n/ — Aujourd'hui (Fil + capture) · /decider — tunnel de triage (pré-remplissable : ?clause=, ?parent=&chain=, ?mandat=) · /decisions — registre · /decisions/memoire — Mémoire (stats, revues, cimetière) · /decisions/[id] — fiche décision (URL permanente de la capture à la révocation) · /decisions/[id]/vote — salle de vote · /textes — bibliothèque · /textes/formules — Atelier des formules · /textes/[slug] — document vivant (pacte inclus, slug 'pacte-…') · /mandats — liste · /mandats/nouveau — wizard · /mandats/[id] — fiche mandat · /creer — onboarding collectif (layout bare) · /donnees — données locales, export/import, identité, mode démo.\n\nCOUCHES CODE : app/types/domain.ts (le noyau) ; app/engine/ (threshold, triage, modeParams, settings, state, impact — purs, vitest) ; app/data/ (persistence.ts IndexedDB + seeds/*.bundle.json + templates.ts gabarits) ; app/stores/ (collective, people, decisions, mandates, texts, votes — contrat commun prêt pour l'adaptateur FastAPI) ; app/composables/ (useMood conservé, useSettings, useFeed — sélecteurs purs, useSearch — index Cmd+K/Q0) ; app/components/ par domaine (verdict/, decisions/, votes/, texts/, mandates/, circles/, common/). Le Fil est un SÉLECTEUR PUR sur les stores — zéro table notification, zéro double-fetch. Budget : 400 lignes max par page, composants extraits (anti-syndrome protocols/index.vue 1545 l.).",
"ecrans": [
{
"route": "/creer",
"nom": "Créer un collectif",
"role": "Onboarding en 3 écrans — le premier usage EST le tutoriel, zéro documentation",
"contenu": "Écran 1 : nom, couleur, mood. Écran 2 : gabarit en 5 cartes qui TRADUISENT le vocabulaire (Informel « à 3-15, on se fait confiance » / Association / Coopérative / Commune / Communauté monnaie libre) — chaque gabarit installe le Pacte pré-rempli (clauses settingKey avec les bons seuils), 4-6 protocoles canoniques et le cercle racine ; textes en langage concret (« qui doit être d'accord ? », jamais « corpus électoral »). Écran 3 : moi (prénom, isMe) + membres initiaux (noms, ajout rapide). Boutons d'import : « Explorer Duniter Ğ1 » et « Explorer l'Atelier du Canal » chargent les bundles seed par le MÊME chemin qu'un import utilisateur. Atterrissage sur / avec la première décision proposée : « Adoptez votre Pacte » (collective, consentement) — réussite < 10 minutes, testée avec des non-théoriciens."
},
{
"route": "/",
"nom": "Aujourd'hui",
"role": "L'écran quotidien unique : capture + Fil personnel — la boîte de réception de la démocratie",
"contenu": "Barre de capture sticky « Qu'est-ce que tu décides ? » (Entrée → /decider avec la phrase). Fil trié par échéance, sections vides masquées : fenêtres d'objection où je suis touché (2 boutons inline « Ça me va / J'objecte », compte à rebours, pastille pause si suspendu) ; avis demandés (3 boutons favorable/réservé/défavorable inline) ; votes ouverts où je suis au corpus (jauge miniature, lien salle de vote) ; revoyures dues (verdict de réalité 3 boutons inline) ; rapports de mandat dus ; objections de frontière à traiter (priorité haute) ; suggestions de la boucle apprenante (« 3e fois — réclame ce mandat », « ce protocole n'a jamais servi — élague »). Badge UNIQUE de dette décisionnelle dans le header de section. Ensuite : l'activité du collectif (selon visibility). Tout est sélecteur Pinia pur — aucun stockage de notifications. Mobile-first absolu : c'est l'écran du comptoir, pas de la réunion."
},
{
"route": "/decider",
"nom": "Le Verdict (tunnel de triage)",
"role": "Une phrase → un chemin exécutable en un tap — 10 s pour le routinier, 3 min pour le stratégique",
"contenu": "Phrase en haut (pré-remplie depuis la capture ou les query params clause/parent/chain/mandat). Résultats Q0 « déjà décidé ? » inline dès la frappe (même index que Cmd+K) : clause en vigueur → « agis » ou « conteste » ; mandat d'un autre → « transmets » ou « conteste le mandat ». 3 chips : touchés (pré-calculés par tags→cercles, avatars visibles, plancher non restrictible), réversibilité (3 options), engagement (3 options → weight). Toggle « urgence » discret (conservatoire). Carte VERDICT live : grande icône de route, règle en français (« R4 — Réversible et 3 personnes touchées → demande leur avis puis décide »), frise qui/combien-de-temps/quel-seuil, revoyure et gravure pré-cochées si exigées, UN bouton principal. « Je choisis autrement » toujours visible : alourdir 1 tap journalisé ; alléger = note obligatoire + fenêtre d'objection imposée. « Pourquoi ? » dépliable (pédagogie ContextMapper recyclée). Suggestion R6 sous le verdict (mandat/règle pré-remplis). Valider crée la Decision dans le bon état avec données STRUCTURÉES (cercles en ids, protocole appliqué — les deux fuites du wizard v1 corrigées)."
},
{
"route": "/decisions",
"nom": "Registre des décisions",
"role": "Toutes les décisions par état — SectionLayout conservé",
"contenu": "Pills d'état (préparation / avis / objection / formulation / vote / en vigueur / clos / rejeté / révoqué) reprises du SectionLayout v1 avec les couleurs du cycle de vie. Filtres : cercle, tag, « me concerne », poids, gravées (井). Recherche locale = même index global. Cartes décision : titre, route (icône), poids, échéance, jauge miniature si vote, badge 井. Lien vers l'onglet Mémoire. Zéro création ici — on crée par la capture."
},
{
"route": "/decisions/[id]",
"nom": "Fiche décision",
"role": "URL permanente de l'objet pivot, de la capture à la révocation — progressive disclosure par état",
"contenu": "En-tête : titre, route+règle de triage en français, poids, badges (urgence conservatoire, dérogation allégée avec note, 井). Timeline verticale du cycle (états traversés, horodatés). Panneau Cercles : avatars empilés calculés (tap → raison d'inclusion) et déclarés (glyphe main, note publique), bouton « Ça me concerne », compte à rebours du snapshot, signal d'affluence (bannière élargissement 1 tap), objection de frontière (suspend la fenêtre — pastille pause). Selon l'état seulement : bloc fenêtre (objection/avis, boutons inline, silence-vaut-accord affiché SEULEMENT si réversible) ; bloc formulation (versions, diff unifié, contre-propositions bornées) ; bloc session (lien salle de vote, résultat, corpus W/T) ; bloc vigueur (garants stewardIds, sunset, revoyure due avec 3 boutons) ; chaînage (parent/enfants : ratification, révision, révocation — cliquables). Poignée « Remettre en question » sur toute décision adoptée : ouvre /decider pré-rempli avec protocole et inertie D'ORIGINE affichés. Actions : export PV markdown (registre de légitimité, pas substitut légal), graver (fiche de preuve : sha256, date, niveau « empreinte locale — démo » — honnête). Budget 400 lignes, composants extraits."
},
{
"route": "/decisions/[id]/vote",
"nom": "Salle de vote",
"role": "Le geste démocratique central — voter au pouce en 20 secondes",
"contenu": "Contexte : titre, texte/diff de la version proposée, lien fiche. Corpus visible : W, T, qui (avatars), snapshot horodaté, critères additionnels Smith/ComTech si protocole. Selon la méthode : consentement (« Ça me va » / « J'objecte » argumentée) ; binaire pour/contre ; nuancé 6 niveaux (0 CONTRE → 5 TOUT À FAIT, commentaire OBLIGATOIRE inline sur 0-1). Jauge inertielle : arc animé, seuil qui DESCEND quand la participation monte, phrase générée en français (« 94 pour requis, car 120 votants sur 7 224 — la formule exige presque l'unanimité à faible participation »), lien « comprendre ce seuil » → Atelier pré-réglé. Mon vote remplaçable (supersedesVoteId — historique audité visible). Clôture : résultat, décompte recalculé depuis les votes, adoption ⇒ application automatique (clause current, mandat créé) — zéro bouton d'acceptation manuel."
},
{
"route": "/decisions/memoire",
"nom": "Mémoire",
"role": "Le miroir : la démocratie rendue mesurable — et le cimetière comme apprentissage",
"contenu": "Statistiques d'autonomie du collectif : ratio seul/mandat/avis/collectif, temps médian de décision par route, taux d'objection, participation moyenne (T/W), dérogations (alourdies/allégées). Revues dues et verdicts de réalité rendus (confirmée/révisée/révoquée). Cimetière des révoquées avec leur chaîne (qui a révoqué, comment, pourquoi). Décisions jamais revues : relance unique puis archivage proposé. Suggestions d'élagage : protocole jamais invoqué, mandat sans trace depuis 6 mois → revue. Filtres personne/cercle/tag/période. Graphiques sobres (skill dataviz à l'implémentation)."
},
{
"route": "/textes",
"nom": "Textes",
"role": "La bibliothèque des documents sous vote permanent — on y consulte et conteste, on n'y travaille pas",
"contenu": "Pacte épinglé en tête (badge « les règles du jeu »). Cartes documents : titre, rôle, nombre de clauses, sessions en cours (mini-jauges), provenance (Ğ1 : Acte d'engagement Certification 33 clauses, Acte d'engagement forgeron 59 clauses v2.0.0-fr, Engagement Comité Technique). Lien Atelier des formules. Filtre gravées."
},
{
"route": "/textes/[slug]",
"nom": "Document vivant",
"role": "L'héritier de documents/[slug] v1 — débranché des mocks, boucle vote⇒texte fermée",
"contenu": "Sections repliables + scroll-spy conservés. Chaque clause : code, titre, pastille d'inertie (low→max, CÂBLÉE au protocole d'amendement), mini-jauge branchée sur la vraie session si version proposée, statut. Tap clause → détail : version courante, versions proposées avec diff, décision fondatrice et amendements chaînés (cliquables). « Proposer une version » → /decider?clause= pré-lié (R3, protocole de l'inertie). Vue projetée conservée : « le document si les votes en cours passaient ». InertiaSlider pédagogique → Atelier pré-réglé. GenesisBlock rendu depuis Provenance normalisée (sources, voteRecord 97/23/19, contributeurs, notes — typos signalées jamais corrigées). Spécifique Pacte : les clauses settingKey affichent la valeur machine EN CLAIR (« Petit groupe : jusqu'à 5 personnes ») et leur effet est IMMÉDIAT à l'adoption (resolveSettings) ; la clause qui règle l'inertie est protégée par l'inertie maximale (G=.6, M=66 %) — modifier les règles de modification exige la quasi-unanimité."
},
{
"route": "/textes/formules",
"nom": "Atelier des formules",
"role": "La pépite v1 conservée telle quelle — la pédagogie du seuil",
"contenu": "FormulaEditor porté : sliders M/B/G/C (+Smith/ComTech), rendu KaTeX de Seuil = C + B^W + (M + (1M)(1(T/W)^G))·max(0,TC), table de participation (seuil pour T croissant), presets d'inertie (low/standard/high/max) comparés. Branché sur engine/threshold.ts UNIQUE — le même module que la jauge et le décompte (divergence v1 threshold.py/votes.py définitivement tuée). Accessible depuis chaque seuil affiché dans l'app, pré-réglé avec les paramètres du contexte (« pourquoi 94 ? »). Cas de référence Forgeron 2026 chargé en un clic (W=7224, T=120 ⇒ 94)."
},
{
"route": "/mandats",
"nom": "Mandats",
"role": "La carte des pouvoirs : qui peut décider quoi, jusqu'à quand",
"contenu": "Cartes par statut (proposé/actif/expiré/révoqué) : titulaire (avatar), domaine (cercles + tags), échéance, prochain rapport dû, jauge de confiance (objections/traces récentes). Taxonomie unifiée (la modale rapide techcomm/smith v1 supprimée). Bouton « Réclamer un mandat » → wizard (le plus souvent pré-rempli par R6)."
},
{
"route": "/mandats/[id]",
"nom": "Fiche mandat",
"role": "Le pouvoir délégué, visible et reprenable",
"contenu": "Titulaire, origine (la décision qui l'a créé — cliquable), domaine explicite (cercles + tags — c'est l'entrée R0b/R0c du triage), période, cercle électeur. Observatoire : flux des décisions prises sous ce mandat (chacune avec sa fenêtre d'objection, contestable). Rapports de redevabilité : dus/rendus, contenu. Jauge de confiance : ratio objections/traces sur la période. « Demander la révocation » en un geste : ouvre /decider chaîné (chainKind revocation) avec le protocole de nomination D'ORIGINE et le cercle électeur comme corpus — jamais improvisée, jamais plus coûteuse que l'élection."
},
{
"route": "/mandats/nouveau",
"nom": "Wizard mandat",
"role": "Le meilleur flux de la v1, conservé et branché sur le pivot",
"contenu": "3 étapes : (1) rôle et domaine (titre, cercles couverts, tags, une phrase de mission) ; (2) modalité de nomination parmi 6 (auto-désignation ratifiée, élection sans candidat, vote nuancé, consentement, tirage au sort, rotation) avec pros/cons pédagogiques ; (3) durée bornée + cadence de rapports + cercle électeur. Sortie : une Decision createsMandate routée collective (la nomination EST une décision) — pré-remplie par la suggestion R6 le cas échéant."
},
{
"route": "/donnees",
"nom": "Données locales",
"role": "Local-first assumé : tes données, ton fichier, ta machine",
"contenu": "Export du bundle JSON (téléchargement, schemaVersion 2), import avec validation et détection de collisions, réinitialisation par collectif. Chargement des seeds (Duniter Ğ1, Atelier du Canal). Identité locale (displayName, isMe). Mode démo « agir en tant que » (switch discret vers les personnes seedées — pour dérouler votes et consentements localement, clairement étiqueté démo). Niveaux de preuve expliqués honnêtement : empreinte locale (v2) / IPFS / ancrage chaîne (à venir — jamais affiché tant que non réel). Note synchro : « un serveur pourra se brancher plus tard, tes données ne changent pas de forme »."
}
],
"seeds": "EXTRACTION — script backend/scripts/export_seed_bundle.py (venv existant) : importe les structures de seed.py (2 552 l. : les 33 items Certification, les 59 items Forgeron, GENESIS_CERTIFICATION, GENESIS_FORGERON, VOTER_NAMES ×11, mandates_data ×3, 3 VotingProtocols + 7 FormulaConfigs, QualificationProtocol) et émet frontend/app/data/seeds/duniter-g1.bundle.json au schéma Bundle v2. TEST DE NON-PERTE (vitest, bloquant) : 33 clauses cert + 59 clauses forgeron (l'incohérence « 51 vs 59 » est tranchée par le comptage du seed actuel = 59), répartition des presets d'inertie conservée, provenance.voteRecord == {for:97, against:23, invalid:19, wotSize:7224, thresholdRequired:97, modeParams:'D30M50B.1G.2S.1'}, 11 personnes dont 5 smiths, 3 mandats, protocoles complets. Le diff est exigé AVANT toute dépréciation de seed.py. Typos des textes votés : reportées dans Provenance.notes, JAMAIS corrigées (textes adoptés — les corriger exige un vote).\n\nMAPPING Ğ1 → NOUVEAU MODÈLE :\n- Organization 'duniter-g1' → Collective{template:'free-currency', color:'#22c55e', isTransparent:true}.\n- 11 DuniterIdentity → Person : Moul, Poka, Hugo, Elois, Cgeek (wotStatus:'smith') ; Galuel, Tortue, Inso, Tuxmain, Matograine, Maaltir ('member').\n- Groups (orphelins v1) → Circles enfin branchés comme corpus : « Toile de confiance » (racine, 11 membres — étiquetée « échantillon de démonstration », le W historique 7 224 vit dans Provenance, pas dans le corpus local) ; « Forgerons » (les 5 smiths, parent TdC, domains ['forge','noeuds','runtime']) ; « Comité Technique » (Elois, Cgeek, Maaltir, Hugo, Tuxmain, parent TdC, domains ['runtime','code','on-chain']).\n- Documents → TextDoc role 'reference' : (1) engagement-certification « Acte d'engagement Certification », 33 Clauses avec presets CÂBLÉS (fin de l'inertie décorative : low→G.1, standard→G.2, high→G.4/M60, very_high→max→G.6/M66), Provenance.sources = Licence Ğ1 v0.3.0 (git.duniter.org) + Charte 1.0 rejetée (topic 31066) + prépa v0.4.0 (topic 32375) + checklist (topic 32412) — LA LICENCE VIT ICI comme source normalisée ; (2) engagement-forgeron « Acte d'engagement forgeron » v2.0.0-fr, 59 Clauses, Provenance.voteRecord complet (97/23/19, W=7224, seuil 97, période 2026-01-07→02-06, urls forum + g1vote) ; (3) engagement-comite-tech « Engagement Comité Technique » v2.0.0-fr — ENFIN seedé, contenu depuis docs/dev (research_duniter_forum.md), la dette v1 soldée.\n- NOUVEAU : pacte-duniter-g1 (TextDoc role 'pact') — clauses settingKey depuis le QualificationProtocol v1 : triage.smallGroupMax=5, triage.collectiveMin=50, consentMax=7, fenêtres 48/72 h, framingDays=14, concernEscalateRatio=0.5, recurrenceThreshold=3, reviewDelayDays=90, + clauses F référençant les protocoles nommés ; la clause d'inertie sous preset 'max'.\n- INVARIANT TENU DÈS LE SEED : chaque clause courante reçoit sa DÉCISION FONDATRICE (Decision route 'collective', status 'adopted', title « Adoption fondatrice — <code> », liée à la ClauseVersion 'current') — « toute clause est une décision », même l'héritage.\n- 3 VotingProtocols + 7 FormulaConfigs → 6 Protocols canoniques (FormulaConfig fusionnée dans Protocol.formula) : Consentement (consent, D7) ; Vote nuancé 6 niveaux (nuanced, D30, params nuanced conservés) ; Vote WoT standard (binary, D30M50B.1G.2) ; Vote forgeron Smith (binary, D30M50B.1G.2S.1) ; Vote Comité Technique (binary, D30M50B.1G.2T.1) ; Élection sans candidat (election, D14). Les 4 presets d'inertie mappés vers clauseByInertia. Le catalogue 18 modalités reste en bibliothèque documentaire (hors seed).\n- 3 Mandates : « Comité Technique — Session 2025-2026 » (holder Cgeek, active, electorCircle TdC, domain [ComTech], steps v1 → originDecision adoptée + reports mi-mandat dû — apparaît dans le Fil) ; « Administrateur des Forgerons — Rotation 2026-Q1 » (proposed : la Decision createsMandate est EN VOTE nuancé, corpus Forgerons — démontre la nomination vivante) ; « Modération Forum » (active, domain tags ['forum','moderation']).\n- Décisions historiques : « Runtime Upgrade 1100 » (adopted, weight structural, gravée proofLevel 'local', revoyure posée) ; « Évolution de la licence v0.4.0 » (framing, versions liées aux clauses cert — la préparation réelle du forum incarnée). Votes seedés sur 2-3 sessions de clauses (corpus 11, jauges vivantes).\n\nDEUXIÈME COLLECTIF — atelier-du-canal.bundle.json (LE test permanent de la marque blanche, greffe V1) : association fictive 12 membres, template 'association', Pacte propre avec seuils DIFFÉRENTS (smallGroupMax=4, fenêtres courtes), « Règlement intérieur » 8 clauses, cercles Bureau/Ateliers/Tous, mandat Trésorerie (rapport dû), et des décisions à TOUS les états de la machine (draft, advice en fenêtre, objection SUSPENDUE par une objection de frontière, framing avec 2 versions et diff, voting nuancé en cours, adopted avec revoyure due, revoked au cimetière, conservatoire + ratification chaînée) — chaque état de l'UI a sa donnée de démonstration, et tout contenu Ğ1 en dur dans le code est structurellement impossible.\n\nGABARITS (/creer) : app/data/templates.ts — 5 mini-modèles (pacte pré-rempli + protocoles + cercle racine) : informal (consentement partout, fenêtres 24 h, pas de mandat), association (cercles + mandats statutaires + nuancé), cooperative (advice process par défaut), commune (corpus larges, binaire inertiel, transparence), free-currency (le mapping Ğ1 ci-dessus en modèle). Les seeds s'importent par le MÊME chemin de code que l'import utilisateur — le seed est un import comme un autre.",
"design_directives": "ICONOGRAPHIE DU TRIAGE (vocabulaire visuel fixe, appris une fois) : chaque route a son icône et sa teinte — solo = i-lucide-zap ; sous mandat = i-lucide-key-round ; transmettre = i-lucide-send ; avis = i-lucide-message-circle ; collectif = i-lucide-users ; urgence/conservatoire = i-lucide-siren ; « déjà décidé » = i-lucide-book-open-check ; récurrence→mandat = i-lucide-repeat. La carte Verdict : icon-container 14 px avec la grande icône de route, nom de route en 700, la règle en une phrase en dessous, frise horizontale qui/durée/seuil, bouton principal pill 20 px plein accent, alternatives en pills fantômes. Teintes de route déclinées des custom properties du mood (jamais de couleurs codées en dur).\n\nREPRÉSENTATION DES CERCLES : stacks d'avatars superposés (initiales sur fond de teinte déterministe dérivée de l'id — pas d'images), débord -8 px, compteur « +N ». Origine distinguée SANS bordure : glyphe en coin de l'avatar (i-lucide-calculator = calculé, i-lucide-hand = déclaré) + fond légèrement teinté pour les déclarés. Tap → popover chaîne d'inclusion (« membre du cercle Forgerons — via la liste du cercle »). Les cercles emboîtés se rendent en chips imbriquées (parent estompé derrière l'enfant). Le plancher calculé est visuellement verrouillé (les avatars calculés ne portent pas de croix de retrait).\n\nCYCLE DE VIE : timeline verticale à pastilles pleines reliées par un trait de fond (pas de bordure) — draft neutre, avis/objection ambre AVEC compte à rebours textuel, vote bleu avec mini-jauge, en vigueur vert, revoyure violette, révoqué terre cuite, clos gris estompé, rejeté neutre barré. SUSPENSION (objection de frontière) : pastille i-lucide-pause + fond légèrement strié + libellé « compte à rebours suspendu — frontière contestée » : l'état le plus important à rendre visible. Les pills du SectionLayout reprennent exactement ces couleurs (un seul mapping état→couleur dans le CSS).\n\nJAUGE INERTIELLE (signature du produit) : arc 270°, remplissage = votes pour, curseur de seuil qui DESCEND visiblement quand la participation monte — l'inertie rendue sensible ; W, T et seuil en chiffres clairs sous l'arc ; phrase d'explication générée en français. KaTeX réservé à l'Atelier (jamais de formule brute dans le flux). Vote nuancé : 6 segments en gradient sémantique (défavorable→favorable) construit depuis la palette du mood via le skill dataviz à l'implémentation, jamais rouge/vert crus ; le commentaire obligatoire s'ouvre inline sous les niveaux 0-1.\n\nMOODS v2 (champ lexical du puits, 2 light + 2 dark) : « Source » (light clair, accent bleu d'eau), « Margelle » (light chaud sable/pierre), « Nappe » (dark bleu profond), « Minuit » (dark neutre encre). Classes .mood-* sur <html> + custom properties, useMood.ts conservé. Socle inchangé : borderless (profondeur par background + box-shadow), arrondis 16/12/20/14, hover cards translateY(-3px) 0.12s, mobile-first clamp(), breakpoints 480/768/1024, touch ≥ 2.25 rem.\n\nGRAVURE ET PREUVE : badge 井 en tampon incliné -10° (cohérent avec le logo-stamp) sur tout objet gravé ; fiche de preuve = sha256 en mono tronqué copiable, date, niveau de preuve en toutes lettres (« empreinte locale — démo ») — la sobriété est l'honnêteté. Sceau hexagramme #48 Tsing : géométrie SVG canonique des consignes (viewBox 112×105, 6 traits, trait 1 en bas = dernier rect), opacity ~0.28, couleur accent, drop-shadow CSS — fixe bas-droite, JAMAIS recouvert ; le FAB « Décider » (56 px, bottom-right mobile) se place AU-DESSUS du sceau avec un décalage vertical qui le laisse visible.",
"hors_scope_v2": [
"Synchronisation backend / adaptateur FastAPI — le contrat des stores Pinia et le Bundle sont prêts ; brancher l'API n'exigera de changer aucun écran",
"Auth Duniter challenge-réponse et vérification Ed25519/Sr25519 — identités locales en v2, champ duniterAddress réservé",
"Multi-appareils et multi-utilisateurs simultanés — v2 mono-poste ; le mode démo « agir en tant que » (étiqueté) exerce les flux collectifs localement",
"Notifications sortantes (email, digest) — tous les mécanismes temporels sont affichés in-app dans le Fil ; en conséquence le silence-vaut-accord est réservé au réversible et présenté comme tel",
"WebSocket temps réel — la réactivité Pinia locale suffit ; useWebSocket conservé en attente de l'adaptateur",
"Délégation liquide / procuration — le modèle chaîné l'accueillera (v3), rien dans l'UI v2",
"IPFS et ancrage on-chain, signatures de vote vérifiées — proofLevel 'local' uniquement, libellé « empreinte locale — démo » ; les champs ipfsCid/chainRef existent mais ne s'affichent jamais tant que non réels",
"Protocoles opérationnels / ProcessTemplate (Embarquement Forgeron 7 étapes, checklists à clauses pièges) — documentés, non construits",
"Jugement majoritaire et le catalogue des 18 modalités × 9 nominations — 6 protocoles canoniques seedés, le reste en bibliothèque documentaire",
"Fédération inter-collectifs et escalade au-delà du collectif racine",
"Suggestion LLM de modalités (stub qualify_ai non porté)",
"Exports juridiques avancés et signatures qualifiées — le PV markdown simple est inclus ; positionnement : registre de légitimité, jamais substitut légal",
"Règles d'appartenance calculées WoT/géographiques — v2 : listes nominatives des cercles ; l'enum de règle est extensible sans migration"
],
"plan_implementation": [
"1. SOCLE ET MOTEURS — branche v2, shell sorti d'app.vue vers layouts/, moods 4 ambiances, types/domain.ts complet, engine/ TS pur (threshold, nuanced, modeParams, settings, triage, state, impact) avec vitest portant test_threshold.py / test_qualifier.py / test_nuanced.py / test_mode_params.py — le cas Forgeron W=7224 T=120 ⇒ 94 vert AVANT tout écran (le bug latent le plus dangereux tué en premier)",
"2. PERSISTANCE ET SEEDS — data/persistence.ts (IndexedDB idb-keyval, export/import Bundle), script backend/scripts/export_seed_bundle.py, bundles duniter-g1 + atelier-du-canal, tests de non-perte bloquants (33/59 clauses, genesis 97/23/19/7224, 11 personnes, 3 mandats, 6 protocoles), gabarits templates.ts",
"3. SHELL ET ONBOARDING — header (WorkspaceSelector, Cmd+K sur l'index unique, MoodSwitcher, bouton Décider), FAB mobile, sceau 井 canonique, /creer 3 écrans + imports seeds, /donnees (export/import/reset, identité, mode démo)",
"4. LE GESTE — /decider complet (Q0 inline, 3 chips, verdict live expliqué, urgence conservatoire chaînée, dérogation asymétrique journalisée, création structurée) + / Aujourd'hui (capture sticky, Fil en sélecteurs purs, boutons inline, badge unique de dette) — mesurer le chemin nominal : 2 gestes, < 10 s",
"5. CYCLE DE VIE — /decisions (registre SectionLayout) + /decisions/[id] (timeline, panneau Cercles auditable, « Ça me concerne », objection de frontière suspensive, signal d'affluence, fenêtres avec silence-vaut-accord réversible seulement, revoyure 3 boutons, poignée « Remettre en question » chaînée, PV markdown, gravure locale honnête)",
"6. LE VOTE — /decisions/[id]/vote (consentement, binaire, nuancé avec commentaire négatif obligatoire), jauge inertielle + explication française, snapshot de corpus (W ≠ 0 à jamais), re-vote audité, adoption ⇒ application automatique (clause current / mandat créé)",
"7. LES TEXTES — /textes + document vivant (clauses, versions/diff, vue projetée, inertie CÂBLÉE, Provenance/GenesisBlock) + Pacte effectif (resolveSettings lu par le triage — la méta-gouvernance devient l'usage) + /textes/formules (FormulaEditor sur le moteur unique)",
"8. LES MANDATS — /mandats, fiche (observatoire des décisions sous mandat, rapports, jauge de confiance, révocation chaînée au protocole d'origine), wizard 3 étapes pré-rempli par R6",
"9. MÉMOIRE ET BOUCLE APPRENANTE — /decisions/memoire (stats d'autonomie, revues dues, cimetière), suggestions dans le Fil (récurrence ⇒ mandat, mandat objecté ⇒ revue, protocole inutilisé ⇒ élagage, sunset échu ⇒ caducité) — le système se simplifie lui-même",
"10. FINITION LIVRABLE — QA mobile+desktop zéro régression (480/768/1024, toucher 2.25 rem), parcours complets sur les 2 seeds ET un collectif vierge (« Adoptez votre Pacte » < 10 min, testé avec un non-théoricien), a11y clavier/contraste, README + CONTRIBUTING, npm run build zéro erreur, screenshots — livrable à toute structure"
]
},
"judgements": [
[
{
"titre": "V1 — La grammaire générative (6 primitives)",
"fidelite": 9,
"ockham": 6,
"faisabilite": 5,
"reve": 8,
"commentaire": "Lentille utilisateur final : la plus complète intellectuellement (Q0 « est-ce déjà décidé ? », cercles auditables, objection d'oubli suspensive, révocation protocolisée dès la création — tout y est), mais le membre de l'association de 12 doit traverser « tension, périmètre, corpus-formule, cheminement » et 6 sections de nav + 10 écrans. La vision admet elle-même le risque (« illisible pour le novice ») sans le résoudre structurellement : le vocabulaire concret est promis, pas conçu. Pour la citoyenne de 40 000, la délégation liquide native et le seuil expliqué en langage naturel sont du vrai pouvoir — si elle arrive jusque-là. Faisabilité : délégation liquide + Sanctuaire + local-first + 6 primitives en une refonte, c'est deux refontes. Le rêve est réel mais c'est le rêve du théoricien de la gouvernance, pas celui de la trésorière d'asso."
},
{
"titre": "V2 — Le compagnon de toutes les décisions",
"fidelite": 9,
"ockham": 9,
"faisabilite": 7,
"reve": 8,
"commentaire": "La seule vision pensée depuis le geste quotidien, exactement l'intention (« tout le monde prend tous les jours des décisions ») : une phrase → verdict → un bouton, 10 secondes, 2 boutons inline « Ça me va / J'objecte » dans le Fil, un seul badge, digest unique. Le membre d'asso de 12 vit dans UN écran ; la citoyenne s'abonne à des tags et reçoit une ligne dans un écran qu'elle ouvre déjà. Ockham est mécanique, pas déclaratif : escalade par exception, formulaires progressifs, système qui s'élague lui-même (protocole inutilisé → suppression suggérée). La boucle apprenante (5 traces → « réclame ce mandat ») est la meilleure idée du lot : les mandats émergent de la pratique. Faisabilité correcte (3 espaces, valeur solo jour 1) mais la boucle apprenante et la détection de similarité sont sous-spécifiées. Faiblesse : le Puits/Mémoire à grande échelle est moins outillé que V3 sur le calcul d'impact — l'inclusion par tags libres est plus fragile qu'un graphe."
},
{
"titre": "V3 — La légitimité calculée (graphe d'attaches, sceau)",
"fidelite": 8,
"ockham": 6,
"faisabilite": 4,
"reve": 7,
"commentaire": "La meilleure réponse à « identifier automatiquement les impactés » : le graphe d'attaches avec inclusion explicable (« vous êtes convoquée parce que signataire de la clause A7 ») donne à la citoyenne de 40 000 un pouvoir qu'aucun régime ne lui a donné — savoir POURQUOI elle a voix. L'escalade automatique par concernement est la subsidiarité rendue honnête. Mais pour l'asso de 12 : déclarer des empreintes, des usages, des territoires avant que le calcul fonctionne, c'est de la saisie de graphe déguisée — le démarrage à froid est reconnu et non résolu (« sceau dégradé » = l'outil avoue qu'il ne marche pas au début). Le sceau de légitimité multi-critères sera lu comme une note technocratique par un non-technicien, la vision l'admet. 8 entités dont ATTACHE générique : le noyau le plus lourd des quatre. Faisabilité la plus basse : graphe + sceau calculé + fédération fractale en une refonte est irréaliste. Le rêve est grandiose (« du foyer à la nation ») mais froid."
},
{
"titre": "V4 — Décider juste, du trio à la toile (4 sections + Trancher)",
"fidelite": 8,
"ockham": 8,
"faisabilite": 8,
"reve": 7,
"commentaire": "La plus livrable et la seule qui pense vraiment au non-technicien à l'entrée : gabarits d'onboarding qui TRADUISENT (« qui doit être d'accord ? » au lieu de « corpus électoral »), 3 écrans, première décision « Adoptez votre Pacte » — le premier usage est le tutoriel, testé hors communauté Ğ1. Le Pacte-comme-document-voté est l'idée la plus élégante des quatre : les réglages ne sont plus une page de settings mais l'usage même du produit, et la méta-gouvernance cesse d'être décorative. Rasoir appliqué à l'outil lui-même (4 sections au lieu de 6, boîte à outils fondue dans le flux, budget 400 lignes/page) et phasage jour1/v2.1/v2.2 explicite avec diff de migration YAML : c'est la seule vision qui ressemble à un plan exécutable. Retrouvailles Ğ1 les plus précises (packs YAML vérifiés par diff, inertie décorative corrigée). En retrait sur le rêve : ton d'ingénieur, et le gradient des concernés (observateur < concerné < lié < garant de V1) y est moins riche ; l'inclusion par graphe y est plus sommaire que V3."
}
],
[
{
"titre": "V1 — La grammaire générative (6 primitives)",
"fidelite": 9,
"ockham": 6,
"faisabilite": 6,
"reve": 9,
"commentaire": "Théoriquement la plus rigoureuse : le pliage « mandat = décision qui crée du pouvoir, protocole = décision sur les décisions, clause = décision qui reste vraie » est réellement génératif — consentement, advice, JM, élection sans candidat, liquide, référendum sont dérivés par composition de gestes, pas énumérés. Ostrom est mobilisé avec précision (frontières calculables, emboîtement, objection d'oubli SUSPENSIVE — la contestation des frontières prime sur le fond, c'est du vrai design institutionnel). Révocation protocolisée à la création et tripwires définis AVANT exécution : de vrais mécanismes, pas des cases. Mais 6 primitives + 4 effets + gestes composables = noyau élégant pour le théoricien, lourd à incarner ; la délégation liquide native et Q0 plein-texte gonflent le jour 1. Le risque théorique propre : la grammaire fuit dans l'UI malgré l'avertissement."
},
{
"titre": "V2 — Le compagnon quotidien (Fil/Puits/Mémoire)",
"fidelite": 8,
"ockham": 9,
"faisabilite": 7,
"reve": 7,
"commentaire": "Le rasoir comme mécanique et non comme slogan : escalade par exception (l'objection est LE geste universel de montée en cran — individuel → consultation → vote, très propre théoriquement), et surtout la boucle apprenante — mandats qui émergent de la pratique (5 traces → réclame un mandat), protocoles inutilisés élagués, système qui se simplifie lui-même : c'est la contribution la plus originale en théorie de la gouvernance adaptative. Mémoire/statistiques d'autonomie rend la démocratie mesurable. Faiblesse de fondation : l'inclusion par croisement de TAGS est un fondement de légitimité flou (qui vote = similarité sémantique ?) — contestable, contrairement aux corpus calculables de V1 ou au graphe de V3 ; et le silence-vaut-accord porte trop de poids à l'échelle. Révocation réelle mais moins outillée (pas de tripwires ni d'observatoire d'indicateurs)."
},
{
"titre": "V3 — La légitimité calculée (graphe d'attaches + sceau)",
"fidelite": 8,
"ockham": 5,
"faisabilite": 5,
"reve": 9,
"commentaire": "La meilleure théorie de la LÉGITIMITÉ des quatre : le sceau comme enregistrement vérifiable {couverture d'information, T/W, seuil, objections, conformité} avec la couverture d'information en condition DURE (« la légèreté sans l'information n'est pas légère, elle est illégitime » — la phrase clé du lot), la dérogation asymétrique (alourdir libre, alléger consenti et inscrit), l'escalade automatique par ratio de concernement qui rend la subsidiarité honnête, et l'Observatoire où la dérive d'indicateur ROUVRE l'acte — évaluation et révocation comme moments normaux du cycle. Mais le prix est exorbitant : 8 entités, graphe d'attaches (usages, territoires, signatures) à entretenir avec cold-start reconnu (« sceau dégradé » en phase déclarative = la légitimité calculée est fausse au démarrage, précisément quand la confiance se joue), protocoles opérationnels dans le scope. La moins Ockham, la moins livrable en une refonte."
},
{
"titre": "V4 — Décider juste (4 sections + Pacte)",
"fidelite": 9,
"ockham": 8,
"faisabilite": 8,
"reve": 7,
"commentaire": "La méta-gouvernance la plus aboutie OPÉRATIONNELLEMENT : le Pacte — les réglages du collectif SONT un document sous vote permanent, la clause d'inertie protégée par l'inertie maximale, « modifier un réglage = proposer une version = voter » — c'est la seule vision où l'auto-référence cesse d'être un discours pour devenir le chemin ordinaire du produit. Révocation réelle et concrète (poignée « revenir sur X » pré-remplie avec l'inertie du protocole d'origine sur TOUTE décision adoptée), revoyure obligatoire sur l'irréversible, R-Urgence avec ratification chaînée automatique, plancher d'inclusion non restrictible (anti-exclusion par construction). Générativité par énumération plutôt que par composition — couvre le même espace que V1 mais sans en démontrer la clôture. Phasage jour1/v2.1/v2.2 et migration YAML avec diff : la plus livrable. Rêve plus sobre — pragmatique assumé."
}
],
[
{
"titre": "Le Puits : une grammaire générative de la décision (6 primitives)",
"fidelite": 9,
"ockham": 6,
"faisabilite": 5,
"reve": 9,
"commentaire": "Le modèle le plus complet intellectuellement : le pliage des 4 effets (acte/norme/pouvoir/règle) unifie vraiment mandats, clauses et protocoles, et l'Épreuve du réel (tripwires définis AVANT exécution, revoyure, cimetière des révoquées) est la meilleure réponse à l'évaluation-révocation. Mais zéro phasage : délégation liquide native + Sanctuaire + sous-toiles + 10 écrans + 6 sections jour 1 = indéliverable en une refonte. Le noyau à 6 primitives est génératif sur le papier mais son vocabulaire d'interface (Le Vivant, Les Pouvoirs, L'Atelier) exige un glossaire — le risque d'abstraction que la vision liste elle-même est réel. Migration Ğ1 bien pensée (YAML + 2e org peuplée comme test permanent de marque blanche : idée à voler)."
},
{
"titre": "Le compagnon de toutes les décisions (3 espaces, pivot Décision)",
"fidelite": 9,
"ockham": 9,
"faisabilite": 8,
"reve": 7,
"commentaire": "La plus fidèle au cœur de l'intention (les cent décisions quotidiennes) et l'audit de code le plus profond et vérifiable : divergence engine/threshold.py vs routers/votes.py, 51 vs 59 items, méta-gouvernance = PUT non protégé, ComTech jamais seedé — cette vision a réellement lu la maquette. Modèle pivot + spécialisations-vues = migration naturelle des machines à états dupliquées ; IA à 3 espaces = la plus navigable ; le système qui s'élague lui-même (mandat sans trace → revue, protocole inutilisé → suppression) est de l'Ockham génératif rare. Faiblesse produit : l'inclusion par croisement de tags libres est le maillon flou du modèle de données (similarité ≠ impact), et le pitch 'compagnon-habitude' fait moins rêver que 'la démocratie qui n'a jamais existé'. Valeur solo jour 1 = vraie parade au démarrage à froid."
},
{
"titre": "La légitimité calculée, du foyer à la nation (graphe d'attaches + sceau)",
"fidelite": 8,
"ockham": 5,
"faisabilite": 4,
"reve": 8,
"commentaire": "Le graphe d'attaches (membre-de/titulaire-de/usager-de/résident-de/signataire-de) est la réponse la plus rigoureuse à 'identifier automatiquement les impactés', et l'escalade par concernement massif est excellente. Mais c'est la vision la moins livrable FINIE : le démarrage à froid du graphe est rédhibitoire (sans attaches déclarées, cercle d'impact faux, donc promesse centrale cassée dès le jour 1), et le sceau de légitimité exige le tracking de couverture d'information — donc toute l'infra de notifications — comme prérequis du concept central. 8 entités + escalier de gravité + protocoles opérationnels + fédération fractale = la machinerie la plus lourde, en contradiction avec son propre discours Ockham. Le sceau reste une idée forte à greffer en version dégradée (niveau de preuve honnête)."
},
{
"titre": "Décider juste, du trio à la toile (4 sections + Trancher, Pacte)",
"fidelite": 8,
"ockham": 8,
"faisabilite": 9,
"reve": 7,
"commentaire": "La seule vision qui livre un OUTIL FINI : phasage jour1/v2.1/v2.2 explicite, diff automatisé seed.py→packs YAML avant suppression, unification de la formule AVANT tout écran de vote (le bug latent le plus dangereux, correctement identifié), contrat DataAdapter avec tests de conformité, budget 400 lignes/page contre le syndrome protocols/index.vue, étiquetage honnête de la crypto. Le Pacte — les réglages du collectif EN document sous vote permanent, clause d'inertie protégée par l'inertie maximale — est la meilleure idée produit des quatre : méta-gouvernance enfin concrète ET tutoriel d'onboarding ('Adoptez votre Pacte'). Rasoir appliqué à la nav elle-même (4 sections, Sanctuaire = badge-propriété, toolbox dissoute). Retraits : l'épreuve du réel est plus mince que la vision 1 (revoyure présente mais sans tripwires/indicateurs), le graphe d'impact via Ressources demande quand même une déclaration initiale, et le pitch est le moins lyrique."
}
]
]
},
"workflowProgress": [
{
"type": "workflow_phase",
"index": 1,
"title": "Comprendre"
},
{
"type": "workflow_phase",
"index": 2,
"title": "Visions"
},
{
"type": "workflow_phase",
"index": 3,
"title": "Jugement"
},
{
"type": "workflow_phase",
"index": 4,
"title": "Synthèse"
},
{
"type": "workflow_agent",
"index": 1,
"label": "lire:frontend-ux",
"phaseIndex": 1,
"phaseTitle": "Comprendre",
"agentId": "ada99a1d33a1d136c",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408018042,
"queuedAt": 1786408018014,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "Le frontend (16 pages, ~21 600 lignes, pas de dossier layou…",
"promptPreview": "Tu cartographies le frontend d'une maquette Nuxt 4 appelée libreDecision (outil de gouvernance collective, UI en français). Racine: /home/yvv/Documents/PROD/DEV/libreDecision/frontend.\nLis en profondeur: app/pages/ (toutes les pages), app/components/ (survole chaque dossier: auth, common, decisions, documents, mandates, protocols, sanctuary, toolbox, votes), app/stores/ (les 8 stores Pinia), app/c…",
"lastProgressAt": 1786408825768,
"tokens": 157125,
"toolCalls": 34,
"durationMs": 807725,
"resultPreview": "{\"summary\":\"Le frontend (16 pages, ~21 600 lignes, pas de dossier layouts/ : tout le shell vit dans app.vue, 740 l.) est une SPA Nuxt 4 avec sidebar 6 sections : Décisions, Documents, Mandats, Protocoles, Outils, Sanctuaire. Le header porte le WorkspaceSelector (organisations, header X-Organization injecté par useApi, refetch des 4 stores au changement) et le MoodSwitcher (4 ambiances via @yvv/nux…"
},
{
"type": "workflow_agent",
"index": 2,
"label": "lire:backend-domaine",
"phaseIndex": 1,
"phaseTitle": "Comprendre",
"agentId": "ad1ed3d42887a0f29",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408018045,
"queuedAt": 1786408018014,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "Backend FastAPI async (SQLAlchemy 2, SQLite/PG, Alembic) or…",
"promptPreview": "Tu cartographies le backend FastAPI d'une maquette appelée libreDecision (gouvernance collective). Racine: /home/yvv/Documents/PROD/DEV/libreDecision/backend.\nLis en profondeur: app/models/ (14 tables: decision, document, group, mandate, organization, protocol, qualification, sanctuary, user, vote, cache), app/routers/, app/engine/ (mode_params, nuanced_vote, qualifier, smith_threshold, techcomm_t…",
"lastProgressAt": 1786408556146,
"tokens": 119188,
"toolCalls": 23,
"durationMs": 538100,
"resultPreview": "{\"summary\":\"Backend FastAPI async (SQLAlchemy 2, SQLite/PG, Alembic) organisé en 4 couches : models (19 tables), engine (calcul pur, testé), services (orchestration), routers (12 modules REST + WebSocket).\\n\\nMODÈLE DE DOMAINE. L'identité est un DuniterIdentity (adresse SS58, wot_status, flags is_smith/is_techcomm) avec sessions bearer hashées. Le workspace est l'Organization (slug, org_type, is_t…"
},
{
"type": "workflow_agent",
"index": 3,
"label": "lire:contenus-seeds",
"phaseIndex": 1,
"phaseTitle": "Comprendre",
"agentId": "ac4dec13083b76353",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408018046,
"queuedAt": 1786408018014,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "La maquette libreDecision embarque un corpus Ğ1 réel et den…",
"promptPreview": "Tu inventories les CONTENUS et CONTEXTES réels d'une maquette de gouvernance collective libreDecision, pour la communauté Duniter/Ğ1 (monnaie libre). Racine: /home/yvv/Documents/PROD/DEV/libreDecision.\nLis: backend/seed.py EN ENTIER (licence Ğ1 v0.3.0, Engagement Certification ~33 items, Forgeron ~51 items, Runtime Upgrade, FormulaConfigs, VotingProtocols, personnes: 1000i100, Natha, Pini, Yvv, el…",
"lastProgressAt": 1786408459467,
"tokens": 90776,
"toolCalls": 11,
"durationMs": 441420,
"resultPreview": "{\"summary\":\"La maquette libreDecision embarque un corpus Ğ1 réel et dense, entièrement en français, réparti entre backend/seed.py (source de vérité des contenus), research_duniter_forum.md (matière brute forum) et docs/content (8 docs user + 11 docs dev).\\n\\nLe seed crée : 2 organisations (« Duniter G1 » slug duniter-g1, « Axiom Team » slug axiom-team) ; 7 FormulaConfigs nommées (« Standard Licenc…"
},
{
"type": "workflow_agent",
"index": 4,
"label": "lire:design-system",
"phaseIndex": 1,
"phaseTitle": "Comprendre",
"agentId": "a15c11f99a48a6141",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408018047,
"queuedAt": 1786408018014,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "Le design system de libreDecision (frontend Nuxt 4, SSR off…",
"promptPreview": "Tu cartographies le SYSTÈME DE DESIGN d'une app Nuxt 4 libreDecision. Racine: /home/yvv/Documents/PROD/DEV/libreDecision/frontend.\nLis: app/assets/css/ (moods.css et tout autre css), app.vue (sceau hexagramme 井 .app-seal), nuxt.config.ts, package.json (note la dépendance @yvv/nuxt-base — trouve-la dans node_modules/@yvv/nuxt-base et lis son contenu: layer Nuxt avec mécanisme d'ambiances useMood), …",
"lastProgressAt": 1786408292265,
"tokens": 45970,
"toolCalls": 23,
"durationMs": 274218,
"resultPreview": "{\"summary\":\"Le design system de libreDecision (frontend Nuxt 4, SSR off, port 3002) repose sur un seul fichier de tokens, app/assets/css/moods.css, et un mécanisme d'ambiances externalisé dans le layer @yvv/nuxt-base (dépendance git v0.1.0, node_modules/@yvv/nuxt-base — 4 fichiers seulement : nuxt.config.ts vide, package.json, README, app/composables/useMood.ts).\\n\\nQuatre moods appliqués via clas…"
},
{
"type": "workflow_agent",
"index": 5,
"label": "vision:theoricien",
"phaseIndex": 2,
"phaseTitle": "Visions",
"agentId": "aa860b5363b4aceb9",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408825804,
"queuedAt": 1786408825778,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "libreDecision v2 — Le Puits : une grammaire générative de l…",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786409173728,
"tokens": 58319,
"toolCalls": 2,
"durationMs": 347924,
"resultPreview": "{\"titre\":\"libreDecision v2 — Le Puits : une grammaire générative de la décision (6 primitives pour toutes les gouvernances)\",\"pitch\":\"On change de ville, on ne change pas de puits (hexagramme 48) : libreDecision fait de chaque décision — du choix d'un café entre trois amis au budget d'investissement d'une population — un objet vivant qui sait qui il engage, comment il doit se prendre, et quand il …"
},
{
"type": "workflow_agent",
"index": 6,
"label": "vision:quotidien",
"phaseIndex": 2,
"phaseTitle": "Visions",
"agentId": "afd47ac8f9951a1f1",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408825805,
"queuedAt": 1786408825778,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "Trois espaces, pas seize pages. Le shell sort enfin de app.…",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786409085102,
"tokens": 44329,
"toolCalls": 1,
"durationMs": 259297,
"resultPreview": "{\"architecture_info\":\"Trois espaces, pas seize pages. Le shell sort enfin de app.vue vers layouts/ ; le header garde le sélecteur de collectif (WorkspaceSelector + X-Organization conservés) et le MoodSwitcher ; recherche omniprésente Cmd+K ; chaque décision a une URL permanente de la capture à la révocation.\\n\\n1. AUJOURD'HUI (/) — l'écran du quotidien, le seul qu'on ouvre chaque jour : la barre d…"
},
{
"type": "workflow_agent",
"index": 7,
"label": "vision:echelle",
"phaseIndex": 2,
"phaseTitle": "Visions",
"agentId": "a33a9df9d0474ea81",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408825806,
"queuedAt": 1786408825779,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "Le Puits — libreDecision v2 : la légitimité calculée, du fo…",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786409074613,
"tokens": 44314,
"toolCalls": 1,
"durationMs": 248807,
"resultPreview": "{\"titre\":\"Le Puits — libreDecision v2 : la légitimité calculée, du foyer à la nation\",\"pitch\":\"Chaque décision porte en elle la carte exacte de ceux qu'elle touche : libreDecision la calcule, convoque le plus petit cercle suffisant, et délivre un sceau de légitimité vérifiable — avec les mêmes règles pour un foyer de 3 personnes et une toile de confiance de plusieurs millions. Plus besoin de devin…"
},
{
"type": "workflow_agent",
"index": 8,
"label": "vision:produit",
"phaseIndex": 2,
"phaseTitle": "Visions",
"agentId": "aeb7195e1e07686eb",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786408825806,
"queuedAt": 1786408825780,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "**Navigation définitive — 4 sections + 1 geste.** Le shell …",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786409105879,
"tokens": 50736,
"toolCalls": 2,
"durationMs": 280073,
"resultPreview": "{\"architecture_info\":\"**Navigation définitive — 4 sections + 1 geste.** Le shell (enfin sorti de app.vue vers layouts/default.vue) porte : le sélecteur de collectif (WorkspaceSelector conservé, X-Organization), le MoodSwitcher, et un bouton « Trancher » toujours visible (header desktop, FAB mobile). Sidebar 4 entrées :\\n\\n1. **Fil** (`/`) — l'accueil. Ce qui M'attend d'abord (votes ouverts avec ja…"
},
{
"type": "workflow_agent",
"index": 9,
"label": "juge:1",
"phaseIndex": 3,
"phaseTitle": "Jugement",
"agentId": "a55185c023a24aaf3",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786409173759,
"queuedAt": 1786409173732,
"attempt": 1,
"lastToolName": "StructuredOutput",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786409303610,
"tokens": 50418,
"toolCalls": 1,
"durationMs": 129851,
"resultPreview": "{\"scores\":[{\"titre\":\"V1 — La grammaire générative (6 primitives)\",\"fidelite\":9,\"ockham\":6,\"faisabilite\":5,\"reve\":8,\"commentaire\":\"Lentille utilisateur final : la plus complète intellectuellement (Q0 « est-ce déjà décidé ? », cercles auditables, objection d'oubli suspensive, révocation protocolisée dès la création — tout y est), mais le membre de l'association de 12 doit traverser « tension, périmè…"
},
{
"type": "workflow_agent",
"index": 10,
"label": "juge:2",
"phaseIndex": 3,
"phaseTitle": "Jugement",
"agentId": "adb229f6b577f0f12",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786409173761,
"queuedAt": 1786409173733,
"attempt": 1,
"lastToolName": "StructuredOutput",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786409373213,
"tokens": 52331,
"toolCalls": 3,
"durationMs": 199452,
"resultPreview": "{\"scores\":[{\"titre\":\"V1 — La grammaire générative (6 primitives)\",\"fidelite\":9,\"ockham\":6,\"faisabilite\":6,\"reve\":9,\"commentaire\":\"Théoriquement la plus rigoureuse : le pliage « mandat = décision qui crée du pouvoir, protocole = décision sur les décisions, clause = décision qui reste vraie » est réellement génératif — consentement, advice, JM, élection sans candidat, liquide, référendum sont dérivé…"
},
{
"type": "workflow_agent",
"index": 11,
"label": "juge:3",
"phaseIndex": 3,
"phaseTitle": "Jugement",
"agentId": "ae92ec5231944066b",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786409173762,
"queuedAt": 1786409173733,
"attempt": 1,
"lastToolName": "StructuredOutput",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786409390632,
"tokens": 52270,
"toolCalls": 4,
"durationMs": 216870,
"resultPreview": "{\"scores\":[{\"titre\":\"Le Puits : une grammaire générative de la décision (6 primitives)\",\"fidelite\":9,\"ockham\":6,\"faisabilite\":5,\"reve\":9,\"commentaire\":\"Le modèle le plus complet intellectuellement : le pliage des 4 effets (acte/norme/pouvoir/règle) unifie vraiment mandats, clauses et protocoles, et l'Épreuve du réel (tripwires définis AVANT exécution, revoyure, cimetière des révoquées) est la meil…"
},
{
"type": "workflow_agent",
"index": 12,
"label": "synthese:blueprint",
"phaseIndex": 4,
"phaseTitle": "Synthèse",
"agentId": "a23137e9888693ced",
"model": "claude-fable-5",
"state": "done",
"startedAt": 1786409390664,
"queuedAt": 1786409390641,
"attempt": 1,
"lastToolName": "StructuredOutput",
"lastToolSummary": "libreDecision",
"promptPreview": "INTENTION DU COMMANDITAIRE (Yvv) pour libreDecision v2 — refonte de zéro:\n\"Le propos est que n'importe quel collectif, du plus structuré au plus informel, puisse aller le plus loin possible dans l'auto-décision de ses membres. Pareil pour l'échelle: d'une organisation à 3 personnes à une population entière. L'outil doit donner la capacité d'une démocratie qui n'a jamais existé.\nTout le monde prend…",
"lastProgressAt": 1786410285801,
"tokens": 90923,
"toolCalls": 12,
"durationMs": 895137,
"resultPreview": "{\"nom_produit\":\"libreDecision\",\"manifeste\":\"Tout le monde décide, tout le temps. libreDecision attrape chaque décision en une phrase et répond en dix secondes : décide seul et trace-le, décide sous mandat, demande leur avis, ou porte-la au collectif — avec le bon cercle, la bonne modalité, le bon seuil, jamais plus lourd que l'enjeu. Les personnes touchées sont incluses par calcul, chacune voit po…"
}
],
"totalTokens": 856699,
"totalToolCalls": 117
}