compiler-orchestrator

Par facebook · react

Orchestrer le portage du compilateur Rust de bout en bout. Découvre la frontière actuelle, corrige les passes défaillantes, porte de nouvelles passes, effectue des révisions et des commits en boucle.

npx skills add https://github.com/facebook/react --skill compiler-orchestrator

Orchestrateur de Compilateur

Avancer automatiquement le port du compilateur Rust en découvrant l'état actuel, en corrigeant les défaillances, en portant de nouvelles passes, en examinant et en validant — dans une boucle continue.

Arguments :

  • $ARGUMENTS : Optionnel. Un nom de pass pour démarrer à partir de là, ou status pour simplement signaler l'état actuel sans agir.

Référence d'Ordre des Passes

Voici les passes dans l'ordre de Pipeline.ts, avec leurs noms de log exacts :

# Nom du Log Kind Notes
1 HIR hir
2 PruneMaybeThrows hir Validation : validateContextVariableLValues, validateUseMemo après
3 DropManualMemoization hir Conditionnel
4 InlineImmediatelyInvokedFunctionExpressions hir
5 MergeConsecutiveBlocks hir
6 SSA hir
7 EliminateRedundantPhi hir
8 ConstantPropagation hir
9 InferTypes hir Validation : validateHooksUsage, validateNoCapitalizedCalls après (conditionnel)
10 OptimizePropsMethodCalls hir
11 AnalyseFunctions hir
12 InferMutationAliasingEffects hir
13 OptimizeForSSR hir Conditionnel : outputMode === 'ssr'
14 DeadCodeElimination hir
15 PruneMaybeThrows (2e) hir Réutilise la fonction existante, nécessite juste 2e appel + log dans pipeline.rs
16 InferMutationAliasingRanges hir Bloc de validation (8 validateurs) après (conditionnel)
17 InferReactivePlaces hir Validation : validateExhaustiveDependencies après (conditionnel)
18 RewriteInstructionKindsBasedOnReassignment hir Validation : validateStaticComponents après (conditionnel)
19 InferReactiveScopeVariables hir Conditionnel : enableMemoization
20 MemoizeFbtAndMacroOperandsInSameScope hir
-- outlineJSX hir Entre #20 et #21, conditionnel : enableJsxOutlining, pas d'entrée de log
21 NameAnonymousFunctions hir Conditionnel
22 OutlineFunctions hir Conditionnel
23 AlignMethodCallScopes hir
24 AlignObjectMethodScopes hir
25 PruneUnusedLabelsHIR hir
26 AlignReactiveScopesToBlockScopesHIR hir
27 MergeOverlappingReactiveScopesHIR hir
28 BuildReactiveScopeTerminalsHIR hir
29 FlattenReactiveLoopsHIR hir
30 FlattenScopesWithHooksOrUseHIR hir
31 PropagateScopeDependenciesHIR hir
32 BuildReactiveFunction reactive
33 AssertWellFormedBreakTargets debug Validation
34 PruneUnusedLabels reactive
35 AssertScopeInstructionsWithinScopes debug Validation
36 PruneNonEscapingScopes reactive
37 PruneNonReactiveDependencies reactive
38 PruneUnusedScopes reactive
39 MergeReactiveScopesThatInvalidateTogether reactive
40 PruneAlwaysInvalidatingScopes reactive
41 PropagateEarlyReturns reactive
42 PruneUnusedLValues reactive
43 PromoteUsedTemporaries reactive
44 ExtractScopeDeclarationsFromDestructuring reactive
45 StabilizeBlockIds reactive
46 RenameVariables reactive
47 PruneHoistedContexts reactive
48 ValidatePreservedManualMemoization debug Conditionnel
49 Codegen ast

Passes de validation (pas d'entrées de log, testées via événements CompileError/CompileSkip) :

  • Après PruneMaybeThrows (#2) : validateContextVariableLValues, validateUseMemo
  • Après InferTypes (#9) : validateHooksUsage, validateNoCapitalizedCalls (conditionnel)
  • Après InferMutationAliasingRanges (#16) : 8 validateurs (conditionnel)
  • Après InferReactivePlaces (#17) : validateExhaustiveDependencies (conditionnel)
  • Après RewriteInstructionKindsBasedOnReassignment (#18) : validateStaticComponents (conditionnel)
  • Après PruneHoistedContexts (#47) : validatePreservedManualMemoization (conditionnel)
  • Après Codegen (#49) : validateSourceLocations (conditionnel)

Journal de l'Orchestrateur

Maintenez un fichier de journal à compiler/docs/rust-port/rust-port-orchestrator-log.md qui suit toute progression.

Format du fichier journal

# Status

HIR: complete (1717/1717)
PruneMaybeThrows: complete (1717/1717)
DropManualMemoization: complete (1717/1717)
...
AnalyseFunctions: partial (1700/1717)
InferMutationAliasingEffects: todo
...

# Logs

## 20260318-143022 Port AnalyseFunctions pass

Ported AnalyseFunctions from TypeScript to Rust. Added new crate react_compiler_analyse_functions.
1700/1717 tests passing, 17 failures in edge cases with nested functions.

## 20260318-141500 Fix SSA phi node ordering

Fixed phi node operand ordering in SSA pass that caused 3 test failures.
All 1717 tests now passing through OptimizePropsMethodCalls.

Section Status

La section # Status liste chaque pass de #1 à #49 avec l'une des options suivantes :

  • complete (N/N) — tous les tests réussis jusqu'à cette pass
  • partial (réussis/total) — certains échecs de test persistent
  • todo — pas encore porté

Mettez à jour la section Status après chaque exécution de tests pour refléter les derniers résultats.

Entrées de journal

Ajoutez une nouvelle entrée de journal (sous la plus récente, de sorte que les entrées les plus récentes soient au bas) chaque fois que :

  • Une pass est nouvellement portée
  • Des défaillances de test sont corrigées
  • Un commit est effectué

Format d'entrée : ## YYYYMMDD-HHMMSS <court-résumé> suivi de 1-3 lignes décrivant ce qui a changé.

Utilisez l'horodatage actuel lors de la création d'entrées. Obtenez-le via date '+%Y%m%d-%H%M%S'.

Initialisation

À la première exécution, si le fichier de journal n'existe pas, créez-le avec la section Status remplie à partir de l'état actuel (lisez pipeline.rs et exécutez les tests pour déterminer les statuts des passes).

Boucle Principale

Rôle du contexte principal : Le contexte principal est UNIQUEMENT une boucle d'orchestration. Il analyse les résultats des sous-agents, met à jour le journal de l'orchestrateur, affiche le statut et lance le prochain sous-agent. Le contexte principal NE DOIT PAS lire le code source, enquêter sur les défaillances, déboguer des problèmes ou apporter des modifications directement. TOUS les travaux de mise en œuvre — correction, portage, examen, vérification — se déroulent dans les sous-agents.

Exécutez ces étapes dans l'ordre, en revenant à l'étape 1 après chaque commit :

Étape 1 : Découvrir la Frontière

Exécutez test-rust-port avec --json pour obtenir des résultats lisibles par machine :

bash compiler/scripts/test-rust-port.sh --json 2>/dev/null

Cela génère un objet JSON unique avec les champs : pass, autoDetected, total, passed, failed, frontier, perPass, failures.

Analysez le JSON pour extraire :

  • Comptages passed, failed, total
  • frontier — la pass la plus précoce avec défaillances, ou null si tout est propre
  • perPass — répartition par pass des comptages réussis/échoués

Si frontier est null, déterminez l'action suivante :

  • Le champ pass affiche la dernière pass portée (détection automatique à partir de pipeline.rs)
  • Cherchez la pass suivante dans la table de Référence d'Ordre des Passes
  • Sinon, le mode est PORT pour cette pass suivante

Si frontier est un nom de pass, le mode est FIX pour cette pass. Utilisez --failures pour obtenir la liste complète des chemins de fixtures défaillants :

bash compiler/scripts/test-rust-port.sh <NomPassFrontière> --failures

Exécutez ensuite des fixtures défaillants spécifiques pour obtenir les diffs pour enquête :

bash compiler/scripts/test-rust-port.sh <NomPassFrontière> <chemin-fixture> --no-color

Vérifiez également si compiler/docs/rust-port/rust-port-orchestrator-log.md existe. Sinon, créez-le avec la section Status remplie à partir de l'état actuel.

Mettez à jour la section Status du journal de l'orchestrateur, puis procédez à l'étape 2.

Étape 2 : Signaler le Statut

Imprimez un rapport de statut :

## Orchestrator Status
- Ported passes: <count> / 49
- Test results: <passed> passed, <failed> failed (<total> total)
- Frontier: #<num> <PassName> (<FIX|PORT> mode) — or "none (all clean)"
- Action: <what will happen next>

Si $ARGUMENTS est status, arrêtez-vous ici.

Étape 3 : Agir sur la Frontière

NE PAS enquêter, lire le code source ou déboguer dans le contexte principal. Déléguez toujours à un sous-agent.

3a. Mode FIX (frontier est une pass portée avec défaillances)

Lancez deux sous-agents en parallèle pour diagnostiquer les défaillances :

  1. Sous-agent d'examen : Exécutez /compiler-review sur la pass défaillante pour identifier les problèmes évidents — fonctionnalités manquantes, portage incorrect de la logique, divergences par rapport à la source TypeScript.

  2. Sous-agent d'analyse : Un sous-agent general-purpose qui enquête sur les défaillances de test réelles. Son prompt DOIT inclure :

    • Le nom de la pass et son numéro de position
    • La sortie complète de défaillance de test (copiez-la textuellement)
    • Instructions : Exécutez les fixtures défaillants individuellement avec bash compiler/scripts/test-rust-port.sh <PassName> <chemin-fixture> --no-color pour obtenir les diffs. Analysez les diffs pour déterminer ce que le port Rust fait mal. Lisez la source TypeScript correspondante pour comprendre le comportement attendu. Signalez les conclusions mais NE FAITES PAS de corrections pour le moment.
    • Chemin du guide d'architecture : compiler/docs/rust-port/rust-port-architecture.md
    • Chemin du pipeline : compiler/crates/react_compiler/src/entrypoint/pipeline.rs

Après la fin des deux sous-agents, synthétisez leurs résultats pour déterminer un plan d'action. L'examen peut révéler des lacunes de portage qui expliquent les défaillances de test, et l'analyse de défaillance peut révéler des problèmes que l'examen a manqués. Utilisez les deux entrées pour former une image complète.

Ensuite, lancez un seul sous-agent general-purpose pour corriger les défaillances. Le prompt du sous-agent DOIT inclure :

  1. Le nom de la pass et son numéro de position
  2. Le diagnostic synthétisé — à la fois les conclusions d'examen et l'analyse de défaillance
  3. Instructions : Corrigez les défaillances de test dans le port Rust. NE RÉALISEZ PAS un nouveau portage à partir de zéro. Utilisez le diagnostic pour guider les corrections. Après correction, exécutez bash compiler/scripts/test-rust-port.sh <PassName> pour vérifier. Répétez jusqu'à 0 défaillance ou vous avez fait 3 tentatives de correction sans progrès.
  4. Chemin du guide d'architecture : compiler/docs/rust-port/rust-port-architecture.md
  5. Chemin du pipeline : compiler/crates/react_compiler/src/entrypoint/pipeline.rs

Après la fin du sous-agent de correction :

  1. Réexécutez bash compiler/scripts/test-rust-port.sh --json 2>/dev/null pour obtenir les comptages et frontier mis à jour
  2. Si toujours défaillant, répétez le cycle diagnostic parallèle + correction (max 3 cycles au total)
  3. Une fois propre (ou après 3 cycles), mettez à jour la section Status du journal de l'orchestrateur et ajoutez une entrée de journal
  4. Allez à l'étape 4 (Examiner et Valider)

3b. Mode PORT (frontier est la pass suivante non portée)

Traitez d'abord les cas particuliers :

  • Deuxième appel PruneMaybeThrows (#15) : Lancez un sous-agent general-purpose pour ajouter un deuxième appel à prune_maybe_throws + log_debug! dans pipeline.rs, puis exécutez les tests.
  • outlineJSX (entre #20 et #21) : Conditionnel sur enableJsxOutlining. N'a pas d'entrée de log. Lancez un sous-agent pour gérer inline ou via le pattern compiler-port.
  • Passes conditionnelles (#3, #13, #19, #21, #22) : Notez la condition lors de la délégation.

Pour les passes standard, lancez un seul sous-agent general-purpose avec ces instructions :

  1. Nom de la pass : <PassName> (position #N dans le pipeline)
  2. Instructions : Portez la pass <PassName> de TypeScript à Rust. Suivez ces étapes : a. Lisez le guide d'architecture à compiler/docs/rust-port/rust-port-architecture.md b. Lisez la documentation de la pass dans compiler/packages/babel-plugin-react-compiler/docs/passes/ c. Trouvez la source TypeScript en suivant l'import dans compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts d. Lisez le pipeline Rust à compiler/crates/react_compiler/src/entrypoint/pipeline.rs et la structure de crate existante e. Portez la pass, créez/mettez à jour les crates selon les besoins, câblez dans pipeline.rs f. Exécutez bash compiler/scripts/test-rust-port.sh <PassName> et corrigez les défaillances en boucle jusqu'à 0 défaillance (max 5 tentatives) g. Signalez : fichiers créés/modifiés, comptage de test final, tous les problèmes restants
  3. Notes spéciales (si applicable — p. ex., gating conditionnel, réutilisation de fonctions existantes)

Après la fin du sous-agent :

  1. Réexécutez bash compiler/scripts/test-rust-port.sh --json 2>/dev/null pour obtenir les comptages et frontier mis à jour
  2. Mettez à jour la section Status du journal de l'orchestrateur et ajoutez une entrée de journal
  3. Allez à l'étape 4 (Examiner et Valider)

Étape 4 : Examiner et Valider

Utilisez /compiler-commit <titre> pour examiner, vérifier et valider les modifications. Cette compétence :

  1. Exécute /compiler-verify (tests, lint, format)
  2. Exécute /compiler-review sur les modifications non validées — s'arrête si des problèmes sont trouvés
  3. Met à jour le journal de l'orchestrateur avec les résultats des tests
  4. Valide avec le préfixe [rust-compiler] correct

Choisissez un titre de commit descriptif basé sur ce que le sous-agent a fait (p. ex., « Port AnalyseFunctions pass » ou « Fix SSA phi node ordering »).

Après validation :

  1. Analysez le hash de commit à partir de la sortie
  2. Ajoutez une entrée de journal notant le commit
  3. Le travail continue — les commits sont des points de contrôle, pas des points d'arrêt

Étape 5 : Boucle

Retournez à l'étape 1. La boucle continue jusqu'à :

  • Toutes les passes sont portées et propres (jusqu'à #49)
  • Une erreur irrécupérable se produit

Principes Clés

  1. La défaillance la plus précoce gagne : Même une seule défaillance de test dans la pass #2 doit être corrigée avant de travailler sur la pass #11. Les erreurs précoces en cascadent — un bug dans l'abaissement peut causer des défaillances fausses dans chaque pass en aval.

  2. Tests cumulatifs : test-rust-port.sh <PassName> teste TOUTES les passes jusqu'à et y compris la pass nommée. Un résultat propre pour la dernière pass implique que toutes les passes antérieures sont également propres.

  3. Commits incrémentiels : Validez après chaque unité significative de progrès. Ne groupez pas plusieurs passes en un commit. Chaque commit doit laisser l'arborescence dans un état propre.

  4. Déléguez tout : Le contexte principal NE DOIT PAS lire le code source, enquêter sur les bugs ou apporter des modifications. Il ne fait que : analyser les résultats des sous-agents, mettre à jour le journal de l'orchestrateur, afficher le statut et lancer le prochain sous-agent. Tous les lectures de code, débogages, corrections, portages, examens et validations se déroulent dans les sous-agents.

Skills similaires