Claims about modernization tools are cheap, so this post is a
walkthrough of the example committed in the repository rather
than a hypothetical. The source: libraries/petro/,
roughly 4,800 lines — seven fixed-form F77 decks written between
1988 and 2004 (black-oil PVT correlations and rock-property
routines: bubble point, viscosity, oil relative permeability,
Peaceman well indices, and neighbors), behind a 2003 F90 facade.
The target: an importable Python package and a verified FastAPI
service. The rule: the Fortran is never edited.
What the decks actually contain
Fixed-form F77 with COMMON blocks and INCLUDE decks. Routines like
PVTRS and KROIL are typed functions —
DOUBLE PRECISION FUNCTION — which matters because
naive discovery patterns only allow a single token before
FUNCTION and skip every one of them. The original
nativegate run had exactly that defect; it found 25 of 49 routines
and generated a service exposing half the API with no warning. That
number — 25/49 → 49/49 — is in the repo's findings file, along with
the fix.
The pipeline, honestly narrated
Underneath the build, the unmodified decks get a
generated, expanded copy — INCLUDEs spliced, parameterized kinds
resolved — and f2py produces the extension. Under
serve, an ordinary FastAPI app answers HTTP with the
same numbers the native binary returns. Under golden
verify, recorded outputs of known configurations are
replayed and compared.
The two details that decide correctness
COMMON blocks mean one call at a time
The exposed routines share process-global COMMON storage — that is how the deck was designed. Two simultaneous calls would silently hand each other's state back. The generated service therefore holds a process-wide lock across each native call for Fortran services. Throughput comes from running more processes, not more concurrency within one. This is a property of the physics of the old design, not a limitation of the wrapper.
The golden record is the deliverable
services/petro_api/golden.json is committed: the
fluid configured at a set of benchmark states and the results the
bindings return. Every regeneration, compiler change, or flag
change gets measured against it. The other artifacts —
Dockerfile, Kubernetes manifests, health probes — matter for
deployment, but the golden record is what makes the modernization
itself defensible.
What it adds up to
A 1988-era correlation deck, unmodified, that a data scientist imports and calls from a notebook; that another team calls over HTTP in a container; that CI proves numerically unchanged after every change. That is modernization without a rewrite, and it generalizes: your deck, whatever domain it models, follows the same path.