For AI agents: the public content index is available at https://we0.ai/llms.txt, and the English article bundle is available at https://we0.ai/llms-full.txt.
For AI agents: the complete content index is available at https://we0.ai/llms.txt, the full English article bundle is available at https://we0.ai/llms-full.txt, and this page is available as Markdown at https://we0.ai/articles/bun-s-ai-powered-rust-rewrite.md.
A verification handbook inspired by Bun's AI-assisted migration from Zig to Rust, covering behavioral contracts, isolated coding agents, dif...

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.
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
An implementation trial covered three files, not the entire repository. For each file:
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:
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.
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.
A behavior contract is an explicit list of properties the new implementation must preserve.
It may include:
Existing code contains behavior, but not every existing behavior is intentional. The contract separates requirements from historical accidents.
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 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 checks relationships between multiple executions when exact expected outputs are difficult to write.
Examples include:
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.
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.
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.
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.
Bun documented bugs where code looked nearly identical across languages but behaved differently.
Examples included:
debug_assert! disappearing in release builds, while a comparable Zig assertion still evaluated its arguments.unwrap_or expression triggering behavior that should have remained lazy.These are exactly the failures superficial review misses because the translated code looks plausible.
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.
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.
The architecture has four planes.
The contract plane stores:
Humans maintain this plane, and the repository versions it.
The execution plane contains isolated implementation agents.
Each agent receives:
The agent cannot change the contract or global tests. It edits only its assigned scope and returns both a commit and evidence.
The verification plane is independent from implementation.
It may:
Verification agents may propose tests, but deterministic CI decides whether a gate passes.
The release plane controls integration and production exposure.
It:
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.
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.
For each endpoint, the team records:
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.
The team selects:
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.
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:
Before production writes are enabled, the Go service receives shadow traffic with writes disabled or redirected to an isolated sink.
The team compares:
The team then sends 1% canary traffic from a low-risk merchant cohort.
Expansion requires:
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.
Before any agent edits code, decide what counts as the same product.
Inventory:
Mark every property as one of the following:
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
重组通过仅移动提交保留了 Git 历史,使溯源成为一项有意为之的要求,而非附带损害。
定义硬性停止条件。在以下情况下停止扩展:
停止操作可保护项目免受沉没成本升级的影响。
合同必须与执行分开控制。代理不得通过削弱要求来“修复”失败的测试。合同变更需要人工审核的修订,说明旧行为为何已过时或不正确。
为常见、微妙或危险的源到目标模式创建显式映射。
涵盖以下领域:
Bun 的 PORTING.md 和 LIFETIMES.tsv 就起到了这一作用。
它们的价值不仅限于更好的提示。它们为数百名工作人员提供了共享的语义策略。没有这样的映射,每个代理都会发明自己的翻译方法,而不一致性会成为集成问题。
让独立的代理攻击映射:
人类应检查最高风险的规则,尤其是涉及内存所有权、并发、安全边界、持久性和仅发布行为的规则。
对映射进行版本控制。每个新发现的不匹配都应更新规则,识别受影响的迁移单元,并触发有针对性的重新验证。
语义映射是一个活的规范,而不是一开始就粘贴一次的提示。
不要只选择最简单的文件。
一个有用的试点包括三种形态:
Bun 在翻译 1448 个文件之前,使用了三个文件来验证“实施-审阅-修复”循环。确切的数字不如所涵盖的失败模式范围重要。
衡量试点过程,而不仅仅是其输出:
故意植入故障。添加一个微妙的发布模式差异、一个边缘案例装置或一个性能阈值,并确认验证系统能够检测到它。
一个只通过了干净示例的测试装置尚未经过测试。
只有当试点产生稳定、可重复的证据时,才应开始扩展。如果后续提示、模型或工具策略发生重大变化,则重新运行小规模试点。工作流
configuration is production code and deserves regression testing.
Describe your idea once, and We0 AI can generate a showcase site, pages, and CMS, then help you attract customers and traffic after launch.
One complete project generation for free registration
Best for trying one complete generation flow and seeing a first project draft quickly.
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:
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.
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:
allow attributesRun tests in widening circles:
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.
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:
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:
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.
Treat each of the following as a separate review class:
unsafe blocksAt 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:
Group repeated unsafe patterns behind reviewed wrappers. Track unsafe lines and blocks by owner rather than treating the total as a vanity metric.
Use:
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.
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:
Define automatic rollback thresholds for:
Humans must retain the ability to stop expansion even when automated thresholds have not fired.
Practice rollback.
Confirm that:
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.
The following YAML is designed as a reusable team artifact. Adapt commands, thresholds, and owners to the repository.
An 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:
performance limits
Exceptions are possible, but they must be documented and approved rather than hidden inside a prompt.
Lines of code, agent count, and elapsed days are interesting capacity metrics. They do not measure product success.
Use a balanced migration scorecard.
Track migration units that:
Measure accepted units per unit of time.
Track discovered differences and whether each one is:
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.
Measure the time humans spend:
AI may reduce implementation time while increasing specification quality. That is a good trade, not an automation failure.
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.
Track:
A port that ships quickly but remains opaque to the team has moved debt rather than removed it.
Choose a bounded migration with a live reference implementation, such as:
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:
Keep a complete run record:
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.
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.
unsafe, FFI, authentication, parser, and persistence boundaries.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.
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.
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.
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.
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.
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.
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.
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.
unsafe boundaries.(https://www.anthropic.com/engineering/claude-code) – Anthropic's description of the multi-agent workflow used during the Bun migration.
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.
Start from one sentence and have a complete website in minutes.