02Active public demo
.NET Modernization Harness (YARP & Shadow Runner)
A legacy .NET monolith is not rewritten in one go. This harness moves one slice at a time, compares the new service with the old one on real traffic and only cuts over when parity allows it.

Context
Applications on .NET Framework, MVC and classic Entity Framework stay in production because they work. Rewriting them whole is a risk almost nobody can take, and migrating them piecemeal without a safety net is another: every slice moved can change a behaviour nobody documents today.
The harness applies the Strangler Fig pattern with shadow execution. A gateway receives all the traffic and decides per route who answers: the monolith or the modern API. One family of routes, say orders, can migrate while invoices stay on the monolith. Before the cut-over, the new version runs in parallel and its responses are compared with the monolith's.
The repository includes the two stand-ins (a monolith that answers in PascalCase and a modern API that answers in camelCase), the gateway, the comparator, a demo that starts the three processes and a command-line tool that produces the parity report.
Architecture
The YARP gateway forwards each request according to its route. In shadow mode the monolith keeps answering the caller and the request is replayed against the modern API; the comparator analyses both JSON documents by meaning, not byte by byte, and records every difference. The parity report summarizes what was recorded and decides whether a route is ready to cut over.
Decisions
- Migrate by route, not by rewrite. The Strangler Fig pattern leaves the monolith as the default answer and moves one family of routes at a time; whatever matches no migrated route keeps going to the legacy system.
- Semantic JSON comparison. The monolith and the modern API need not serialize the same way: the comparison normalizes field names and lets you declare ignored fields, such as timestamps or the response's origin, so only real differences count.
- The parity report as a continuous integration gate. The tool sends the same requests to both systems, compares and writes a self-contained HTML report. Its exit codes distinguish ready, not ready and bad arguments; an empty report is never ready.
- Deliberately different stand-ins. The two sample services answer with different conventions on purpose, so the demo shows real differences instead of a trivial exercise. The public demo is a static page with no server, in Spanish and English.
What you can verify in the demo
- Move the migrated-traffic control and watch the orders route move to the modern API while the invoices route stays on the monolith.
- Read a shadow-run panel with both responses side by side: one matches and the other differs in an amount, with the field counts behind each verdict.
- Follow the four-step walkthrough: carve out the slice, run in the shadow, compare and cut over.
- Open two sample parity reports: one not ready, with a differing field and a missing one, and one ready, with the ignored fields declared.