# 📦 WP-153b — `docs: fuse 0.12 validated against the Phase 14 rows`

> Engineering log · [Phase 13 — Contributor admission, augmentation guard and keypoint parity, v0.6.0](https://borda.github.io/lucid-YOLO/engineering/phase-13-contributor-admission/)
>
> 🔗 Depends on [WP-153](https://borda.github.io/lucid-YOLO/work_packages/wp-153/) · Needed by [WP-153c](https://borda.github.io/lucid-YOLO/work_packages/wp-153c/)
>
> ⬅️ [WP-153](https://borda.github.io/lucid-YOLO/work_packages/wp-153/) · [Roadmap](https://borda.github.io/lucid-YOLO/ROADMAP/) · [WP-153c](https://borda.github.io/lucid-YOLO/work_packages/wp-153c/) ➡️


## WP-153b — the phase is unblocked, and three of its rows described upstream wrongly

<a id="wp-153b"></a>

`fuse` 0.12 landed every capability Phase 14 waits on: FA-1 through FA-5, FA-7 and FA-8, with FA-6 and FA-9 declined exactly as the plan agreed. The phase is unblocked. Validating it against the rows that consume it turned up more than a green light, which is the reason to validate before implementing rather than during.

**Two capabilities arrived better than they were specified.** FA-7 imposes no canonical form on a rotated box — no `w >= h` swap, no angle range — and takes `canonicalize=` as a caller callback instead, on the reasoning that the long-edge convention belongs with the assigner, loss and evaluation kernel that share it. That is A22's argument, reached independently upstream, and it is what keeps [WP-157](https://borda.github.io/lucid-YOLO/work_packages/wp-157/)'s design intact. FA-8 decides when to permute keypoint pairs off the sign of the composed matrix's determinant rather than off whether a flip appears in the pipeline, and applies it on every routing path including the two that never build a warp grid. Two mirrors compose back to a rotation that must not swap, and a rotation past 90 degrees looks like a flip while being none; the local unconditional swap gets both wrong, so this is a capability that arrives stronger than the code it replaces.

**Three rows named upstream mechanisms that do not exist.** [WP-154](https://borda.github.io/lucid-YOLO/work_packages/wp-154/) planned to pin `align_corners=False` in the frozen suite, "which `fuse` currently does not" use. 0.12 declined to add the flag at all and measured the equivalence instead: it samples with `align_corners=True` against the normalization sandwich derived for that same flag, so the convention cancels and the pixel-space map is the one an `align_corners=False` implementation produces for the same matrix, verified against an independently constructed reference to `atol=1e-5`. There is nothing left to pin, and the residual that does survive is a different quantity — the composition centre, `((W-1)/2, (H-1)/2)` upstream against `(W/2, H/2)` here. [WP-156](https://borda.github.io/lucid-YOLO/work_packages/wp-156/) attributed geometric fusion to `clip_policy="final"`; `clip_policy` decides when a fused *colour* chain clamps and shares nothing with geometry, a confusion upstream anticipated well enough to warn against by name in its own docstring. Fusion is adjacency-driven, so a colour operation between two geometric ones splits the run and `return_matrix` then reports the last segment alone, silently — which makes that row's tier-C single-segment invariant more load-bearing than when it was written, not less. [WP-157](https://borda.github.io/lucid-YOLO/work_packages/wp-157/) planned to delete `rotated_aug.py`; upstream refuses to clip a rotated box on the grounds that the clipped shape is a polygon and not a rotated box, so `clip_rboxes_to_canvas` has nowhere to go, and `check_rotated_pairing` validates a local `Targets` invariant that was never a resampling concern. The module shrinks and does not vanish.

**What a green gate would not have caught.** None of the three errors is detectable by any check this repository runs. They are prose in a scope cell, describing a repository the gate never reads, and each would have surfaced as an implementing agent reaching for a parameter that is not there — the same failure mode as [WP-139](https://borda.github.io/lucid-YOLO/work_packages/wp-139/)'s golden that was never written and [WP-146](https://borda.github.io/lucid-YOLO/work_packages/wp-146/)'s register that named the wrong commit. The pattern is consistent enough to name: what the gate reads is safe, and what it does not read drifts silently.

**Three decisions the measurement forced, taken by the principal.** The first is the pin. `fuse` has no tags, local or remote, and PyPI's latest is `0.10.0.dev0`, so 0.12 exists as a pushed bump commit rather than a release; the phase proceeds on a commit pin, and `v0.12.0` is tagged from that same commit once the roll-out here is clean. That inverts ADR-005's step order and is deliberate — this project is `fuse`'s first real consumer, so the tag follows the integration that proves it, which is the reciprocal battle-test contract rather than an exception to it. The second is the letterbox. The geometry matches exactly, verified in both directions on integer arithmetic, but the pixels do not: this project resizes with an antialiased bilinear interpolate, upstream runs one `grid_sample` with antialias off by default and a Gaussian mipmap prefilter when on, so any downscale differs and `Letterbox` is the inference preprocessor for six evaluation and prediction call sites. The delegation proceeds, with the eval delta measured first and re-frozen in a row of its own; keeping the local resize would have kept a second implementation of the package's whole subject, which is what the migration exists to stop. The third is the mirror axis: upstream reflects about `(width - 1) / 2` and this project about `width / 2`, so every mirrored centre moves a pixel. Upstream's axis is adopted and the convention change recorded, on the reasoning that one convention across image and coordinate transport is worth a re-freeze and two conventions inside one pipeline are worth nothing.

**What this row deliberately does not do.** No DoD moves and no row splits — [WP-153c](https://borda.github.io/lucid-YOLO/work_packages/wp-153c/) does both. [WP-154](https://borda.github.io/lucid-YOLO/work_packages/wp-154/) needs splitting — the pin bump moves the synthetic fixtures, because upstream redesigned the triangle from obtuse-scalene to equilateral and replaced the minimum-area OBB derivation with an upright-frame one, and triangle is 25 of 90 detseg and 17 of 61 obb annotations against goldens whose tolerance is zero — so a re-freeze rides with that bump and must not ride with a swap. [WP-155](https://borda.github.io/lucid-YOLO/work_packages/wp-155/) and [WP-157](https://borda.github.io/lucid-YOLO/work_packages/wp-157/) need their DoDs rewritten to match the two decisions above. All of that is a row edit rather than a correction, and it follows rather than accompanies the correction of what was simply wrong.

