DEV Community

Dakota Huang
Dakota Huang

Posted on

The Process Oracle Comes Before the Helper Extract

A messy repository fails a rewrite when behavior is unfrozen.
Snapshot one process seam before any helper extract lands.
Then allow a one-file change budget, nothing larger.

Why whole-tree rewrites fail

Brownfield trees mix side effects, caches, and silent branches.
Existing tests are missing, stale, or tied to internals.
A broad model rewrite then breaks callers without warning.

The tempting move is a clean module in one pass.
That pass is expensive once production traffic hits it.
You need a freeze that does not require a clean design.

What counts as a process seam

A process seam is an input and output you already own.
CLI stdout, HTTP JSON, or a batch file all qualify.
Pick the edge that callers already treat as a contract.

Do not start inside a helper with undocumented callers.
Do not start with a rename that spans twelve packages.
Start where a subprocess or request can still be replayed.

Locale, clocks, and map key order are not the seam.
They are noise sources that make snapshots lie later.
Pin or canonicalize them before the first freeze run.

Worked example: a tangled invoice CLI

The following listing is a labeled sketch, not production telemetry.
It models a small Python CLI with mixed concerns together.
Treat SKUs and amounts as fixtures, not measured traffic.

# invoice_cli.py — messy starting point (example)
import json, sys

TAX = 0.0875
_cache = {}

def run(argv):
    cmd = argv[1] if len(argv) > 1 else "help"
    if cmd == "quote":
        sku = argv[2]
        qty = int(argv[3])
        if sku in _cache:
            price = _cache[sku]
        else:
            price = 19.99 if sku.startswith("A") else 29.99
            _cache[sku] = price
        sub = price * qty
        if qty >= 10:
            sub *= 0.9
        total = round(sub * (1 + TAX), 2)
        print(json.dumps({"sku": sku, "qty": qty, "total": total}))
        return 0
    if cmd == "help":
        print("usage: quote SKU QTY")
        return 0
    print("unknown", file=sys.stderr)
    return 2

if __name__ == "__main__":
    raise SystemExit(run(sys.argv))
Enter fullscreen mode Exit fullscreen mode

Pricing, cache, tax, and CLI parsing share one function.
That mix is typical of a repository that grew without seams.
The refactor target is this process, not a new architecture.

Artifact: a characterization harness

Build the oracle outside the code you plan to touch.
Replay fixed argv rows and canonicalize stdout plus codes.
Store that result as a snapshot later diffs must match.

# characterize.py — example harness
import json, subprocess, sys, hashlib, pathlib

ROOT = pathlib.Path(__file__).resolve().parent
CASES = [
    ["quote", "A100", "1"],
    ["quote", "A100", "10"],
    ["quote", "B200", "2"],
    ["quote", "A100", "1"],  # cache path
    ["help"],
    ["nope"],
]

def run_case(args):
    proc = subprocess.run(
        [sys.executable, str(ROOT / "invoice_cli.py"), *args],
        capture_output=True, text=True,
    )
    stdout = proc.stdout
    try:
        stdout = json.dumps(json.loads(proc.stdout), sort_keys=True)
    except Exception:
        stdout = proc.stdout.replace("\r\n", "\n")
    return {
        "args": args,
        "code": proc.returncode,
        "stdout": stdout,
        "stderr": proc.stderr.replace("\r\n", "\n"),
    }

def main():
    mode = sys.argv[1] if len(sys.argv) > 1 else "check"
    snap = ROOT / "seam.snapshot.json"
    rows = [run_case(c) for c in CASES]
    blob = json.dumps(rows, indent=2, sort_keys=True) + "\n"
    if mode == "freeze":
        snap.write_text(blob)
        print("froze", hashlib.sha256(blob.encode()).hexdigest()[:12])
        return
    if not snap.exists():
        raise SystemExit("no snapshot; run freeze first")
    if snap.read_text() != blob:
        raise SystemExit("seam drift")
    print("seam ok")

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode
# example targets
.PHONY: freeze check
freeze:
    TZ=UTC PYTHONHASHSEED=0 python characterize.py freeze
check:
    TZ=UTC PYTHONHASHSEED=0 python characterize.py check
Enter fullscreen mode Exit fullscreen mode

Run freeze once on the known-good tree, then commit it.
Keep seam.snapshot.json beside the messy CLI it describes.
Every later edit must keep make check fully green.

Choose rows with intent

Cover the happy path, a discount path, and a cache hit.
Cover help text and one unknown-command failure path.
Skip rows that need live network, clocks, or user input.

If a branch has no row, you must not delete that branch.
Add the row first, freeze again, then consider deletion.
Absence of a snapshot row is not proof of dead code.

Duplicate a case that hits a module-level cache on purpose.
The second A100 quote exists to lock cache behavior.
Without it, an extract can drop the cache unnoticed.

Numbered workflow

1. Inventory the observable edge

List commands, flags, and payloads the process already accepts.
Keep only rows you can replay on a clean checkout.
Write them as data, not as comments in a test file.

2. Pin nondeterminism

Set TZ=UTC and PYTHONHASHSEED=0 for the harness process.
Reject timestamps in stdout, or replace them with a stub.
Sort JSON object keys before you write the snapshot file.

TZ=UTC PYTHONHASHSEED=0 python characterize.py freeze
Enter fullscreen mode Exit fullscreen mode

3. Freeze the seam

Run the harness against the current tree, not the desired tree.
Commit the snapshot as an oracle, not as pretty documentation.
Do not fix surprising totals while you freeze behavior.

4. Budget one file

Name the single file allowed to change in this pass.
If the edit needs a second file, the budget is blown.
Split the work and ship the first file alone.

5. Change one concern

Extract tax, cache, or parsing, never all three at once.
Keep names that any in-process caller already imports.
Prefer a local helper over a new package layout now.

# invoice_cli.py — after one concern extract (example)
import json, sys

TAX = 0.0875
_cache = {}

def price_for(sku):
    if sku in _cache:
        return _cache[sku]
    price = 19.99 if sku.startswith("A") else 29.99
    _cache[sku] = price
    return price

def run(argv):
    cmd = argv[1] if len(argv) > 1 else "help"
    if cmd == "quote":
        sku = argv[2]
        qty = int(argv[3])
        sub = price_for(sku) * qty
        if qty >= 10:
            sub *= 0.9
        total = round(sub * (1 + TAX), 2)
        print(json.dumps({"sku": sku, "qty": qty, "total": total}))
        return 0
    if cmd == "help":
        print("usage: quote SKU QTY")
        return 0
    print("unknown", file=sys.stderr)
    return 2

if __name__ == "__main__":
    raise SystemExit(run(sys.argv))
Enter fullscreen mode Exit fullscreen mode

Only the pricing lookup moved in this pass.
Tax, discounts, and CLI parsing stayed in run().
That is the point of a one-file, one-concern budget.

Run make check before any second extract starts.
A red check means revert, not a snapshot refresh.

6. Classify drift before you fix it

When make check fails, do not refresh the snapshot immediately.
Classify the first mismatch as encoding, key order, or behavior.
Only a behavior mismatch should block the extract.

The other two classes are harness bugs to fix.
Do not treat every red check as a product defect.
Read the first differing row before you touch either tree.

# classify_drift.py — example classifier, not a shipped metric
import json, pathlib, sys

def load(path):
    return json.loads(pathlib.Path(path).read_text())

def classify(old, new):
    if len(old) != len(new):
        return "length-mismatch"
    for left, right in zip(old, new):
        if left == right:
            continue
        if left["args"] != right["args"]:
            return "harness-row-mismatch"
        same_code = left["code"] == right["code"]
        if left["stdout"].strip() == right["stdout"].strip() and same_code:
            return "encoding"
        try:
            ja = json.loads(left["stdout"])
            jb = json.loads(right["stdout"])
            if ja == jb and same_code:
                return "key-order"
        except Exception:
            pass
        return "behavior"
    return "unknown"

if __name__ == "__main__":
    print(classify(load(sys.argv[1]), load(sys.argv[2])))
Enter fullscreen mode Exit fullscreen mode

Encoding drift means newline or JSON spacing changed by accident.
Key-order drift means canonicalization is incomplete or skipped.
Behavior drift means the extract changed a total, code, or message.

Revert the extract when the drift is real behavior.
Repair the harness when encoding or key order drifted.

Never mix a snapshot refresh with a helper extract commit.
Those are different reviews with different failure costs.

Decision table: smallest safe change

Observed problem Allowed change Stop if
Long function, one concern mixed Extract one helper in the same file A second file is required
Duplicated literal Name a constant in that file Callers outside the file need it
Hidden branch Add a comment or a local name Behavior of the seam would change
Dead branch with no snapshot row Add a characterization row first You delete code without a row
Cross-file rename urge Reject in this pass The budget is one file

Use the table during review, not after the merge lands.
The stop column is the gate for every pass.
A larger cleanup waits for a new freeze cycle later.

Wire the check into CI

Add one job that clones the repo and runs the pinned check.
Fail the job on any seam drift, including stderr text changes.
Do not parallelize against a shared cache file on disk.

CI is the second machine that does not share your editor buffer.
If it cannot clone and check, the oracle is not portable.
Fix path assumptions before you extract another helper.

Where a free coding model fits

A model is useful after the snapshot exists, not before it.
Ask it to extract one helper inside the budgeted file only.
Reject any patch that edits a second path or the snapshot.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.
MonkeyCode provides free model access and a free server option.
Those two facts are the only product claims used here.

A free server can run make freeze and make check remotely.
That keeps the oracle off the laptop that drafts the diff.
The model proposes the one-file extract for review.
The free server runs the seam check against that patch.

Do not prompt for a greenfield rewrite of the invoice CLI.
Do not ask for a new framework, types, or package split.
Prompt for the smallest diff that keeps characterize.py quiet.

Limitations

This method does not prove internal correctness of helpers.
It only locks the chosen process seam for listed rows.
Unlisted flags, encodings, and race paths remain free to break.

Floating time, random IDs, and unordered maps will false-fail.
Canonicalize or pin those sources before you freeze anything.
Subprocess checks are slow relative to in-process unit tests.

A seam that talks to a live database is a weak oracle.
You would be characterizing the database, not the messy module.
Stub I/O at the process edge or skip this method entirely.

Who should not use this

Do not use this on a greenfield service with a real suite.
Do not use this when the CLI contract must change today.
Do not use this as cover for deleting error handling you dislike.

Security-sensitive parsers need adversarial tests instead of snapshots.
Numeric ledgers need property tests, not three SKU fixture rows.
If you cannot name one seam, you are not ready to edit.

Close

Freeze one process seam before you edit the tree.
Budget one file for the extract, then stop.
Change one concern behind that seam, then ship.

The messy repository can wait for another freeze cycle.
The snapshot cannot wait if you plan to extract.
Ship the small diff only while make check stays green.

Draft that one-file diff with a free remote model.
Keep this harness as the only reviewer.

Top comments (0)