Markdown for LLMs
Duty pitfalls
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# Duty 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`.
## 1. Tautological goal: the duty is always SATISFIED
```law
when contract_signed(s, c);
then duty Deliver {
bearer s;
goal achievement { condition contract_signed(s, c); window [...]; }
};
```
The goal condition is already established when the position is created. The engine answers
`SATISFIED` always. Diagnostics: warning `LDC-E1371`.
Detection: `law engine check` + reading the warnings.
Fix: the goal condition is a performance
predicate (`goods_delivered`) absent from the body.
## 2. Two VIOLATED for one prohibition breach
A prohibition + a paired `maintenance` duty with `not_done(x)`.
The prohibition itself gives `VIOLATED`; the pair — a second one. Detection: two
`VIOLATED` in `positions()` for one action fact. Fix: delete the pair.
## 3. A dated boundary is effective, not window
A norm "in force since March 1" is written `effective [@2026-03-01, infinity);`
on the rule; the goal window is the performance deadline. At a `legal_time` outside
`effective` there is no position at all; at a `legal_time` outside `window` there is one
(`PENDING` / `UNDETERMINED`). Detection: `why_not` names the candidate
`NOT_APPLICABLE`.
## 4. unless binds not all payload variables
`unless force_majeure(s)` with `beneficiary c` — rejection `LDC-E4101` on
`DeliveryRule/unless/0`. The
`unless C then not Duty` form — `LDC-E1302`: a position has no complement.
Detection: `law engine check` fails (`ok: false`).
## 5. Mandatory fields and date kinds
`duty` without `bearer`, a goal without `window` — `LDC-E1305` for each. The string `"2026-03-31"` passes `check` as `Text` and breaks only at
runtime — write `@2026-03-31`.
## 6. A second goal is rejected
A second `goal` in one norm — `LDC-E0201`. Two goals means two rules
or two `then` clauses.
## 7. Traps for automated authors
- `_` in `goal.condition` passes `check`, but a literal with `_` is never
found in the store: the duty stays `ACTIVE`, performance is silent (a known
open gap). Bind
the variable with the rule body.
- `valid_when a and b;` without parentheses — `LDC-E0201` + `LDC-E1305`, compilation
fails; write `valid_when (a and b);`.
- A body conjunction reads positively: the goal condition must be a NEW
predicate, not a copy of a premise (see [the tautological-goal trap](#1-tautological-goal-the-duty-is-always-satisfied)).
- Rule name = position name — `LDC-E1338`: name the rule
with a `Rule` suffix.
- Silent outcome: `UNDETERMINED` after the window with no explicit non-performance is
not `VIOLATED` and not a package defect.
## 8. `unless` on a strict rule — `LDC-E4110`
A position with an exception is written `defeasible`: a `strict` rule with
an `unless` clause is rejection `LDC-E4110`. Detection:
`law engine check` fails (`ok: false`).
## 9. The parties to a duty
Write the obligated party in `bearer` and the beneficiary in
`beneficiary` ([§129.1](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/18-part-xvii-normative-positions.ru.md#1291-притязание-через-duty)). Check that the parties match the act before running
the scenarios.