Skip to content

Deleting a rule's fields escapes #452's check and makes the rule maximally permissive — the symmetric twin of #451 #456

Description

@derek73

#451 banned a rule carrying fields and no name_regex — no name narrowing, so it claimed every name whose diff fit its roles. The mirror image is still legal, and #452 made it worse by giving it a second job.

name_regex = "Smith"      # and no `fields`

Measured: such a rule claims 127 of 127 possible diff shapes on any name its regex reaches. No role narrowing at all.

Why #452 made this urgent

over_declared_rules skips a rule with no fields — correctly, since a rule declaring no roles cannot over-declare them. But that turns deleting fields into an opt-out: the response to an OVER-DECLARED failure that requires the least thought both silences the check and makes the rule maximally permissive. That is the #372 failure mode, reached by following a gate error message.

The ban costs no migration

expected_since_1.4.0.toml: 70 rules, 0 without `fields`
expected_since_2.0.0.toml: 58 rules, 0 without `fields`
expected_since_2.1.0.toml: 51 rules, 0 without `fields`

That is exactly the argument validate_rules already makes for #451's ban in its own docstring: free to enforce, because nothing has the shape.

The symmetry is the point

validate_rules already rejects a rule with neither key ("it would match every diff and shadow every later rule") and, since #451, one with fields and no name_regex. This closes the third corner. After it, every ledger rule carries both — narrowed by name AND by role — and the three rejections read as one rule with one reason rather than three special cases.

Decided, so it is not re-litigated

No escape hatch for a "genuinely unbounded" rule, declined until one appears — the same call #452 made and for the same reason. dormant covers "explains nothing"; nothing covers "explains everything", and no such rule exists in any ledger. If one ever does, it should argue for a key the way dormant was argued for in #373, rather than finding one already built.

Open in the design

Metadata

Metadata

Assignees

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions