Skip to content

Decisions

Newest first.

ADR-005: Follow the official Chadwick release exactly (0.11.0), including -Q

Decision (2026-10-08, owner: "same results as the C tools every time, including future versions"). chadwickpy follows the released Chadwick (tag v0.11.0, 2026-09-10), not a development commit. That includes its command line: the quiet switch is -Q (-q is rejected as "Invalid option", as in the C), and -D dir exists. No -q alias. The change ships as 0.4.0 (breaking for scripts that pass -q) with the difference listed in the release notes and the FAQ. Why. The project rule is that the port is a translation of the C and its output is compared with the real tools byte for byte; an alias would be a deliberate difference that every future comparison has to carve out. A weekly workflow builds the newest Chadwick and runs the whole suite, which is how 0.11.0 was found (4,680 of 5,083 tests differed on the first run). Revisit if: many users ask for a -q alias.

ADR-004: Speed is acceptable for 1.0; workers follow container CPU limits

Decision (2026-10-07, owner). (1) The port ships at its current speed: about 10 times slower than the C program on one core, and within about 1.7 times of the one-core C program with 16 cores (measured on cwevent, 8 files of 2023, busy 40-core host). Output is identical at every core count, so speed is not a correctness question. A faster build (for example Rust) is a later, separate decision if users ask for it. (2) The automatic worker count honours a Linux container or service CPU quota (Docker --cpus, Kubernetes limits, systemd CPUQuota=; cgroup versions 1 and 2) as well as CPU affinity, so a process limited to 2 CPUs on a 64-core host starts 2 workers, not 63. Why. Correct, reproducible output is the product; an unbounded worker count only wastes memory. Checked in real containers: --cpus=2 gives 2 workers, --cpus=0.5 gives 1, no limit gives 39 on a 40-core host; output identical on Python 3.12 (fork) and 3.14 (forkserver). Revisit if: users report the speed as a blocker, or a quota type is found that is not read.

ADR-003: Where the port differs from C on purpose

Decision (2026-10-07). When the C tool crashes or reads past an array on malformed input, the port raises a clear error (or defines the value) instead of copying the fault. Cases: a game with no or unreadable date, a month of 0 or 13, badj with no batter, more than 50 line-score innings, more than 40 positions or 20 double-play players, a pickoff-caught-stealing play naming a base other than 1-3, H or 4 (the C writes outside its array and corrupts neighbouring output fields; the port ignores the write), cwbox text on a game with no plays (this is what the real cwbox does on the box-score-only seasons 1901-1907: it crashes, and the port reports an error; cwbox -X works in both). The port also adds -j/--jobs/CHADWICK_JOBS. Dates shorter than ten characters are the exception: #24 made the port print what the C prints. Chadwick 0.11.0 review (box scores). cwbox text on the box-score-only seasons 1901-1907 still crashes in 0.11.0 (re-checked on the real files): unchanged. A box-score event file with a team outside 0-1, a bline slot outside 0-9, a dline sequence outside 1-40 or position outside 1-9 used to index outside the arrays (undefined behaviour); 0.11.0 validates them and exits 1 with an error, so the port now matches that exactly (not a deviation). A starter with no position in a CR LF file now loses its record under the 0.11.0 line reader and cwbox crashes: the port reports an error. A date with only a month (2020/01) still reads an uninitialised day: the port refuses it. Why. Matching undefined behaviour would be copying bugs; the tests record both outputs so any change shows. Real seasons are unaffected (byte-identical). Revisit if: a user needs the exact C output on such input.

Scoped exception (2026-10-08). Where the C result itself is not stable because it reads an uninitialised variable (an unreadable date: a crash on one machine, output on another, seen in CI), a test cannot record the C's output as a reference. Those cases assert only that the port refuses the input (test_cwbox_unreadable_date_is_refused, test_unreadable_date_is_refused and the KNOWN date cases in tests/test_game_targeted_differential.py). Every other case still compares both outputs.

ADR-002: SportsML output (cwbox -S) is deprecated

Decision (2026-10-07, owner direction). The SportsML box-score format is labelled deprecated. It stays in the port as shipped, but is excluded from the completeness and coverage targets. Why. The C cwbox -S crashes on nearly every game, so there is no reference output to prove the port against. Revisit if: a user needs SportsML and a working reference appears.

ADR-001: chadwickpy is only the port; retrosheetpy owns download and prep

Decision (2026-10-07, owner direction). chadwickpy translates the six Chadwick C tools and nothing else. Downloading, caching and table shaping live in retrosheetpy, which depends on chadwickpy. Why. One reason to change per package; the port can be verified against the C tools in isolation. Revisit if: a second consumer needs download logic.