💳 Secure Payment

Full-Service Web & Software Agency · Klamath Falls and Redding

Python, the team’s way

Work with Sean

Python lets a program do almost anything from anywhere: change a global, read a file halfway through a calculation, shuffle with whatever seed the process happens to hold. The Sean Dinwiddie’s Webmastery team gives most of that freedom up, gladly, for something better: the same inputs give the same outputs on every machine, and a failing test can say exactly which rule broke.

Eight habits get it there. Each comes with a small example that runs on the standard library and pytest. From here on the module works in Python, because the libraries that train and measure a model are written for Python first, as the Module 6 opener sets out. Every boundary it crosses is held to a contract the way this page holds its training rows, from the config and the design files in the module’s shared format to a model’s output.

One layout, run as modules

Code is grouped by what it does, one package per domain, and nothing sits loose at the top of the repository. Configuration and data live beside the package, never inside it:

pyproject.toml       what the project uses, and its Python
uv.lock              every package at an exact version, resolved from it
pytest.ini
config/train.json    every value a run depends on
data/
pipeline/
  config/read.py
  data/catalog_rows.py
  data/contract.py
  evaluation/
  release/
tests/

Every entry point runs as a module from the repository’s root, so its imports are absolute and resolve the same way from a terminal, a test or a scheduled job. An entry point’s main() returns an exit code, and the module hands it to the shell:

# pipeline/data/catalog_rows.py
"""Print training rows as JSON lines, one per row."""

from __future__ import annotations

import json
import sys

from pipeline.data.contexts import CATALOG
from pipeline.data.order import rotate


def catalog_rows(count: int) -> tuple[dict[str, str], ...]:
    return tuple(
        {"id": f"row-{index:03d}", "place": rotate(CATALOG, index).place}
        for index in range(count)
    )


def main(argv: list[str] | None = None) -> int:
    args = sys.argv[1:] if argv is None else argv
    count = int(args[0]) if args else 4
    for row in catalog_rows(count):
        print(json.dumps(row, sort_keys=True))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
$ python -m pipeline.data.catalog_rows
{"id": "row-000", "place": "the north trail"}
{"id": "row-001", "place": "the east parking lot"}
{"id": "row-002", "place": "the library annex"}
{"id": "row-003", "place": "the north trail"}

Run it as a file instead, and the same code falls over. Python puts the file’s own folder first on the import path, not the root:

$ python pipeline/data/catalog_rows.py 2>&1 | tail -1
ModuleNotFoundError: No module named 'pipeline'
Where an import starts looking A folder tree: the repository's root holds pipeline/, which holds data/, which holds catalog_rows.py. Run with python -m from the root, Python looks first in the current directory, the root, and a highlighted line shows import pipeline finding pipeline/ there. Run as a file, it looks first in data/, which holds no pipeline/, so the import fails. the rootpipeline/data/catalog_rows.pypython -mlooks here firstimport pipeline: founda file run looks herefirst: no pipeline/
Python puts one folder first on its import path. With python -m it is the current directory, here the root, so import pipeline finds the package (the violet line). Run as a file, it is the file’s own folder, data/, and there is no pipeline/ in there.

A locked environment

Each project has its own virtual environment, made from a lock. People edit pyproject.toml: what the project uses, the Python it runs on, and a date after which nothing new is taken:

[project]
name = "trail-notices"
version = "0.1.0"
requires-python = "==3.11.*"
dependencies = []

[dependency-groups]
dev = ["pytest"]

[tool.uv]
exclude-newer = "2026-09-01T00:00:00Z"

uv resolves it into uv.lock: every package and every dependency at an exact version, with a hash for each file and nothing uploaded after that date, for every platform the project allows. Lock it again next month and you get the same lock.

The environment is made from the lock alone. uv sync --locked installs exactly what the lock names, and removes anything it doesn’t:

$ uv sync --locked
Using CPython 3.11.15 interpreter at: /usr/local/bin/python3
Creating virtual environment at: .venv
Resolved 7 packages in 2ms
Installed 5 packages in 7ms
 + iniconfig==2.3.0
 + packaging==26.3
 + pluggy==1.6.0
 + pygments==2.21.0
 + pytest==9.1.1

--locked means the lock must already match pyproject.toml, and uv never rewrites it on the way. On its own, uv lock --locked is the check:

$ uv lock --locked
Resolved 7 packages in 3ms

Add six to the dependencies by hand, without locking again, and the same check stops the run before anything installs it:

$ uv lock --locked; echo "exit $?"
Resolved 8 packages in 9ms
The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`.
exit 1

Pure functions, the same answer every time

A function that reads only its arguments and returns a new value can be tested with plain data and trusted on any machine. Data generation holds to that strictly.

A row’s content is chosen by its index, turning through a fixed catalog like a dial; nothing is drawn at random. Where an order has to be shuffled, the shuffle gets a generator of its own, seeded from the run’s settings. The global one belongs to every library in the process, and any of them can disturb it:

# pipeline/data/order.py
"""Deterministic choices: the same inputs give the same rows on every machine."""

from __future__ import annotations

import random
from typing import Sequence, TypeVar

T = TypeVar("T")


def rotate(items: Sequence[T], index: int) -> T:
    """The item for row `index`: a fixed rotation, never a random draw."""
    return items[index % len(items)]


def seeded_order(count: int, seed: int) -> tuple[int, ...]:
    """Row indices in a shuffled order that the seed fixes."""
    rng = random.Random(seed)  # its own generator, not the global one
    indices = list(range(count))
    rng.shuffle(indices)
    return tuple(indices)

The hash() trap

For strings, Python’s built-in hash() is salted afresh in every process, so anything derived from it changes from run to run. The seeded order doesn’t budge:

$ for run in 1 2 3; do python -c "print(hash('north trail') % 1000)"; done
928
563
205
$ for run in 1 2 3; do python -c "from pipeline.data.order import seeded_order; print(seeded_order(8, seed=11))"; done
(1, 0, 2, 5, 3, 4, 6, 7)
(1, 0, 2, 5, 3, 4, 6, 7)
(1, 0, 2, 5, 3, 4, 6, 7)

A little housekeeping

Three small rules let two runs be compared line by line:

  • output is sorted;
  • JSON is written with sorted keys;
  • floats are rounded before they are compared.

Heavy libraries are imported inside the functions at the edge that need them, so a test of the core never loads a GPU stack.

The lecture What Is a Function? sets out what makes a function pure, and Functional Programming in Other Languages draws the line between the pure core and the shell around it.

Frozen data

Records are frozen dataclasses. A frozen record can’t change after it is made, so a value passed into a function is the same value when the function returns. A change is a new record, made with dataclasses.replace:

# pipeline/data/contexts.py
"""The made-up situations that training rows are written about."""

from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class Context:
    place: str
    state: str
    reason: str


CATALOG = (
    Context("the north trail", "closed until Friday", "a washed-out bridge"),
    Context("the east parking lot", "open from 7 in the morning", "new gate hours"),
    Context("the library annex", "closed on Mondays", "a change in staffing"),
)
from dataclasses import FrozenInstanceError, replace

from pipeline.data.contexts import CATALOG

trail = CATALOG[0]
try:
    trail.state = "open"
except FrozenInstanceError as error:
    print("refused:", error)

reopened = replace(trail, state="open")
print(reopened)
print(trail)
refused: cannot assign to field 'state'
Context(place='the north trail', state='open', reason='a washed-out bridge')
Context(place='the north trail', state='closed until Friday', reason='a washed-out bridge')

The trail in the catalog is still closed until Friday; the reopened one is a new record beside it.

One config, read once

Every value a run depends on sits in one file, config/train.json: the model and its pinned revision, the data files, the seed, the training settings. It is short enough to review at a glance, and changing a run means changing that file:

{
  "model": "example/base-model",
  "revision": "pinned",
  "train": "data/train.jsonl",
  "validation": "data/validation.jsonl",
  "seed": 11,
  "epochs": 2
}

A run reads it once, at its entry point, into a frozen record, and hands the record to whatever needs it. Nothing deeper opens the file again, so every part of the run sees the same values.

Reading checks every key against the record’s fields and reports every fault at once, the way the next section’s contract does:

# pipeline/config/read.py
"""Read the run's config once, at its entry point, into a frozen record."""

from __future__ import annotations

import json
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import Any, get_type_hints


@dataclass(frozen=True)
class Config:
    model: str
    revision: str
    train: str
    validation: str
    seed: int
    epochs: int


def config_errors(raw: Any) -> tuple[str, ...]:
    """Every way the file differs from Config, all in one report."""
    if not isinstance(raw, dict):
        return ("a config is one JSON object",)
    kinds = get_type_hints(Config)
    return (
        *(f"unknown key {key!r}" for key in sorted(set(raw) - set(kinds))),
        *(f"missing key {key!r}" for key in kinds if key not in raw),
        *(
            f"{key} should be {kind.__name__}, found {type(raw[key]).__name__}"
            for key, kind in kinds.items()
            if key in raw and type(raw[key]) is not kind
        ),
    )


def read_config(path: Path) -> Config:
    raw = json.loads(path.read_text(encoding="utf-8"))
    errors = config_errors(raw)
    if errors:
        raise ValueError("\n".join(errors))
    return Config(**raw)


def main(argv: list[str] | None = None) -> int:
    args = sys.argv[1:] if argv is None else argv
    print(read_config(Path(args[0])))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
$ python -m pipeline.config.read config/train.json
Config(model='example/base-model', revision='pinned', train='data/train.jsonl', validation='data/validation.jsonl', seed=11, epochs=2)

A draft with a stray key, a missing one and a seed written as text gets all three back in one report:

from pipeline.config.read import config_errors

draft = {
    "model": "example/base-model", "revision": "pinned", "train": "data/train.jsonl",
    "seed": "11", "epochs": 2, "learning_rate": 0.0002,
}
for error in config_errors(draft):
    print(error)
unknown key 'learning_rate'
missing key 'validation'
seed should be int, found str
One config, read once config/train.json goes once into read_config, which reports every fault in one report. Out comes a highlighted box, Config, frozen. Highlighted lines carry that one record to building rows, training and evaluating, so each gets the same record. config/train.jsonread_configConfig, frozenbuild rowstrainevaluateread onceevery fault,one reporteach gets the same record
The file is read once, at the run’s entry point. Building rows, training and evaluating each get the same frozen record (the violet lines), and none of them opens the file again.

The lecture Practical Applications of Functional Programming freezes its configuration too, with caller overrides layered over defaults in an explicit order. Here the file holds every value, so there is nothing to layer.

A design file in the format Geometric reasoning as data sets out is read the same way: once, by a reader of its own, from the one place it lives, the way Geometric reasoning in model training reads data/trail.design.json.

Contracts that report every fault

Data crosses a boundary only after it is checked against its contract:

  • the keys a row must carry, and the one it may carry (the oracle, which Geometric reasoning in model training gives every row it writes itself);
  • the allowed values;
  • the rules between fields.

The checks are independent of each other, so all of them run, and the validator raises once with every fault, not just the first. A rule about a value judges only a key the row has, so a missing key is reported once, as missing. Whoever fixes the data file gets the whole list in one go.

Counts and other derived facts are recomputed from the data, never trusted as declared:

# pipeline/data/contract.py
"""Check training rows against their contract and report every fault at once."""

from __future__ import annotations

import json
import sys
from collections import Counter
from pathlib import Path
from typing import Any, Iterable, Mapping

REQUIRED_KEYS = frozenset({"id", "split", "prompt", "chosen", "rejected"})
OPTIONAL_KEYS = frozenset({"oracle"})  # what its answers must and must not say
SPLITS = frozenset({"train", "validation", "test"})


def row_errors(row: Mapping[str, Any]) -> tuple[str, ...]:
    keys = set(row)
    rules = (  # each rule and what to say when it doesn't hold
        (keys <= REQUIRED_KEYS | OPTIONAL_KEYS, f"unexpected keys {sorted(keys - REQUIRED_KEYS - OPTIONAL_KEYS)}"),
        (keys >= REQUIRED_KEYS, f"missing keys {sorted(REQUIRED_KEYS - keys)}"),
        ("split" not in row or row["split"] in SPLITS, f"unknown split {row.get('split')!r}"),
        ("prompt" not in row or bool(str(row["prompt"]).strip()), "empty prompt"),
        (not keys >= {"chosen", "rejected"} or row["chosen"] != row["rejected"], "chosen and rejected are the same"),
    )
    return tuple(message for holds, message in rules if not holds)


def count_errors(declared: Mapping[str, int], rows: Iterable[Mapping[str, Any]]) -> tuple[str, ...]:
    """Recount the rows in each split rather than trusting the declared counts."""
    found = Counter(row.get("split") for row in rows)
    return tuple(
        f"{split}: declared {declared.get(split, 0)}, found {found.get(split, 0)}"
        for split in sorted(set(declared) | set(found), key=str)
        if declared.get(split, 0) != found.get(split, 0)
    )


def validate(rows: Iterable[Mapping[str, Any]], declared: Mapping[str, int]) -> None:
    rows = tuple(rows)
    errors = (
        *(f"{row.get('id', '?')}: {error}" for row in rows for error in row_errors(row)),
        *count_errors(declared, rows),
    )
    if errors:
        raise ValueError("\n".join(errors))


def main(argv: list[str] | None = None) -> int:
    rows_path, counts_path = sys.argv[1:] if argv is None else argv
    rows = [json.loads(line) for line in Path(rows_path).read_text().splitlines() if line]
    validate(rows, json.loads(Path(counts_path).read_text()))
    print(f"{len(rows)} rows match their contract")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
from pipeline.data.contract import validate

rows = (
    {"id": "row-000", "split": "train", "prompt": "Is the north trail open?",
     "chosen": "It is closed until Friday.", "rejected": "Closed till Friday!"},
    {"id": "row-001", "split": "trian", "prompt": " ", "note": "draft",
     "chosen": "Open from 7 a.m.", "rejected": "Open from 7 a.m."},
)
try:
    validate(rows, declared={"train": 2})
except ValueError as error:
    print(error)
row-001: unexpected keys ['note']
row-001: unknown split 'trian'
row-001: empty prompt
row-001: chosen and rejected are the same
train: declared 2, found 1
trian: declared 0, found 1

The lecture Practical Applications of Functional Programming accumulates errors the same way in TypeScript.

Tests named for the behavior

Each test’s name states the rule it proves, so a failing run reads as a list of broken rules.

A contract is tested by breaking a valid row one way at a time and checking that each break is refused, by name. Several breaks at once have to come back in one error:

# tests/test_contract.py
import pytest

from pipeline.data.contract import validate

VALID = {
    "id": "row-000",
    "split": "train",
    "prompt": "Is the north trail open?",
    "chosen": "It is closed until Friday.",
    "rejected": "Closed till Friday!",
}

BROKEN = (
    ("unknown-split", {"split": "trian"}, "unknown split 'trian'"),
    ("empty-prompt", {"prompt": " "}, "empty prompt"),
    ("same-answers", {"rejected": VALID["chosen"]}, "chosen and rejected are the same"),
    ("extra-key", {"note": "draft"}, r"unexpected keys \['note'\]"),
)


def test_a_valid_row_passes():
    validate((VALID,), declared={"train": 1})


@pytest.mark.parametrize("change, error", [case[1:] for case in BROKEN], ids=[case[0] for case in BROKEN])
def test_each_broken_row_is_refused_by_name(change, error):
    with pytest.raises(ValueError, match=error):
        validate(({**VALID, **change},), declared={"train": 1})


def test_a_wrong_declared_count_is_refused():
    with pytest.raises(ValueError, match="train: declared 2, found 1"):
        validate((VALID,), declared={"train": 2})


def test_every_fault_is_reported_in_one_error():
    with pytest.raises(ValueError) as raised:
        validate(({**VALID, "split": "trian", "prompt": ""},), declared={"train": 1})
    assert len(str(raised.value).splitlines()) == 4

A test that has to fail

A test that has never failed has proved nothing, so a test can break the code on purpose. Here one test swaps in a broken rotation and expects the rotation test to fail. The last two hold the shuffled order to its seed:

# tests/test_rows.py
import pytest

import pipeline.data.catalog_rows as build
from pipeline.data.contexts import CATALOG
from pipeline.data.order import seeded_order


def test_rows_rotate_through_the_catalog():
    places = [row["place"] for row in build.catalog_rows(4)]
    assert places == [context.place for context in (*CATALOG, CATALOG[0])]


def test_the_rotation_test_fails_when_the_rotation_breaks(monkeypatch):
    monkeypatch.setattr(build, "rotate", lambda items, index: items[0])  # broken on purpose
    with pytest.raises(AssertionError):
        test_rows_rotate_through_the_catalog()


def test_the_same_seed_gives_the_same_order():
    assert seeded_order(8, seed=11) == seeded_order(8, seed=11)


def test_a_new_seed_gives_a_new_order_of_the_same_rows():
    first, second = seeded_order(8, seed=11), seeded_order(8, seed=12)
    assert first != second and sorted(first) == sorted(second)

The run itself

Every run reads its settings from pytest.ini at the root: where the tests are, no cache left behind, and the classic output without a progress percentage:

[pytest]
testpaths = tests
addopts = -p no:cacheprovider
console_output_style = classic
$ python -m pytest -v --no-header tests/test_contract.py tests/test_rows.py
============================= test session starts ==============================
collecting ... collected 11 items

tests/test_contract.py::test_a_valid_row_passes PASSED
tests/test_contract.py::test_each_broken_row_is_refused_by_name[unknown-split] PASSED
tests/test_contract.py::test_each_broken_row_is_refused_by_name[empty-prompt] PASSED
tests/test_contract.py::test_each_broken_row_is_refused_by_name[same-answers] PASSED
tests/test_contract.py::test_each_broken_row_is_refused_by_name[extra-key] PASSED
tests/test_contract.py::test_a_wrong_declared_count_is_refused PASSED
tests/test_contract.py::test_every_fault_is_reported_in_one_error PASSED
tests/test_rows.py::test_rows_rotate_through_the_catalog PASSED
tests/test_rows.py::test_the_rotation_test_fails_when_the_rotation_breaks PASSED
tests/test_rows.py::test_the_same_seed_gives_the_same_order PASSED
tests/test_rows.py::test_a_new_seed_gives_a_new_order_of_the_same_rows PASSED

============================== 11 passed in 0.02s ==============================

A skip means a test didn’t run, and a green run hides it. So conftest.py fails any run with a skip:

# tests/conftest.py
"""A run with a skip in it fails: the skipped test never ran."""


def skipped(config):
    reporter = config.pluginmanager.get_plugin("terminalreporter")
    return len(reporter.stats.get("skipped", ())) if reporter else 0


def pytest_terminal_summary(terminalreporter, config):
    if skipped(config):
        terminalreporter.write_line(f"{skipped(config)} skipped: every test must run")


def pytest_sessionfinish(session):
    if skipped(session.config):
        session.exitstatus = 1

The whole suite holds 17 tests: these eleven, four in tests/test_config.py for the config reader (the frozen record, every fault in one report, True refused as a number, and a config that isn’t one object), and the two in tests/test_inputs.py further down. With a skipped test added, the run reports it and exits non-zero:

$ python -m pytest -q; echo "exit $?"
.............s....
1 skipped: every test must run
17 passed, 1 skipped in 0.03s
exit 1

Try it: four faults, and one the contract can’t see

Work in a copy of the layout, so the runs further down still print what this page shows. The data file data/practice.jsonl holds six rows and four faults the contract can see, each against a different rule, and data/practice-counts.json declares the six: {"train": 6}.

{"id": "row-000", "split": "train", "prompt": "Is the north trail open?", "chosen": "It is closed until Friday, because of a washed-out bridge.", "rejected": "Closed till Friday!"}
{"id": "row-001", "split": "train", "prompt": "Why is the north trail closed?", "chosen": "A washed-out bridge. It reopens on Friday.", "rejected": "Ask a ranger.", "source": "posted notice"}
{"id": "row-002", "split": "train", "prompt": "When does the east parking lot open?", "chosen": "At 7 in the morning, under the new gate hours."}
{"id": "row-003", "split": "train", "prompt": "", "chosen": "Yes, from 7 in the morning.", "rejected": "Yes."}
{"id": "row-004", "split": "train", "prompt": "Is the library annex open on Mondays?", "chosen": "No. It is closed on Mondays, because of a change in staffing.", "rejected": "No. It is closed on Mondays, because of a change in staffing."}
{"id": "row-000", "split": "train", "prompt": "Which days is the library annex open?", "chosen": "Every day but Monday, because of a change in staffing.", "rejected": "Most days."}

Run the contract once, and fix all four from its report:

$ python -m pipeline.data.contract data/practice.jsonl data/practice-counts.json 2>&1 | tail -4
ValueError: row-001: unexpected keys ['source']
row-002: missing keys ['rejected']
row-003: empty prompt
row-004: chosen and rejected are the same

One line per fault, each naming its row and the rule it broke, so every fix comes straight from the report:

  • row-001: drop source (if every row should carry one, that is a change to the contract, made on purpose);
  • row-002: add the rejected answer it lacks;
  • row-003: write the question its answers reply to;
  • row-004: write a rejected answer that differs from the chosen one.

Then run it again:

$ python -m pipeline.data.contract data/practice.jsonl data/practice-counts.json
6 rows match their contract

It passes, and it still holds a fault. The first and last rows are both row-000: the last was copied from the first and edited, and the id came along. Nothing in the contract compares ids across rows, so a report about row-000 would point at two rows. That fifth fault needs a new rule: each id names one row.

Its test comes first, named for the rule:

# tests/test_contract.py, one test added
def test_a_repeated_id_is_refused():
    copy = {**VALID, "prompt": "Which days is the library annex open?"}
    with pytest.raises(ValueError, match="row-000: id used by 2 rows"):
        validate((VALID, copy), declared={"train": 2})

Run it before the rule exists. It has to fail, and it does, by name:

$ python -m pytest -q tests/test_contract.py
.......F
=================================== FAILURES ===================================
________________________ test_a_repeated_id_is_refused _________________________

    def test_a_repeated_id_is_refused():
        copy = {**VALID, "prompt": "Which days is the library annex open?"}
>       with pytest.raises(ValueError, match="row-000: id used by 2 rows"):
E       Failed: DID NOT RAISE ValueError

tests/test_contract.py:45: Failed
=========================== short test summary info ============================
FAILED tests/test_contract.py::test_a_repeated_id_is_refused - Failed: DID NO...
1 failed, 7 passed in 0.02s

Then the rule, beside count_errors, and one line in validate that runs it with the others. It counts only rows that have an id: a row without one is the missing-keys rule’s to report, so no fault is reported twice.

# pipeline/data/contract.py, with the new rule added
def id_errors(rows: Iterable[Mapping[str, Any]]) -> tuple[str, ...]:
    """Each id names one row, so every line of a report points at one row."""
    found = Counter(row["id"] for row in rows if "id" in row)
    return tuple(
        f"{row_id}: id used by {found[row_id]} rows"
        for row_id in sorted(found, key=str)
        if found[row_id] > 1
    )


def validate(rows: Iterable[Mapping[str, Any]], declared: Mapping[str, int]) -> None:
    rows = tuple(rows)
    errors = (
        *(f"{row.get('id', '?')}: {error}" for row in rows for error in row_errors(row)),
        *count_errors(declared, rows),
        *id_errors(rows),
    )
    if errors:
        raise ValueError("\n".join(errors))

Now the test passes, and the practice file’s report names the repeated id:

$ python -m pytest -q tests/test_contract.py
........
8 passed in 0.01s
$ python -m pipeline.data.contract data/practice.jsonl data/practice-counts.json 2>&1 | tail -1
ValueError: row-000: id used by 2 rows

Give the last row its own id, row-005, and the file passes the contract, new rule and all:

$ python -m pipeline.data.contract data/practice.jsonl data/practice-counts.json
6 rows match their contract

One command checks everything

The config and the data each get a test, so the test run checks them with everything else:

# tests/test_inputs.py
"""The run's own inputs meet their contracts: the config reads, and the rows pass."""

import json
from pathlib import Path

from pipeline.config.read import read_config
from pipeline.data.contract import validate

ROOT = Path(__file__).resolve().parents[1]


def test_the_config_reads():
    read_config(ROOT / "config/train.json")


def test_the_training_rows_the_config_names_meet_their_contract():
    config = read_config(ROOT / "config/train.json")
    rows = [json.loads(line) for line in (ROOT / config.train).read_text().splitlines() if line]
    validate(rows, json.loads((ROOT / "data/counts.json").read_text()))

data/train.jsonl holds six preference rows that meet the contract, and data/counts.json declares them: {"train": 6}. Each row asks for a brief, formal, cautious voice; its chosen answer keeps it, and its rejected answer misses by one trait.

uv run --locked --exact runs a command in the project’s environment. It stops if the lock no longer matches pyproject.toml, brings the environment exactly in line with the lock, removing anything the lock doesn’t name, and only then runs the command. So one command checks, before any training run:

  • the lock is current;
  • the config reads;
  • the training rows the config names meet their contract;
  • every test passes.
$ uv run --locked --exact python -m pytest -q
.................
17 passed in 0.02s

It never writes the lock, the config or the data. Regenerating data is a separate command, so checking can never change what it checks.

Next, these habits go to work before any training starts: Measuring reasoning on the geometry writes the measurement first, the way a scenario comes before its code.

Copyright Sean Paul Payne Dinwiddie
All Rights Reserved