Bun 的 AI 驱动 Rust 重写:百万行代码迁移的验证手册

一份受 Bun 从 Zig 迁移到 Rust 的 AI 辅助实践启发的验证手册,涵盖行为契约、隔离编码智能体、差分测试、模糊测试、unsafe 代码审查、进度度量和安全发布。

发布于 2026年7月12日generalGEO 评分: 011 次阅读
图片展示的是Bun的AI驱动Rust重写相关内容。背景为深色,左侧有一个卡通人物头像,右侧有Rust齿轮图标。图片中间大字“Bun’s AI-Powered Rust Rewrite”中“AI-Powered”为紫色,“Rust Rewrite”为蓝色。下方有两段代码,左侧为JavaScript代码,右侧为Rust代码,分别展示了函数处理请求的示例。图片与文档中介绍Bun AI辅助从Zig到Rust迁移的内容相呼应,直观呈现了AI在Rust重写中的应用。

Bun’s AI-Powered Rust Rewrite: A Verification Playbook for Million-Line Migrations

Introduction

The headline is difficult to ignore: Bun reportedly migrated a major implementation from Zig to Rust in 11 days using a dynamic Claude Code workflow. The published accounts describe thousands of commits, as many as 64 Claude agents, roughly 780,000 lines of Rust, two adversarial reviewers for each implementation unit, and a progression from code that did not compile to a port that could pass the test suite and ship.

The wrong lesson is that language rewrites have become one-click tasks. The useful lesson is that implementation throughput and verification throughput are now separate engineering problems.

AI agents can generate code faster than a human team can read it. Once that happens, conventional pull-request review can no longer serve as the primary safety mechanism. Teams need a system that converts a massive probabilistic change into small claims backed by machine-checkable evidence.

Bun’s later production report made this unusually concrete. The team reported 19 known regressions, all subsequently fixed; 11 rounds of security review; continuous coverage-guided fuzzing across parsers; and about 27,000 Rust lines inside unsafe blocks out of roughly 780,000 total lines. These facts do not weaken the migration story. They show what serious migration work looks like after the impressive demo is over.

This guide turns that experience into a reusable verification playbook. The goal is not to copy Bun’s scale. It is to provide a method for any migration—language ports, framework replacements, API modernization, database conversions, or repository-wide refactors—where AI coding agents can write more code than the team can responsibly inspect line by line.

Key Takeaways

  • Bun’s rewrite shows that AI agents can compress implementation time. It does not show that verification time can be removed.
  • The transferable asset is the migration system: written behavior contracts, risk maps, small pilots, isolated workers, independent reviewers, deterministic gates, and recoverable commits.
  • Compilers and legacy test suites catch different failure classes. Neither catches every cross-language semantic mismatch, release-mode difference, performance regression, or unsafe boundary.
  • Large diffs require evidence-oriented review. Humans should inspect contracts, risk hotspots, counterexamples, test gaps, and rollout decisions rather than pretending every generated line receives equal scrutiny.
  • Teams can adopt the same pattern without attempting a million-line rewrite: require agents to prove behavior one slice at a time, then grant broader autonomy only after measured results.

What Bun Actually Did—and What the Headline Leaves Out

The engineering account began before large-scale code generation.

Jarred Sumner reportedly spent about three hours creating PORTING.md, which mapped recurring Zig patterns to Rust. A separate workflow analyzed structure fields, proposed Rust lifetimes, sent those choices to two adversarial reviewers, and serialized the results into LIFETIMES.tsv. These artifacts were also reviewed manually.

The first implementation trial covered three files, not the entire repository. For each file:

  1. One agent implemented the Rust version.
  2. Two fresh agents reviewed behavioral equivalence and compliance with the migration documentation.
  3. Another agent applied the approved fixes.

Only after this pilot did the work fan out across 1,448 Zig files.

The first large-scale run failed. Agents shared a workspace and used commands such as git stash, git stash pop, and git reset --hard. Their changes interfered with one another. The workflow was then changed to prohibit unsafe coordination commands and use four worktrees, each with 16 agents.

That detail matters more than the peak line-generation rate. Parallel coding is a distributed-systems problem. Shared state, conflicting writers, expensive global operations, ownership, and recovery all need explicit rules.

The generated code did not work immediately. Bun used compiler errors as a queue and advanced one crate at a time. At one point, around 16,000 compiler errors were assigned to agents. The loop used one fixer, two reviewers, and one application agent, while limiting how often expensive commands such as cargo check and Git operations could run.

This was not magical translation. It was staged convergence driven by deterministic feedback.

Anthropic’s dynamic-workflow announcement reported that 99.8% of the existing suite passed at the time of the initial write-up, while explicitly noting that the port was not yet in production. Bun’s later article covered the work that followed: security reviews, fuzzing, production regressions, semantic fixes, and reduction of unsafe code.

Read together, the sources describe two different milestones:

  • Implementation-complete enough to merge
  • Evidence-complete enough to run safely

Terms You Need to Know: Port, Oracle, Differential Testing, and Unsafe Surface

These definitions matter because a team cannot verify a migration until it agrees on what the evidence must prove. They also separate an agent’s confidence statement from an externally checkable result.

Port

A port reimplements software in a new language, runtime, platform, or framework while preserving a defined set of behaviors.

“Preserve behavior” needs a boundary. A port may preserve public APIs and outputs while intentionally changing internal architecture, performance characteristics, error messages, or unsupported edge cases.

Behavior Contract

A behavior contract is an explicit list of properties the new implementation must preserve.

It may include:

  • Inputs and outputs
  • Error behavior
  • Ordering
  • Side effects
  • Concurrency semantics
  • Resource limits
  • Supported platforms
  • Performance budgets
  • Observability requirements

Existing code contains behavior, but not every existing behavior is intentional. The contract separates requirements from historical accidents.

Test Oracle

A test oracle determines whether an output is correct.

A unit-test assertion is one oracle. A reference implementation, protocol specification, golden file, database invariant, or human-authored rule can also act as an oracle.

Anthropic’s guidance on long-running scientific coding emphasizes that autonomous work needs references, measurable goals, or test suites so agents can determine whether they are making progress.

Differential Testing

Differential testing sends the same inputs to the old and new implementations, then compares observable results.

It is especially useful when the old implementation is trusted but a complete formal specification does not exist. Agreement does not prove that both implementations are correct, but disagreement creates a precise investigation queue.

Metamorphic Testing

Metamorphic testing checks relationships between multiple executions when exact expected outputs are difficult to write.

Examples include:

  • Serializing and parsing a value should preserve it.
  • Reordering independent inputs should not change a set-valued result.
  • Running an idempotent migration twice should not change state on the second run.
  • Retrying the same idempotency key should not produce a duplicate side effect.

Unsafe Surface

The unsafe surface is code where the target language’s normal guarantees are weakened or bypassed.

In Rust, unsafe may be necessary at C or C++ FFI boundaries, inside custom allocators, or for low-level runtime integration. The raw count is not a verdict. The team needs ownership, invariants, tests, and an explicit plan for each unsafe boundary.

Escaped Defect

An escaped defect is a migration-induced bug discovered after the gate that should have detected it—after merge, canary deployment, release-candidate testing, or production rollout.

Escaped defects are feedback about the verification system, not only the implementation.

The Causal Chain: Why Faster Generation Requires Stronger Verification

Agent parallelism changes the economics of implementation. If 64 workers translate files at the same time, code-generation time may shrink dramatically. The dependency graph, target-language semantics, and shared test environment do not disappear. Throughput simply moves the bottleneck downstream.

Bottleneck 1: Integration

Individually reasonable files may fail when compiled together.

Bun’s roughly 16,000 compiler errors and cyclic crate dependencies illustrate the gap between local translation and global consistency. The compiler is an excellent deterministic oracle for types, ownership, lifetimes, names, and some control-flow properties. It is not an oracle for product behavior.

Bottleneck 2: Semantic Equivalence

Bun documented bugs where code looked nearly identical across languages but behaved differently.

Examples included:

  • Side effects placed inside Rust debug_assert! disappearing in release builds, while a comparable Zig assertion still evaluated its arguments.
  • An eager unwrap_or expression triggering behavior that should have remained lazy.
  • Byte-slice and boundary semantics differing between implementations.
  • Odd-length UTF-16 inputs exposing a crash.

These are exactly the failures superficial review misses because the translated code looks plausible.

Bottleneck 3: Review Correlation

If the same model writes and reviews a change using the same context and assumptions, it may reproduce the original mistake.

Anthropic’s Claude Code best-practices documentation recommends using a fresh reviewer context. The reviewer sees the diff and the standard without inheriting the author’s reasoning. Independence does not guarantee correctness, but it reduces shared-context bias.

Bottleneck 4: Operational Evidence

Tests can pass while latency doubles, memory use grows, one operating-system target breaks, or observability disappears.

The larger the change, the more likely the team discovers a violated requirement only after deployment. That is why a migration plan must include canaries, rollback, telemetry comparison, and a process that converts every escaped defect into a new contract rule or test.

The causal conclusion is simple:

AI does not eliminate migration cost. It moves the cost from typing toward specification, harness design, evidence review, and deployment control.

A team that ignores this shift may finish generating code quickly and then spend months determining whether the rewrite actually works.

A Verification Architecture for AI-Driven Migrations

The architecture has four planes.

1. Contract Plane

The contract plane stores:

  • Public behavior
  • Compatibility promises
  • Intentional changes
  • Supported platform matrix
  • Performance budgets
  • Security constraints
  • Observability requirements

Humans maintain this plane, and the repository versions it.

2. Execution Plane

The execution plane contains isolated implementation agents.

Each agent receives:

  • One migration unit
  • Relevant source files
  • The approved contract
  • The semantic map
  • Narrowly scoped tools
  • Targeted checks

The agent cannot change the contract or global tests. It edits only its assigned scope and returns both a commit and evidence.

3. Verification Plane

The verification plane is independent from implementation.

It may:

  • Compile the candidate
  • Run targeted and global tests
  • Execute old-versus-new differential checks
  • Fuzz parsers and protocol boundaries
  • Scan security-sensitive code
  • Benchmark representative workloads
  • Ask fresh reviewers to search for counterexamples

Verification agents may propose tests, but deterministic CI decides whether a gate passes.

4. Release Plane

The release plane controls integration and production exposure.

It:

  • Merges in dependency order
  • Produces reproducible artifacts
  • Identifies builds with immutable versions or hashes
  • Runs shadow traffic where possible
  • Expands canaries gradually
  • Monitors service-level indicators
  • Preserves a tested rollback path

We0 AI can sit between these planes as an orchestration and evidence layer. Teams can use tasks to assign migration slices, isolate worktrees, attach contracts, collect test output, and require review before work advances.

The important boundary is that orchestration coordinates evidence. It does not turn an agent’s claim of success into release permission.

Example Scenario: Migrating a Payment Service from Python to Go

Consider a 120,000-line Python payment service being migrated to Go. The business objective is to reduce tail latency and simplify deployment.

A dangerous prompt would be:

Rewrite this service in Go and make all tests pass.

That prompt leaves transaction semantics, error behavior, monetary precision, idempotency, and rollout undefined.

Step 1: Write the Contract

For each endpoint, the team records:

  • Request and response schemas
  • Authorization rules
  • Idempotency-key behavior
  • Currency rounding
  • Retry semantics
  • Database transactions
  • Event ordering
  • Error codes
  • Telemetry requirements

It also marks intentional changes, such as removing a Python-specific debugging header. The team defines the supported platform and dependency matrix, then sets p95 and p99 latency budgets and a peak-memory ceiling.

Step 2: Choose Three Pilot Slices

The team selects:

  1. A pure currency-formatting module
  2. An idempotency repository with database side effects
  3. A read-only HTTP endpoint

The first tests mechanical translation. The second tests transactions and concurrency. The third tests HTTP compatibility.

One implementation agent handles each slice. Fresh reviewers receive only the contract, the old source, the proposed diff, and the validation commands.

Step 3: Use the Old Service as a Differential Oracle

A sanitized corpus of historical requests is replayed against both versions.

Responses are normalized only where the contract permits differences, then compared. For write paths, both implementations run against disposable database snapshots. The resulting rows and emitted events are compared.

Metamorphic tests then:

  • Repeat the same idempotency key
  • Change harmless JSON key ordering
  • Introduce retry timing variations
  • Exercise boundary monetary values

Step 4: Shadow and Canary the New Service

Before production writes are enabled, the Go service receives shadow traffic with writes disabled or redirected to an isolated sink.

The team compares:

  • Latency distributions
  • Error classifications
  • Dependency calls
  • Trace shapes
  • Memory use
  • Event behavior

The team then sends 1% canary traffic from a low-risk merchant cohort.

Expansion requires:

  • Zero unexplained financial mismatches
  • Error-rate parity
  • Latency within the agreed budget
  • A successful rollback drill

The implementation may still move quickly. Safety comes from transforming “rewrite the service” into observable claims.

This example also shows why domain expertise remains essential. Agents can translate code, but payment experts know that duplicate events, rounding differences, and retry behavior are business requirements.

Phase 0: Define the Migration Contract and Stop Conditions

Before any agent edits code, decide what counts as the same product.

Inventory:

  • Public APIs
  • CLI behavior
  • File formats
  • Database effects
  • Environment variables
  • Telemetry
  • User-visible error messages
  • Supported platforms
  • Performance characteristics

Mark every property as one of the following:

  • Preserve
  • Intentionally change
  • Deprecate
  • Unknown

Unknowns are not permission to guess. They become discovery tasks.

Run the old system, search issues and changelogs, inspect production traces, or ask maintainers. Bun’s pre-migration source-tree reorganization preserved Git history through move-only commits, making provenance an intentional requirement rather than collateral damage.

Define hard stop conditions. Stop fan-out when:

  • Pilot mismatch rates exceed the threshold.
  • Workers repeatedly modify protected global tests.
  • The compiler-error queue grows faster than it closes.
  • Target performance misses the budget.
  • A rollback artifact cannot be built.
  • Evidence is incomplete or unreadable.

Stopping protects the project from sunk-cost escalation.

The contract must be controlled separately from execution. An agent must not “fix” a failing test by weakening the requirement. Contract changes require a human-reviewed amendment explaining why the old behavior is obsolete or incorrect.

Phase 1: Build a Semantic Map Before Large-Scale Generation

Create explicit mappings for common, subtle, or dangerous source-to-target patterns.

Cover areas such as:

  • Ownership and lifetime rules
  • Nullability
  • Exceptions and error handling
  • Integer overflow
  • Time calculations
  • String encoding
  • Concurrency primitives
  • Allocator ownership
  • FFI
  • Debug-versus-release behavior
  • Platform-specific code

Bun’s PORTING.md and LIFETIMES.tsv served this purpose.

Their value was not limited to better prompts. They gave hundreds of workers a shared semantic strategy. Without such a map, every agent invents its own translation approach, and inconsistency becomes an integration problem.

Ask independent agents to attack the map:

  • Give one reviewer source-language semantics.
  • Give another target-language risks.
  • Give a third representative code examples.
  • Require concrete counterexamples.

Humans should inspect the highest-risk rules, especially those involving memory ownership, concurrency, safety boundaries, persistence, and release-only behavior.

Version the map. Every newly discovered mismatch should update the rules, identify affected migration units, and trigger targeted revalidation.

The semantic map is a living specification, not a prompt pasted once at the start.

Phase 2: Design Deliberately Difficult Pilots

Do not choose only the easiest files.

A useful pilot includes three shapes:

  1. A simple, representative unit
  2. A dependency-heavy unit
  3. A semantic hotspot

Bun used three files to validate the implement-review-fix loop before translating 1,448 files. The exact number matters less than the range of failure modes covered.

Measure the pilot process, not only its output:

  • Did workers respect file ownership?
  • Were commits atomic?
  • Did reviewers find real defects or mostly produce noise?
  • Could the fixer apply suggestions without violating the contract?
  • Was the evidence still readable?
  • How much context and compute did each accepted unit consume?

Seed faults deliberately. Add a subtle release-mode difference, an edge-case fixture, or a performance threshold and confirm the verification system detects it.

A harness that has only passed clean examples has not yet been tested.

Fan-out should begin only when the pilot produces stable, repeatable evidence. If the prompts, models, or tool policies later change substantially, rerun the small pilot. Workflow configuration is production code and deserves regression testing.

Phase 3: Fan Out with Isolation, Ownership, and Atomic Commits

Create migration units aligned with the dependency graph.

File-level partitioning is convenient, but it may be the wrong boundary when behavior crosses modules. Assign one writer to each unit and make ownership machine-readable. Workers may read dependencies but can edit only their scope unless they request a coordinated change.

Use separate worktrees, containers, or ephemeral virtual machines where practical.

Bun’s shared-workspace failure shows why. Restrict destructive Git commands and expensive global build commands for leaf workers. Let a coordinator perform ordered integration.

Short-lived credentials and network allowlists reduce the impact of prompt injection or dependency exfiltration. Anthropic’s sandboxing guidance describes filesystem and network boundaries as foundations for safer autonomy.

Every accepted unit should produce an atomic commit containing:

  • Source identifier
  • Applicable contract rules
  • Commands executed
  • Test and check outputs
  • Reviewer results
  • Approved exceptions

Git becomes both a coordination and recovery mechanism.

Anthropic’s long-running workflow guidance recommends meaningful commits and testing before each commit, because recoverable history prevents a long agent run from becoming one opaque artifact.

Do not optimize for lines per minute. Optimize for verified units per hour.

High generation throughput combined with a growing integration queue is negative progress.

Phase 4: Treat Compiler Errors and Tests as Queues, Not Proof

Compiler output creates structured work.

Group errors by ownership unit or dependency layer, remove duplicate cascades, and fix root causes before leaf symptoms.

Prohibit shortcuts unless the contract explicitly allows them, including:

  • Empty stubs
  • Ignored results
  • Broad allow attributes
  • Disabled assertions
  • Placeholder implementations
  • Tests changed only to make the candidate pass

Run tests in widening circles:

  1. Unit tests for the changed module
  2. Contract tests at public boundaries
  3. Integration tests across dependencies
  4. Cross-platform suites
  5. Full regression testing

Keep failed output as an artifact. A final green run without history can hide whether workers repeatedly weakened checks along the way.

Where possible, separate test authorship from implementation.

One agent can derive edge cases from the contract and old implementation, while another writes the port. Lock approved compatibility tests so implementation workers cannot modify them. Fresh reviewers should ask whether the code passes for the intended reason.

Bun’s production regressions demonstrate the gap between a green suite and semantic completeness.

A release-only HMR failure came from a side effect inside debug_assert!. An odd-length UTF-16 crash reflected different slice behavior. Every escaped defect should become both a permanent regression test and a new semantic-map rule.

Phase 5: Add Differential Testing, Fuzzing, and Performance Budgets

Run the old and new implementations against the same corpus.

Compare:

  • Exit codes
  • Normalized output
  • Error categories
  • Side effects
  • Database state
  • Emitted events
  • Traces

Build boundary-value generators for:

  • Empty inputs
  • Maximum sizes
  • Malformed encodings
  • Times around the Unix epoch
  • Concurrent races
  • Platform-specific paths
  • Resource exhaustion

Fuzz parsers and protocol boundaries continuously.

Bun reported that its coverage-guided fuzzers executed parser code roughly 100 billion times and generated around 15 fix pull requests. The absolute number depends on the workload. The transferable pattern is to connect crash discovery to reproducible tests, agent-proposed fixes, and human-reviewed pull requests.

When users depend on performance, performance is part of behavior.

Benchmark:

  • Cold start
  • Throughput
  • p50 latency
  • p95 latency
  • p99 latency
  • Peak memory
  • Binary size
  • Build time
  • CPU under representative workloads

Compare distributions rather than averages. Set budgets before migration so the team cannot rationalize regressions after investing heavily in the rewrite.

Run soak tests as well. Memory leaks, descriptor leaks, queue growth, allocator fragmentation, and rare races may require hours or days to surface.

A language with stronger memory-safety guarantees can remove entire bug classes while still introducing different allocation, scheduling, or performance behavior.

Review Unsafe Code, FFI, and Security Boundaries Separately

Treat each of the following as a separate review class:

  • unsafe blocks
  • FFI calls
  • Raw pointers
  • Custom allocators
  • Cryptographic boundaries
  • Parsers
  • Deserializers
  • Permission checks
  • Authentication logic
  • Persistence boundaries

At the time of the source report, Bun described roughly 27,000 lines inside unsafe blocks out of about 780,000 Rust lines, much of it related to C and C++ integration.

That surface needs more than ordinary code review.

Require an invariant comment near every unsafe boundary:

  • What must be true?
  • Who establishes the invariant?
  • How long does the pointer remain valid?
  • Which thread owns the value?
  • Which test exercises the condition?

Group repeated unsafe patterns behind reviewed wrappers. Track unsafe lines and blocks by owner rather than treating the total as a vanity metric.

Use:

  • Static analysis
  • Sanitizers
  • Dependency audits
  • Fuzzing
  • Manual security review

Bun’s 11 security-review rounds are evidence of continued hardening, not evidence that defects were absent.

Automated security review should complement domain review, especially around authentication, sandbox escape, secrets, and supply-chain changes.

Review the migration mechanism itself. Agents execute repository content, build scripts, and tool output. A compromised dependency or hidden instruction in source code can influence the run.

Filesystem isolation, network restrictions, scoped tokens, and immutable CI checks reduce this risk.

Release in Stages and Practice Rollback Before You Need It

Merge is not release.

Build versioned artifacts from known commits, toolchains, dependency locks, and evidence manifests. Keep the old implementation buildable.

If old and new binaries can coexist, add a runtime switch or routing layer rather than irreversibly replacing the path.

Start with shadow execution when side effects can be isolated.

Then canary by:

  • Internal users
  • Low-risk tenants
  • Platform
  • Region
  • Traffic percentage

Define automatic rollback thresholds for:

  • Correctness mismatches
  • Crash rate
  • Latency
  • Memory
  • Error categories
  • Support signals

Humans must retain the ability to stop expansion even when automated thresholds have not fired.

Practice rollback.

Confirm that:

  • The old artifact starts successfully.
  • Schemas remain compatible.
  • Queued work can drain.
  • Observability identifies which implementation served each request.
  • The measured rollback time meets the operational target.

Rollback documentation that has never been executed is only a hypothesis.

After every escaped defect, update the contract, semantic map, test corpus, and risk model.

Bun’s 19 known regressions are useful because they expose recurring translation hazards. A migration is complete when the new implementation is operable and the team has learned from it—not when the generated diff is merged.

Reusable AI Migration Policy and Evidence Manifest

The following YAML is designed as a reusable team artifact. Adapt commands, thresholds, and owners to the repository.

We0 AI or another orchestration system can attach this policy to migration tasks and require the evidence manifest before review.

ai_migration:
  name: payments-python-to-go
  contract: docs/MIGRATION_CONTRACT.md
  semantic_map: docs/PORTING_RULES.md
  old_reference: artifacts/payments-python@sha256:OLD
  new_candidate: artifacts/payments-go@sha256:NEW

  worker_policy:
    isolation: ephemeral_worktree
    one_writer_per_unit: true
    forbidden_commands:
      - "git reset --hard"
      - "git stash"
      - "git push --force"
    editable_paths: ["cmd/", "internal/", "tests/migration/"]
    protected_paths: ["tests/contracts/", "docs/MIGRATION_CONTRACT.md"]

  required_gates:
    compile: "go build ./..."
    unit: "go test ./..."
    contracts: "./scripts/run-contract-tests.sh"
    differential: "./scripts/compare-old-new.sh --corpus fixtures/replay"
    fuzz: "./scripts/fuzz.sh --hours 24 --unique-crashes 0"
    security: "./scripts/security-scan.sh --severity high"
    performance:
      p99_latency_regression_pct: 5
      peak_memory_regression_pct: 10
    platforms: [linux-amd64, linux-arm64]

  independent_review:
    fresh_context: true
    reviewers_per_unit: 2
    require_counterexample_search: true

  rollout:
    shadow_hours: 48
    canary_percentages: [1, 5, 20, 50, 100]
    rollback_artifact_required: true
    rollback_drill_required: true

  evidence_manifest:
    include:
      - contract_version
      - source_and_target_commits
      - changed_units
      - commands_and_exit_codes
      - differential_mismatches
      - fuzzing_summary
      - benchmark_distributions
      - unsafe_or_ffi_inventory
      - reviewer_findings
      - approved_exceptions
      - rollback_drill_result

This policy deliberately prevents implementation workers from editing the contract or approved contract tests.

It requires:

  • Reference artifacts
  • Independent review
  • Quantitative performance limits
  • Rollout evidence
  • A tested rollback path

Exceptions are possible, but they must be documented and approved rather than hidden inside a prompt.

Measure Verified Progress, Not Generated Volume

Lines of code, agent count, and elapsed days are interesting capacity metrics. They do not measure product success.

Use a balanced migration scorecard.

Verified Unit Throughput

Track migration units that:

  • Compile
  • Pass targeted contract checks
  • Receive independent review
  • Integrate without regression

Measure accepted units per unit of time.

Mismatch Closure

Track discovered differences and whether each one is:

  • Explained
  • Fixed
  • Approved as intentional
  • Still unresolved

Escaped Defects

Track defects that pass a gate that should have caught them.

Each escaped defect should identify a missing contract rule, test, oracle, review step, or rollout threshold.

Human Attention

Measure the time humans spend:

  • Defining contracts
  • Resolving ambiguity
  • Reviewing high-risk code
  • Investigating mismatches
  • Operating deployment

AI may reduce implementation time while increasing specification quality. That is a good trade, not an automation failure.

Compute and Tool Cost

Measure total model, compute, and tool cost per accepted unit.

Dynamic workflows may consume more tokens than ordinary sessions. Parallelism is justified when it reduces waiting time for high-value work without creating a larger verification backlog.

Post-Migration Maintainability

Track:

  • Startup time
  • Build speed
  • Change-failure rate
  • Review latency
  • Defect density
  • Ownership of unsafe modules
  • Ease of debugging
  • Quality of operational documentation

A port that ships quickly but remains opaque to the team has moved debt rather than removed it.

How a Team Can Start Without a Million-Line Rewrite

Choose a bounded migration with a live reference implementation, such as:

  • One SDK version change
  • One framework subsystem
  • One CLI command
  • One service endpoint

Write a one-page behavior contract and three risk-focused pilot cases.

Use separate agent tasks for implementation and review so their contexts remain independent.

Before implementation:

  1. Lock the acceptance checks.
  2. Require the implementer to return a commit and evidence, not a prose claim.
  3. Ask the reviewer to find counterexamples and identify missing tests.
  4. Run the checks in CI outside the model.
  5. Expand only to the next dependency layer after the pilot succeeds.

Keep a complete run record:

  • Prompt
  • Model
  • Tool scope
  • Source commit
  • Target commit
  • Changed paths
  • Checks
  • Failures
  • Reviewer findings
  • Exceptions
  • Cost
  • Final decision

This record lets the team compare harness versions and investigate defects without guessing what the agent saw.

Use a simple adoption rule:

Autonomy must be earned.

A workflow that repeatedly produces verified units may receive a broader file scope or longer unattended runtime. It does not automatically receive deployment permission.

Capability, evidence, and authority remain separate.

Limitations: What the Bun Case Does Not Prove

Bun is an unusual project.

Its creator led the migration, had deep knowledge of the codebase, and held direct architectural authority. The old implementation had a large test suite, Rust provided strong compiler feedback, and the project could use substantial parallel compute.

Most teams will not share all of those advantages.

The case was also presented through Anthropic, and the source article says the work used a prerelease Claude Fable 5 model. It is valuable primary evidence, but it is not an independent vendor comparison.

Claims about how long a human team would have needed are counterfactual estimates. Teams should not make procurement decisions from one successful migration.

The 19 reported regressions are known regressions, not a guarantee of the complete count. Fuzzing executions and security-review rounds measure effort, not the absence of defects.

The strongest defensible conclusion is modest:

Large AI-driven migrations are feasible when paired with strong deterministic feedback and expert orchestration, but their risk remains an engineering problem after code generation is complete.

That conclusion is still meaningful. Teams can attempt modernization projects that were previously delayed by cost, provided they budget for specification, verification, and controlled rollout at the same scale as implementation.

Practical Migration Checklist

  • Define preserved, changed, deprecated, and unknown behaviors.
  • Inventory platform, performance, telemetry, error, and side-effect contracts.
  • Build a semantic map for risky source-to-target patterns.
  • Protect contracts and approved tests from implementation workers.
  • Run difficult pilot units before repository-wide fan-out.
  • Isolate writers and restrict destructive Git and network operations.
  • Require atomic commits with commands, outputs, and contract references.
  • Use fresh-context adversarial reviewers for high-risk units.
  • Run compiler, unit, contract, integration, and cross-platform gates.
  • Compare old and new implementations on representative corpora.
  • Add metamorphic, fuzz, sanitizer, and performance checks.
  • Inventory unsafe, FFI, authentication, parser, and persistence boundaries.
  • Preserve a reproducible rollback artifact and run a rollback drill.
  • Roll out through shadow and canary stages with automatic stop thresholds.
  • Convert every escaped defect into a contract or verification improvement.
  • Measure verified units, mismatches, human attention, cost, and maintainability.

FAQ

What did Bun rewrite in Rust?

Bun migrated a major implementation that had previously been written in Zig into Rust. The published account describes roughly 780,000 lines of Rust and a highly parallel AI-assisted workflow, followed by extensive testing, security review, fuzzing, and production hardening.

Did AI complete Bun’s Rust rewrite without human review?

No. Human-authored migration rules, manual artifact review, isolated workflows, compiler feedback, independent agent reviewers, security review, fuzzing, and production rollout controls all played important roles. The case is better understood as AI-accelerated engineering than unattended code conversion.

Why are existing tests not enough for a language migration?

Existing tests usually cover only part of the observed behavior. They may miss release-only semantics, platform differences, performance regressions, unsafe boundaries, telemetry changes, or edge cases that were never encoded in the suite.

What is differential testing in a code migration?

Differential testing runs the old and new implementations with the same inputs and compares their observable outputs and side effects. It is particularly useful when the old system is trusted but no complete formal specification exists.

Why should implementation and review agents use separate contexts?

A fresh reviewer is less likely to inherit the authoring agent’s assumptions and reasoning errors. The reviewer can focus on the contract, diff, evidence, and counterexamples rather than defending the implementation path that produced the change.

How should teams review unsafe Rust code during migration?

Every unsafe block or FFI boundary should have a named owner, documented invariants, targeted tests, and a clear explanation of pointer validity, lifetime, and thread ownership. Static analysis, sanitizers, fuzzing, dependency review, and manual security review should be applied separately from ordinary code review.

What metrics should an AI-assisted migration track?

Track verified unit throughput, mismatch closure, escaped defects, human attention, compute cost, rollout health, and post-migration maintainability. Lines generated and agent count are capacity metrics, not proof of correctness.

Can a small team use this playbook without running dozens of agents?

Yes. Start with one bounded component, a written behavior contract, three risk-focused pilots, separate implementation and review contexts, deterministic CI gates, and a tested rollback path. Scale the workflow only after it repeatedly produces verifiable results.

Related Tools

  • Bun: An all-in-one JavaScript and TypeScript toolkit whose Rust migration provides the main case study for this playbook.
  • Rust: A systems programming language with strong compile-time safety guarantees and explicit unsafe boundaries.
  • Claude Code: Anthropic’s agentic coding environment, used in the dynamic workflow described by the source material.
  • GitHub Actions: A CI/CD platform suitable for deterministic compile, test, security, benchmark, and evidence gates.
  • cargo-fuzz: A standard fuzzing tool for Rust projects built on libFuzzer.
  • Miri: A Rust interpreter that can detect certain forms of undefined behavior in unsafe code.

Related Links

Summary

Bun’s Rust rewrite demonstrates that AI coding agents can compress implementation time dramatically, but it also shows why verification must become a first-class engineering system. Contracts, semantic maps, isolated workers, independent review, differential testing, fuzzing, performance budgets, and staged rollout are what turn generated code into credible migration evidence.

The practical lesson is not to copy the number of agents or lines of code. It is to break a migration into bounded claims, require deterministic proof for each claim, and expand autonomy only after the workflow repeatedly produces reliable results.

A large AI-assisted rewrite is complete only when the new system is verified, operable, recoverable, and understood—not when the generated code has been merged.