Skip to content

feat(sitegen): group thousands with U+202F, and route the last renderer through numbers - #18

Merged
P0w3r223 merged 1 commit into
mainfrom
feat/the-separator-clause-8
Sep 8, 2026
Merged

P0w3r223 merged 1 commit into
mainfrom
feat/the-separator-clause-8

Conversation

@P0w3r223

@P0w3r223 P0w3r223 commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Why

0007 §5 clause 8 of the portfolio page specification asks every grouped figure on a
published page for a narrow no-break space, U+202F. This repository writes three figures, in
three spellings from three places — which is the drift sitegen/numbers.py exists to end,
reproduced inside the repository that argues against it.

figure written by carried
10,000 numbers.integer() comma
1 000-resample a literal in sitegen/page.py:219, and a hand-typed twin in README.md plain space
14,745 examples/validation_table.py:130, a format string of its own comma

The third one is the point

sitegen/numbers.py opens with "no renderer is allowed a format string of its own", and
docs/decisions/0007-the-page-is-generated.md:19-22 tabulates this exact script as the
divergence the package argues against. It still had {:,}. It now calls numbers.integer(),
and the figure it writes — n = 14 745/arm — reaches docs/data/findings.json,
docs/index.html and README.md verbatim.

The separator is written "\u202f" in Python sources rather than as the character. U+0020 and
U+202F are one string in a diff, a terminal and a grep, and a module whose whole purpose is
that surfaces cannot disagree about a number should not rely on a reader spotting an invisible
one. README.md gets the character, being Markdown.

What the re-record turned up

--record moved two fields beyond the scenario string:

  • recorded_on: 2026-08-21 → 2026-09-08.
  • ab_lab_version: 0.3.0.dev0 → 0.4.1. The published provenance named a version two
    minor releases behind the package.

Every one of the five measured rates reproduced to the digit — 0.0538, 0.0497, 0.8077,
0.7929, 0.0110 — so the seed is honest and the version gap moved no result. That is the check
worth having, and it is why the re-record is reported here rather than assumed.

What tests/test_record.py:86 actually guards

It re-derives the sample size closed-form and asserts the recorded scenario names it. It is
re-pinned to the new spelling, and it applies the substitution itself rather than calling
numbers.integer — a guard that formats through the function it guards asserts nothing about
the formatting.

Mutation-tested, and the result corrects a natural assumption about it:

mutation result
validation_table.py:130 back to {:,}, without re-recording passed — the guard reads the committed artifact, not the script
the scenario string in docs/data/findings.json back to a comma FAILED, as named
validation_table.py:130 back to {:,} and re-recorded FAILED, as named
numbers.integer back to a comma FAILED — all three of test_site_committed.py's byte guards

So the guard is live over the recorded evidence and over the script through a re-record, and
is deliberately blind to an un-recorded script edit. That is correct — findings.json is a
committed artifact — but it is not what the test's name suggests, so it is written down.

Verification

  • pytest — full suite green.
  • python examples/validation_table.py --record, then python -m sitegen.build, which
    rewrote docs/index.html and the generated: regions of README.md.
  • The index checker now reads this surface clear: ok 8 separator U+202F 3.

…er through numbers

`0007` §5 clause 8 of the portfolio page specification asks every grouped figure
on a published page for a narrow no-break space. This repository wrote three, in
three spellings from three places, which is the exact drift `sitegen/numbers.py`
was written to end.

`numbers.integer()` now groups with U+202F, written `"\u202f"` rather than as the
character: U+0020 and U+202F are one string in a diff, a terminal and a `grep`,
and a module whose whole purpose is that surfaces cannot disagree about a number
should not depend on a reader spotting an invisible one.

The other two were not reached by changing that function, and the interesting one
is the second:

- `sitegen/page.py:219` and its hand-typed twin in `README.md` carry `1 000-resample`
  in prose. Both move, so the two surfaces keep saying the same sentence.
- `examples/validation_table.py:130` had a format string of its own — `{:,}` — in
  direct contradiction of `numbers.py`'s opening line, "no renderer is allowed a
  format string of its own", and of `docs/decisions/0007-the-page-is-generated.md`,
  which tabulates this exact script as the divergence the package argues against.
  It now calls `numbers.integer()`. The number it writes, `n = 14 745/arm`, reaches
  `docs/data/findings.json`, the page and the README verbatim.

`tests/test_record.py:86` re-derives that figure closed-form and asserted it with
`{:,}`. It now applies the substitution itself rather than calling `numbers.integer`
— a guard that formats through the function it guards asserts nothing about the
formatting.

Re-recording `docs/data/findings.json` moved two fields beyond the scenario string,
and both are worth stating. `recorded_on` is today. `ab_lab_version` was `0.3.0.dev0`
and is now `0.4.1`: the published provenance named a version two minor releases
behind the package. **Every one of the five measured rates reproduced to the digit**
— 0.0538, 0.0497, 0.8077, 0.7929, 0.0110 — so the seed is honest and the version
gap moved no result.
@P0w3r223
P0w3r223 merged commit 5f3a802 into main Sep 8, 2026
2 checks passed
@P0w3r223
P0w3r223 deleted the feat/the-separator-clause-8 branch September 8, 2026 14:29
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