Skip to content

fix(ci): unblock main — de-symlink workshop bib (sdist) + deterministic pixel font test#189

Merged
abrichr merged 2 commits into
mainfrom
fix/ci-sdist-symlink-and-flaky-fonttest
Jul 20, 2026
Merged

fix(ci): unblock main — de-symlink workshop bib (sdist) + deterministic pixel font test#189
abrichr merged 2 commits into
mainfrom
fix/ci-sdist-symlink-and-flaky-fonttest

Conversation

@abrichr

@abrichr abrichr commented Jul 20, 2026

Copy link
Copy Markdown
Member

Fixes the two pre-existing main failures that block CI on every in-flight PR (#181, #179, #177, and the LOOP/visualizer/benchmark PRs).

Fix 1 — wheel gate (sdist packaging)

paper/workshop/references.bib was a git symlink (mode 120000 → ../references.bib), introduced with the workshop paper. hatchling ships it into the sdist as a symlink member, and scripts/check_release_consistency.py --require-dist (the wheel job) rejects any non-file/dir member:

source distribution contains a link/device/special member:
'openadapt_flow-<v>/paper/workshop/references.bib'

Fix: replace the symlink with a byte-identical regular-file copy of paper/references.bib, and add a check_artifacts.py assertion that the two bibliographies stay identical (no silent drift). The workshop build already runs from paper/workshop/, so bibtex resolves the local copy unchanged.

Verified: make -C paper builds both PDFs (full report + 6-page workshop), check_artifacts.py passes, python -m build succeeds, and the release-consistency gate now exits 0 with no symlink members in the sdist.

Fix 2 — flaky test_blocker2_mismatch_is_scale_invariant

Two root causes made it flip on CI Linux:

  1. Host-dependent font_scalable_font preferred macOS Arial and only fell back to DejaVuSans on Linux, so the same identifier rendered differently dev-vs-CI and the pixel metrics differed with it. Now it prefers matplotlib's bundled, version-pinned DejaVuSans (a guaranteed dev/CI dep) → byte-identical renders on every platform; skips cleanly if no vector font is available (never asserts on the degenerate bitmap default).
  2. Wrong asserted property — the test used an O/0 homonym (AC50061 vs AC5OO61). A pure O/0 confusable is deliberately outside the pixel tier's remit: the glyphs are near-identical, so the tier correctly abstains and defers the homonym to the OCR-canonicalization tier. Asserting a pixel mismatch on it asserted un-guaranteed behaviour that flips with the font. Now it asserts scale-invariant mismatch on a genuinely different MRN (one digit, 0→8) — the same different-identifier the non-flaky wide-cell sibling test already proves, and exactly the Blocker-2 anti-dilution property this test is meant to pin. Robust with a real margin at every cell width.

Verified deterministic across repeated runs (10×, plus the full non-harness crop suite: 22 passed). No new lint/format findings (CI's ruff check targets openadapt_flow only; the pre-existing test-file I001/E731 findings are unchanged; ruff format --check passes).

🤖 Generated with Claude Code

https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM

abrichr and others added 2 commits July 20, 2026 15:29
paper/workshop/references.bib was a git symlink (mode 120000) to
../references.bib. hatchling ships it verbatim into the sdist as a symlink
member, and scripts/check_release_consistency.py --require-dist (the `wheel`
CI gate) rejects any non-file/dir member:

    source distribution contains a link/device/special member:
    'openadapt_flow-<v>/paper/workshop/references.bib'

That failed the packaging gate on every in-flight PR. Replace the symlink
with a byte-identical regular-file copy of paper/references.bib so the sdist
contains only regular files, and add a check_artifacts.py assertion that the
two bibliographies stay identical so they can never silently drift. Both PDFs
(full report + workshop) still build via `make -C paper` and check_artifacts
still passes; `python -m build` + the release-consistency gate now succeed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
test_blocker2_mismatch_is_scale_invariant rendered glyphs with PIL and
asserted a pixel MISMATCH, but was flaky on CI Linux. Two root causes:

1. Host-dependent font. _scalable_font preferred macOS Arial and only fell
   back to DejaVuSans on Linux, so the same identifier rendered differently on
   dev vs CI, and the pixel metrics (spike/floor/uniqueness) differed with it.
   Fix: prefer matplotlib's bundled, version-pinned DejaVuSans (a guaranteed
   dev/CI dependency) so renders are byte-identical on every platform; platform
   TTFs are only a fallback, and the render tests skip (never assert on the
   degenerate bitmap default) if no vector font is available.

2. Wrong asserted property. The test used an O/0 homonym ("AC50061" vs
   "AC5OO61"). A pure O/0 confusable is deliberately OUTSIDE the pixel tier's
   remit -- the glyphs are near-identical, so the tier correctly ABSTAINS (its
   localized-spike uniqueness heuristic cannot separate a homonym from
   same-value anti-aliasing jitter) and defers the confusable to the
   OCR-canonicalization tier. Asserting a pixel MISMATCH on it asserted
   behaviour the tier does not guarantee, and the verdict flipped with the
   font. Fix: assert scale-invariant mismatch on a GENUINELY different MRN
   (one digit, 0->8) -- the same different-identifier the non-flaky wide-cell
   sibling test proves -- which is exactly the Blocker-2 anti-dilution property
   the test is meant to pin. Robust with a real margin at every cell width.

Verified deterministic across repeated runs on macOS (now using the same
DejaVuSans CI uses).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM
@abrichr
abrichr merged commit ce94d97 into main Jul 20, 2026
15 checks passed
abrichr added a commit that referenced this pull request Jul 21, 2026
… not a symlink) (#199)

The paper byline is now set (Richard Abrich, OpenAdapt / MLDSAI Inc.), so the
README's "no named byline" note and "replace the contributor placeholder"
submission blocker were stale. Also corrects the build note: the workshop shares
references.bib via a byte-identical regular-file copy (de-symlinked in #189 so
the sdist packages cleanly and check_artifacts.py asserts they stay identical),
not a symlink as the README claimed. Docs-only; no LaTeX or benchmark change.


Claude-Session: https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant