Skip to content

Commit 06fc731

Browse files
HarperZ9claude
andcommitted
Gate the outcome band against a note that runs out of its box
The outcome boxes sit at a fixed width and neither line inside one wraps or clips, so an over-long note simply runs into the next box with nothing failing. That was the one silent overflow the suite did not cover: card notes are checked against the wrapper, and the tagline against its rule, but the terminal band was unguarded. The REFUTED note was one character over the budget the new test derives, so it is reworded. Like the tagline budget it counts characters rather than measuring glyphs, and it is anchored to the widest note that has been read on a rendered page. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 5a8e4a2 commit 06fc731

3 files changed

Lines changed: 28 additions & 2 deletions

File tree

docs/art/claim-oracle.svg

Lines changed: 1 addition & 1 deletion
Loading

docs/art/index.art.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
],
2929
"outcomes": [
3030
{"label": "MATCH", "note": "the graph carries the edge, with file and line", "tone": "verified"},
31-
{"label": "REFUTED", "note": "the graph is complete here and has no such edge", "tone": "drift"},
31+
{"label": "REFUTED", "note": "the graph is complete here, with no such edge", "tone": "drift"},
3232
{"label": "UNVERIFIABLE", "note": "an endpoint sits outside the scanned workspace", "tone": "none"}
3333
]
3434
}

tests/test_repo_art.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,29 @@ def test_the_tagline_stays_inside_its_rule():
152152
tagline = spec["header"]["tagline"]
153153
assert len(tagline) <= TAGLINE_BUDGET, (
154154
f"{len(tagline)} characters runs past the rule: {tagline!r}")
155+
156+
157+
# An outcome box is one unwrapped line of label over one unwrapped line of note,
158+
# inset 14px inside a box that is (960 - 88 - 26 * (n - 1)) / n wide. Neither
159+
# line wraps and neither is clipped, so an over-long note simply runs out of its
160+
# box and into the next one. Like the tagline budget above, these count
161+
# characters rather than measure glyphs: a guardrail, not a typographic fact.
162+
# The widths come from the box at three outcomes, which is what every spec so
163+
# far uses, and shrink with the box when a spec uses more.
164+
def _outcome_budgets(count: int) -> tuple[int, int]:
165+
span = (960 - 44 * 2 - 26 * (count - 1)) / count
166+
usable = span - 14 - 10
167+
return int(usable / 7.0), int(usable / 5.4)
168+
169+
170+
def test_no_outcome_runs_out_of_its_box():
171+
for spec in _specs():
172+
for flow in spec.get("flows", []):
173+
outcomes = flow["outcomes"]
174+
label_budget, note_budget = _outcome_budgets(len(outcomes))
175+
for item in outcomes:
176+
assert len(item["label"]) <= label_budget, (
177+
f'{item["label"]!r} is wider than its box')
178+
assert len(item["note"]) <= note_budget, (
179+
f'the note under {item["label"]} is wider than its box: '
180+
f'{item["note"]!r}')

0 commit comments

Comments
 (0)