Skip to content

Commit d8a2dd4

Browse files
tcoratgerclaude
andauthored
fix(testing): make finalized-safety head check scheme-independent (leanEthereum#916)
A fork-choice vector asserted head_slot=5 at the step that adds an empty sibling block above the canonical head. At that step both children of the justified block carry zero distinguishing fork-choice weight, so the head is a pure tie broken by the larger block root. A block root embeds the post-state root, which embeds the validator public keys, so the tie resolves differently under the test and production signature schemes. The vector passed under the test scheme and failed under production, where the sibling at slot 6 won the tie. Stop asserting which sibling is head at the tie step. Assert instead that the empty fork block changes neither justification nor finalization, which holds under both schemes. The genuine "above fork wins" property is still asserted at the next step, where the fork gathers the votes that justify it and move the head onto it with no tie. Also add a repository rule: every test change must update the associated documentation in the same change, per the documentation rules. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 992b7a6 commit d8a2dd4

2 files changed

Lines changed: 15 additions & 2 deletions

File tree

CLAUDE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,14 @@ subspecifications that the Lean Ethereum protocol relies on.
117117
metacharacters escaped); prefer the explicit full-equality assertion above.
118118
- This mirrors the full-equality rule for ordinary assertions: assert the whole object, never a
119119
piece of it.
120+
- **CRITICAL - KEEP TEST DOCUMENTATION IN SYNC WITH THE TEST**: This is a STRICT requirement. Every
121+
time you change a test, update the documentation that describes it in the SAME change, following
122+
the documentation rules (`.claude/rules/documentation.md`, and for `tests/consensus/` the
123+
Given/When/Then standard in that file). A test's docstring is part of the test; a change that
124+
leaves the docstring describing the old behavior is incomplete.
125+
- When you add, remove, or change a step, assertion, or expected value, reconcile the docstring so
126+
it still describes exactly what the test does.
127+
- For `tests/consensus/` vectors, the step assertions and the Given/When/Then docstring must stay
128+
one-to-one: if an assertion changes, the matching docstring line changes with it.
129+
- Do not weaken a docstring into vagueness to avoid updating it; describe the new behavior
130+
precisely, as the doc-writer rules require.

tests/consensus/lstar/fork_choice/test_finalized_safety.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,10 @@ def test_fork_above_finalized_wins_at_or_below_loses(
323323
BlockStep(
324324
block=BlockSpec(slot=Slot(6), parent_label="block_4", label="above_6"),
325325
checks=StoreChecks(
326-
head_slot=Slot(5),
327-
head_root_label="block_5",
326+
latest_justified_slot=Slot(4),
327+
latest_justified_root_label="block_4",
328+
latest_finalized_slot=Slot(3),
329+
latest_finalized_root_label="block_3",
328330
),
329331
),
330332
BlockStep(

0 commit comments

Comments
 (0)