DEV Community

Dakota Huang
Dakota Huang

Posted on

Snapshot Hidden Process State Before You Split a God Module

God modules fail at process edges, not syntax. Hidden env, cwd, clocks, and caches leak. Snapshot that state before any extract. Then change one pure helper. Larger edits remain guesses.

This workflow is a gate, not a taste test. The oracle must fail closed. A coding model may draft later. It does not replace the snapshot.

The failure you actually hit

A messy file looks local. It is not. It reads environment keys through nested helpers. It writes caches from os.getcwd(). It formats stamps with host locale rules.

A green unit test still lies. It never pinned those channels. Your extract then changes a path or key. Production drifts without a trusted traceback.

This is not a naming problem. It is an unrecorded process contract. Refactors that ignore it ship silent behavior change.

What to pin before any split

Record four process channels on every run. Miss one channel and the golden is incomplete. Incomplete goldens bless the wrong extract.

  1. Environment keys the module actually reads.
  2. Working directory and resolved path strings.
  3. Files created, truncated, or deleted.
  4. Clock, locale, and module-level mutable maps.
Channel Symptom after a “safe” split Pin method
Env reads Missing cache, wrong home path Trace os.environ gets
CWD / paths FileNotFoundError on CI runners Freeze cwd and abspath
Filesystem writes Stale or duplicate cache files Temp dir plus path log
Clock / locale / globals Flaky keys and shuffled maps Fake clock, copy globals

Treat the table as a merge gate. No extract starts until every row has a fixture. Do not argue about elegance first.

Artifact: a god module and a process oracle

The listings below are illustrative examples. They are not production measurements. Run them in an empty directory you control. Do not point them at a real home directory.

Layout

messy_refactor/
  god_cache.py
  charter.py
  goldens/
    build_entry.v1.json
Enter fullscreen mode Exit fullscreen mode

Keep the god file intact on commit one. The oracle is the only new code. That ordering is the whole method.

The messy module

# god_cache.py
from __future__ import annotations

import json
import os
from datetime import datetime, timezone
from pathlib import Path

_MEMO: dict[str, dict] = {}


def build_entry(relpath: str) -> dict:
    home = os.environ.get("HOME", "")
    cache_root = os.environ.get("CACHE_DIR", os.path.join(home, ".cache"))
    cwd = os.getcwd()
    abs_src = os.path.abspath(os.path.join(cwd, relpath))
    day = datetime.now(timezone.utc).strftime("%Y-%m-%d")
    key = f"{abs_src}|{day}"
    if key in _MEMO:
        return _MEMO[key]
    stamp = datetime.now().astimezone().isoformat()
    payload = {
        "key": key,
        "src": abs_src,
        "cache": str(Path(cache_root) / "god" / Path(relpath).name),
        "stamp": stamp,
        "cwd": cwd,
    }
    Path(payload["cache"]).parent.mkdir(parents=True, exist_ok=True)
    Path(payload["cache"]).write_text(json.dumps(payload), encoding="utf-8")
    _MEMO[key] = payload
    return payload
Enter fullscreen mode Exit fullscreen mode

This function looks like one unit. It is five coupled channels. HOME, CACHE_DIR, cwd, clock, and _MEMO all leak into the return value.

The characterization harness

# charter.py
from __future__ import annotations

import json
import os
import tempfile
from datetime import datetime, timezone
from pathlib import Path
from unittest.mock import patch

GOLDEN = Path("goldens/build_entry.v1.json")
FIXED = datetime(2026, 9, 4, 12, 0, 0, tzinfo=timezone.utc)


class FrozenDateTime(datetime):
    @classmethod
    def now(cls, tz=None):
        if tz is None:
            return FIXED.replace(tzinfo=None)
        return FIXED.astimezone(tz)


def capture() -> dict:
    import god_cache as god

    god._MEMO.clear()
    old_cwd = os.getcwd()
    with tempfile.TemporaryDirectory() as tmp:
        env = {
            "HOME": str(Path(tmp) / "home"),
            "CACHE_DIR": str(Path(tmp) / "cache"),
        }
        Path(env["HOME"]).mkdir(parents=True, exist_ok=True)
        Path(env["CACHE_DIR"]).mkdir(parents=True, exist_ok=True)
        try:
            os.chdir(tmp)
            with patch.dict(os.environ, env, clear=False):
                with patch("god_cache.datetime", FrozenDateTime):
                    before = {
                        p.as_posix()
                        for p in Path(tmp).rglob("*")
                        if p.is_file()
                    }
                    result = god.build_entry("src/app.py")
                    after = {
                        p.as_posix()
                        for p in Path(tmp).rglob("*")
                        if p.is_file()
                    }
        finally:
            os.chdir(old_cwd)
        written = sorted(after - before)
        return {
            "env_used": ["HOME", "CACHE_DIR"],
            "src_endswith": result["src"].replace("\\", "/").endswith("src/app.py"),
            "key_date_fragment": "2026-09-04",
            "key_has_date": result["key"].endswith("2026-09-04"),
            "memo_len": len(god._MEMO),
            "written_count": len(written),
            "cache_name": Path(result["cache"]).name,
            "result_keys": sorted(result.keys()),
        }


def write_golden() -> None:
    GOLDEN.parent.mkdir(parents=True, exist_ok=True)
    payload = capture()
    GOLDEN.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
    print(f"wrote {GOLDEN}")


def check_golden() -> int:
    actual = capture()
    expected = json.loads(GOLDEN.read_text())
    if actual != expected:
        print("ORACLE MISMATCH")
        print("expected:", json.dumps(expected, sort_keys=True))
        print("actual:  ", json.dumps(actual, sort_keys=True))
        return 1
    print("oracle ok")
    return 0


if __name__ == "__main__":
    import sys

    cmd = sys.argv[1] if len(sys.argv) > 1 else "check"
    if cmd == "record":
        write_golden()
        raise SystemExit(0)
    raise SystemExit(check_golden())
Enter fullscreen mode Exit fullscreen mode

The harness does not score design quality. It pins observable process effects. That is the only honest first step on a god file.

The frozen clock is an example. Naive datetime.now() follows host timezone rules. Later goldens should pin TZ as well. Do not treat this freeze as a full time model.

Numbered workflow

Run the sequence in order. Do not skip record. Do not extract during record.

  1. Copy the two files into an empty working tree.
  2. Create goldens/ before the first python invocation.
  3. Run python charter.py record once on a quiet machine.
  4. Commit god_cache.py, charter.py, and the golden JSON together.
  5. Run python charter.py check and confirm oracle ok.
  6. Extract one pure helper. Touch nothing else.
  7. Run python charter.py check again. Revert on mismatch.

Commands stay local and boring on purpose.

python charter.py record
python charter.py check
Enter fullscreen mode Exit fullscreen mode

If check fails before any edit, the harness is wrong. Fix the oracle first. Never “correct” the golden to match a hoped extract.

The smallest safe change

The first legal edit is a pure key builder. It must not mkdir. It must not read env. It must not touch _MEMO. It must not format stamps.

def _compose_key(abs_src: str, day: str) -> str:
    return f"{abs_src}|{day}"
Enter fullscreen mode Exit fullscreen mode

Wire it with one call-site swap.

day = datetime.now(timezone.utc).strftime("%Y-%m-%d")
key = _compose_key(abs_src, day)
Enter fullscreen mode Exit fullscreen mode

That is the entire first patch. Cache path logic stays in build_entry. Memoization stays in build_entry. Filesystem writes stay in build_entry.

A larger “cleanup” is out of scope. Moving mkdir into a helper changes process effects. Changing path join order changes CI. Those edits need new goldens, not bravado.

Re-run the oracle after the extract

Check must stay byte-stable on the pinned fields. result_keys should match. key_has_date should stay true. written_count should stay one. memo_len should stay one.

python charter.py check
# expected stdout: oracle ok
Enter fullscreen mode Exit fullscreen mode

Mismatch means the extract leaked. Diff the JSON, not your intent. Restore the god file if the leak is unclear. Split a smaller piece on the next attempt.

Add a second golden only after the first stays green. A second case might use a nested relative path. It might use a missing CACHE_DIR. Do not add cases while the first oracle is red.

Where a free coding model belongs

A model belongs after the golden exists. Not before. Prompt it with the god file and the JSON fixture. Ask for one pure helper. Reject diffs that touch env, cwd, clock, or writes.

Disclosure: This article was prepared as part of MonkeyCode's product outreach. MonkeyCode offers free model access and a free server option. Those two facts are the only product claims used here. No model name, quota, or hardware figure is implied.

Keep the loop mechanical. Draft remotely if you want. Gate locally with python charter.py check. The model is a drafter. The process oracle is the merge gate.

If goldens already live in the tree, a free remote draft is enough to try the one-function split. Review the oracle bytes, not the pitch.

Limitations

This method does not prove correctness. It proves unchanged process effects under a frozen envelope. That is a weaker claim. State it that way in review notes.

The freeze is incomplete by design. It does not cover threads. It does not cover network sockets. It does not cover native extensions. It does not cover cryptographic randomness you must not pin.

Path fields in the golden are shape checks, not full abspath dumps. Host temp prefixes differ. Do not snapshot raw /tmp strings. Snapshot suffixes, counts, and key fragments instead.

patch.dict will not see C-level getenv calls. Some libraries cache env at import time. Import the god module inside capture() if import-time reads appear. Re-record after that change.

Who should not use this approach

Do not use this on a greenfield module with no side effects. Ordinary unit tests are cheaper there. Do not use this when you cannot import the file in-process.

Do not use this for live unpaid network calls. Stub or refuse that work. Do not use this as permission to rewrite the god file in one pass.

Skip it if your change must ship without a golden. Skip it if no one on the team can run local Python. Skip it if the “extract” includes mkdir, env, or clock movement.

Teams chasing coverage percentage will misuse the oracle. A matching golden is not a design review. It is a tripwire against silent process drift.

Stop condition

Stop when one helper is extracted and check stays green. Do not chain three extras in the same patch. Each extra needs its own oracle cycle.

God modules shrink by measured slices. Process snapshots make those slices visible. Syntax-only diffs do not.

Top comments (0)