Latent inconsistency flagged during the ocr.py refactor: solve_location()
already excludes a compass-word bearing (bearing_tolerance_deg set) from
its own bearings list before triangulating, since a toleranced bearing
names a sector, not a precise ray, and shouldn't be treated as if it
were one. explain_unresolved()'s bearings list didn't have the same
exclusion, so a toleranced-only bearing plus a distance clue could get
described as inconsistent geometry ('the bearing from X never crosses
the Ykm circle...') when the real reason nothing resolved is just that
the bearing was never usable for that math in the first place. Locked
in with a new test.
No test suite existed before this, which is exactly how a real
regression (the bold-span coordinate-squashing bug, and the
'Type#id:'/'<ref>: <value>' header collision, both from this session)
went unnoticed until manually re-triggered. One test per format,
cross-referenced against the full commit history so nothing already
shipped gets silently dropped by a future change:
tests/test_ocr.py: standard blocks, the calibration target line,
destruction reports (digit and letter id), train-arrival intel,
ad-hoc Enemy installations (+ their destroyed reports), Listening
Post/Coastal Battery, Marine Garrison fire-support requests, multi-
word RP names, bare-name-header targets, the bold-span coordinate-
squashing regression specifically, forward-observer report
triangulation, the '<ref>: <value>' clue grammar (+ its header-
collision regression specifically), 16-point compass tolerance, and
grid-only coordinates.
tests/test_solver.py: direct bearing+distance resolution, two-bearing
triangulation, genuine two-distance ambiguity, the nested-circles
compromise-point fallback, toleranced bearings never being used to
triangulate, and manual coord overrides clearing a stale note.
Runs via ============================= test session starts ==============================
platform linux -- Python 3.14.6, pytest-8.4.2, pluggy-1.6.0
rootdir: /home/dodox/Projects/FeNigma
configfile: pytest.ini
plugins: anyio-4.13.0
collected 21 items
tests/test_ocr.py ............... [ 71%]
tests/test_solver.py ...... [100%]
============================== 21 passed in 0.72s ============================== (pythonpath configured in pytest.ini), dev-only
dependency in requirements-dev.txt so the app itself stays
dependency-light. Documented in the README.