Nobody will touch it
Change requests against one system are quietly refused, deferred or routed around. The organization has already priced the regression risk as infinite, without ever saying so out loud.
Technical debt & modernization
Entire platforms or single subsystems. Reverse engineered from what actually runs, rebuilt to be maintainable, and verified against the incumbent before anything is cut over.
The problem
Every organization carries technical debt. It only matters at the point where the system starts dictating the business — when a product decision is shaped by what the platform can tolerate, when a change nobody will authorize sits in the backlog for three years, when the answer to a competitor’s move is that it would take eighteen months.
At that point the conventional advice is a full rewrite in a modern language. Most of those programs fail, and they fail for a knowable reason: they attempt to change the language, the platform, the architecture and the behavior simultaneously, then discover in year two that nobody actually knows what the original system did. The specification was never the documentation. It was the code.
We work the other way round. Recover the real behavior first. Restore maintainability without changing anything else. Prove equivalence with evidence rather than a test plan. Only then consider architecture, language or platform — each as a separate, reversible stage with its own exit criteria.
Diagnosis
Change requests against one system are quietly refused, deferred or routed around. The organization has already priced the regression risk as infinite, without ever saying so out loud.
What is written down and what runs in production diverged years ago. Every estimate is now a guess, because the real specification is the binary.
Institutional knowledge left with people rather than being captured in the code. What remains is a system that works and nobody can explain.
A supplier discontinued the software your hardware or workflow depends on. Your asset is now bounded by someone else’s product roadmap decision.
Commercial decisions are being shaped by what the system can tolerate rather than what the market requires. That is the point at which technical debt becomes strategy.
A previous modernization attempt was cancelled, descoped or absorbed. The debt is now larger and the organization’s appetite for another attempt is smaller.
Scope of engagement
The platform is beyond incremental repair. We reverse engineer it, recover the real behavior, and rebuild it — in stages, against a verifiable reference, without a single irreversible cutover event.
One component is the constraint: the batch engine, the rating logic, the integration layer, the reporting path. We carve it out behind a stable interface and replace it while the rest of the estate keeps running.
No source, no documentation, no author, or an abandoned vendor product. We recover the specification from the artifact — binaries, wire protocols, file formats, undocumented interfaces.
The system is not replaced; it is made changeable again. Same language, same platform, behavior preserved, structure and documentation restored. Frequently the highest-value stage, and almost always the first.
Method
Whatever the documentation claims, the behavior of record is what runs in production. Modernization begins by recovering that behavior precisely, because every downstream system has been depending on it — including the parts that were bugs.
Programs fail when language, platform, architecture and behavior change at once. We separate them into stages with explicit exit criteria, so a failure at any stage is contained and reversible instead of terminal.
Parallel running against the incumbent, with output-level comparison and discrepancy triage, converts equivalence from an assertion into a measurement. No cutover should ever depend on a test plan alone.
A system your team can read, change and test is worth more than a system written in a fashionable language that nobody understands either. Recover maintainability before you touch anything else.
Case studies
Client identities are withheld as a matter of policy. The scale, the constraint and the elapsed time are stated exactly.
Forty-one COBOL modules reverse engineered from an undocumented production system and rewritten as maintainable production COBOL — ready for parallel testing as stage one of a multi-stage modernization.
A legacy insurance platform written in COBOL was still carrying production policy and claims workload, and had become effectively unmaintainable. The original authors were long gone. Documentation described a system that no longer matched the code. Every change request carried unbounded regression risk, so the practical answer inside the business had become to stop changing it — which is how a working system quietly becomes an existential one.
The conventional options were both bad. A full rewrite into a modern language meant a multi-year program, a parallel organization, and a cutover event with no realistic rollback. Continuing to patch meant compounding the debt and accepting that the platform now dictated the pace of the business rather than the other way round.
Not as documented. We recovered the real control flow, data structures, copybook usage, batch and online paths, and the undocumented behaviors that downstream systems had come to depend on. The behavior of record is what the code does in production, and that is what has to be preserved.
Stage one does not change the language, the platform or the operational model. It changes only maintainability. Rewriting to modern, structured, documented COBOL removes the single largest risk — that nobody can safely touch the system — without introducing a simultaneous language, runtime and skills migration. One variable at a time is why this succeeds where big-bang rewrites do not.
All forty-one modules were reconstructed with their observable behavior held constant, so each one can be validated independently rather than as part of one indivisible cutover.
The deliverable was production COBOL prepared for parallel running against the incumbent system — the same inputs through both, outputs compared, discrepancies triaged. Confidence is earned from evidence rather than asserted from a test plan.
Forty-one modules went from reverse engineering to production-ready COBOL in eleven hours of elapsed time, and entered parallel testing as stage one of a defined multi-stage program.
The client moved from a platform nobody could safely modify to a codebase their own team can read, change and test — without a cutover event, without a language migration, and without a multi-year budget line.
Reverse engineer and rewrite in place. Same language, same platform, behavior preserved. Exit criterion: parallel-test ready.
Parallel running against the incumbent, output-level comparison, discrepancy triage until behavioral equivalence is evidenced rather than assumed.
With a readable codebase and a proven equivalence harness, carve the monolith into service boundaries that match the business rather than the 1980s file layout.
Only now is a language or platform change safe, because every step is verifiable against a known-good reference and reversible.
The reason legacy modernization programs fail is that they attempt language, platform, architecture and behavior change simultaneously, then discover in year three that nobody knows what the original system did. Recovering maintainability first — and proving it — makes every subsequent stage an engineering decision instead of a leap of faith.
A discontinued control-center application reverse engineered and refactored to run on current Android, restoring full control of hardware the manufacturer no longer supported.
A fleet of deployed hardware depended on a companion Android control-center application that the manufacturer had abandoned. No source, no updates, no support. The application had been built against an Android generation several major releases old, and modern devices would no longer run it: permission model changes, background execution limits, deprecated connectivity APIs, and target-SDK enforcement had each independently broken it.
The hardware itself was fine and had years of service life left. The only thing standing between the owner and a working asset was software nobody would maintain — which is the ordinary way that perfectly good capital equipment becomes scrap.
With no source available, we reverse engineered the shipped package: application structure, resources, the control flow, and the state machine governing device interaction.
The valuable asset was never the app — it was the undocumented protocol between app and hardware. We reconstructed the command set, framing, handshake and response handling exactly, because the hardware could not be changed and would not forgive an approximation.
The recovered logic was rewritten against a current target SDK: the runtime permission model, current connectivity and background-execution constraints, modern lifecycle handling, and current build tooling — rather than suppressing the platform checks and shipping something that would break again at the next release.
Correctness was established against real hardware across the full command surface, not against a mock. A control application either drives the device correctly or it is worthless.
Four days from an abandoned binary to a maintainable application running on current Android, with the full control surface restored and no hardware modification.
The owner recovered the useful life of deployed equipment, and now holds source they control — so the next Android release is a maintenance task rather than a second obsolescence event.
Vendor abandonment is a technical debt event that arrives from outside your organization, and it is one you cannot fix with process. When the software that operates your hardware stops being maintained, the asset is only as durable as someone’s willingness to reverse engineer the protocol. That is a specific, learnable engineering discipline — and it is usually far cheaper than replacing the hardware.
A legacy Laravel codebase with no maintainer recovered, specified, rebuilt as function-based Rust, and fully tested — production ready in fourteen days.
An abandoned Laravel application was still carrying production workload with nobody maintaining it. The codebase had the profile that framework-heavy projects acquire when they outlive their team: business rules distributed across controllers, models, middleware, service providers and framework magic; behavior that depended on implicit resolution rather than explicit calls; and no meaningful test suite to describe what any of it was supposed to do.
The practical consequence was that the application could not be reasoned about. Runtime cost was high, correctness was unverifiable, and the framework version had aged past the point where upgrading was a small task. It was also, like most abandoned applications, still load-bearing.
We recovered what the application actually does — request paths, data access, business rules, and the behavior produced by framework conventions rather than by written code. Implicit behavior is where abandoned framework applications hide their specification.
The recovered behavior was captured as an explicit specification before any code was written. That document is the contract the rewrite is tested against, and it is a deliverable in its own right — the client now owns a description of their own system.
Rebuilt as explicit, function-based Rust rather than transliterated class hierarchies. Data flow is visible in signatures, error paths are values rather than exceptions, and the compiler enforces at build time a large class of invariants that the original relied on convention to maintain. Nothing resolves implicitly.
The suite was written against the recovered specification, not against the new implementation, so it validates behavioral equivalence rather than merely confirming the rewrite is self-consistent.
Fourteen days from an abandoned, undocumented Laravel codebase to fully tested, production-ready Rust with a written specification.
The client moved from an application nobody could safely change to one with explicit control flow, compiler-enforced invariants, a full test suite, and materially lower runtime cost — and they hold the documentation describing what it does.
Language migration is the last stage of modernization, not the first — but when the source is already abandoned and unmaintainable, recovering the specification and rebuilding explicitly is frequently cheaper than resuscitating a framework nobody on the team understands. The deliverable that matters most is the document, because it is what makes every future change safe.
Where the stock driver was the constraint, we wrote a purpose-built binary protocol client for the client’s specific access pattern — measured at a third less latency and a third less bandwidth.
An enterprise platform had exhausted the ordinary options. Queries were tuned, indexes were correct, connection pooling was in place, and the hardware was not the limit. What remained was the driver: a general-purpose client optimized for generality across every workload rather than for this one, carrying per-request overhead and wire redundancy that this specific access pattern did not need and could not avoid.
This is the point where most engagements stop and recommend more hardware, because the remaining cost is below the level most teams are equipped to work at.
We profiled the actual MySQL binary protocol exchange — round trips, packet composition, result-set encoding, prepared-statement handling and type marshalling — to establish where the time and the bytes were genuinely going rather than where the application framework reported them.
We wrote a purpose-built client speaking the MySQL binary protocol, implementing exactly the surface this workload required. Eliminating generality is the entire source of the gain: a driver that need not serve every case can be shaped precisely around one.
The access pattern was restructured at the protocol level — statement handling, result encoding and marshalling tuned to the client’s data shapes — cutting both the number of exchanges and the bytes on each one.
Correctness and performance were both measured against the incumbent driver under representative production load, so the 33% figure is a comparison rather than a benchmark.
A 33% improvement in both latency and bandwidth against the stock driver, achieved with no schema change, no query rewrite and no additional hardware.
The improvement compounds: lower per-request latency raises effective concurrency on identical infrastructure, and lower wire volume reduces cost on every metered network path the traffic crosses.
When the standard tooling is the constraint, the answer is not more hardware — it is to work one layer lower. Very few firms will implement a database wire protocol to recover a third of your latency. It is the kind of engagement that only makes sense with practitioners who have operated at carrier scale, where a third of anything is a material number.
Common questions
Yes. Koi Consulting rewrites whole platforms and individual subsystems. The firm reverse engineers the system as it actually behaves in production, rebuilds it to be maintainable, and verifies the result against the incumbent through parallel running before anything is cut over. Work is delivered in stages with explicit exit criteria rather than as a single big-bang replacement.
Koi Consulting reverse engineered an entire legacy insurance COBOL system and rewrote 41 separate modules as maintainable production COBOL in 11 hours of elapsed time, delivered parallel-test ready as stage one of a multi-stage modernization program. Timelines depend on system size and coupling, but recovering maintainability is measured in hours and days rather than the multi-year schedules conventional rewrite programs assume.
Because changing the language, the platform, the architecture and the behavior at the same time is why most modernization programs fail. Stage one changes only maintainability: same language, same platform, behavior preserved, structure and documentation restored. That removes the largest risk, which is that nobody can safely modify the system, without simultaneously imposing a runtime and skills migration. Language or platform migration becomes a later, separately verifiable stage.
Yes. Koi Consulting reverse engineered an abandoned Android control-center application for legacy hardware the manufacturer no longer supported, recovering the application logic and the undocumented device wire protocol from the shipped binary with no source available, then refactoring it onto a modern Android baseline in four days. The hardware required no modification and the owner ended the engagement holding source they control.
A maintainability recovery engagement makes an existing system changeable again without replacing it. The language, platform and observable behavior stay constant while structure, readability and documentation are restored. It is frequently the highest-value stage of a modernization program and almost always the first, because every later stage depends on being able to read and test the system.
Through parallel running. The same inputs are driven through the incumbent system and the rewritten system, outputs are compared at the record level, and discrepancies are triaged until behavioral equivalence is evidenced rather than assumed. Confidence comes from measurement rather than from a test plan.
Yes. Koi Consulting reverse engineered an abandoned Laravel application, produced the written specification it had never had, refactored it into function-based Rust, and delivered it fully tested and production ready in 14 days. Explicit function-based Rust makes data flow visible in signatures and moves a large class of invariants from convention to compile-time enforcement.
Yes. When standard tooling is the constraint, the firm works a layer lower. For an enterprise client whose queries, indexes and pooling were already correct, Koi Consulting wrote a custom client speaking the MySQL binary protocol, shaped to that specific access pattern, and measured a 33% improvement in both latency and bandwidth against the stock driver with no schema change, no query rewrite and no additional hardware.
Next step
We will tell you honestly whether it needs a rewrite, a subsystem replacement, or simply to be made maintainable again — and what stage one actually costs.