Skip to content

Guard every generic sweep over MAPPINGS against a keyless mapping - #23

Merged
bbfrederick merged 1 commit into
mainfrom
keyless-mapping-sweep-guards
Sep 27, 2026
Merged

bbfrederick merged 1 commit into
mainfrom
keyless-mapping-sweep-guards

Conversation

@bbfrederick

Copy link
Copy Markdown
Owner

What this fixes

Making Mapping.ascconv_key optional for the preview-only 1st Signal/Mode entry needed three guards in mappings.py — display reads the preview instead, resolve refuses with a reason, is_churn is not asked. Those are the three the feature itself traverses. Four other sites read the field generically, and only one of them failed.

The full suite was red at 1 failed, 3742 passed before this.

The four sites, by how they failed

Site Behaviour Fix
test_every_enum_choice_agrees_with_the_corpus Failed. Selected enums as m.choices and m.bit is None, so it asked the ASCCONV block for a key that by construction does not exist — reported the mapping as disagreeing on 418 readings over 261 scans Excludes keyless mappings, naming the preview-side sweep that covers them
test_no_two_mappings_claim_the_same_ascconv_key Passed, would invert. Entry identity is (ascconv_key, sequences, when, bit); unique with one keyless mapping, a false collision with two Identity is the preview_path where there is no key
test_no_protocol_has_two_mappings_writing_one_key Passed, would invert. Same shape on (ascconv_key, bit) — would report a write race between two mappings that write nothing at all, resolve refusing both Leaves out a mapping that never writes
probe._is_mapped Passed vacuously. _is_mapped("") became True; the empty key joined the claimed set and the empty stem joined stems. Safe only because no real ASCCONV key splits to an empty stem Answers for real keys only

build.stored_display was saved by accident — it returns early on mapping.choices and never reaches the key. A keyless mapping without choices would have gone straight through.

The two that passed are the expensive ones. A check that inverts on the second instance of a thing is worse than one that fails on the first, since the first instance is when someone is looking.

Verification

  • Full suite green: 3743 passed, 26 skipped with -n auto (12:15)
  • The enum sweep still bites: mutating a real choice (Averaging 1=None → 1=99) fails it, so the exclusion did not gut it. Mutation reverted in try/finally and the file verified clean afterwards
  • Duplicate-key fix falsified both ways: clears two distinct preview-only mappings, still catches two sharing a preview_path
  • black (91 files), isort, codespell clean

CLAUDE.md

Three entries: the finding itself (a scoping rule enforced in the table and not in the sweeps over the table is enforced nowhere — the sibling of the round-5 widening bug); that piping a suite run through tail discards pytest's exit code, which is why the failing run was first read as green; and a one-clause pin on the probe section's "115 to 249" so a future reader doesn't reconcile it against a MAPPINGS count of 250.

Two figures in the write-up were measured after being drafted from guesswork — 418/261 and 49 grep lines replaced invented "~320" and "30".

🤖 Generated with Claude Code

Making `Mapping.ascconv_key` optional for the preview-only
`1st Signal/Mode` entry needed three guards in mappings.py, and those
are the three the feature itself traverses.  Four other sites read the
field generically and only one of them failed.

`test_every_enum_choice_agrees_with_the_corpus` selected its enums as
`m.choices and m.bit is None`, so it asked the ASCCONV block for a key
that by construction does not exist and reported the mapping as
disagreeing with the corpus on 418 readings over 261 scans.  It now
excludes keyless mappings and names the preview-side sweep that covers
them.

The two duplicate-key checks are the expensive ones, because they
passed: with one preview-only mapping their identity tuples stay
unique, and with a second they would pair the two on their shared empty
key and report a collision between mappings that write nothing at all.
Entry identity is now the `preview_path` where there is no key, and the
write-race check leaves out a mapping that never writes.

`probe._is_mapped("")` had become True, safe only because no real
ASCCONV key splits to an empty stem; it now answers for real keys only.

Verified: full suite 3743 passed, 26 skipped with -n auto; the enum
sweep still fails on a mutated choice, so the exclusion did not gut it;
the duplicate-key fix clears two distinct preview-only mappings and
still catches two sharing a preview_path.

CLAUDE.md records the finding, and separately that piping a suite run
through `tail` discards pytest's exit code -- which is why the failing
run was first reported as green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bbfrederick
bbfrederick merged commit 44d2abb into main Sep 27, 2026
9 checks passed
@bbfrederick
bbfrederick deleted the keyless-mapping-sweep-guards branch September 27, 2026 21:16
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