📦 WP-176 — release: v0.8.0 the audit remediations¶
Engineering log · Phase 15 — Audit remediation, v0.8.0
WP-176 — v0.8.0, the audit remediations¶
The release whose subject is a class of defect rather than a capability. Nothing in 0.8.0 detects anything 0.7.0 could not. What the sixteen rows have in common is that every defect they fixed was invisible to a green gate: an assigner whose one-to-many localization objective was annihilated at 4.12e-09 while all 43 offline goldens passed, a merge path dropping a modality, entry points validating types but not values, four acceptance floors compared once at a prompt, and a record describing a three-task repository against four shipped tiers. So the gates moved with the fixes — ci-tests.yml runs make test rather than a narrower subset, goldens/frozen/MANIFEST.sha256 makes a frozen value uneditable alongside its own tolerance, the accelerator half has a nightly workflow instead of a Makefile comment claiming to be one, and FloorNotMet raises where the score is produced. The one number the release moves is the keypoint overfit floor, 0.335667 to 0.574728, which is what the assigner defect cost measured after the fact.
The mechanics, which are four lines. __version__ moves 0.7.0 to 0.8.0 and that is the whole version change, pyproject.toml declaring it dynamic and reading the module attribute. [Unreleased] closes as [0.8.0] - 2026-09-05. make freeze-goldens MINOR=0.8 copies seven live metric sets into goldens/frozen/0.8/ — the same seven 0.6 and 0.7 hold, data_checksums.json and fixture_checksums.json still skipped as generator-derived under WP-154c's "freezable": false — and the offline gate goes from 43 goldens to 50. The README's Current release line is rewritten, which for the first time is load-bearing rather than courtesy: WP-175 added check_readme_names_the_current_version, so a release that bumped the attribute and left the prose behind would now fail its own gate instead of drifting three minors the way 0.4.0 did.
The row's own premise was wrong, and the freeze is ordinary because of it. The scope cell says two of this phase's rows moved a value pinned in every frozen set from 0.2 forward, "so this freeze is also where those moves stop being recorded exceptions and become the baseline a later release is held against". Written in advance, that was a prediction about WP-169 and WP-172, each of which carried a DoD clause requiring a principal ruling in docs/ESCALATION.md before any frozen value moved. Both rows measured instead of assuming, and neither moves a frozen value: WP-169's two fixes leave assignment_cases.json bit-identical live and frozen from 0.2 forward, and WP-172's merge-path repair moves no golden at all. docs/ESCALATION.md therefore gains no entry here, and the 0.8 snapshot normalizes nothing — it is an ordinary release freeze. Phase 14's two overrides of AGENTS.md §7 remain the only ones, and remain non-precedential.
One value that looks like drift and is not. aug_invariants.json stores rotated_rbox_area as 96.1934; the producer emits 96.1934585571289, which rounds to 96.1935 at four decimals and therefore reads as one ulp of disagreement in any four-decimal report. The unrounded value sits 8.6e-06 above the 96.19345 rounding boundary, and the stored tolerance is 0.5, so nothing fails and nothing has moved. It is copied into 0.8 exactly as 0.6 and 0.7 hold it, and recorded here because a later reader comparing a rounded report against the stored literal would otherwise open an investigation into a representation difference.
D21, and a decision left unedited. docs/DECISIONS.md D1 still reads "Pose and classification remain future 0.x work" against a keypoint tier released at 0.5.0 — the stale claim WP-175 found and deliberately did not touch, on the grounds that rewriting a recorded decision to match what later happened is how a decision log stops being evidence. This row is [PRINCIPAL] and can do what WP-175 could not: D21 supersedes the keypoint half of D1's scope clause and nothing else. Classification and YOLOE-26 stay out of scope, and no row proposes them. The entry carries two qualifications D1's wording could not: the tier is keypoints, not pose, K being a constructor argument that nothing in the head, loss or decode interprets; and it is the one accepted tier not drawn from R1, its loss and evaluation protocol coming from R14 (RLE, arXiv:2107.11291) because no allowlisted paper publishes a keypoint architecture or parameter table to check the head against (A65, A66) [struck 2026-09-17: false — R1 sec. 3.4.2, Table 9 and Table S10 do; D22 withdraws this clause of D21 and records what the tier is instead, a partial reproduction of R1's pose objective]. D1's word "pose" therefore never named what shipped, which is the second reason to supersede rather than amend.
What this release still does not do. No tag is cut and no distribution is published, as at 0.4.0 through 0.7.0; five release commits now stand ahead of the train's own tags. release.yml fires on a pushed version tag and re-runs the guard, and both are the operator's to trigger. D20 stands unchanged: fuse-augmentations is pinned as a direct reference to a5a276a, which is legal to build and install and illegal to upload, so this distribution remains unpublishable to PyPI until a 0.12 reaches it — at which point a >=0.12,<0.13 range replaces the reference and nothing else changes. No trained weights ship (D14).