# Deadlines and calendar: pitfalls Wrong forms, silent outcomes, diagnostics, typical mistakes of formalizers and AI agents, how to detect them. Items marked "confirmed by run" were reproduced during this research on the installed `law` (semantics `law.core/0.2`). ## 1. Wrong `start_count` — a one-day mistake with no diagnostics (confirmed by run) 15.01 + 1 month: `same_day` → 15.02, `next_day` → 16.02. Both dates "look right", there are no diagnostics — the mistake shows only against the text ("from the day" vs "from the next day"). In trials this is what gave the first red tests: the rule concluded, but not that date (`NEITHER` on the expected one). Detection: the directory's second package (`start-count/`) pins both dates; in the corpus — a pair of cases on both sides of the boundary. ## 2. No `month_end` on a month step — `MISSING_POLICY` 31.01 + 1 month without `month_end` is a refusal, not "February's last day". The field is mandatory with `calendar_month`/`calendar_year` and read only by them (a field unrelated to the unit does not land in the trace). At the query result this is a `MISSING_POLICY` status with `missing_inputs` and the rule address. Detection: an edge test on the 31st is a mandatory neighbour of every monthly period. ## 3. Units do not mix — `TYPE_ERROR` `business_day` on `add_calendar_period` and calendar units on `add_business_days` are type errors. The `calendar_day` unit is allowed in both terms deliberately: the operations differ (Nth counted day with roll vs fixed step), not the unit. Detection: read the term name, not the unit. ## 4. `add_business_days` without a snapshot — always a refusal The calendar snapshot is always required: even with `no_roll`, even for `calendar_day` — the computation asks `is_working_day`. Zero nodes — `MISSING_CALENDAR`; two or more without a choice — `AMBIGUOUS_CALENDAR`; a date outside coverage — `CALENDAR_OUT_OF_RANGE`. Detection: the halal device — do not count without a calendar; take the number as a case fact instead. ## 5. Invented calendar — a mistake to the dangerous side A "weekends-only" snapshot without holidays gives a period earlier than real. Counting business days without national and religious holidays is forbidden not by taste but by mistake direction (the halal comment). Detection: a snapshot without `sourceArtifacts` and coverage is a removal candidate, not a completion candidate. ## 6. Policy as a term argument — `LDC-E2116` (confirmed by run) Standard-term arity is 2; calendar and policy come via the environment, not as an argument. A trial with named arguments (`after = …, count = …, policy = …`) gave: ```text error LDC-E2116: add_calendar_period: объявленная арность стандартного терма — 2; передано 6 ``` plus `LDC-E0201`/`LDC-E1330` on the names. Detection: positional call + `deadline_policy Name;` in the case context (inline — as with the French, or by profile — as with the medics). ## 7. `cutoff` outside the canon — `DEADLINE_POLICY_INVALID` `cutoff` and the readable `after_time` are eight ASCII `HH:MM:SS`, hours 00–23, minutes/seconds 00–59. A bad cutoff is a policy refusal, a bad readable `after_time` — `TYPE_ERROR`; there is no silent normalization. Detection: always write time with seconds (`"18:00:00"`, not `"18:00"`). ## 9. Bare name as a deadline-window boundary — `LDC-E2115` A window boundary is a value (a date, an instant, a rule variable, `infinity`/`-infinity`, a term with a policy), not a domain constant: `window [moment, infinity)` with an undeclared name is rejection `LDC-E2115`. A corpus floor instead of a bare name is `[@0001-01-01, infinity)` (see the [duty](/constructs/duty/) pages). ## 8. Words after "bearer" — lowercase only Write `bearer`/`holder` only as lowercase keywords.