Skip to content
docs
Arxo ↗

Duty: who, what, and by when

For LLMs7 sections

Until now every norm derived a fact: admitted, refused, check requested. But more often law does not state but prescribes: “must return”, “must keep”, “must notify in time”. Such a prescription has a bearer, an aim, and a window, and its answer is not “yes” or “no” but a status: not yet due, active, fulfilled, violated. This is a normative position, and then duty is the corpus’s second most frequent head: 3,023 occurrences in 234 packages out of 508 (measured 05.09.2026).

The archive issues documents for home use. A researcher must return a document by its term and keep it intact for the whole issue period.

Arxo Law
language "law.core" version "0.2";
package tutorial.archive version "0.5.0";
namespace "urn:law:tutorial:archive";
entity Person;
relation document_lent(p: Person, issued: Date, due: Date) kind empirical { key(p); }
relation document_returned(p: Person) kind empirical;
relation document_intact(p: Person) kind empirical;
relation extension_granted(p: Person) kind institutional;
relation non_return_recorded(p: Person, on: Date) kind empirical { key(p); }
relation late_fee_due(p: Person) kind institutional;

The return duty is an achievement aim: the condition must become established inside the window. The window here is not a literal but two dates from the issue fact — the corpus’s most frequent form. Extending the issue removes the duty; the exception is written with an unless clause, so the rule is defeasible.

Arxo Law
rule ReturnRule defeasible {
for p: Person;
for issued, due: Date;
when document_lent(p, issued, due);
then duty Return {
bearer p;
goal achievement {
condition document_returned(p);
window [issued, due];
}
};
unless document_lent(p, issued, due) and extension_granted(p);
}

bearer is the duty-holder, the only mandatory party field; beneficiary is not named here. condition is the fulfilment predicate, and it is absent from the rule body: the aim reads a conclusion, not a premise. Write in condition the same document_lent as in when and the duty will be fulfilled at the moment it arises, requiring nothing.

Issue from 1 to 31 March 2026. Let us ask the position’s status on different dates of law.

legal_timeFacts beyond issueReturn
15 February—PENDING
15 March—ACTIVE
15 MarchreturnSATISFIED
10 April—UNDETERMINED
10 Aprilnon-return recorded 5 AprilVIOLATED
15 Marchnon-return recorded 10 MarchACTIVE
10 AprilextensionDEFEATED

The second row in the case language looks like this (why the block does not compile together with the page — below):

Arxo Law
test "срок не вышел — обязанность активна, не нарушена" {
given {
context {
decision_time @2026-05-01T09:00:00+05:00;
knowledge_time @2026-05-01T09:00:00+05:00;
legal_time @2026-03-15;
timezone "Asia/Almaty";
}
assert document_lent(entity_ref("urn:tutorial:ivanova"), @2026-03-01, @2026-03-31) {
id "assert-lent";
origin case_input;
}
}
evaluate positions();
expect position(Return, ACTIVE);
expect not position(Return, VIOLATED);
expect evaluation_status == COMPUTED;
}

The test name reads: “Term unexpired — the duty is active, not violated.”

The positions() query collects all positions of the case; the position(Template, STATUS) observation is targeted — it concerns one duty. The summary normative_status field with several norms in the case answers UNDETERMINED, and one position cannot be checked with it. This observation lives only in the test file: inside the page-package, position(…) would read as a call of an undeclared function, and check would refuse. So the block above is text, while the ready-made test file holding all twelve scenarios of this page is executed separately.

The fourth row is the point of the page. The term has expired, nothing is known about return, and the answer is UNDETERMINED, not VIOLATED. A violation is not derived from silence: absence of proof of fulfilment is not proof of non-fulfilment. For VIOLATED, the aim condition must hold a negative support — the very kind the negation tutorial was about. Here a control act gives it: an archive officer recorded the non-return, and the norm translates the record into “not returned”.

Arxo Law
rule NonReturnRecorded strict {
for p: Person;
for on: Date;
when non_return_recorded(p, on);
then not document_returned(p);
}

Legally it must be so: non-return is established by control, not by the calendar. The sixth row is the same record, but the term has not yet expired: the duty is alive, ACTIVE. The date of law must stand after the window.

The seventh row is the extension. The defeater produced by the unless clause defeats the rule’s application, and the position shows with the DEFEATED status. This is not “the duty was and ceased”: the very ground on which it would have arisen is defeated. Note the defeater must bind every payload variable — here the bearer and both window bounds — which is why unless repeats the issue fact. A defeater binding only the bearer would defeat positions it said nothing about, and the compiler will not accept it.

Intactness is a maintenance aim: the condition must hold across the whole window, not become true once.

Arxo Law
rule KeepIntactRule strict {
for p: Person;
for issued, due: Date;
when document_lent(p, issued, due);
then duty KeepIntact {
bearer p;
goal maintenance {
condition document_intact(p);
window [issued, due];
}
};
}
legal_timeFacts beyond issueKeepIntact
15 Marchdamage establishedVIOLATED
15 March—ACTIVE
10 April—UNDETERMINED

The asymmetry is deliberate. Maintenance can be violated by one counterexample, read at once without waiting for the window’s end. It cannot be fulfilled by one fact: saying SATISFIED needs completeness of observation over the whole window — a monitoring certificate, a closure covering the window entirely, or an authority’s decision. Without them, UNDETERMINED remains after the window. “Nobody noticed damage” does not mean “there was no damage”.

StatusWhen
PENDINGthe window has not started
ACTIVEthe window runs, the condition is not established
SATISFIEDachievement: the condition established in the window; maintenance: observation completeness confirmed
VIOLATEDachievement: the window closed and non-fulfilment established; maintenance: a counterexample in the window
EXPIREDthe window closed on a liberty or a ban — they are neither fulfilled nor violated
UNDETERMINEDthe window closed, with nothing to establish either fulfilment or violation
DEFEATEDthe position’s ground is defeated by a defeater
CONFLICTEDincompatible statuses established at one moment

Statuses are not an enum field but institutional literals with their own support: violated(Return) holds the same four states as any statement, and CONFLICTED is BOTH on a status.

The overdue fine is not a property of the duty but another norm, on consequences. It is written from the same established facts: the non-return record is dated past the term.

Arxo Law
rule LateReturnFee strict {
for p: Person;
for issued, due, on: Date;
when document_lent(p, issued, due) and non_return_recorded(p, on) and on > due;
then late_fee_due(p);
}
Non-return recordlate_fee_due
5 AprilTRUE_ONLY
10 MarchNEITHER

The first row is the test from this page, byte for byte; it is an ordinary truth query, and it compiles together with the page:

Arxo Law
test "штраф: невозврат зафиксирован после срока — TRUE_ONLY" {
given {
context {
decision_time @2026-05-01T09:00:00+05:00;
knowledge_time @2026-05-01T09:00:00+05:00;
legal_time @2026-04-10;
timezone "Asia/Almaty";
}
assert document_lent(entity_ref("urn:tutorial:ivanova"), @2026-03-01, @2026-03-31) {
id "assert-lent";
origin case_input;
}
assert non_return_recorded(entity_ref("urn:tutorial:ivanova"), @2026-04-05) {
id "assert-non-return";
origin case_input;
}
}
evaluate truth(late_fee_due(entity_ref("urn:tutorial:ivanova")));
expect truth_status == TRUE_ONLY;
}

So violation, liability, and sanction stay different layers: a VIOLATED on the position says the duty was not fulfilled; the fine says what is due for it; and whether there are grounds to release from the fine is a third norm, cancelling neither the first nor the second.

A duty holds two different times, and confusing them is the costliest mistake on this layer. The rule’s effective (the time tutorial) says from which date the norm exists; the aim’s window says by when to fulfil. Outside effective there is no position at all; outside window there is one — PENDING before and UNDETERMINED or EXPIRED after. “The norm does not yet exist” and “the term has not started” are different answers, and both are needed.

Hence the rule: the “from 1 January 2027” milestone goes into the rule’s effective, while the aim window counts from the event — issue, notice, entry into force for this person. A duty’s window must not be taken from an edition’s validity term: the term to return a document does not match the archive rules’ validity term.

There are two mandatory fields, with a refusal for each missing:

Output
error LDC-E1305: duty "Return" без bearer (§123)
error LDC-E1305: goal нормы "KeepIntact" без window (§124: обязателен)

The diagnostics read: ‘duty “Return” without bearer’ and ‘the “KeepIntact” norm’s goal without window’.

A window boundary is a value: a date, a rule variable, or infinity. A bare name found among neither binders nor constants is rejected by the compiler:

Output
error LDC-E2115: имя "moment" в границе интервала §20 не объявлено: оно не
связано ни `for` правила, ни `let`, и не объявлено ни `const` §54 …

The diagnostic reads: ‘name “moment” in an interval boundary is not declared: it is bound by neither the rule’s for nor let, and declared by no const …’.

A position’s exception lives only in a defeasible rule. Make ReturnRule strict, keeping unless — a refusal:

Output
error LDC-E4110: ReturnRule: `unless` на strict-правиле (§149) — сделайте
правило defeasible либо внесите условие применимости в strict-тело

The diagnostic reads: “‘ReturnRule’: unless on a strict rule — make the rule defeasible or move the applicability condition into the strict body”.

A position has no contrary form: unless … then not Return is a refusal, because a “non-duty” means nothing. Opposing positions goes by the conflict patterns, not by negation:

Output
error LDC-E1302: rule "ReturnRule": контрарная форма `unless … then …` при
норм-голове не определена (§107.1): комплемента у позиции нет

The diagnostic reads: ‘rule “ReturnRule”: the unless … then … contrary form on a norm head is undefined: a position has no complement’.

And that very defeater that bound only the bearer. Replace unless with a bare extension_granted(p):

Output
error LDC-E4101: ReturnRule/unless/0: норм-голова "Return" (поля:
goal.window) использует несвязанные переменные [issued, due]

The diagnostic reads: ‘ReturnRule/unless/0: the “Return” norm head (fields: goal.window) uses unbound variables [issued, due]’.

All six refusals belong to the language. One lesson cannot be pinned the same way: a second goal clause in one duty silently replaces the first, check is clean, the CLIR keeps the last. Two aims are two rules.

Duty is one of four modalities. Ban, liberty, power, and immunity are the track’s next page; there it will turn out that a ban in the core is not violated by itself, and violation is expressed by a paired duty. And how to count an aim window not from a fact’s date but “within ten business days” is told by the tutorial on terms.

The exercise for this page is /tutorials/exercise-duty/.

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.