Skip to main content
Geeks Around Globe
Information & Tech
Enterprise migration

IBM Chief Enterprise Architect Anshul Kumar Purohit on Why Migration Programs Live or Die on the Boundary Decisions Nobody Sees

Enterprise migration succeeds when teams can defend critical boundary decisions, verify behavioral equivalence, document tradeoffs, and prove rewritten systems preserve their original functionality.

The IBM Inventor and enterprise architect who reviews decisions at a scale where a bad call costs years, not sprints, spent 72 hours applying that same discipline to hackathon-scale language ports. He found that the difference between an engineered rewrite and a generated one comes down to whether a team can defend every non-obvious decision it made.

In July 2025, the U.S. Defense Advanced Research Projects Agency committed roughly five million dollars to a program with a blunt name: TRACTOR, short for Translating All C TO Rust. A team spanning the University of Wisconsin-Madison, UC Berkeley, the University of Illinois, and the University of Edinburgh is building a system that combines formal verification with large language models to convert legacy C codebases into memory-safe Rust, not as a translation exercise but as a program whose stated bar is that the output must "preserve the core functionality of the original C program and also satisfy desired security properties." Getting that wrong at national-infrastructure scale is not a bug ticket. It is the kind of failure a Senate committee asks about.

Anshul Kumar Purohit spends his working life adjacent to that same class of decision, just inside a different institution. As Chief Enterprise Architect at IBM, he has spent more than nineteen years designing and reviewing enterprise architecture at a scale where a wrong call compounds for years before anyone can undo it. He holds patents that read like a checklist for exactly this kind of work: one uses community detection with domain-node filtering to identify subdomains and function boundaries inside large monolithic legacy applications, the precise problem a team hits the moment it tries to carve a real codebase out of one language and rebuild it in another. He is an IBM Inventor, a Master Certified Solution Architect with The Open Group, an IBM Certified Senior Architect at Level 2 Expert, and sits on both IBM's Invention Development Board and its Architect Certification Review Board, the committee that decides whether another architect's reasoning holds up.

That background made him an unusual fit for Port Mortem 2026, a Hackathon Raptors event that gave 148 teams 72 hours to take a real, widely used open-source library and rewrite it in a language it was never written in, on the condition that the rewrite could prove, not just claim, that it behaved exactly like the original. Purohit reviewed a batch of those submissions the way his day job trains him to: not by asking whether the code compiled, but by asking whether the team could produce the paper trail an enterprise architecture review board would demand before signing off on a production migration.

The bridge that found its own bugs

TinyColor, the JavaScript color manipulation library, was ported to Rust by a team called AIBros and compiled to a live, in-browser color lab. The interesting engineering was underneath the demo. TinyColor depends on Math.pow, and Math.pow is not guaranteed to be bit-identical across JavaScript engines, a well-documented source of floating-point non-determinism that has quietly broken cross-platform reproducibility in far larger systems than a color library. The team's response was to treat that as a research question rather than an inconvenience: they narrowed the divergence down to a specific 256-integer domain, then tabulated exactly how V8 behaves across it before deciding which of that behavior their Rust port needed to reproduce and which it could safely diverge from.

"The fuzz harness is the most rigorous correctness proof in this review cycle, and it's architecturally motivated, not bolted on," Purohit writes. The differential harness ran the pinned reference JavaScript and the Rust port side by side in the same process, comparing 45 operations per generated input at bit-level IEEE-754 precision, so that NaN, negative zero, and infinity stayed distinct instead of collapsing into each other under naive comparison. A 300-second run produced 689,345 test cases and just over 31 million individual comparisons with zero divergences.

What makes the submission worth studying, in Purohit's reading, is that the same architectural decision that made that verification possible is also what generated every defect the team found in its own code. The bridge between the Rust core and the JavaScript-facing shim runs through a single JSON-RPC dispatch function instead of forty-five separate FFI signatures, a simplification that made the differential harness tractable to write and also the exact surface where a handle-table memory leak lived undetected until roughly 4.6 million constructed color objects into a longer run. "A 60-second run would have reported zero divergences and been honest about it," he notes, "because the handle-table leak only triggered after 4.6 million colours were constructed. The 5-hour cumulative budget is what found it." The team's own numeric core, jsnum.rs, reproduces JavaScript's rounding and string-parsing quirks not because they are elegant but because TinyColor's real call sites depend on them in specific, load-bearing ways. Where the port silently corrected one of those quirks rather than reproducing it, the team caught it, proved the divergence was unobservable, and documented the decision rather than hiding it.

A 427-service monolith and a credential cache that has to match

Where TinyColor is a small, self-contained library, an anonymous team's port of the AWS CLI is closer to the kind of system Purohit's patent work is actually built for: a sprawling, decades-accreted piece of software spanning 427 distinct AWS services, being carved apart and rebuilt one boundary at a time. The team reached roughly 40 to 45 percent completion by symbol count and said so plainly, rather than rounding up.

"The test infrastructure is the most trustworthy in this review cycle," Purohit writes. The suite pulls 33,395 test cases directly from data files AWS itself publishes: 13,825 endpoint-resolution cases spanning all 427 services, 625 protocol serialization cases, and 30 SigV4 signature checks compared byte-for-byte against AWS's own reference suite. Because the fixtures are AWS's own data rather than hand-authored expectations, a disagreement is definitionally the port's bug, never a mistyped test. The endpoint harness wraps each of the 13,825 cases in its own panic boundary so that one failure cannot silently swallow the rest of the report, and it asserts on the case count itself, a small but telling detail, since a harness that quietly stops iterating and reports zero failures looks identical to a passing one unless something checks that it actually ran everything it claims to have run.

The dependency choices carried the same discipline. The team picked ureq over the more common reqwest because reqwest's blocking client spawns a full async runtime per client, a resource-governance decision rather than a style preference. It pulled in the zlib-rs backend for flate2 specifically because the default miniz_oxide backend produces different deflate output than CPython's own zlib implementation, a 97-versus-95-byte discrepancy that broke an upstream test. And it took a dependency on the sha1 crate for exactly one reason: the assume-role credential cache key is computed as sha1(json.dumps(...)), and that hash has to match Python's output byte-for-byte, or every cached credential silently invalidates and forces a fresh multi-factor prompt. None of that is documented as a policy in a markdown file. It is enforced: the CI job counts occurrences of unsafe in the codebase and fails the build if the count is non-zero.

Purohit was equally direct about where the port fell short. A differential fuzzer running 445 random commands in 90 seconds surfaced 322 divergences from the real CLI, a 72 percent divergence rate on that sample. The team's own fuzz log broke the causes down honestly, and the largest single bucket, 119 cases, turned out to be one cosmetic error-message format difference rather than a correctness failure. But roughly 200 cases across the remaining buckets included exit-code differences, and for a command-line tool, the exit code is the public contract that shell scripts actually depend on. "The error-reporting layer is the public contract for shell scripts," he writes; fixing the two largest remaining buckets would close most of the gap and move the submission into a materially different category.

Reproducing a bug on purpose

A team calling itself DƎCAYING MINDS ported cJSON, the widely used C JSON library, to Rust, including its patch-and-diff utilities, a smaller and less-traveled corner of the library that most ports skip. Their differential harness closed a loop that unit tests alone cannot: it generated a JSON patch using the new Rust code, applied that patch using the real, unmodified upstream C function cJSONUtils_ApplyPatchesCaseSensitive, and validated the result with the real cJSON_Compare. That proves interoperability with the actual C library, not just internal self-consistency against a hand-written oracle.

The decision Purohit singled out sits at utils.rs:851-862. The real C implementation of cJSON_Utils.c's patch-creation logic has no case cJSON_Raw: in its switch statement; it silently falls through to a default no-op whenever a raw JSON value differs between two documents being diffed. That is, by any normal definition, a bug in the original library. The team did not fix it. They reproduced the exact silent no-op in the Rust port, documented the decision inline in the code, explained the rationale in their own decision log, and then wrote a separate bug report describing the upstream defect with a reproduction case and a suggested fix, ready to file against the original project. "The two-track approach, reproduce the bug for equivalence, report it upstream separately, is exactly the right posture for a port," Purohit notes. It is a small decision, but it is the same decision an enterprise migration has to make constantly: match the system you are replacing first, and treat "the old system was wrong" as a separate conversation from "the new system disagrees with it."

When the policy that matters isn't written in the README

Not every finding in Purohit's reviews concerned the port's own code. A team called ams0301 rebuilt Go's oklog ULID library in Rust with what he described as airtight behavioral equivalence: 27 of 27 original Go tests ported with named cross-references back to the source, 554 million fuzz iterations with zero divergences, and a written performance methodology covering full latency percentile distributions. The team even used Rust's type system to make an overflow invariant impossible to violate at compile time rather than catching it at runtime, and kept the library dependency-free and no_std-capable, which removes an entire category of supply-chain risk by construction.

The gap he flagged was one line most reviewers would never think to check: the project's Dockerfile pulled its base images from docker.io, the public Docker Hub. "IBM policy requires images from registry.redhat.io (UBI-minimal)," he wrote. "The multi-stage build structure is sound, only the FROM lines need changing." It is not a comment a generic code reviewer would make, because it is not a general best practice. It is the specific base-image policy of one specific enterprise, applied because Purohit happens to be the person who enforces it internally. The rest of the finding was equally precise: the fuzz harness thoroughly exercised the library's encode and decode paths but never reached the one component doing anything stateful, the monotonic entropy generator responsible for guaranteeing strictly increasing IDs under concurrent load, which was also the exact site of a latent bug the team had already documented.

The paper trail is the point

Every one of these teams produced some version of the same artifact: a written log explaining what they decided, why, and what they gave up in the process. It has become common practice at Port Mortem for teams to ship a file called DECISIONS.md alongside their code, and while none of the participants likely knew it, they were independently reinventing a documentation pattern with a name and a fifteen-year history. Software architect Michael Nygard formalized it in a widely cited 2011 post as the Architecture Decision Record: a short document capturing one significant decision, the context that forced it, and its consequences, so that six months later nobody has to reverse-engineer the reasoning from the code alone. The practice exists because the alternative, a decision that lives only in one engineer's memory, does not survive a team's first reorganization, let alone a multi-year migration program.

The verification method underneath nearly every strong submission also has a name older than most of the participants: differential testing, formalized by William McKeeman in a 1998 paper for Digital's own technical journal. The idea is almost embarrassingly simple: run two implementations against the same input and look for disagreement. It remains one of the few testing techniques that can catch a semantic bug with no crash and no failed assertion, because it does not require anyone to have anticipated the specific input that exposes the divergence. Every fixture-hash, every byte-for-byte comparison against a live original, every fuzzer counting divergences instead of asserting a pass, is a hackathon-scale instance of a methodology that ships in production compiler test suites and certificate-validation fuzzers today.

Why the stakes keep getting bigger

None of this is a hypothetical exercise in language preference. Microsoft's Azure CTO, Mark Russinovich, has said publicly that it is time to stop starting new C and C++ projects and to write in Rust instead wherever a garbage collector is not disqualifying, and components of the Windows kernel, including region-handling code in Win32k, long one of the most consistent sources of elevation-of-privilege vulnerabilities in the operating system, are now shipping in production as Rust. A separate initiative inside Microsoft has stated an explicit goal of eliminating C and C++ from the company's codebase entirely by 2030, using a combination of algorithmic code analysis and AI-assisted translation at a scale measured in a million lines of code per engineer per month. DARPA's TRACTOR program is the same bet made at the level of national infrastructure, with formal verification standing in for the kind of manual review no team could perform at that scale.

IBM's own research organization has been working the adjacent problem for years. Mono2Micro, developed by IBM Research and first published in 2021, uses AI-driven partitioning and dependency analysis to identify functionally cohesive boundaries inside monolithic Java applications and propose a microservice decomposition. It is the same underlying question Purohit's own patented invention addresses from a different angle: where, inside a system nobody fully understands anymore, do the real seams actually run. Port Mortem gave 148 teams 72 hours to answer a smaller version of that question for a single library each, under conditions where the only way to earn a high score was to show the receipts. The teams Purohit rated highest were the ones who understood, whether they had ever heard the terms differential testing or architecture decision records or not, that the actual deliverable was never the port. It was the evidence that the port could be trusted.



Port Mortem 2026 was organized by Hackathon Raptors, a Community Interest Company supporting innovation in software development. The event featured 148 teams competing across 72 hours, porting real open-source libraries between C, TypeScript, Python, JavaScript, and Go into Rust, Go, and C++ implementations verified against the originals through hashed test suites, differential fuzzing, and documented benchmarks. Anshul Kumar Purohit served as a judge evaluating submissions on Functionality & Reliability, Behavioral Equivalence, Code Quality, and Innovation.

Newsletter

From obsession to clarity — one original question every week.

We answer one noisy topic at a time, in full. No daily roundup, no thread bait — just the question, the principles, and the system.