Sample Dossier · survey of 2026-09-18

See what a read-only assessment actually produces.

Meridian Holdings · Legacy Systems Portfolio Dossier

Meridian Holdings is fictional. The three code bases are real: a small .NET data-access library written by one author between 2016 and 2025, a web application built in August 2013 that consumes that library at a 2013 version, and eShopOnWeb, the open-source .NET 8 e-commerce reference application with 641 commits by 83 authors and a live test suite.

What follows is an excerpt, lightly condensed. The full engineering Dossier runs twenty-one pages; a shorter executive brief for the CTO and lead architects is produced from the same artifacts. Both are downloadable below. Every technical figure traces to a named survey artifact. Business context the survey cannot see is marked as an assumption. Effort figures are planning bands, not quotes.

How to read the labels

  • Automated Tool-measured. Traceable to a named artifact.
  • Partial Tool-measured, then judged by an engineer.
  • Manual Human work the survey informs but does not perform.
  • Inferred Lifted from code with file and line. States what, not why.

1. Executive summary

What Meridian owns. Three .NET systems. Two are from one lineage: Needletail, a data-access library (3 modules, 29 files, one author), and CloudWars, a web application (8 modules, 128 files) built in 2013 that consumes Needletail at a 2013 version. The third, eShopOnWeb, is unrelated: a .NET 8 application (14 modules, 379 files) with a live test suite. The survey found no dependency between eShopOnWeb and the other two.

The recommended first move is a Confirm and Pin phase on all three systems, run alongside the dated runtime moves: interview the five authors who hold the history, resolve 118 package references against a live advisory feed, decide the library's version policy, clear the patterns that block pinning, pin the ten areas that need it, and retarget eShopOnWeb and the library's test application before their runtimes leave support on 2026-11-10.

What it buys. A behavioral baseline on all three systems, a known security posture, the authors' reasoning on record, and uninterrupted vendor support for the one system that still has it. Declining leaves the legacy pair changeable only by unverified edits and puts eShopOnWeb out of support within the quarter.

  • 61%of the survey is tool-driven by section weight: 5 sections automated, 7 partial, 2 manual
  • 168business rules lifted from code with file and line; one enforced two ways
  • 63migration-risk coding patterns to clear before behavior can be pinned
  • 12modernization types assessed per system. Each one that fits comes with an estimate, its basis and its confidence.

2. The portfolio at a glance

Automated inventory, dependency, and history figures; Partial rules, testability, and opportunities. With human interpretation.

Needletail CloudWars eShopOnWeb
What it isData-access library, 3 modules, 29 filesWeb application, 8 modules, 128 files, 7 projects (vendored package folders excluded).NET 8 e-commerce application, 14 modules, 379 files, 10 projects
History17 commits, 1 author, 2016 to 202524 commits, 3 authors, August 2013 to April 2015641 commits, 83 authors, 2017 to 2025; 17 commits since 2024
Public surface24 types, 124 methods, 2 areas56 types, 121 methods, 7 areas250 types, 244 methods, 7 areas
Runtime targets.NET Standard 2.0 (active); test app on .NET 9 (maintenance, ends 2026-11-10)5 × .NET Framework 4.5 and 2 × 4.0, all out of support since 2016-01-12.NET 8 for all 10 projects; maintenance, ends 2026-11-10
Packages2, both behind current41 in pre-SDK manifests; advisories not checked77 references, centrally versioned; advisories not checked
Test files / areas reached0 / 0 of 20 / 0 of 745 / 5 of 6
Business rules lifted4320105 (1 enforced two ways)
Migration-risk patterns12, five of them in one file14, ten of them static state37, sixteen in the one untested area
Clusters / proposed waves2 / 23 / 55 / 6
Opportunities4 (1 mechanical)13 (1 mechanical)6 (1 mechanical)
RelationshipsThe library CloudWars consumesUses Needletail at a 2013 version, with its own repository layer on topNo dependency on the other two found

Interpretation. The legacy pair is one problem with two faces. Needletail is small, structurally simple and still active, but one author, one 1,691-line file holding all 41 of its guards and 5 of its 12 migration-risk patterns, and no tests make it a single point of failure. CloudWars has not changed in eleven years, targets frameworks that left support in 2016, keeps game state in static fields, and consumes Needletail at a version thirteen years behind the library. Six of its eight modules form one tightly coupled cluster, so it moves as a unit or not at all.

eShopOnWeb is a different kind of asset. It is layered, tested and centrally configured; the survey found only six opportunities and none is a platform rewrite. Its risks are a calendar (one runtime target with under eight weeks of support left), a concentration of untested and hard-to-test code in one area (the administration client), and a history in which 83 authors mostly touched configuration while one wrote the commercial path.

3. Findings that change decisions

Each finding states what the data says, what it means, and what it costs to leave alone.

Unsupported and expiring runtimes

Automated dependency lifecycle

All seven CloudWars projects target .NET Framework 4.0 or 4.5, both out of support since 2016-01-12; the survey notes that such binaries run in place on 4.6.2 and later, which remain supported. eShopOnWeb's central build file sets .NET 8 for all ten projects, and Needletail's test application targets .NET 9. Both leave support on the same day, 2026-11-10, 53 days after the survey.

What it means. After 2026-11-10, no executable project in the portfolio targets a supported runtime. For CloudWars the exposure is not the runtime on the server, which a host can keep patched; it is that none of its projects can be built, tested or patched against a supported target. The eShopOnWeb move is one central edit across ten projects, so the constraint is time, not scope.

What it costs to leave alone. Any vulnerability disclosed against CloudWars' 2013-era web stack, or against eShopOnWeb's package family after November, has no vendor remediation path except in-house patching.

Assumption, to be confirmed with Meridian Which systems are internet-facing and which process personal or payment data. eShopOnWeb's account, two-factor and public-API surfaces suggest it does, which makes 2026-11-10 a compliance date.

The verification gap

Automated test census · Partial pinnability judgment

Needletail (22 files scanned) and CloudWars (73) have zero test files; all nine areas are test deserts. eShopOnWeb (245 files scanned) has 45 test files reaching five of its six areas; the administration client is reached by none.

What it means. In the legacy pair, no change can be verified before release except by undocumented manual testing, which blocks the runtime fixes above. The I/O evidence says pinning is feasible: eight of nine legacy areas and all six eShopOnWeb areas are rated "likely pinnable"; the CloudWars game module (61 I/O sites, 44 of them time-dependent) is rated "pin at seams".

What it costs to leave alone. Every change to the legacy pair, and every change to eShopOnWeb's admin client, is an unverified edit to production.

Knowledge concentration

Automated history · Partial interview targets

Needletail's two hottest files are 100% one author's work and change together half the time. CloudWars' web configuration is 100% one author's and its project file 83%, last touched a decade ago. eShopOnWeb has 83 authors, but 22 of its 25 concentrated files belong to one person, who holds the basket, cart and account code, the commercial path. Activity is down to 17 commits since 2024.

What it means. In each system, one person's absence removes the ability to explain why the core files are the way they are. The seeded knowledge bases carry fourteen open questions of the form "who besides this author understands this file?"

What it costs to leave alone. Every week without interviews raises the chance the answers are lost. Capturing them is days of effort in all three systems: the cheapest and most perishable item in the plan.

The dependency picture

Automated with a stated blind spot

No package advisory was checked in CloudWars or eShopOnWeb. CloudWars' 41 references sit in pre-SDK manifests; eShopOnWeb's 77 were read statically. "0 outdated, 0 advisories" in the source data means not checked, not clean. The posture of 118 package references is unknown. Resolving them is hours to days of mechanical work and precedes every runtime move.

What it costs to leave alone. An unknown number of published vulnerabilities in two web applications with external login.

4. The calendar

These findings get worse without anyone touching the code.

DateWhat it isStatus at survey
2016-01-12End of support for .NET Framework 4.0 and 4.5, the targets of all seven CloudWars projectsPassed, ten years ago. The binaries run in place on 4.6.2 and later, which remain supported
2026-11-10End of support for .NET 8, the single target of all ten eShopOnWeb projects53 days from the survey date
2026-11-10End of support for .NET 9, target of Needletail's test applicationSame day. Matters less if the application is a sample harness (to be confirmed)
April 2015Last change to CloudWarsEleven years without a commit; author availability decays with time

5. Business rules the code enforces

Partial Every rule is Inferred: lifted from source with file and line evidence, stating what the code does and not why. Where a comment and the code disagree, the code is authoritative.

The survey lifted 168 rules across the three systems: state vocabularies, validation limits, guards, thresholds, and author notes. A few of the kind it finds:

  • Catalog. An item's price must be between 0.01 and 1000 on create, and between 0.01 and 10000 on update. Both limits are live. Which applies depends on which path a request takes, and no comment records which is intended. The rule enforced two ways.
  • Sessions. A cookie is valid for 60 minutes; the admin user cache refreshes every 60 seconds; the default cache is 30 seconds; seeding retries up to 10 times.
  • Game engine. A worker role compares elapsed time against 30 seconds; a display name over 50 characters is handled specially. A command is one of eight states; a game action one of five.
  • Data access. 41 guards in one 1,691-line file: reject a blank connection-string or table name; the isolation level cannot change until the transaction is committed; insert and update reject a null item or an undeterminable primary key.
  • Author notes that describe unfinished production work. "Don't use this in production" and "change this to an environment variable" on authorization constants; "wire this up to actual email sending logic" on an email service that is a stub; a factory left unbuilt in the worker role.

The why requires interviews. Nothing above records why a price cap is 1000 or 10000, why a cookie lasts 60 minutes, or why a CloudWars turn times out at 30 seconds. Those answers, and any rule living only in someone's head, are the Manual half of this section, scheduled in Phase 0.

The rules that make CloudWars a game (turn order, damage, win conditions) are not in a form the survey can lift; they exist in method bodies and in people. The Dossier says so rather than guessing.

One hygiene finding: the usage table shows code under a misspelled namespace alongside the correctly spelled one. Any rename must account for both spellings.

6. What makes these systems hard to change

Partial This is not a style review. Only patterns with a direct line to "you cannot safely transform this yet" are reported. Formatting and naming are excluded; vendored code is skipped.

PrincipleNeedletailCloudWarseShopOnWebMigration consequence
Avoid shared mutable state31013Shared across every test in the process; characterization tests are hardest to write against exactly this
Dependency inversion314Cannot be exercised without the real dependency, so cannot be pinned before migration or swapped afterwards
Do not block on asynchronous work0012A known deadlock class; an async migration moves together or not at all
Method length218Too long to characterize with a focused test; migrated whole and verified by eye
Keep interfaces narrow200Easy to transpose two arguments of the same type, which no compiler catches
File size120Every diff is one no reviewer can fully verify
Fail visibly100A migration that breaks this path produces no error and no log line

Where the refactoring budget goes. Needletail: one file. CloudWars: the data-access layer, whose repository class keeps game state in static fields; no characterization test of it can run in isolation until that state is instance-scoped. eShopOnWeb: the administration client, at once the only untested area and the home of 16 of 37 patterns, including nine synchronous waits in one service.

Two rows need a human reading. The eight long eShopOnWeb methods are generated migration code and are regenerated rather than refactored. The two oversized CloudWars files are jQuery scripts committed inside the web project. And a pattern's absence is a statement about these checks, not a clean bill of health.

7. Modernization options

Automated From the survey's options report, which reads a readiness scan of every project and the client intake. The grading and every estimate are the tool's.

The report assesses twelve modernization types against each system, from an in-place platform upgrade to retire-and-replace, and grades each one. Fits: the code and the client's goals both call for it. Possible, not indicated: always available, but nothing has asked for it yet; it keeps its estimate as the comparison, and the report says what would make it a yes. Not assessed: a survey cannot judge it. No type is rejected.

TypeNeedletailCloudWarseShopOnWeb
Dependency replacementFits: its SQL client is superseded. 1 working dayFits: the pinned library release, the login library and the 2013 web stack are unmaintained or no longer serviced. 4 to 8 working daysPossible, not indicated: no unmaintained dependency detected. 2 to 3 working days
Platform upgrade in placeFits (test application). 1 working dayFits (all seven projects, all in the legacy project format). 3 to 5 working daysFits (all ten projects). 3 to 6 working days
Upgrade and containerizeFits. 1 to 2 working daysFits. 3 to 6 working daysFits. 3 to 6 working days
Module extractionPossible, not indicated: too few modules. 2 to 3 working daysFits. 3 to 6 working daysFits. 5 to 9 working days
Partial rewrite by layerPossible, not indicated. 1 working dayPossible, not indicated: fewer than two layer-shaped projects. 1 working dayFits, outside the recommended sequence. 2 to 3 working days
Language or stack migrationPossible, not indicated. 1 to 2 working daysFits: the web project's System.Web surface. 1 working dayPossible, not indicated. 2 to 3 working days
Full behavior-preserving rewritePossible, not indicated. 2 to 3 working daysPossible, not indicated. 5 to 10 working daysPossible, not indicated. 7 to 14 working days
Re-architecturePossible, not indicated. 2 to 3 working daysPossible, not indicated. 4 to 8 working daysPossible, not indicated. 5 to 9 working days
Recommended sequenceReplace, upgrade, containerizeReplace, upgrade, containerize, extract, migrateUpgrade, containerize, extract

The big-bang path next to the incremental one. A full rewrite becomes the choice if the client sets that appetite; a re-architecture, if they state a scale or service-boundary goal. The Dossier keeps both on the table with their estimates, so the comparison is visible: for CloudWars, 5 to 10 working days for the rewrite against 4 to 8 and then 3 to 5 for the recommended replacement and upgrade. It also says what that number leaves out: the rewrite preserves only business rules, data and contracts, and the estimate does not price the parallel run, the golden data, or the acceptance of a system in which every line is new. Cloud re-platform, data migration and lift-and-shift wait on a hosting or engine answer; retire-and-replace is not assessed, because build-versus-buy needs the market, not the code.

How to read the estimates. They have one basis: a pilot modernization of this same CloudWars code base, eight landed increments in 10.9 hours. Confidence is low throughout, and the bands exclude interviews, decisions, acceptance and sign-off. The survey's own opportunity list bands CloudWars' platform successors at months each. The Dossier reports both and says the distance between them is the honest measure of what is still uncertain.

Assumption, to be confirmed: the whole intake Meridian is fictional, so every intake answer took its default: keep the systems supportable, target the latest long-term-support release, upgrade in place where possible, hosting and budget undecided. A different answer changes the grading, so every "not indicated" here is a question for the client, not a verdict.

8. Recommended sequence

Partial Wave proposals, opportunity bands and option estimates are the tool's; the phasing is human judgment. No effort figure is a human estimate, and every one is at low confidence.

PhaseTrackWhat happensExit criterionThe tool's estimate
0. ConfirmAllReplace the assumed intake with the client's answers; interview the five dominant authors; resolve all 118 package references; decide the library version policy; triage the 13 author notes; settle the price cap; capture any manual regression practiceEvery open question has an owner; the intake and the version policy are written downNot estimated; hours to days per item
1. PinAllClear the blocking patterns (instance-scoped state in the repository class; seams in the game module; injected connection factories in the library; the synchronous waits and static state in the admin client), then pin the nine legacy areas and the admin clientZero test deserts; a pinnability judgment per area; the full suite green as the baselineCounted inside each option as its pins
2e. Dated upgradesDatedChange eShopOnWeb's central target to the next long-term-support runtime; update the package family per the advisory report; re-run the suite. Retarget the library's test application off .NET 9Suite unchanged on the new target; no project on an expiring runtime; completed before 2026-11-103 to 6 working days; 1 working day
2. LibraryLegacyReplace the superseded SQL client behind an adapter; update the 2 outdated packages; publish a current packageSuite unchanged; a confirmed consumer builds against the new package1 working day
3. CloudWarsLegacyRetire the empty placeholder project if confirmed; replace the unmaintained libraries behind adapters; convert all seven projects to the current format and retarget them, foundation firstSuite passes on the new targets; no legacy-format project; zero open advisories4 to 8, then 3 to 5 working days
4. OptionalAll, once hosting is decidedContainerize the upgraded builds; extract modules behind seams; move CloudWars' System.Web surface; replace one eShopOnWeb layerThe pinned suites pass in the new shapePer option, above

Phases 0, 1 and 2e are the first funding decision, and the dated track must finish by November. Needletail's 831-line method is deliberately not split before it is pinned; that is the change the survey warns "quietly changes behaviour". Phase 4 is decided, not assumed.

Assumption, to be confirmed Meridian's intent for CloudWars. If it is to be retired or frozen, Phase 3 does not apply; Phases 0 and 1 still do, because a frozen system still needs a security patch to be provable.

9. How each phase would be proven

Manual Written from the survey's stated method: pin current behavior, transform, prove parity.

Phase"Done" meansEvidence producedSign-off
0Every open question has an owner and, where answerable, an answerTwo advisory reports; interview transcripts filed as expert-testimony entries; the version-policy decision; the note triage; the price-cap decisionEngineering lead
1Every area has reaching tests and a pinnability judgment; blocking pattern rows closedTest census re-runs showing 0 deserts; coding-practices re-runs showing the shared-state, sync-over-async and dependency rows gone or accepted; suites in source controlEngineering lead, against the interview findings
2eEvery eShopOnWeb project and the library's test application builds, and every test passes, on the new targetsDependency inventory re-run: active runtime, 0 open advisories; unchanged suite results; build log dated before 2026-11-10Security owner; engineering lead
3All seven CloudWars projects build in the current format on a supported target, with a clean, checkable manifestReadiness and dependency re-runs: no legacy-format project, no runtime out of support; unchanged suite resultsSecurity owner; engineering lead
4The chosen option is in place and behavior is unchangedThe pinned suites passing in the new shapeEngineering lead and product owner

Each phase re-runs the same survey that produced this document, so the "after" evidence is in the same format as the "before".

10. What we do not yet know

A static survey sees files, references, manifests and commit history. It does not see runtime behavior, production data flows, actual usage, deployment topology, operational practice, or anything held only in people's heads. The Dossier lists every question it raised and cannot answer, each with a method and a rough cost.

  • Which systems are deployed, where, and on how many hosts? Decides whether the runtime and advisory findings are live exposure or dormant debt. Ask operations. Hours.
  • Are the five dominant authors available? Every "why" in the plan comes from them. If not, Phase 0 extends and characterization proceeds at higher risk. Hours.
  • Does anything else consume the library? One consumer found; "shared component" implies more. Search the repositories and package feeds. Days.
  • Which price cap is intended, 1000 or 10000? The code enforces both. Interview; deployment configuration.

The same survey, on your system.

Read-only, fixed scope, success criteria agreed in writing before we start. Tell us what the system does, how old it is, what it's built on, and what's making the question urgent.