carbon-docs

Par crbnos · carbon

Créez, modifiez ou étendez le site de documentation Carbon dans `docs` (une application Fumadocs + Next.js déjà compilée). À utiliser dès lors que vous créez ou modifiez de la documentation destinée aux lecteurs pour Carbon : chapitres du Guide éditorial, pages de Référence/entité, l'architecture d'information des docs, ou les demandes de type « documentez cette fonctionnalité » — tout ce qui est destiné au site de documentation. Couvre le workflow de rédaction ancré dans les sources, l'architecture du Guide basée sur les flux, les vrais composants MDX pour chaque surface, le style maison « papier chaud », et la boucle de vérification du build. Se déclenche même si l'utilisateur ne dit pas « docs » mais souhaite clairement du contenu écrit explicatif, destiné aux lecteurs, sur le fonctionnement de Carbon.

npx skills add https://github.com/crbnos/carbon --skill carbon-docs

Documentation Carbon

docs est un site de documentation construit, avec opinions — Fumadocs + Next.js (React 19), light-only, esthétique papier-chaud. Il n'est plus généré ; il existe et livre du contenu. Ce skill explique comment ajouter ou modifier la documentation dans ce système, en respectant son style maison, ancré dans du vrai code Carbon.

Annoncez au démarrage: "Using the carbon-docs skill — authoring docs for {topic}."

La plus grosse erreur est d'écrire une prose générique et plausible. Le comportement de Carbon est spécifique et souvent contre-intuitif (WIP est un solde GL et non une table ; payment est un champ et non une entité ; les frais généraux ne sont pas absorbés ; la cession d'immobilisation est scrapping-only). Chaque affirmation est ancrée dans la source. Voir la directive première ci-dessous — elle prime sur tout.

Ce qu'est Carbon : un système de fabrication — ERP (le bureau) + MES (l'atelier), une plateforme sur un seul modèle de données. Academy n'est pas un troisième pilier produit : elle héberge juste des vidéos de formation, pas une application SaaS qu'un client achète. Ne présentez jamais Carbon comme « ERP, MES et formation/Academy » ; le site, la méta et la copie marketing restent ERP + MES. (L'app academy peut figurer dans un listing architecture/monorepo — c'est ok ; décrivez-la comme de l'hébergement de vidéos, pas comme un pilier.)

La directive première — ancrer tout dans la source

La source de vérité absolue est le code source réel + les DERNIÈRES migrations base de données (packages/database/supabase/migrations/, les plus récentes par timestamp) — PAS la connaissance générale ERP/CMMS, PAS .ai/rules/ seul (c'est souvent stale).

  • Vérifiez avant d'écrire. Chaque entité, valeur d'enum de statut, et transition nommées dans la doc doivent exister dans le code réel. Confirmez les chaînes exactes ("To Ship and Invoice", "Fully Depreciated"), les actions qui les pilotent (fonctions de service, routes, edge functions dans packages/database/supabase/functions/), et ce qui les poste/gère (par ex. companySettings.accountingEnabled).
  • Lisez la migration la plus récente, pas la première. Les timestamps les ordonnent ; une refonte 2026 peut avoir reconstruit un sous-système que le cache décrit encore de l'ancienne façon.
  • Documentez uniquement les vraies features ACTIVES. Omettez les placeholders / inactifs / pas-encore-livrés (par ex. les entrées du registre d'intégration avec active: false comme QuickBooks/Sage/Zapier). Ne les surfacez pas.
  • Quand le code et le cache divergent, le code gagne — et notez le décalage.
  • Méthode : dispatcher un sous-agent de recherche par feature → retourner des faits vérifiés avec références file:line → puis écrire. C'est ainsi que chaque flux du Guide a été construit. Ne le sautez pas pour rien de non-trivial.

Trois surfaces (savez laquelle vous touchez)

Surface Chemin / route Ce que c'est Écrit ?
Guides content/guides/*.mdx/guides Tours narratives éditoriales, groupées en flux. Deuxième personne, avec opinions, illustrées. Le parcours + le « pourquoi ». MDX écrit à la main
Référence content/docs/**/*.mdx/docs Une page par entité/concept. Scannables : tableaux, cartes, lignes de champs. Le « quoi ». MDX écrit à la main
Référence API app/api-reference/[module]/[resource] Docs d'endpoint PostgREST, généré au build à partir du swagger. Généré — NE PAS éditer à la main. Éditez scripts/generate-api-docs.mjs ou le schéma swagger.

Entreliez les surfaces et flux : un Guide pointe vers la Référence pour les détails ; la Référence pointe vers le Guide pour l'histoire. (Les chapitres du Guide ont eu 12 liens inter-flux — l'entrelacement est attendu, pas optionnel.)

Flux d'auteur (chaque changement)

  1. Recherche (ancrée). Un sous-agent vérifie la feature contre la source + migrations récentes. Obtenez les noms exacts table/colonne/enum/transition + file:line. Signalez ce qu'une description générique raterait.
  2. Choisissez la surface + le placement. Flux de Guide + frontmatter, ou dossier Référence + ordre meta.json.
  3. Écrivez dans la voix maison avec les vrais composants de la surface (ci-dessous). Commencez par un exemple concret.
  4. Vérifiez — contre le serveur dev en exécution de l'utilisateur, en lecture seule. Ils ont généralement pnpm --filter docs dev lancé. Jamais pkill/restart, next build, ou rm .next dessous — vérifiez en récupérant les pages :
    cd docs
    pnpm exec fumadocs-mdx                 # regen .source si une frontmatter/content change n'a pas HMR
    curl -sS -X GET http://localhost:3002/docs/<slug> | grep -o "your new heading"   # confirmer qu'il s'est affiché

    Un pnpm --filter docs build vert (✓ Generating static pages N/N) est l'étalon-or — mais seulement dans un checkout propre / quand aucun serveur dev n'est en cours. tsc est bruyant (un skew React 18/19 @types que next.config ignore) — filtrez vos propres fichiers des erreurs plutôt que d'attendre zéro.

Guides — l'architecture de flux

Frontmatter (schéma source.config.ts) :

---
title: From quote to order
description: An RFQ becomes a quote; an accepted quote becomes a sales order.
label: "(I)"          # marqueur d'affichage, chiffre romain, par-flux
index: 0              # ordre DANS le flux (0,1,2…)
flow: quote-to-cash   # id flux (omis → défaut "make-to-order")
flowName: Quote to cash   # libellé onglet flux
flowIndex: 1          # ordre du flux dans la subnav (0 = premier)
---
  • Les chapitres sont triés par (flowIndex, index). La subnav est un commutateur de flux ; la barre latérale + sélecteur mobile + « lire suivant » sont limités au flux actif. Les 5 chapitres d'origine (order/build/plan/floor/ship) ne portent pas de champs flow et se replient dans make-to-order (flowIndex 0) via les défauts.
  • Ajoutez un chapitre à un flux : même flow/flowName/flowIndex, index suivant + label.
  • Ajoutez un flux : nouveau flowIndex + flowName ; ses chapitres commencent à index: 0, label: "(I)".
  • Tous les corps de chapitre s'affichent côté serveur sur chaque page (le lecteur s'estompe, pas de nav de route), ainsi les liens vers /guides/<slug> se résolvent. Pas de code fences dans les guides (prose + composants seulement).

Composants (components/editorial/mdx.tsx) :

  • <Figure illustration="flow-overview" caption="…" /> — SVG du registre. illustration DOIT être une vraie clé de components/editorial/illustrations.tsx (sinon elle s'affiche silencieusement comme rien). Clés valides : flow-overview, order-split, bom-tree, demand-forecast, planning-engine, shopfloor-loop, eight-d, traceability-graph, method-types, kit-vs-subassembly, reorder-policy, outside-processing, mes-station, issue-workflow, schedule-board, get-method, conversion-factor, opportunity-thread, cash-cycle, rfq-fanout, receive-bill-axes, wip-inflow, wip-to-cogs, depreciation-curve, asset-exit. Pour tout sans clé appropriée, utilisez <Screenshot> à la place — ne créez pas de clés.
  • <Screenshot label="Sales order dashboard" caption="…" ratio="wide|tall|square" /> — un emplacement pour une vraie capture Carbon. Utilisez-le quand le lecteur doit voir l'UI réelle (dashboard, un formulaire/champ, statut, board, où cliquer) — pas comme décoration. Libellisez l'écran réel, actuel + l'état avec précision (vérifiez qu'il existe) pour qu'une vraie capture puisse y tomber directement et la doc reste synchro avec le Carbon UI en direct. ratio="wide" par défaut.
  • <Callout tone="neutral|blue|green|amber" badge="WHY BATCH" title="…">body</Callout> — le cheval de trait. Utilisez-le pour porter la vérité Carbon-spécifique qu'une description générique rate. Tons : blue = explicatif « pourquoi », green = bon à savoir/résultat, amber = mise en garde/contraste, neutral = définitionnel.
  • <Divider /> — ferme un chapitre avant sa ligne de conclusion.
  • <Term>make to order</Term> — terme de glossaire inline : trait pointillé ; clic/tap ouvre un popover avec une définition d'une ligne ancrée + un lien optionnel « En savoir plus ». Même composant sur les deux surfaces ; les définitions vivent dans docs/lib/glossary.ts. Voir « Entrelacement & le glossaire » ci-dessous.

Chaque titre ## devient une entrée de barre latérale — structurez les chapitres comme 3–5 sections ##.

Référence — pages d'entité

  • Frontmatter : title + description seulement.
  • Nav = tableaux pages de meta.json (ordonnés). Dossiers : content/docs/{reference,platform,integrate}/. Ordre racine dans content/docs/meta.json ; ordre d'un dossier + titre barre latérale dans son propre meta.json ({ "title": "Product reference", "defaultOpen": true, "pages": [...] }). Ajoutez une page → ajoutez son slug aux pages du dossier. Ne listez pas index dans pages — fumadocs traite index.mdx comme l'index du dossier et le nav l'affiche comme "Overview" ; le lister duplique le titre comme un frère. Les intégrations sont leur propre section top-level (content/docs/integrations/) groupées par catégorie — documentez seulement les intégrations active (omettez les placeholders active: false + les commentées).
  • Composants (components/editorial/reference-components.tsx + components/mdx.tsx) :
    • <Callout type="info|note|warn|warning|error|success|tip" title?>…</Callout> — type → badge+tone (info/note→NOTE/blue, warn/warning/error→HEADS UP/amber, success/tip→GOOD TO KNOW/green). Notez que c'est une API Callout différente de celle des Guides (type vs tone+badge).
    • <Cards><Card title href icon?>…</Card></Cards> — grille de cartes-lien (navigation inter-surfaces).
    • <EnvVars><EnvVar name type? default? required?>…</EnvVar></EnvVars> — lignes de champ/paramètre. La page des env-vars les utilise ; pour une référence de champ d'entité préférez <FieldTable> (ci-dessous).
    • <FieldTable><Field name type? required?>desc</Field></FieldTable> (components/editorial/field-table.tsx) — la référence accordion champ/paramètre, la prise papier-chaud sur le TypeTable de Fumadocs. Utilisez-la pour une table de forme | Field | Type | Description | (champs item/job/line, routing, work-center, champs de politique reorder/shelf-life, paramètres d'intégration). type = le token de type (omis quand la table n'a pas de colonne type) ; required seulement quand la source le marque ; l'enfant est la description comme MDX (ainsi `code` inline, italiques, <Term> s'affichent — c'est pour ça que c'est des enfants, pas une prop type={{}}) Enregistré dans les deux mdx.tsx et editorial/mdx.tsx.
    • <StatusFlow><Status name accent? branch? terminal?>meaning</Status></StatusFlow> (components/editorial/status-flow.tsx) — un widget interactif de cycle de vie (pilules sélectionnables → un Callout de détail montrant le sens) qui remplace une table | Status | Meaning | linéaire. Enfants en ordre source (cycle de vie) ; les sens sont MDX. Drapeaux : accent = le seul jalon pivot (≤1, optionnel) ; branch = une pause temporaire retournable (Paused, On Hold, Needs Approval) ; terminal = une sortie hors-chemin (Cancelled, Voided, Lost, Expired). Utilisez-le SEULEMENT pour un cycle de vie linéaire — une matrice de comparaison 2-axes (par ex. factures vente-vs-achat) ou une petite liste enum reste un tableau markdown.
    • <PlanBadge plan="Business" /> — signale une feature payante. Gate page entière → définir plan: Business en frontmatter ; s'affiche comme une petite pilule "Paid" inline avec le titre de la page (le libellé est fixé à "Paid" ; la valeur plan nourrit seulement le tooltip au survol + la copie bannière). Gate section → déposer <PlanBadge> en corps. Features gatées = packages/ee/src/plan.ts. Ne badgez pas les libres (email, exchange-rates).
    • Les pages plan-gatées reçoivent aussi une barre d'annonce pleine largeur (components/plan-banner-bar.tsx, PlanBannerBar) affichée par la layout des docs (app/docs/[[...slug]]/layout construit une carte url→plan à partir du frontmatter plan et la passe) — sticky sous l'en-tête, couvrant la zone contenu. Ajouter le frontmatter plan: Business suffit ; le badge et la barre s'allument tous les deux. Ne posez pas à la main une bannière en MDX.
    • Modèle de licence — ayez ceci juste, c'était faux avant. Voir docs/content/docs/platform/licensing.mdx (la page canonique). Éditions (packages/utils/src/types.ts enum Edition) : Community (auto-hébergé, noyau ouvert AGPLv3), Enterprise (auto-hébergé + licence commerciale), Cloud (géré). Features EE = code sous packages/ee ou tout fichier .ee → nécessitent une licence commerciale per la LICENSE du repo.
      • Carbon Cloud = le SaaS hébergé à https://app.carbon.ms — PAS le déploiement /docs/platform/.... Les recettes auto-hébergement (Docker avec Caddy, AWS avec SST) vivent sous docs/content/docs/platform/self-hosting/.
      • Plans Cloud = Starter et Business seulement. L'enum Plan a aussi Partner, mais Partner est interne-only — ne le mentionnez jamais dans la doc destinée aux lecteurs. N'écrivez pas « plans Business et Partner ».
      • N'écrivez jamais « l'auto-hébergement n'est pas plan-gatée ». La gate runtime est Cloud-only (packages/ee/src/plan.server.ts retourne tôt quand CarbonEdition !== Edition.Cloud), mais la licence gouverne toujours : l'auto-hébergement tourne en mode community ; les features Enterprise/EE nécessitent une licence commerciale. Présentez-le comme une frontière de licence, pas un verrouillage technique — les features ne sont pas « désactivées » en Community.
    • <Steps>/<Step>, <Tabs>/<Tab> (fumadocs-ui), tableaux markdown, et code fences (panneau foncé).
    • <Term id?>…</Term> — terme de glossaire inline (trait pointillé → popover de définition). Le même composant que le Guide ; voir « Entrelacement & le glossaire » ci-dessous.
  • La voix est plus technique/scannable que les Guides — champs, contraintes, tableaux — mais nomme quand même le piège et pointe vers le Guide pour la narration.

Voix maison

  • Deuxième personne, concret, narratif. Ancrez dans l'exemple en cours (la commande de 90 robots humanoïdes). « Ouvrez le tableau de bord des commandes de vente. » / « Vous ne construisez pas 90 robots comme un seul travail monolithique. »
  • Citez les vrais noms de statut exactement, entre guillemets : **"To Ship and Invoice"**, **"Posted"**, **"Open"**. Les chaînes de statut vivent sur une entité spécifique — confirmer qu'une valeur appartient à l'en-tête ou la ligne (par ex. "To Ship and Invoice"/"To Invoice" sont salesOrderStatus, PAS l'enum salesOrderLineStatus Ordered/In Progress/Completed) avant de l'attribuer, et énoncez la transition complètement (une commande à "To Ship and Invoice" bascule à "To Invoice" une fois tout expédié mais non facturé — n'implicitez pas qu'elle reste à une valeur jusqu'à fermeture complète).
  • Allez facile sur les tirets cadratins. Empilés, ils se lisent comme un tic — max un par paragraphe, jamais une paire tiret-parenthétique en phrase d'ouverture. Préférez un point ou une virgule ; atteignez le tiret seulement quand il vraiment bat les deux. (« Trop de tirets cadratins » est la note de copie la plus courante de la révision.) S'applique aux chaînes caption= et title= aussi, pas juste la prose du corps.
  • Gardez les noms et chiffres de l'exemple en cours exacts. C'est la commande de vente (ne dérivez pas vers une « commande » simple quand vous instruisez le lecteur) et c'est 90 unités (pas « un robot »). Une fois que vous nommez l'entité et la quantité, restez cohérent chaque fois — la dérive est ce qui rend un tour brouillon.
  • Ancrez chaque « où cliquer ». Quand vous dites au lecteur d'agir dans l'UI, copiez les vrais libellés bouton / modal / champ de la JSX (entre guillemets) et confirmez que la capacité existe exactement sur ce chemin. Une feature qui vit ailleurs n'est pas la même qu'une sur l'écran que vous décrivez — « Carbon divise la commande en trois travaux » était faux : le dialogue "Make to Order""Convert Line to Job" de la ligne de commande de vente crée un travail par clic (la division N-travaux-de-M est un flux séparé bulk-jobs). Vérifiez l'action, pas juste le concept.
  • Les callouts portent la vérité contre-intuitive — la chose que les gens ratent. Le titre est une affirmation, le corps est le pourquoi. (« Les devis sont optionnels — l'opportunité est le fil. »)
  • Expliquez le pourquoi, nommez l'erreur, pointez vers l'étape suivante. Si un paragraphe ne fait aucune de celles-ci, supprimez-le.
  • Entreliez aux coutures naturelles ([make-to-order tour](/guides/order)).
  • Menez, ne libellisez pas. Ne ouvrez pas une page avec un titre générique, répété — pas de ## Introduction sur les chapitres du guide (le titre du chapitre est affiché pour vous) et pas de ## Why it matters sur les pages de référence. Ouvrez avec 1–2 phrases d'introduction substantives, puis allez droit aux vraies sections. Un titre identique sur chaque page est du remplissage. Les pages landing/index sont "Overview", jamais "Introduction".
  • Nommez les choses telles qu'elles sont maintenant. Utilisez le nom actuel d'une feature ; ne narrez jamais l'historique de renommage/suppression (« anciennement item rules », « les storage units avaient l'habitude de… »). Quand un ancien nom et le code divergent, le code gagne.

Entrelacement & le glossaire

Deux mécanismes de liaison — utilisez les deux, délibérément, chaque fois que vous touchez une page. La liaison interne se compose : une page qui lie dehors et glose son jargon vaut plus que la même prose en isolation.

  • Les liens markdown portent la navigation. Liez le nom, inline, aux coutures naturelles ; jamais « cliquez ici ». Un Guide se lie à la Référence pour les champs ; la Référence se relie au Guide pour l'histoire ([make-to-order tour](/guides/order)). Les liens inter-surfaces et inter-flux sont attendus, pas optionnels. Mais liez seulement quand le titre de la destination reprend votre texte d'ancrage. Un saut dur dont la page d'arrivée porte un H1 différent désoriente le lecteur — lier la phrase « quote to cash » à un chapitre intitulé From quote to order a été signalé comme confus. Quand l'ancre est un concept (un nom de flux, une catégorie) plutôt qu'une page littéralement appelée ainsi, glosez-la comme une <Term> (popover de définition + optionnel « En savoir plus » via href) au lieu d'un lien nu — le lecteur obtient le sens sur place et peut quand même naviguer s'il choisit.
  • <Term> porte les définitions. Enveloppez un terme de fabrication/Carbon qu'un lecteur peut rencontrer froid (type de méthode, système de réapprovisionnement, WIP, opération externe, kit/sous-assemblage…) pour qu'un clic donne la glose sans quitter la page.
    • <Term>make to order</Term> slugifie le texte pour trouver l'entrée ; <Term id="make-to-order">made</Term> quand le texte d'affichage diffère du slug.
    • Première occurrence par page seulement — pas chaque instance. Souligner chaque « order » est du bruit.
    • Les définitions sont une source unique de vérité : docs/lib/glossary.ts (slug → { term, definition, href? }). Ajoutez l'entrée là avant d'utiliser un nouveau terme, et ancrez la définition dans la source (la directive première s'applique — valeurs enum exactes, comportement réel). Omettez href quand il n'y a pas encore de page dédiée (le popover affiche quand même la définition) ; le lien « En savoir plus » s'auto-cache quand il pointerait sur la page où vous êtes déjà.
    • Slug inconnu → s'affiche comme texte simple (jamais casse la prose) — une typo échoue proprement, pas bruyamment.

Passe d'enrichissement. Chaque fois que vous créez ou éditez une page, terminez avec une passe de liaison : enrobez le jargon de première occurrence dans <Term>, ajoutez des liens croisés markdown aux coutures, et ajoutez toute entrée glossaire manquante. Le moins cher moyen de relever la connectivité de tout le site.

Design / style

  • Light-only. Palette papier-chaud : page bg #FBFBF9 / #F5F5F2 ; encre #262323 (+ rgba(38,35,35,0.x) pour faible) ; accent #1E84B0 (liens) / #00B0FF (focus/brand) ; hairlines #E7E7E3 / #E3E3DF.
  • Valeurs Tailwind arbitraires inline (text-[15px], bg-[#FBFBF9], border-[#E7E7E3]) — cette app est autonome (PAS @carbon/react, PAS le thème ERP). Correspondez à la densité et aux couleurs du composant environnant ; n'introduisez pas une nouvelle palette.
  • Polices : DM Sans (corps), Fira Code (mono). Callout tone remplissages/bordures : neutral #EFEFEB/#DADAD5, blue #DFF5FF/#A9DAF3, green #E4F8DA/#A8DB91, amber #FFF2D8/#E6CFA3.

Pièges (acquis difficilement)

  • Frontmatter est YAML — ne laissez jamais un deux-points sans guillemets dans une valeur. Une valeur title:/description: contenant : (deux-points-espace) est parsée comme un mapping imbriqué et lance YAMLException: bad indentation of a mapping entry. Soit citez la valeur entière (description: "How it works: the short version.") soit reformulez pour abandonner le deux-points (une virgule/point est généralement mieux). Un mauvais frontmatter 500s le site entier, pas juste cette page — fumadocs charge la collection source entière au chargement du module, le symptôme est chaque page (guides inclus) retournant 500 avec le chemin .mdx offensant dans la pile. Cela mord le plus dur lors d'un balayage em-dash : remplacer un em-dash de description avec un deux-points casse silencieusement YAML. pnpm exec fumadocs-mdx regen NE le détecte PAS (il passe) — le seul contrôle fiable est récupérer une page (n'importe laquelle) et voir 200 vs 500. Quand vous déléguez des édits de prose à des sous-agents, dites-leur explicitement : en frontmatter, n'introduisez jamais un deux-points sans guillemets.
  • Thème Shiki (source.config.tsrehypeCodeOptions.themes) : définissez les deux light et dark au même "github-dark-default". Un theme simple (ou un github-light manquant) casse le build pour tout fichier content/docs avec une code fence (ShikiError: Theme github-light not found). Les guides n'ont pas de fences, donc sont immunisés — utile pour isoler un build rouge à la côté Référence.
  • Regen .source avant typecheck après tout changement frontmatter/schéma (le schéma est cuit dans .source/ au temps de génération).
  • Les clés Figure doivent exister — voir la liste ci-dessus ; une typo s'affiche rien, silencieusement.
  • Bare {…} en MDX est une expression JS. Un token en prose comme {item.id} (par ex. inside une règle message d'exemple) casse le build avec item is not defined. Enrobez tout littéral accolades/tokens en backticks : `{item.id}`.
  • Write blocs sur les fichiers existants — protection naturelle de collision quand une session parallèle co-écrit la doc. Écrivez juste le prochain gap découvert ; ne pausez pour coordonner sauf demandé.
  • curl GET peut 405 dans ce sandbox (une requête sans-méthode se lit comme POST) — utilisez l'outil WebFetch pour les pages externes ; le registre pnpm marche bien.
  • Ne hand-éditez pas la référence API (générée) — changez le générateur/schéma et rebuildez.

Références de deep-dive (lisez quand vous atteignez la phase pertinente)

  • references/components.md — APIs de composants complets pour les deux surfaces + le registre d'illustration.
  • references/writing-guide.md — la voix, la règle d'ancrage, exemples travaillés.
  • references/information-architecture.md — l'IA flux et la nav meta.json Référence.
  • references/design-language.md — palette, polices, la convention Tailwind-inline.

Note : references/scaffold.md, references/brand-integration.md, et assets/templates/* sont ère scaffolding (comment l'app a d'abord été montée, avec Geist/@carbon/react/modèles signature-touch). L'app a divergé d'eux. Les composants en direct dans docs/components/{editorial,api}/ sont la source de vérité — lisez ceux-ci, pas les modèles, en cas de doute.

Barre de vérification

Ne déclarez jamais la doc faite sans : le nouveau contenu s'affichant (dans le serveur dev en exécution de l'utilisateur, ou un pnpm --filter docs build propre), chaque lien interne se résolvant, tout nouveau <Term> entrée glossaire ancrée dans la source + ses popovers s'affichant, noms correspondant au vrai code, pas de titres générique répétés, et une relecture qui confirme que chaque page dit ce qui importe / nomme l'erreur / pointe vers l'avant. Puis enregistrez le progrès (le fichier plan .ai/plans/ s'il en existe, + mémoire). Ne tuez ni ne rebuildez sous le serveur dev en exécution de l'utilisateur.

Skills similaires