Skip to content

Pin the spec to LF, and give the outcome gate a control that can fail it - #35

Merged
HarperZ9 merged 1 commit into
mainfrom
feat/art-outcome-box
Sep 3, 2026
Merged

Pin the spec to LF, and give the outcome gate a control that can fail it#35
HarperZ9 merged 1 commit into
mainfrom
feat/art-outcome-box

Conversation

@HarperZ9

@HarperZ9 HarperZ9 commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Three changes to the artwork gate. No drawing changes.

The spec was not pinned

.gitattributes pinned docs/art/*.svg to LF but left docs/art/*.art.json
unpinned. Measured on this checkout:

bytes endings
index.art.json, before 2354 CRLF
index.art.json, after 2318 LF

2318 is what render_repo_art.py actually wrote. The gate's receipt records a
byte count and a SHA-256 read from the checked-out file, so unpinned those two
numbers depend on who cloned the repository.

What the pin does not do. It does not make the comparison work. Both sides
are read through Path.read_text, which applies universal-newline translation,
so the comparison passes on a CRLF checkout with or without the pin. Only the
receipt's size and hash fields are byte-sensitive. The comment in
.gitattributes now says that narrower thing instead of the broader claim it
carried before.

The budget had the geometry copied into it

_outcome_budgets computed the box width from literals: (960 - 44 * 2 - 26 * (count - 1)) / count. Move a margin in repo_flow and the gate keeps passing
while measuring a box that no longer exists. It reads FLOW.W, FLOW.PAD and
FLOW.GAP now, so the two move together.

The check had no control

The overflow logic is extracted into _outcomes_that_overflow so
test_that_check_can_actually_fail can feed it two outcomes it must reject.
Without that, a green run proved only that the check ran.

The module docstring also claimed the test compares bytes. It compares the
rendered text with line endings normalized away. Corrected.

13 art tests pass. Both budgets still count characters rather than measure
glyphs, so neither can tell mmmm from iiii: a guardrail, not a typographic
fact.

🤖 Generated with Claude Code

Three changes to the artwork gate, none of them to the drawings.

The .gitattributes pinned the SVGs to LF but not the spec they are rendered
from. On this checkout index.art.json came out of the index at 2354 bytes with
CRLF endings; with the pin it is 2318 bytes with LF, the same 2318 bytes the
renderer wrote. The gate's receipt records a byte count and a SHA-256 read from
the checked-out file, so without the pin those two numbers depend on who cloned
the repository. The comparison itself is unaffected either way, because both
sides are read through Python's text layer, which normalizes line endings. The
comment now says the narrower thing that is true.

The outcome budget had the page geometry written into it as literals: 960, 44,
26. Move a margin in repo_flow and the gate keeps passing while measuring a box
that no longer exists. It reads FLOW.W, FLOW.PAD and FLOW.GAP now.

The overflow check is extracted into a helper so a negative control can feed it
two outcomes it has to reject. Before, a green run proved only that the check
ran.

The module docstring said the test compares bytes. It compares the rendered
text with line endings normalized away. Corrected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@HarperZ9
HarperZ9 merged commit 6576b13 into main Sep 3, 2026
2 checks passed
@HarperZ9
HarperZ9 deleted the feat/art-outcome-box branch September 3, 2026 09:00
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