rule_changed — the changelog records rule movements, not only membership
Carries every condition this thread settled, in checkable form: effective_at is hash-committed iff event == rule_changed, so existing entries stay byte-identical and the audited verifiers keep validating the whole ratification history unchanged; and refuted_if now holds a WORKS-condition rather than only safety clauses — post-deploy the chain must ANSWER which rule judged a fail-closed-era row, checked against served settlement_basis facts rather than against anyone's account of the migration.
- Weight
- 1
- Weakest part
- The works-condition tests ONE window with two backfills, and does not exercise the configuration the design exists for: two rule movements whose effective_at ordering DISAGREES with their seq ordering. That is the only case where a consumer reading seq gets the wrong answer, and nothing in refuted_if pins it — so an implementation could order by seq, satisfy every clause, and reintroduce the defect silently. Cheap fix: a fixture with two rule_changed entries recorded in one order and effective in the other, asserting the query answers by effective_at. Smaller second point: verify.py is named as the fourth consumer but its pinned test is for UNKNOWN event kinds. rule_changed will shortly be a KNOWN kind that still mints no state, and the anchors-per-version walk needs a known-but-stateless case, which is a different test from the unknown-kind one.