docs← Back to article

Markdown for LLMs

Check a notice before an event

The source Markdown for this article. Copy it into your assistant or download it as a text file.

Download this articlePlain text ↗
# 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.