| 1 | # React Compiler Rust Port — Workflow Guide |
| 2 | |
| 3 | Analysis of 141 Claude Code sessions from 2026-03-13 to 2026-04-10, totaling ~17,460 tool invocations across the Rust compiler port. |
| 4 | |
| 5 | --- |
| 6 | |
| 7 | ## 1. Project Timeline & Phases |
| 8 | |
| 9 | | Phase | Dates | Focus | Sessions | |
| 10 | |-------|-------|-------|----------| |
| 11 | | **Research** | Mar 13–14 | Feasibility study, shared mutability analysis, pass-by-pass research | ~10 | |
| 12 | | **Planning** | Mar 14–16 | Architecture docs, numbered plans (0001–0005), scope types | ~15 | |
| 13 | | **Core Implementation** | Mar 16–25 | Babel AST crate, HIR lowering, pass porting, BuildHIR | ~50 | |
| 14 | | **Testing & Stabilization** | Mar 25–31 | Snap tests, test-rust-port 100%, OXC/SWC frontends | ~30 | |
| 15 | | **E2E & Diagnostics** | Apr 1–4 | Error formatting, diagnostic events, CI, e2e tests | ~20 | |
| 16 | | **Internal Validation** | Apr 6–10 | Testing against Meta internal code, minimize-rust-delta, hermes-parser | ~10 | |
| 17 | |
| 18 | ### Key Milestones |
| 19 | - **Mar 25**: All 1717/1717 pass-level + code-level tests passing |
| 20 | - **Mar 30**: Snap tests 1717/1718 (99.9%) |
| 21 | - **Mar 31**: OptimizeForSSR ported, snap 1725/1725 |
| 22 | - **Apr 2**: E2E babel 1722/1724, diagnostic events aligned |
| 23 | - **Apr 4**: CI workflow configured, SWC/OXC e2e progress |
| 24 | - **Apr 6–10**: Internal codebase validation against Meta internal production code |
| 25 | |
| 26 | --- |
| 27 | |
| 28 | ## 2. Custom Skills (Claude Code) |
| 29 | |
| 30 | Seven custom skills were created in `compiler/.claude/skills/`. These are critical to the workflow and should be loaded at the start of each session: |
| 31 | |
| 32 | | Skill | Usage Count | Purpose | |
| 33 | |-------|-------------|---------| |
| 34 | | `/compiler-verify` | 47 | Detects TS vs Rust changes, runs appropriate test suites | |
| 35 | | `/compiler-commit` | 30 | Runs verify + review, then commits with `[compiler]` or `[rust-compiler]` prefix, updates orchestrator log | |
| 36 | | `/compiler-review` | 21 | Launches a review subagent that compares Rust port against TS originals | |
| 37 | | `/compiler-orchestrator` | 5 | Autonomous loop: discover frontier → fix failures → port next pass → review → commit | |
| 38 | | `/compiler-port` | 5 | Port a single named pass end-to-end (looks up in Pipeline.ts, maps to Rust crate, implements, tests) | |
| 39 | | `/rust-port-status` | — | Reports current test pass rates | |
| 40 | | `/plan-update` | — | Updates numbered plan documents | |
| 41 | |
| 42 | ### Typical Workflow Loop |
| 43 | |
| 44 | ``` |
| 45 | 1. /compiler-orchestrator (or manual work) |
| 46 | └── Discovers current test state |
| 47 | └── Fixes failures or ports next pass |
| 48 | └── Calls /compiler-verify internally |
| 49 | └── Calls /compiler-review internally |
| 50 | └── Calls /compiler-commit when ready |
| 51 | |
| 52 | 2. Manual variant: |
| 53 | > "Fix X" |
| 54 | > /compiler-verify |
| 55 | > /compiler-review |
| 56 | > /compiler-commit |
| 57 | ``` |
| 58 | |
| 59 | ### Important Skill Loading Note |
| 60 | |
| 61 | The `/compiler-orchestrator` skill sometimes fails to auto-load. The workaround is: |
| 62 | |
| 63 | ``` |
| 64 | > load the skill compiler/.claude/skills/compiler-orchestrator/SKILL.md |
| 65 | ``` |
| 66 | |
| 67 | This happened multiple times in the trajectory history and your team should be aware of it. |
| 68 | |
| 69 | --- |
| 70 | |
| 71 | ## 3. Test Commands & Infrastructure |
| 72 | |
| 73 | ### Primary Test Scripts (by frequency of use) |
| 74 | |
| 75 | | Command | Invocations | Purpose | |
| 76 | |---------|-------------|---------| |
| 77 | | `bash compiler/scripts/test-rust-port.sh` | 1,345 | Compare Rust vs TS compiler output per-pass for all fixtures | |
| 78 | | `bash compiler/scripts/test-e2e.sh` | 269 | End-to-end: code output + diagnostic events across babel/swc/oxc | |
| 79 | | `cargo check` | 251 | Fast Rust compilation check | |
| 80 | | `npx tsx` | 207 | Run TypeScript scripts directly | |
| 81 | | `cargo build` | 179 | Full Rust build | |
| 82 | | `bash compiler/scripts/test-babel-ast.sh` | 174 | Babel AST round-trip serialization tests | |
| 83 | | `yarn snap --rust` | 121 | Snap fixture tests using Rust compiler backend | |
| 84 | | `yarn snap` | 63 | Snap fixture tests using TS compiler | |
| 85 | | `cargo test` | 46 | Rust unit tests | |
| 86 | |
| 87 | ### Test Result Formats |
| 88 | |
| 89 | `test-rust-port.sh` supports `--json` for machine-readable output: |
| 90 | ```bash |
| 91 | bash compiler/scripts/test-rust-port.sh --json 2>/dev/null |
| 92 | # Returns: { pass, autoDetected, total, passed, failed, frontier, perPass, failures } |
| 93 | ``` |
| 94 | |
| 95 | `test-e2e.sh` reports in table format: |
| 96 | ``` |
| 97 | | variant | code | events | total | |
| 98 | | babel | 1725/1725 (100%) | 1725/1725 (100%) | ... | |
| 99 | | swc | 1723/1725 (99.9%) | ... | ... | |
| 100 | ``` |
| 101 | |
| 102 | ### Test Against Internal Codebase |
| 103 | |
| 104 | Recent work (Apr 6–10) tested against Meta internal production code. Key patterns: |
| 105 | |
| 106 | ```bash |
| 107 | # Run with specific compilation mode against an external directory |
| 108 | bash compiler/scripts/test-rust-port.sh --mode syntax <path-to-source-dir> |
| 109 | |
| 110 | # Use test-internal-files.sh with the production config and source root |
| 111 | bash compiler/scripts/test-internal-files.sh <config-path> <source-root> [flags] |
| 112 | ``` |
| 113 | |
| 114 | - Files with `@flow` need hermes-parser (recently added to test-rust-port.ts) |
| 115 | - Must pass `compilationMode` to match production config |
| 116 | - Use `yarn snap minimize-rust-delta <path>` to find minimal repro for TS/Rust differences |
| 117 | |
| 118 | --- |
| 119 | |
| 120 | ## 4. Cargo & Rust Workflow |
| 121 | |
| 122 | ### Crate Structure |
| 123 | |
| 124 | | Crate | Purpose | |
| 125 | |-------|---------| |
| 126 | | `react_compiler` | Main entrypoint, pipeline orchestration | |
| 127 | | `react_compiler_ast` | Babel AST types + serde | |
| 128 | | `react_compiler_hir` | HIR types, environment, visitors | |
| 129 | | `react_compiler_lowering` | BuildHIR, HIRBuilder (AST → HIR) | |
| 130 | | `react_compiler_inference` | Mutation/aliasing/type inference | |
| 131 | | `react_compiler_optimization` | Optimization passes | |
| 132 | | `react_compiler_validation` | Validation passes | |
| 133 | | `react_compiler_reactive_scopes` | Reactive scope building + codegen | |
| 134 | | `react_compiler_diagnostics` | Error types, code frames | |
| 135 | | `react_compiler_e2e_cli` | E2E test binary | |
| 136 | | `react_compiler_swc` | SWC frontend | |
| 137 | | `react_compiler_oxc` | OXC frontend | |
| 138 | |
| 139 | ### Common Cargo Patterns |
| 140 | |
| 141 | ```bash |
| 142 | # Fast check (most common, 214 invocations) |
| 143 | cargo check --manifest-path compiler/crates/Cargo.toml |
| 144 | |
| 145 | # Build the NAPI binary for JS interop |
| 146 | cargo build --manifest-path compiler/crates/Cargo.toml |
| 147 | |
| 148 | # Run Rust unit tests |
| 149 | cargo test --manifest-path compiler/crates/Cargo.toml |
| 150 | ``` |
| 151 | |
| 152 | --- |
| 153 | |
| 154 | ## 5. Agent Patterns |
| 155 | |
| 156 | 994 total agent invocations across sessions. |
| 157 | |
| 158 | | Agent Type | Count | Typical Use | |
| 159 | |------------|-------|-------------| |
| 160 | | `general` / `general-purpose` | 748 | Implementation, fixing, research | |
| 161 | | `meta_codesearch:code_search` | 204 | Codebase exploration | |
| 162 | | `Plan` | 20 | Architecture/implementation planning | |
| 163 | | `Explore` | 16 | Codebase navigation | |
| 164 | | `statusline-setup` | 4 | Terminal UI configuration | |
| 165 | |
| 166 | ### Common Agent Patterns |
| 167 | |
| 168 | 1. **Parallel pass research**: Launch one agent per compiler pass to analyze TS implementation for port feasibility |
| 169 | 2. **Review agents**: Dedicated "Review Rust port changes" agents (14 invocations) |
| 170 | 3. **Fix-specific agents**: "Fix AnalyseFunctions failures" (4x), "Fix PruneMaybeThrows validation failures" (2x) |
| 171 | 4. **Worktree isolation**: 16 worktree entries for isolated implementation work |
| 172 | |
| 173 | ### Worktree Usage |
| 174 | |
| 175 | Worktrees were used for larger changes that might need to be abandoned: |
| 176 | - `worktree-build-hir-impl` — BuildHIR implementation |
| 177 | - `worktree-structured-yawning-forest-rust` — test-rust-port enhancements |
| 178 | - `worktree-ts-to-rust-transpiler` — explored mechanical TS→Rust transpilation (abandoned) |
| 179 | - `worktree-module-type-provider` — module type provider work |
| 180 | |
| 181 | --- |
| 182 | |
| 183 | ## 6. Key Files (by edit frequency) |
| 184 | |
| 185 | ### Most Frequently Modified Files |
| 186 | |
| 187 | | File | Edits | Reads | Purpose | |
| 188 | |------|-------|-------|---------| |
| 189 | | `rust-port-orchestrator-log.md` | 135 | 104 | Running log of orchestrator progress | |
| 190 | | `build_hir.rs` | 112 | 162 | Core HIR lowering from AST | |
| 191 | | `program.rs` (entrypoint) | 103 | 173 | Main compilation entrypoint | |
| 192 | | `rust-port-research.md` | 85 | 47+21 | Research & analysis document | |
| 193 | | `test-rust-port.ts` | 77 | 90 | Primary test comparison script | |
| 194 | | `pipeline.rs` | 48 | 64 | Compiler pass pipeline | |
| 195 | | `test-e2e.ts` | 42 | 27 | End-to-end test script | |
| 196 | | `hir_builder.rs` | 37 | 53 | HIR builder utilities | |
| 197 | | `infer_mutation_aliasing_effects.rs` | 32 | 48 | Most complex inference pass | |
| 198 | | `runner.ts` (snap) | 32 | 35 | Snap test runner | |
| 199 | |
| 200 | --- |
| 201 | |
| 202 | ## 7. Repeated Workflow Patterns |
| 203 | |
| 204 | ### Pattern 1: "Analyze → Don't Fix → Report" |
| 205 | Used extensively in recent internal validation work: |
| 206 | ``` |
| 207 | > Try running test-rust-port.sh with --mode 'syntax' against <path>. Analyze success/failure to categorize and report back. Do not proactively fix. |
| 208 | ``` |
| 209 | |
| 210 | ### Pattern 2: "Research → Plan → Implement → Verify → Review → Commit" |
| 211 | The standard development cycle: |
| 212 | ``` |
| 213 | > Do additional research into <topic> |
| 214 | > Create a plan in compiler/docs/rust-port/... |
| 215 | > Implement the work in <plan> |
| 216 | > /compiler-verify |
| 217 | > /compiler-review |
| 218 | > /compiler-commit |
| 219 | ``` |
| 220 | |
| 221 | ### Pattern 3: "Team of Agents" |
| 222 | For large implementation tasks: |
| 223 | ``` |
| 224 | > Use a team of agents (opus) to implement the remainder of the items in <plan>. Make sure to thoroughly test, verify the implementation against the plan. Use /compiler-verify and /compiler-commit. |
| 225 | ``` |
| 226 | |
| 227 | ### Pattern 4: "Orchestrator Loop" |
| 228 | For autonomous progress: |
| 229 | ``` |
| 230 | > /compiler-orchestrator |
| 231 | (or: load the skill compiler/.claude/skills/compiler-orchestrator/SKILL.md) |
| 232 | ``` |
| 233 | |
| 234 | ### Pattern 5: "Debug CI" |
| 235 | ``` |
| 236 | > debug the GitHub CI failure run at <github-actions-url> |
| 237 | > <paste error output> |
| 238 | > /compiler-commit |
| 239 | ``` |
| 240 | |
| 241 | ### Pattern 6: "Minimize Delta" |
| 242 | For finding minimal repros of TS/Rust differences: |
| 243 | ``` |
| 244 | > yarn snap minimize-rust-delta <path> |
| 245 | ``` |
| 246 | |
| 247 | ### Pattern 7: "Interrupt and Redirect" |
| 248 | Joe frequently interrupts Claude mid-task to correct course: |
| 249 | - `[Request interrupted by user]` appears ~50+ times |
| 250 | - Common pattern: interrupt → provide specific guidance → continue |
| 251 | - Example: "you should be using `env.record_error(...)?`." |
| 252 | |
| 253 | --- |
| 254 | |
| 255 | ## 8. Key Architectural Decisions (from trajectory) |
| 256 | |
| 257 | These came up repeatedly in prompts and are important context: |
| 258 | |
| 259 | 1. **InstructionId over InstructionValue references**: Key insight that caches in InferMutationAliasingEffects can use `InstructionId` (interned) instead of holding references to `InstructionValue` objects, avoiding Rust borrow conflicts. |
| 260 | |
| 261 | 2. **Environment is shared mutable**: Like HIR, the Environment object is mutably shared. Both needed careful Rust representation. |
| 262 | |
| 263 | 3. **Error handling convention**: `env.record_error(...)?` — record_error returns `Err` only for Invariant category errors. Use `?` for short-circuit. Only use `let _ = ...` when both the category is non-Invariant AND you explicitly want to continue. |
| 264 | |
| 265 | 4. **Keep logic in Rust core**: The babel/swc/oxc integrations should be thin wrappers. All interesting logic belongs in the Rust crates. |
| 266 | |
| 267 | 5. **Commit prefix convention**: `[rust-compiler]` for changes to `compiler/crates/`, `[compiler]` for everything else. |
| 268 | |
| 269 | 6. **No normalization in tests**: Minimize output normalization — run code through prettier only, compare directly. Added: reparse with babel → regenerate with `compact:true` → prettier. |
| 270 | |
| 271 | --- |
| 272 | |
| 273 | ## 9. Current State & Remaining Work |
| 274 | |
| 275 | ### Test Results (as of latest orchestrator log) |
| 276 | - **test-rust-port**: 1724/1724 (100%) |
| 277 | - **yarn snap --rust**: 1725/1725 (100%) |
| 278 | - **E2E babel**: 1722/1724 (2 inherent platform differences) |
| 279 | - **E2E swc**: Partial — event matching in progress |
| 280 | - **E2E oxc**: Partial — event matching in progress |
| 281 | |
| 282 | ### Active Work Streams (as of Apr 10) |
| 283 | 1. **Internal validation**: Testing against Meta internal production code with production configs |
| 284 | 2. **Minimize rust deltas**: Using `yarn snap minimize-rust-delta` to find minimal repro cases for TS/Rust differences |
| 285 | 3. **New test-internal-files script**: `compiler/scripts/test-internal-files.ts` — for testing against an external codebase with its production config |
| 286 | 4. **compilationMode: 'syntax'** support was recently added and validated |
| 287 | 5. **hermes-parser integration**: For `@flow` files in the internal codebase |
| 288 | |
| 289 | ### Remaining Gaps |
| 290 | - SWC/OXC e2e event differences (structural, not code) |
| 291 | - Some internal codebase fixtures still show code differences between TS and Rust |
| 292 | - Internal skip list exists at `compiler/.test-internal-skip-list` |
| 293 | - Performance optimization: potential for returning per-function replacements instead of full program |
| 294 | |
| 295 | --- |
| 296 | |
| 297 | ## 10. Recommendations for Team Picking Up |
| 298 | |
| 299 | ### Getting Started |
| 300 | 1. Read `compiler/docs/rust-port/rust-port-research.md` and `rust-port-notes.md` for architectural context |
| 301 | 2. Read all numbered plans in `compiler/docs/rust-port/rust-port-0001-*` through `0005-*` |
| 302 | 3. Review `compiler/docs/rust-port/rust-port-orchestrator-log.md` for chronological progress |
| 303 | 4. Review `compiler/docs/rust-port/rust-port-gap-analysis.md` for known gaps |
| 304 | |
| 305 | ### Essential Skill Loading |
| 306 | At the start of each Claude session: |
| 307 | ``` |
| 308 | > load the skill compiler/.claude/skills/compiler-orchestrator/SKILL.md |
| 309 | ``` |
| 310 | This ensures all six custom skills are available. If a skill isn't recognized, load it explicitly. |
| 311 | |
| 312 | ### Daily Workflow |
| 313 | ```bash |
| 314 | # Check current state |
| 315 | bash compiler/scripts/test-rust-port.sh |
| 316 | bash compiler/scripts/test-e2e.sh |
| 317 | yarn snap --rust |
| 318 | |
| 319 | # After making changes |
| 320 | /compiler-verify |
| 321 | /compiler-review |
| 322 | /compiler-commit <title> |
| 323 | ``` |
| 324 | |
| 325 | ### Key Commands to Know |
| 326 | ```bash |
| 327 | # Fast iteration cycle |
| 328 | cargo check --manifest-path compiler/crates/Cargo.toml |
| 329 | bash compiler/scripts/test-rust-port.sh |
| 330 | yarn snap --rust |
| 331 | |
| 332 | # Debug a specific fixture |
| 333 | yarn snap --rust -p <fixture-name> -d |
| 334 | |
| 335 | # Compare TS vs Rust for a specific file |
| 336 | npx tsx compiler/scripts/test-rust-port.ts <pass-name> |
| 337 | |
| 338 | # Find minimal repro for TS/Rust difference |
| 339 | yarn snap minimize-rust-delta <fixture-path> |
| 340 | |
| 341 | # Test against an external codebase with its production config |
| 342 | bash compiler/scripts/test-internal-files.sh <config-path> <source-root> [flags] |
| 343 | |
| 344 | # E2E test across all frontends |
| 345 | bash compiler/scripts/test-e2e.sh |
| 346 | ``` |
| 347 | |
| 348 | ### Working Style Notes |
| 349 | - Joe used Opus 4.6 as the primary model throughout |
| 350 | - Frequent use of `/clear` between logical work units |
| 351 | - Heavy use of "analyze and report, don't fix" for investigation phases |
| 352 | - Corrections were provided inline with specific code patterns (e.g., "you should be using `env.record_error(...)?`") |
| 353 | - Plans were maintained in numbered markdown docs and updated as work progressed |
| 354 | - The orchestrator log (`rust-port-orchestrator-log.md`) serves as the canonical progress record |
| 355 | |
| 356 | ### CI Configuration |
| 357 | GitHub CI workflow: `.github/workflows/compiler_rust.yml` |
| 358 | - Triggers on changes to `compiler/` directory |
| 359 | - Runs: `cargo check` → `cargo build` → `test-babel-ast.sh` → `test-rust-port.sh` → `yarn snap --rust` |
| 360 | - Job name appears as "React Compiler (Rust) Tests" in GitHub |
| 361 | |
| 362 | --- |
| 363 | |
| 364 | *Generated 2026-04-10 from analysis of 141 Claude Code conversation trajectories.* |