I asked the engineering lead to sit for a short interview, in which I would ask him three questions about how, precisely, he intends to approach the business of reimplementing a seventy-country health platform in a different programming language without, as the folk saying has it, losing the patient on the operating table. He sat. He answered at some length and with the kind of patience I have come to associate with people who have been asked similar questions before, in similar rooms, over three decades. What follows is edited for length only. The voice is his.
1. Why open with a gateway in front of the Java core, instead of writing the whole thing in Go first
"The honest answer is that writing the whole DHIS2 Web API in Go from day one is a reimplementation of DHIS2, and I have seen that proposal made and quietly abandoned often enough that I treat it with respect but not with much hope. The Web API encodes behaviour, not just JSON shapes. Sharing and ACLs, org-unit scopes, category combos, period types, data approval, program rules, tracker import semantics, metadata import with dependency resolution. The Android Capture app depends on all of it. If we were to emulate that surface in Go from day one, we would be building, by the back door, a second DHIS2. That has been tried.
"The strangler-fig pattern lets us do something smaller and more honest. A Go gateway in front of the Java core, proxying everything by default. Compatibility is free on day one, because the Java core is still answering. Then we peel endpoints off, one at a time, with a shadow-mode harness that compares the Go response to the Java response for the same input. We retire a Java endpoint only when parity is proven. The first vertical slice is
/api/organisationUnits, because the semantics are small enough to hold in one engineer's head and the test corpus is tractable."I will add one caveat. The reason this path works at all is that the cost of reimplementing a single endpoint under modern conditions has fallen enough that a small team can afford to try. That is a new fact. Ten years ago, this discussion would have been theoretical."
The decision, for the record, is documented in the project's first Architecture Decision Record, ADR-0001, which the chief signed this morning along with two of his specialists. It is not a long document; it did not need to be.
2. What proves the port is actually correct
"The reference target is stock DHIS2 v43 running on the Sierra Leone demo dataset. That is the dataset HISP themselves use to back the play servers; it is the canonical realistic corpus for the platform. We run both backends against it. The differential oracle compares the responses.
"The oracle runs in two places. During development, every time a specialist writes a function with observable behaviour, the oracle fires a thousand simulated inputs through both the Go function and the Java endpoint and asserts bit-equal results after a short list of normalisations. We publish the normalisations; nothing is handwaved. Before an endpoint flips from 'proxied to Java' to 'handled by Go', the oracle runs a replay of real anonymised traffic through both backends; the result has to be clean before the switch flips. Nothing goes live on a feeling.
"The costs are modest in exchange. You get a system whose compatibility is proved per endpoint, by playback, on a public fixture, over hundreds of thousands of inputs. That is the kind of discipline that lets you tell a ministry CIO, honestly, that the switch is safe. In our sector that discipline is worth a lot."
3. The hardest open decision the program still has to make
"D1, the addon power model. I will say that even though I would rather be talking about the first endpoint. We have a lean toward what the brief calls Model B — metadata extension plus sandboxed hooks running out-of-process. But I would not pretend that is settled. Model A, an Odoo-style in-process ecosystem, delivers more addon power at the cost of isolation. Model C, Wasm components in-process, delivers isolation at the cost of the Python data-science stack. Each has real precedent and real cost; each wants a different runtime underneath it.
"We will resolve D1 the way you resolve most of these: by building the smallest piece of the thing we think we want, running two real addons against it, and seeing which model survives contact with the second addon. Not by writing another position paper. The position papers are in the drawer; they lost that round years ago.
"In the meantime, D4 — the legacy strategy — lets us make progress without blocking on D1. That is a design dependency we exploited deliberately when we laid out the opening moves. The first endpoint lands. The oracle proves parity. The specialists discover a dozen things we did not expect about how DHIS2 actually behaves under its documented behaviours. We write those discoveries up. By the time D1 forces a decision, we will have a lot more data to make it with."
What I took from the conversation
Three things, briefly, since the chief said more than I can carry here.
The first is that the opening move is deliberately small. A single read endpoint. A single demo dataset. One language on each side of the fence. A gateway between them. The ambition is not reduced; it is deferred, slice by slice, until each slice has earned its own ground.
The second is that the oracle is the serious discipline. Shadow-mode diffing is older than this project and older than most of its practitioners, but applying it to a national health-information platform, under a public fixture, as a hard gate, is unusual. I asked the chief whether he thought the sector was ready for this level of transparency about parity, and he said, briefly, "it was ready when I joined WHO in 1997; the sector just hasn't noticed yet." I let that one sit.
The third is that the method matters as much as the result. There is a short list of ways to kill a reimplementation of a large platform: write it all in a dark room for a year; translate the old code line-for-line; declare feature parity before any user tries it. The chief, from the opening moves, has declined all three. We will see how it goes.
— Mulberry

