test(mutants,assets): a mutant is judged by the suite that owns it, 45 of 45
The runner could only run one test file, which is why PM's three
survivors from `43331fc` could not be added: two are held by the gate's
row 3 and one by the soft-hyphen door's suite. A mutant now names its
suite; the catalogue goes 39 to 45.
X3 and X4 rewritten against the code as it now stands -- a mutant table
is a copy of the code it mutates, and this round moved the lines both of
them quoted. X6 is the defeated state exactly, X7 cuts the ledger off at
its source, X8 removes the cursor rule, P6/P11/P12 are PM's three.
Two survivors on the first run, both findings, both closed:
- X4 survived because every forgery arm now fails on the ledger check
before the binding is reached. An arm was added where the run DID book
the pair and the block stating it points at another picture.
- X5 survived the WHOLE suite -- 2134 passed with the disarming removed
-- because a document-supplied field can no longer reach the gate. The
property is about the BUNDLE and not about one judge, so it is kept and
measured in `tests/test_assets.py`, with a known-positive counting the
run's own two fields on the same expression.
killed 45 of 45, exit 0. Report, CHANGELOG and CLAUDE.md written.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6d7dc7a660
commit
44ad845e29
6 changed files with 431 additions and 17 deletions
71
CHANGELOG.md
71
CHANGELOG.md
|
|
@ -282,6 +282,77 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Fixed
|
||||
|
||||
- **The conversion claim the content-accounting gate believes now comes from
|
||||
the RUN, not from the bundle's prose (0.10.1).** The previous round bound
|
||||
the claim to a pointer block, which closed the two forgeries PM had
|
||||
measured and did not close the class: a pointer block is two lines of
|
||||
markdown, and one ordinary HTML file with two `<p>` elements writes them.
|
||||
Reproduced through the real `okf build` — a BMP refused `asset_too_large`
|
||||
and absent from `assets/` read as CARRIED, from a document naming one
|
||||
digest that is public in the bundle and one that is computable in advance.
|
||||
- `okf build --accounting` now books every conversion the run performed:
|
||||
`assets.conversion` names the `(source digest, asset digest)` pair,
|
||||
`DocumentAssets.conversions` carries it out of the run and the accounting
|
||||
JSON states it per document as `conversions: [{from, to}]`.
|
||||
- The gate reads the pair from there and uses the bundle text only to
|
||||
CONFIRM it. The confirmation can be forged and the ledger cannot, which is
|
||||
why the ledger decides.
|
||||
- **Chosen over neutralising pointer-shaped text at extraction**, because
|
||||
that fix changes what every document SAYS in order to defend a tool
|
||||
outside the build: a source quoting a bundle listing would come out
|
||||
altered and existing bundles would move bytes.
|
||||
- A build run with no accounting door has no ledger, so a converted image
|
||||
is reported claimed-and-not-found rather than believed. That is the same
|
||||
reading the gate had before the conversion route existed.
|
||||
- Measured: the three arms PM reproduced go forged → refused, 3 of 3, with
|
||||
the known-positive (a BMP the run really does convert) True in all three.
|
||||
The text-level regression guard goes 3 arms to 13. R761 rebuilt is
|
||||
`diff -r`-identical, 50 assets (29 JPEG + 21 PNG), 19 of 19 conversions
|
||||
confirmed against 19 declared, SHY 71, u = 0, d = 0.
|
||||
- **An RLE8 stream that stops before the frame is refused (0.10.1).** The
|
||||
terminator rule added earlier in this version asks only that a stream SAY it
|
||||
is finished, and a stream can say so anywhere: measured 2026-09-19, one
|
||||
whose FIRST two bytes are the end-of-bitmap escape was carried with 32 of 32
|
||||
pixels never decoded, while an independent decoder refuses the same file.
|
||||
`_bmp_rle8_rows` now also requires the cursor to stand at or past the end of
|
||||
the last row (`asset_samples_invalid`).
|
||||
- **The line is the cursor and not the pixels.** A delta escape and an
|
||||
end-of-line escape state their skip, so the pixels they pass over keep
|
||||
index 0 and every decoder produces the same picture; a pixel-coverage
|
||||
count would refuse both constructions the format defines. The corpus
|
||||
cannot choose between the two rules — over the 25 RLE8 BMPs the R761
|
||||
delivery ships, 25 of 25 paint every pixel, 25 of 25 reach the end of the
|
||||
frame and 0 of 25 use a delta — and an independent decoder can: Pillow
|
||||
reads 5 of the 8 streams in the table and refuses the same 3 the new rule
|
||||
does, one of them short by a single pixel.
|
||||
- Two docstrings this round was sent to correct are rewritten: the test no
|
||||
longer claims every pixel is decoded, and `_bmp_rle8_rows` no longer
|
||||
frames the delta argument as read off the corpus, which it never was.
|
||||
- **The published `tbx:` count is one number, guarded without the delivery
|
||||
(0.10.1).** `assert sum(tbx.values()) == 568` sat behind a `skipif` on a file
|
||||
only one machine has, so on a fresh clone the sentence five files publish was
|
||||
unguarded — the state in which 574 survived in four docstrings. `N101_TBX_TAGS`
|
||||
is now the one place it lives and a second test holds all five published
|
||||
sentences to it, with no corpus and no clock. What it does not prove is
|
||||
stated: five files agreeing is agreement, not a count.
|
||||
- **The mutant runner judges a mutant by the suite that owns it, and the
|
||||
catalogue goes 39 to 45 (0.10.1).** It could only run one test file, which is
|
||||
why PM's three survivors from `43331fc` could not be added. `X3`/`X4` were
|
||||
rewritten against the code as it now stands; `X6` is the defeated state
|
||||
exactly (a pointer block believed without the run having booked it); `X7`
|
||||
cuts the ledger off at its source; `X8` removes the cursor rule; `P6`, `P11`
|
||||
and `P12` are PM's three. Two survivors appeared on the first run and both
|
||||
were findings — the asset binding had stopped being exercised, and the
|
||||
`_inline` disarming survived the WHOLE suite (2134 passed) because the gate
|
||||
no longer reads its claim from the bundle. The disarming is KEPT and now
|
||||
measured in `tests/test_assets.py`: the property is about the bundle, not
|
||||
about one judge. `killed 45 of 45`, exit 0.
|
||||
- **`test_the_four_existing_goldens_are_untouched` skips, with its reason, in
|
||||
a `git archive` extract (0.10.1).** It called `git status` with `check=True`
|
||||
outside a repository and raised. It was the single failure of the whole
|
||||
suite run from a clean extract, twice reported as a round's one failure by a
|
||||
round that had not touched the file.
|
||||
|
||||
- **A truncated RLE8 BMP is refused instead of carried as a partly blank PNG
|
||||
(0.10.1).** `_bmp_rle8_rows` painted what the stream held and left the rest
|
||||
of the frame at palette index 0 — which is what the format says about a
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue