Skip to content

Skeleton leftovers: quote cited bullets, Except-fence review lesson, retired-ID guard (#761 follow-up) - #788

Merged
derek73 merged 4 commits into
masterfrom
fix/issue-761-skeleton-leftovers
Oct 21, 2026
Merged

derek73 merged 4 commits into
masterfrom
fix/issue-761-skeleton-leftovers

Conversation

@derek73

@derek73 derek73 commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Follow-up to #761. This lands three loose ends the skeleton migration left behind. No rule text, example or parse result changes, and the corpus and snapshot do not move.

1. Citation comments quote the bullet they name

Fourteen comments named a rule's bullet by description and quoted nothing ("C14's Except", "R3's Accepted clause", "W4's interpunct Except", …), so tests/v2/test_doc_citations.py could not check them. These include the four found after the migration plus ten more that a grep for 's Except|Accepted|Precedence and "Then bullet" turned up. Each comment now has three parts:

  • the bullet quoted next to its rule ID (an Except bullet quotes its whole bold lead, which bullet_lead_findings holds it to);
  • a line saying which clause the code implements or the test pins;
  • a decisions/ pointer.

The citation test now reads all of them. bullet_lead_findings counts 7 citations that name a bullet, up from 2.

Two comments had named the wrong bullet:

  • test_parser.py's "M2's Accepted row" is M2's Except bullet on a marker in post-comma text.
  • test_pieces.py's "no-comma peel's Accepted limit" is S7's.

Review found two comments next to new citations that were false about how names parse, measured on this tree:

Not touched: the notes= strings in tests/v2/cases.py, and two en.toml notes that say "P6's Accepted clause". They are data strings rather than comments, and the citation sweep reads neither.

2. Design review, axis 3: check Except fence rows against their bullet

docs/design/AGENTS.md axis 3 is amended in place. A row in an Except fence must be one where Then does not hold. Read each row against its bullet's bold lead. A row Then still decides moves out of the fence: to the main fence, or to the Accepted bullet that records it as a cost. Nothing checks which fence a row stands in.

Two cases are on record, both caught in review:

A third case, a T1 row in PR #782, was in my brief, but neither that PR's body nor its commits record it, so I left it out.

3. Retired rule IDs are guarded

#786 changed the tombstone wording to "A retired rule's decisions entry records the retirement", which left "never reused" unenforced. As decided:

  • A retired rule's decisions file carries a line of its own opening Retired:.
  • test_no_rule_reuses_a_retired_id refuses a rule file whose ID a decisions file records that way. The readers (rule_file_ids, retired_ids, reused_id_findings) are in tests/v2/design_docs.py.
  • Two more cases are findings, because either would switch the refusal off silently: a Retired: line in a file keyed by no rule ID, and a line that misspells Retired: (bold, a list marker or number, lowercase, an indent).
  • The convention is stated in both docs/design/rules/README.md and docs/design/decisions/README.md.

No rule is retired today, so the real-tree test refuses nothing. Its own assertions check only that both readers reach the folders.

The negative control is test_a_rule_file_reusing_a_retired_id_is_refused. It builds a synthetic decisions folder recording X9 as retired and a rules folder with X9-reused.md, then runs them through the same readers:

  • It fails with the ID check disabled (measured).
  • Its control half, the same files with Folded: in place of Retired:, passes.

The 1. Retired: misspelling row failed against the first version of the pattern before the fix.

Verification

  • uv run pytest: 22197 passed, 123 skipped, 3 xfailed.
  • uv run mypy: clean.
  • uv run ruff check: clean.
  • The design-docs reviewer ran on the branch. Its six findings are fixed in 9355e31, and a second pass over that fix commit found nothing.

🤖 Generated with Claude Code

derek73 and others added 4 commits October 20, 2026 18:48
Fourteen comments named a rule's Except or Accepted bullet by
description and quoted nothing, so test_doc_citations could not check
them. Each now quotes the bullet (an Except bullet by its whole bold
lead, which bullet_lead_findings holds it to) beside its rule ID, says
which clause the code implements or pins, and points at the decisions
entry. Two named the wrong bullet: test_parser.py's 'M2 Accepted row'
is M2's Except bullet on post-comma text, and test_pieces.py's
'no-comma peel's Accepted limit' is S7's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-up)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR #786 replaced the tombstone with 'A retired rule's decisions entry
records the retirement', which left 'never reused' unenforced. A
retired rule's decisions file now carries a line opening 'Retired:',
and test_no_rule_reuses_a_retired_id refuses a rule file with that ID.
The reader lives in tests/v2/design_docs.py. A misspelled Retired line
and one in a file keyed by no rule ID are findings too, since either
would switch the refusal off silently.

No rule is retired yet, so the real-tree test refuses nothing;
test_a_rule_file_reusing_a_retired_id_is_refused builds a synthetic
decisions file and a rule file reusing its ID and is the negative
control (it fails with the ID check disabled, measured).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- test_properties: drop the two maiden-clause pairs said to differ;
  measured, both spellings of each read alike since #601, and M2's
  bullet the new citation quoted accepts no such split.
- _extract: the M3 contrast is a suffix word ('née PhD'), not V, which
  M2 also reads as the maiden name.
- Retired: a numbered '1. Retired:' line is a misspelling too (the new
  row failed against the old pattern first).
- docs/design/AGENTS.md axis 3: two incidents on the record (H1 in
  #779, S3's Msc.Ed. row in #783), not three; a row Then decides may
  belong under Accepted. The skip list names the new guard.
- cases.py: shape 7's U+00B7 half is what the W4 Except decides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@derek73 derek73 added docs Documentation fixes and updates tests design labels Oct 21, 2026
@derek73 derek73 self-assigned this Oct 21, 2026
@codecov

codecov Bot commented Oct 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.05%. Comparing base (9932592) to head (9355e31).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #788   +/-   ##
=======================================
  Coverage   99.05%   99.05%           
=======================================
  Files          47       47           
  Lines        4642     4642           
=======================================
  Hits         4598     4598           
  Misses         44       44           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@derek73
derek73 merged commit 845fc87 into master Oct 21, 2026
12 checks passed
@derek73
derek73 deleted the fix/issue-761-skeleton-leftovers branch October 21, 2026 02:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

design docs Documentation fixes and updates tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant