Markdown for LLMs
Exercise 15. A complaint term in business days
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# Exercise 15. A complaint term in business days
An exercise for the [terms](/tutorials/deadlines/) page. The archive
answers a request within ten business days. The rules allow fifteen for
a complaint, counted under the same policy: from the next day, including
the last, rolling to a business day.
**Setup.** Write the complaint-reply term norm and find the date for
a complaint received Friday 6 March 2026 under Kazakhstan's official
calendar. Verify with a date a day earlier that the term is exactly that
day.
**Hint.** The answer cannot be reached by counting days on a wall
calendar: March holds holidays, and they shift. Let the engine name the
date, and explain where it came from.
Below is the solution. Try it yourself first.
## Solution
The calendar and policy from the page, plus two relations:
```law
language "law.core" version "0.2";
package tutorial.archive version "0.6.1";
namespace "urn:law:tutorial:archive";
entity Person;
source KZ_OFFICIAL_CALENDAR_2026 {
kind law;
jurisdiction KZ;
number "calendar-2026";
}
calendar archive_calendar_2026 {
timezone "Asia/Almaty";
timezone_db "iana-tzdb@2026a";
period [@2026-01-01, @2027-01-01);
source KZ_OFFICIAL_CALENDAR_2026;
resource "artifact:corpus/clir/kz-official-2026.calendar.json";
format "law.calendar/0.1";
content_hash "sha256:a17b851ac08e622c05c116637ecf8d818bc7b480568f5560407d69461c4b8c21";
}
deadline policy ARCHIVE_BUSINESS_DAYS {
start_count next_day;
include_end true;
roll next_working_day;
}
relation complaint_received(p: Person, on: Date) kind empirical { key(p); }
relation complaint_reply_due(p: Person, due: Date) kind institutional;
rule ComplaintReplyDeadline strict {
for p: Person;
for on: Date;
when complaint_received(p, on);
then complaint_reply_due(p, add_business_days(on, 15 business_day));
}
```
The test with the engine-named date:
```law
test "жалоба получена в пятницу 6 марта — ответ до 3 апреля" {
given {
context {
deadline_policy ARCHIVE_BUSINESS_DAYS;
decision_time @2026-04-15T09:00:00+05:00;
knowledge_time @2026-04-15T09:00:00+05:00;
legal_time @2026-03-06;
timezone "Asia/Almaty";
calendar archive_calendar_2026;
}
assert complaint_received(entity_ref("urn:tutorial:ivanova"), @2026-03-06) {
id "assert-complaint";
origin case_input;
}
}
evaluate truth(complaint_reply_due(entity_ref("urn:tutorial:ivanova"), @2026-04-03));
expect truth_status == TRUE_ONLY;
expect evaluation_status == COMPUTED;
}
```
The test name reads: "Complaint received Friday 6 March — reply due by 3 April."
Where 3 April comes from. Counting starts the next day, 7 March, and by
the 2026 calendar March holds more days off than usual: 8 March shifted
to Monday the 9th, 15 March shifted to the 16th, Nauryz 21–23 March
shifted to the 24th and 25th, plus weekends. Business days run so: 10–13
March are four, 17–20 eight, 26–27 ten, 30 March – 3 April fifteen. The
fifteenth business day is Friday 3 April, with nothing to shift. The
page's request answer, ten days from the same date, ended 27 March by the
same chain.
## Check
Both tests are in `tests/45-exercise-deadlines.lawtest`: the solution's
date and a date a day earlier expecting `NEITHER`. The policy is declared
both in the program and in the test file: without the second declaration
the runner refuses `LDC-E1333`, without the first —
`EVALUATION_REQUEST_INVALID` at runtime.
What the exercise teaches. A business-day term is a function of three
things: date, policy, and calendar. The norm implies none of them: the
policy is named in the case context, the calendar pinned by hash, and the
same test on another calendar yields another date, and without
a calendar none at all.