# Strict rules: pitfalls > Updated 3 October 2026: `concept`, `except_when`, `claim`, `definition … sufficient`, and `default` strength have been removed, together with their special deprecation diagnostic. References below to the former behavior and corpus sources are historical. New source uses `relation`, `unless`, `duty`, a strict rule, and `defeasible`. Wrong forms, silent outcomes, `LDC-E` diagnostics, typical mistakes of formalizers and AI agents, and how to detect them. Items marked “confirmed by runs” were reproduced during this research on the installed engine. ## 1. Head variable bound only by comparison (confirmed by runs) ```law rule SmallEnterprise strict { for e: Enterprise; for n: Integer; when n <= 100; // нет позитивного литерала с n then small_enterprise(e); } ``` `LDC-E4101`: every head variable must occur in a positive body conjunct; comparison, negation, and `not_known` do not bind variables. Fix: add the literal that binds the variable (`employee_count(e, n)`), as in the `research.rule_strict.strict_guard` teaching package. The AI agent often writes the guard first and forgets the binding literal. ## 2. `unless` on a strict rule `LDC-E4110`: a strict rule has no exceptions by definition, exception nodes are not generated. Fix: either the rule becomes `defeasible`, or the applicability condition is added to the strict body as a conjunct. The reverse mistake is making a rule `defeasible` “just in case” when there are no exceptions: then any defeater can remove its support. ## 3. Defeater against a strictly produced head `LDC-E4112`: a defeater must have a defeasible producer of the same head and polarity; a target produced only by strict rules rejects the attack at `check`. The older lesson about a “powerless defeater on a strict head” is outdated: such a defeater now fails to compile instead of silently not working. ## 4. Silent Not established, not refuted: expected refusal, got absence of inference If no rule fired — the answer is Not established, not refuted, not Refuted. Three different causes look the same: - guard not met (250 employees against a threshold of 100); - no fact at all; - premise in Contradiction — a bare literal reads as established, and a contested fact does not activate the rule. Detection: the why-not explanation names the unestablished conjunct; a guard test on Not established, not refuted must state which of the three causes is meant, otherwise the test fixes ignorance, not behaviour. ## 5. Priority does not resolve a conflict of two strict rules Two strict rules with opposite heads give a preserved conflict Contradiction, and `priority` is powerless here — moreover, priority over a strict rule is rejected with `LDC-E4105`. Confirmed by runs: the `research.rule_strict.strict_conflict` teaching package answers Contradiction on both facts without any diagnostics. The AI agent, seeing Contradiction, first declares priority — on strict heads that is a compiler rejection, not a fix. Fix: decide which norm is actually special, and make the pair `defeasible` + `priority` (see the [priority page](/constructs/priority/)), or recognise the conflict as substantive and keep Contradiction. ## 6. A separate `relation` for a `definition` name (finding, confirmed by runs) ```law relation minor(p: Person) kind institutional; definition minor(p: Person) exact { ... } // LDC-E1201 + LDC-E1338 ``` The name is already declared: definitions and relations share one namespace, and redeclaration is a static rejection `LDC-E1201` (plus `LDC-E1338` on the doubled StableId). The compiler synthesizes the relation itself: a lone definition stands without any companion `relation`. Do not redeclare the definition's synthesized relation; that creates a duplicate name. If a publishable vocabulary symbol is needed, publish the definition itself. ## 7. No rule strength; repeated applicability clause A rule without strength (`rule R { … }`) or a malformed clause is a rejection `LDC-E0201`: strength is mandatory; choose `strict`, `defeasible`, or `defeater`. A repeated `scope`, `effective`, or `defeat` clause in one block is `LDC-E1329`. Detection: `law engine check` names the clause; fix — one clause of each kind per block. ## 8. Keyword name as a binder; head block without lowering `for event: …` is a rejection `LDC-E0203` (`event`, `case`, `calendar`, `action` are hard keywords; `state`, `period`, `window`, `holder` are contextual words and may be names). The grammar accepts a `then { a; b; }` block, but the compiler does not lower it: warning `LDC-E1302`, zero rules in the compiled output; fix — separate `then` clauses, each becoming a separate head rule.