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
statuspour 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 passpartial (réussis/total)— certains échecs de test persistenttodo— 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, ounullsi tout est propreperPass— répartition par pass des comptages réussis/échoués
Si frontier est null, déterminez l'action suivante :
- Le champ
passaffiche 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 :
-
Sous-agent d'examen : Exécutez
/compiler-reviewsur la pass défaillante pour identifier les problèmes évidents — fonctionnalités manquantes, portage incorrect de la logique, divergences par rapport à la source TypeScript. -
Sous-agent d'analyse : Un sous-agent
general-purposequi 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-colorpour 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 :
- Le nom de la pass et son numéro de position
- Le diagnostic synthétisé — à la fois les conclusions d'examen et l'analyse de défaillance
- 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. - 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 du sous-agent de correction :
- Réexécutez
bash compiler/scripts/test-rust-port.sh --json 2>/dev/nullpour obtenir les comptages et frontier mis à jour - Si toujours défaillant, répétez le cycle diagnostic parallèle + correction (max 3 cycles au total)
- 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
- 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-purposepour 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 :
- Nom de la pass :
<PassName>(position #N dans le pipeline) - Instructions : Portez la pass
<PassName>de TypeScript à Rust. Suivez ces étapes : a. Lisez le guide d'architecture àcompiler/docs/rust-port/rust-port-architecture.mdb. Lisez la documentation de la pass danscompiler/packages/babel-plugin-react-compiler/docs/passes/c. Trouvez la source TypeScript en suivant l'import danscompiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.tsd. Lisez le pipeline Rust àcompiler/crates/react_compiler/src/entrypoint/pipeline.rset 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écutezbash 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 - Notes spéciales (si applicable — p. ex., gating conditionnel, réutilisation de fonctions existantes)
Après la fin du sous-agent :
- Réexécutez
bash compiler/scripts/test-rust-port.sh --json 2>/dev/nullpour obtenir les comptages et frontier mis à jour - Mettez à jour la section Status du journal de l'orchestrateur et ajoutez une entrée de journal
- 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 :
- Exécute
/compiler-verify(tests, lint, format) - Exécute
/compiler-reviewsur les modifications non validées — s'arrête si des problèmes sont trouvés - Met à jour le journal de l'orchestrateur avec les résultats des tests
- 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 :
- Analysez le hash de commit à partir de la sortie
- Ajoutez une entrée de journal notant le commit
- 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
-
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.
-
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. -
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.
-
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.