Time and calendars
Task and place
Section titled “Task and place”Every legal answer holds as of a date. This stage dates the norms (when each rule takes part), dates the case facts (when each statement holds), and stamps every scenario with the four axes the machine reads instead of the system clock. It sits between rule drafting and scenario writing: rules name their windows, this stage fixes the contexts scenarios run under, and review replays them.
Inputs
Section titled “Inputs”- The act’s entry-into-force provisions and any later amendments with their dates.
- The pinned edition dates: adoption and force interval where the act states them.
- The case event dates: when the loss occurred, when payment fell due, when delay began.
- The forum timezone, written as a zone name such as Asia/Almaty, never as a bare offset.
Actions
Section titled “Actions”- Stamp every scenario with all four axes: legal_time (the date whose law applies), decision_time (when the answer is issued), knowledge_time (the boundary of known data), and timezone.
- Date each norm once, in one place: either a window on the rule for norms that enter into force apart from the act, or the force interval of the edition the rule’s source anchor points to.
- Compare event dates in the rule body, against the fact’s own date — never against legal_time.
- Keep kinds apart: dates compare with dates, instants with instants; the machine refuses mixed comparisons with LDC-E2108.
- Never read the system clock: a scenario without explicit axes is incomplete, not current.
Decisions
Section titled “Decisions”- One window per rule: a second window clause in the same block is refused (LDC-E1329), so overlapping force periods must be modeled as separate rules or separate editions.
- Rule window or edition dating: a lone article with its own commencement date earns a window on its rule; an act dated as a whole is dated by its edition, and a spare window on the rule will sooner or later drift from the edition interval.
- Date or instant thresholds: write the threshold in the kind of the fact it meets.
Artifact
Section titled “Artifact”The artifact is a time matrix plus boundary checks. The matrix lists every dated element of the package, names the axis that filters it, and states the silent-answer symptom when the filter removes it:
| Dated element | Filtering axis | Symptom when filtered out |
|---|---|---|
| Rule window | legal_time | the rule takes no part; the answer stays undecided |
| Edition force interval | legal_time | anchored rules take no part |
| Fact validity window | legal_time | the fact is excluded from supports |
| Event-date comparison in a rule body | none — the fact’s own date decides | the rule stays silent on non-matching facts |
| Answer moment and data boundary | none — they stamp the answer | not applicable |
Boundary checks are scenario pairs that differ only in legal_time: one date inside each window, one outside. Each pair pins the reading that prose alone leaves open.
EAI example
Section titled “EAI example”The running example is time-flat, and the matrix says so explicitly. Package kz.corpus.employee_accident_insurance, version 0.1.0, language 0.2: all seven scenarios share one context, with answer moment and data boundary at 2026-09-13T12:00+05:00, law date 2026-09-13, zone Asia/Almaty:
context { decision_time @2026-09-13T12:00:00+05:00; knowledge_time @2026-09-13T12:00:00+05:00; legal_time @2026-09-13; timezone "Asia/Almaty";}No rule carries its own window; the pinned edition EAI_EDITION carries an adoption date but no force interval; no case fact carries a validity window; no rule compares an event date. Materialization is PINNED_UNOFFICIAL_COPY — an Adilet API copy retrieved 2026-09-13, sha256 pinned, local copy kept in the package. Per path, each axis filters nothing here: legal_time admits every rule and every fact on any date, while the answer moment and data boundary only stamp the run. That flatness is a matrix entry, not an oversight: the duty, tariff, payout, and penalty branches of the four modeled articles carry no commencement split in the pinned edition, so every matrix row reads absent — and any amendment with its own commencement date reopens this page.
Read the contract of that flatness narrowly. The absence of a separate commencement for four modeled articles does not establish that the edition as a whole has no temporal boundary: the act may have entered into force on a date the pinned copy does not state per article, and unmodeled articles may carry their own windows. The running example is a snapshot of the model under one law date, not a historical choice of applicable law — it answers “what follows from these rules on 2026-09-13”, never “which edition governed this event”. A case with an event date outside the retrieval date needs the edition’s own force interval first; this page’s matrix has no row to give it.
Pitfall
Section titled “Pitfall”The costly confusion is reading decision_time as the law selector: an answer issued this year about last year’s event still counts under last year’s law. Only legal_time selects norms. The second confusion is a dateless edition: an edition without a force interval dates nothing, so rules anchored to it float free of legal_time — the suite stays green on any date, which looks like stability and is actually silence about time. Name it in the matrix either way.
Verify
Section titled “Verify”The stage is done when the check passes, all seven scenarios pass, and the matrix covers every dated element including the absent ones. Observed with tool version law 0.1.0, semantics law.core/0.2:
$ law engine check corpus/laws/kz/laws/employee-accident-insurancecheck OK: corpus/laws/kz/laws/employee-accident-insurance$ law test corpus/laws/kz/laws/employee-accident-insurance ok [kz.corpus.employee_accident_insurance#authored] tests/core.lawtest / EAI-EMPLOYER-MUST-INSURE ok [kz.corpus.employee_accident_insurance#authored] tests/core.lawtest / EAI-MINING-CLASS-22-PREMIUM ok [kz.corpus.employee_accident_insurance#authored] tests/core.lawtest / EAI-LOSS-THIRTY-QUALIFIES ok [kz.corpus.employee_accident_insurance#authored] tests/core.lawtest / EAI-LOSS-TWENTY-NINE-IS-NOT-INSURER-PAYOUT ok [kz.corpus.employee_accident_insurance#authored] tests/core.lawtest / EAI-SPECIAL-LATE-PAYMENT-PENALTY ok [kz.corpus.employee_accident_insurance#authored] tests/goals.lawtest / GoalEstablishedCapacityLossHasPayout-world ok [kz.corpus.employee_accident_insurance#authored] tests/goals.lawtest / urn:kz:corpus:clir:employee-accident-insurance#GoalEstablishedCapacityLossHasPayoutCriterion: rerun the suite with legal_time moved to a second date and confirm the matrix predicts the outcome row by row — for the running example, identical results, because the matrix claims flatness. Any divergence means a hidden window the matrix missed.
The running example proves flatness; it cannot prove that windows work. The executable half of this stage is the time drill — a synthetic package with two windowed rules over one question and one counted term with a pinned calendar. Observed with the same tool version:
$ law test docs/handbook/files/fixtures/time-termslaw test demo.handbook.time_terms: world demo.handbook.time_terms ok [demo.handbook.time_terms#authored] tests/window.lawtest / inside the old window ok [demo.handbook.time_terms#authored] tests/window.lawtest / inside the new window ok [demo.handbook.time_terms#authored] tests/window.lawtest / before every window stays silent ok [demo.handbook.time_terms#authored] tests/window.lawtest / decision moment does not select the law ok [demo.handbook.time_terms#authored] tests/deadline.lawtest / thirty calendar days from filing ok [demo.handbook.time_terms#authored] tests/deadline.lawtest / function form counts one day later (TIME-F1, observed) ok [demo.handbook.time_terms#authored] tests/deadline.lawtest / no policy means no counted datetotal: 7 checked, 7 passed, 0 failed, 0 not run; code 0Each scene was inspected in the suite files; the setups and expectations read:
| Scene | Setup | Expects |
|---|---|---|
| inside the old window | legal_time 2024-06-01, registered | TRUE_ONLY, OldTerm applied, NewTerm excluded |
| inside the new window | legal_time 2025-06-01, registered | TRUE_ONLY, NewTerm applied, OldTerm excluded |
| before every window stays silent | legal_time 2023-06-01, registered | NEITHER, neither rule applied |
| decision moment does not select the law | legal_time 2024-06-01, decision_time 2026 | TRUE_ONLY via OldTerm |
| thirty calendar days from filing | filed 2026-02-01, policy selected | 2026-03-03, derived by hand from the policy |
| function form counts one day later | same inputs, add_calendar_period | 2026-03-04, observed (TIME-F1, open) |
| no policy means no counted date | same inputs, no policy | MISSING_POLICY |
Two facts deserve emphasis. First, the applied expectations pin which rule fired: the window pair proves the boundary moves the derivation, not just the answer. Second, the two deadline entry points disagree by one day on identical inputs — the term counts to the hand-derived 2026-03-03, the function form to 2026-03-04 — and pinning the calendar changes nothing for the function form. That disagreement is recorded as open finding TIME-F1 with an observed expectation, in the same style as the compatibility case on the coverage page: the drill proves counting runs, and it also proves the two ways of counting do not agree.
The calendar pin is enforced, not decorative: flipping one byte of the resource copy makes the run refuse before evaluation with a contentHash ... diverges message naming both hashes (probed on a scratch copy, whole suite SKIP, code 2).
Limits
Section titled “Limits”This page covers dating fully and counting for calendar days; working-day counting is the stated profile limit. The drill counts thirty calendar days on a synthetic Mon–Fri calendar, but no scene counts business days against an official calendar — add_business_days without a calendar ends in MISSING_INPUT, and the bundle ships no official calendar to select. A deadline reading that depends on working days is therefore provisional by construction: record its policy openly and do not claim a verified count. The running example sets no deadlines at all: the penalty counts plain days of delay from a fed fact, so no calendar enters. A matrix row marked absent is a promise to recheck on amendment, not proof the act is silent forever.
Next step
Section titled “Next step”Continue with Calculations and external inputs, which fixes money, rounding, and table policy for the amounts dated here.
Sources
Section titled “Sources”- Time
- Tutorials — the full drill track behind this handbook.
- Language reference — dates, instants, and windows.
- Command line — the check and test commands used above.
- Recording decisions — where close time readings earn records.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.