📦 WP-131 — feat(data): keypoints fixture, geometric-only det/obb/seg categories¶
Engineering log · Phase 12 — Keypoint detection, v0.5.0
WP-131 — a dependency fixed upstream, checked rather than trusted¶
The upstream half of WP-121b's "still-open finding" landed same-day: class_names(class_mode, shapes=...) (opt-in, defaulting to the old full-vocabulary span when omitted, so every existing caller is unaffected), a mirrored SyntheticConfig.colors field, and the Task.KEYPOINTS segmentation-emission fix WP-121b already depended on. Verified rather than assumed fixed: the first check found the new parameter existed and its own tests passed, but generate_dataset -- the convenience function this project's fixtures actually call, not the primitive directly -- still called the bare unscoped class_names(config.class_mode) at its one writer-construction call site, so generate_dataset(..., shapes=DEFAULT_SHAPES, ...) kept emitting all 16 categories regardless. Reported back with the exact line and the one-line fix it needed; landed within the hour as an amended commit (74af985), re-verified empirically both ways -- shapes=DEFAULT_SHAPES now yields exactly ['circle', 'rectangle', 'square', 'triangle'], shapes=animal_shapes(2) yields exactly ['duck', 'elephant'] -- before trusting it for anything downstream.
Pinned by commit, not by version (R21). fuse-augmentations' version string had not moved (0.10.0.dev0) across every commit in this saga, and PyPI forbids re-uploading that string, so a bare uv lock re-resolve would have kept silently re-pinning the stale 2026-08-02 wheel. pyproject.toml's dependency became a git+commit-SHA pin instead (git+https://...@74af985...) -- matching R21's own provenance row, which already cited a fixed commit rather than a floating version, closer to A26's original intent than the PyPI-registry pin the project had drifted to. uv lock's re-resolution incidentally also picked up onnx/onnxruntime into the lock for the first time; both had been declared in the dev dependency group but were absent from uv.lock entirely, a pre-existing drift unrelated to this row that a plain uv sync --frozen had exposed by removing the two packages someone had evidently pip installed by hand outside the lock.
Goldens verified unchanged, not re-frozen. generate_detseg_fixtures/generate_obb_fixtures gained an explicit shapes=DEFAULT_SHAPES argument -- defensive, not corrective, since that was already the implicit default -- so the fix restores exactly the 4-category vocabulary the frozen goldens were built against. Full make gate after the pin bump: 2325 passed (2322 plus the two new keypoints-fixture tests plus one doctest), 27/27 goldens passed with no --freeze needed, confirming the restored parity rather than assuming it.
generate_keypoints_fixtures. 12 images, animal_shapes(2) -- duck and elephant, not fuse-augmentations' full 12-animal vocabulary -- specifically to keep an eventual overfit-style milestone run's category count low; more animal classes means a wider vocabulary a memorization-style run has to fit before its own metric means anything. Mirrors generate_detseg_fixtures/generate_obb_fixtures's existing shape exactly: idempotent, seeded (KEYPOINTS_SEED), a matching keypoints_fixture_dir session fixture in conftest.py. test_keypoints_set_loads pins every annotation's landmark table at fuse-augmentations' fixed 16-point animal schema and the category count at or under KEYPOINTS_ANIMAL_COUNT; test_keypoints_generation_deterministic mirrors the existing det/obb determinism tests byte-for-byte.