polycratia

The ugliest function in the payment service I inherited had eleven branches and no comments, plus a variable called tmp2.

I wanted to delete it on day one.

The plan looked reasonable: finish the Python 2 to 3 migration, then carve the payment attribution layer out of the monolith and rewrite it properly. Normalized requisites, deterministic matching, clean code. I had built that layer before, from scratch, more than once. I knew what good looked like.

The migration went fine. The rewrite went fine too, right up until real money started moving through it.

Then unmatched payments started piling up in the exception queue. Not many at first. Enough that someone had to work them by hand every morning.

Every one of them traced back to a branch I had removed.

A reference field that arrived truncated from one bank and full from another. A partial payment that had to attach to an existing obligation instead of opening a new one. A duplicate that was a genuine second transfer, not a retry. None of that was in any spec. It was in the code, because someone before me had learned it the expensive way and encoded it where it would actually run.

I put the branches back one at a time, each with a test named after the failure it prevents. The function is still ugly. It is now also documentation.

So when someone asks me what to ask before a rewrite, I have a list of five questions, and one of them outranks the rest: what does this code know that no document does?

The way I answer it now is boring and it works. Before I touch anything, I instrument the old path. Log which branch fires, how often, and on what input. Let it run through a full billing cycle, because the interesting cases are monthly, not daily. Branches that never fire are dead and I delete them with a clear conscience. Branches that fire are requirements, and I owe each one a test before it disappears.

A rewrite is not a chance to be right from first principles. It is a migration of knowledge, most of it undocumented, some of it load-bearing, and all of it yours the moment you merge.

I write more about working inside inherited systems here: https://polycratia.com/c/bc9dbe56

If you have inherited something you badly wanted to rewrite, you probably already know which piece of the mess turned out to be load-bearing.

react

$ new-project --brief

or email hey@polycratia.com