# Check a notice before an event ## Intention I want to check a presented notice date three business days before a visit. ## Incorrect form and why it stays silent A backward step passes statics but is rejected at execution: ```text title="Incorrect form" add_business_days(visit_on, -3 business_day) ``` Comparing days_between with `0 calendar_day` is another error: the result is Integer. ## Correct form ```law language "law.core" version "0.2"; package recipes.e.r02 version "0.1.0"; namespace "urn:recipe:e-time:02"; entity Person; relation registered(p: Person); source SyntheticCalendar { kind standard; jurisdiction "none"; number "E-CALENDAR"; } calendar Calendar { timezone "Asia/Almaty"; timezone_db "iana-tzdb@2026a"; period [@2024-01-01, @2028-01-01); source SyntheticCalendar; resource "resources/calendar-2024-2027.json"; format "law.calendar/0.1"; content_hash "sha256:dfd0181e1347cc2fd48b5fd81d27f3551cabae10eaefbf8b4dffb70bcbb3cd12"; } deadline policy Days { start_count next_day; include_end true; roll next_working_day; } relation sent(p: Person, on: Date); relation visit(p: Person, on: Date); relation timely(p: Person); rule Timely strict { for p: Person; for sent_on: Date; for visit_on: Date; when sent(p, sent_on) and visit(p, visit_on) and days_between(add_business_days(sent_on, 3 business_day), visit_on) >= 0; then timely(p); } ``` ## Frozen execution scene | Facts / cut | Question | Answer | |---|---|---| | notice 06.03, visit 12.03 | timely | TRUE_ONLY | | notice 06.03, visit 11.03 | timely | NEITHER | | backward step from 12.03 | date | RUNTIME_ERROR, DEADLINE_POLICY_INVALID | ```law test "visit on cutoff day counts timely" { given { context { legal_time @2026-03-10; decision_time @2027-12-31T09:00:00+05:00; knowledge_time @2027-12-31T09:00:00+05:00; timezone "Asia/Almaty"; deadline_policy Days; } assert sent(entity_ref("urn:recipe:e-time:02:a"), @2026-03-06); assert visit(entity_ref("urn:recipe:e-time:02:a"), @2026-03-12); } evaluate truth(timely(entity_ref("urn:recipe:e-time:02:a"))); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` ```law test "early visit misses cutoff" { given { context { legal_time @2026-03-10; decision_time @2027-12-31T09:00:00+05:00; knowledge_time @2027-12-31T09:00:00+05:00; timezone "Asia/Almaty"; deadline_policy Days; } assert sent(entity_ref("urn:recipe:e-time:02:a"), @2026-03-06); assert visit(entity_ref("urn:recipe:e-time:02:a"), @2026-03-11); } evaluate truth(timely(entity_ref("urn:recipe:e-time:02:a"))); expect truth_status == NEITHER; } ``` ```law test "negative step rejected" { given { context { legal_time @2026-03-10; decision_time @2027-12-31T09:00:00+05:00; knowledge_time @2027-12-31T09:00:00+05:00; timezone "Asia/Almaty"; deadline_policy Days; } } evaluate add_business_days(@2026-03-12, -3 business_day); expect evaluation_status == RUNTIME_ERROR; expect issue(DEADLINE_POLICY_INVALID); } ``` The calendar is synthetic: Mon–Fri, 9 March 2026 is a conventional non-working day; this is not an official calendar. ## Counterfactual The negative-step scene pins a runtime rejection. teaches changes the comparison-threshold type and requires E2108. ## Boundary The form judges a completed action; it does not build the last admissible day. Whether the event day itself is included depends on the text: the strict boundary is analysed in [Fold bridges into one deadline rule](/recipes/e-time/shared-deadline/). ## Pitfall An incorrect negative step must not spoil the status of neighbouring results; here the rejection is pinned by a separate query, without promising a reverse calendar API.