Books / Constructions / Chapter 10
Part III · Chapter 10
What Is Permitted, What Is Required, What Happened
Contents of Constructions
In the last chapter we separated an open way from permission to enter. If the petitioner then crosses the threshold, another record may appear: that the entry took place. By itself that record says nothing about whether the entry was permitted.
Such distinctions reach far beyond law. A pronunciation rule says how a word should be read. A communications standard imposes requirements on a program’s behaviour. In both cases we must ask separately what is prescribed and what happened. We begin with a relation whose meaning includes a prohibition. We then add a way to say who bears a duty, what state it requires, and how reported behaviour bears on its fulfilment. The new construction here is a duty; permission remains a separate question, as in the preceding chapter.
What “may not” means in a relation’s name
In §33 of the “Söz sazy” (The Melody of Speech) section of Rabigha Syzdyq’s Қазақ тілінің анықтағышы (A Handbook of Kazakh, Elorda, 2000), full and shortened verb forms are considered. In reading, the form chosen in the text must be kept. For example, a written “кеп” (“kep”, shortened) may not be replaced in pronunciation with the full “келіп” (“kelip”). Where the full form is given, shortening it is likewise not allowed[^chapter-10-pronunciation].
Consider the first half of this rule in the corpus package:
@source(YQSH_F_SOZ_33)
rule YqshamdyTolyqAituBolmaidy strict {
label kk-KZ official "§ 33: ықшам жазылғанды толық етіп айтуға болмайды";
label ru-KZ translation "§ 33: написанное сокращённо нельзя произносить полным";
for w: EtistikTulgasy;
when yqsham_turinde_berilgen(w);
then yqshamdy_tolyq_etip_aituga_bolmaidy(w);
}
The variable w denotes a verb form of the type
EtistikTulgasy. The premise yqsham_turinde_berilgen(w)
reports that the form is given shortened. The conclusion
yqshamdy_tolyq_etip_aituga_bolmaidy(w) means that it may not be
pronounced in full (“bolmaidy” — “may not, is not allowed”). The
translation mark on the Russian label denotes a translation;
the mark itself does not certify its accuracy.
The first scenario states the form “кеп” (“kep”):
assert yqsham_turinde_berilgen(entity_ref("urn:kz:grammar:clir:yqsham-tulgalar#Kep")) {
id "assert-a0";
origin case_input;
}
The question asks whether the prohibition has support:
evaluate truth(yqshamdy_tolyq_etip_aituga_bolmaidy(entity_ref("urn:kz:grammar:clir:yqsham-tulgalar#Kep")));
expect evaluation_status == COMPUTED;
expect truth_status == TRUE_ONLY;
The words “may not be pronounced” are part of the relation’s
meaning. This is still an ordinary one-argument assertion:
the rule derives it, and truth checks its support. TRUE_ONLY
means that the prohibition is supported for this form. It says
nothing about how anyone actually pronounced the word.
The model identifies neither a particular reader nor an act of reading aloud. To establish a violation, we would need to name the person bound by the prohibition, record how that person pronounced the word, and state rules linking the two. That is this vocabulary’s boundary: it lets us reason about word forms without describing individual acts of reading.
The Kazakh material in this section stays in Kazakh, with a Latin-script transliteration beside each form; all English renderings of Syzdyq’s text are the translator’s own.
Whom the requirement concerns
Now take BCP 14 — the documents RFC 2119 and RFC 8174 on the meaning of key words in standards. To begin we need one word: MUST. In section 1 of RFC 2119 it marks an unconditional requirement of the specification[^chapter-10-bcp]. The wording below follows the English original of RFC 2119.
The package binds such a requirement to a program that claims
conformance to the document. In the vocabulary it is called an
implementation, Implementation; the requirement has the type
Requirement. In the relation subject_to(i, r) the first
argument is the implementation, the second the requirement
that applies to it. absolute_requirement(r) reports that the
requirement is ranked at the MUST level or that of an equivalent word.
Both conditions meet in the rule’s familiar opening:
@source(RFC2119_S1)
rule AbsoluteRequirementBindsTheImplementation strict {
label en official "an absolute requirement of the specification binds every implementation which claims conformance";
for i: Implementation; for r: Requirement;
when subject_to(i, r) and absolute_requirement(r);
then duty SatisfyAbsoluteRequirement {
bearer i;
goal maintenance {
condition requirement_satisfied(i, r);
window [@1997-03-01, infinity);
}
};
}
The new construction begins after then. In place of an assertion
stands duty SatisfyAbsoluteRequirement: a named duty with a
body of its own. When the conditions hold for particular values
of the variables, a duty arises for that implementation with
respect to that requirement. This duty is a normative position:
it has a bearer and a state of its own, distinct from the rule
that creates it and the assertion it requires to hold.
Let us read the body in order:
| Entry | What it states |
|---|---|
bearer i |
The implementation that bears the duty |
goal maintenance |
The goal: continued maintenance of a state |
condition requirement_satisfied(i, r) |
The state to be maintained: this implementation satisfies this requirement |
window [@1997-03-01, infinity) |
The interval during which that state is to be maintained |
Unlike a one-time achievement, maintenance requires keeping
the condition. One successful check does not yet prove it was
kept before and will always be kept. The interval’s start is
included; no end bound is stated. We take the date from the
model; we will examine ways of recording and checking time in
the thirteenth chapter[^chapter-10-maintenance].
Creating the duty does not establish the truth of
requirement_satisfied. That condition is still to be checked
against information about the implementation’s behaviour.
From recorded behaviour to a violation
In the study scenario there is a server and a requirement
denoted by the address allow. The given records in order:
the document uses BCP 14; the requirement lives in that
document; the server claims conformance to it; the requirement
is marked with the word MUST written in capital letters; the
server’s behaviour departs from the requirement.
Must and AllCapitals are values in the vocabulary for the word and
its capitalization. The remaining participants are named by
entity_ref links. Let us read the whole scenario:
test "urn:query:bcp14-test-must-breached" {
given {
context { decision_time @2026-08-30T12:00:00Z; knowledge_time @2026-08-30T12:00:00Z; legal_time @2026-08-30; timezone "UTC"; }
assert adopted_bcp14(entity_ref("urn:ietf:rfc:9110")) { id "bcp14-t1-a"; origin case_input; }
assert stated_in(entity_ref("urn:ietf:rfc:9110#allow"), entity_ref("urn:ietf:rfc:9110")) { id "bcp14-t1-b"; origin case_input; }
assert claims_conformance(entity_ref("urn:case:impl:server"), entity_ref("urn:ietf:rfc:9110")) { id "bcp14-t1-c"; origin case_input; }
assert keyword_written(entity_ref("urn:ietf:rfc:9110#allow"), Must, AllCapitals) { id "bcp14-t1-d"; origin case_input; }
assert behaviour_deviates(entity_ref("urn:case:impl:server"), entity_ref("urn:ietf:rfc:9110#allow")) { id "bcp14-t1-e"; origin case_input; }
}
evaluate positions();
expect result_kind == NORM_POSITION;
expect evaluation_status == COMPUTED;
expect normative_status == VIOLATED;
}
Here is a new question: positions(). It asks for the
normative positions that have arisen. So the answer’s kind is
NORM_POSITION, and the field checked is normative_status.
In this scenario one duty arises, and its status is expected to
equal VIOLATED, “violated”.
How is that result reached? Other rules in the package, not
printed here, use the first three entries to derive subject_to
and the fourth to establish the requirement’s level. Those
conclusions suffice for the duty to arise. The last entry takes
part in a separate rule:
@source(RFC2119_S1)
rule DeviatingBehaviourFailsTheRequirement defeasible {
label en official "observed deviating behaviour fails the requirement";
for i: Implementation; for r: Requirement;
when subject_to(i, r) and behaviour_deviates(i, r);
then not requirement_satisfied(i, r);
}
The conclusion carries an explicit denial:
not requirement_satisfied. So in this case the duty’s
condition stands refuted. That is a ground for establishing a
violation of the standing duty. The chain holds two
distinguishable steps: first the duty appears, then the
behaviour information lets us assess its state.
In a copy of the scenario, replace the question and its
expectations. Now ask the ordinary truth question, whether
the requirement is satisfied:
evaluate truth(requirement_satisfied(entity_ref("urn:case:impl:server"), entity_ref("urn:ietf:rfc:9110#allow")));
expect result_kind == PROPOSITION;
expect evaluation_status == COMPUTED;
expect truth_status == FALSE_ONLY;
FALSE_ONLY concerns support for the assertion of fulfilment;
VIOLATED concerns the duty’s state. These answers fit together
here, but they do not mean the same thing. Neither status can
stand in for the other.
Run the scenario about the duty with this command from the reader companion directory:
law engine test corpus/laws/org/ietf/bcp14/tests/01-must-breached-is-violated.lawtest \
--program corpus/clir/ietf-bcp14.lawir.json --imports contexts/ietf-bcp14.json
If test is replaced with explain, the explanation begins
with the line позиций: 1 (“positions: 1”) and the node
norm_creation. This tree shows why the duty arose: why the
server is bound by the requirement and why the requirement
counts as unconditional. It does not by itself show why the
maintenance condition was refuted. To inspect that second chain,
run explain on the copy containing the truth question; the
path leads to the denial of requirement_satisfied.
The duty stands, but there is no information about fulfilment
Delete only the behaviour_deviates entry. The old VIOLATED
expectation no longer passes: the position receives ACTIVE.
The duty’s conditions for arising survive, but this case no
longer contains information about its violation.

The question about requirement_satisfied then receives
NEITHER. The duty stands, while the requirement’s fulfilment is
neither established nor refuted. ACTIVE does not mean the
behaviour was checked and judged conforming.
Now report behaviour_conforms instead of a departure, with the
same two arguments: the observed behaviour conforms to the
requirement. TRUE_ONLY appears for requirement_satisfied,
but the duty stays ACTIVE. The requirement to maintain the
state remains in force; a positive observation does not complete
it.
Compare the three versions of the same case:
| Behaviour information | Is the requirement fulfilled: truth_status |
Duty: normative_status |
|---|---|---|
| Departure reported | FALSE_ONLY |
VIOLATED |
| No information | NEITHER |
ACTIVE |
| Conformance reported | TRUE_ONLY |
ACTIVE |
In all three variants the calculation has the status
COMPUTED. What differs is the assertion’s support and the
duty’s state.
Now change the case at an earlier point. Restore the report of
deviating behaviour, but delete
claims_conformance, the server’s claim of conformance to the
document. This case no longer yields subject_to, so no
duty is created. explain shows позиций: 0 (“positions: 0”).
When the old VIOLATED expectation is checked, the overall
answer will be UNDETERMINED; the position list shows this is
about a duty’s absence, not a new state of the old one.
That is the chosen model’s result. By itself the absence of a conformance claim does not prove the server has no other duties in a real situation.
When a departure calls for justification
The word SHOULD has another sense. Section 3 of RFC 2119 admits departing from a recommendation for weighty reasons in particular circumstances; the implications must be understood and carefully weighed before choosing another path. The bare fact of a departure does not create those grounds.
Here the last chapter comes in handy. The relation
valid_reason_to_ignore(i, r) is declared an outside judgment.
In the model the question is addressed to the Implementor,
the implementation’s developer. That is the model’s chosen
assessor; the RFC itself institutes no body of that name.
A separate relation implications_understood_and_weighed
records that the implications were considered. Together these
premises serve the rule:
@source(RFC2119_S3)
rule DeviationFromRecommendationIsJustified strict {
label en official "ignoring a recommended item is justified when valid reasons exist and the full implications have been weighed";
for i: Implementation; for r: Requirement;
when subject_to(i, r)
and implications_understood_and_weighed(i, r)
and valid_reason_to_ignore(i, r);
then deviation_from_recommendation_justified(i, r);
}
In scenario 04 it is already reported that the implications were weighed, but the decision about the reasons’ weight is not supplied. The question about the departure’s justification receives the familiar pair:
evaluate truth(deviation_from_recommendation_justified(entity_ref("urn:case:impl:server"), entity_ref("urn:ietf:rfc:9110#allow")));
expect result_kind == PROPOSITION;
expect truth_status == NEITHER;
expect evaluation_status == REQUIRES_JUDGMENT;
This is a question about the grounds of a possible departure.
It does not report that the server already departed: this
scenario holds no such fact. REQUIRES_JUDGMENT concerns
exactly the requested justification.
Other scenarios supply the missing positive judgment. With
subject_to established, that judgment and the record that the
implications were understood and weighed let the rule derive
that a departure is justified. Rules and priorities not printed
here then set aside the ground that makes the recommendation
binding, so the matching duty is not created. The judgment alone
is not enough: the implications must also have been weighed.
The possibility of departure thus has conditions of its own,
distinct from a report that a departure actually occurred.
Try separating the questions
Work with a copy of the separate BCP 14 scenario 01, keeping the file header. Start each trial anew.
- Ask about
requirement_satisfiedinstead ofpositions(). Before running, record the expected kind and state of the answer. Then considerexplain: which rule linked the observed behaviour to the denial of fulfilment? - Delete
behaviour_deviates, then in a separate copy replace it withbehaviour_conforms. For each variant check both the position and the fulfilment assertion. Explain why twoACTIVEs come with differenttruthanswers. - Delete only
claims_conformance. Check the number of positions throughexplainand find the missing premise of the rule that establishessubject_to. - Return to the Syzdyq example. To consider reading by a particular person, name the duty’s bearer, the required behaviour, and the information about how that person read the word aloud. Mark what is taken from the text and what must be added to describe that instance of reading.
Now we can separately record a requirement, its bearer, and the information about behaviour. One question remains that was so far taken as settled: where did the information itself come from, and on what ground is it trusted? The next chapter is devoted to that.
[^chapter-10-pronunciation]: Rabigha Syzdyq, Қазақ тілінің анықтағышы (Elorda, Astana, 2000), “Söz sazy” section, §33: the source handbook, the verb-form rules and the scenarios. [^chapter-10-bcp]: RFC 2119, §§1 and 3 defines MUST and SHOULD; RFC 8174, §2 refines the meaning of writing in capitals. The requirement’s link to the implementation’s conformance claim is set by package.law. [^chapter-10-maintenance]: The Arxo specification: §123 — kinds of goals, §137 — keeping a state. The BCP 14 rules are in 02-requirement-levels.law; the examples in scenarios 01: MUST violation and 04: departure justification.
Contents · PDF · EPUB · Original text under CC BY 4.0 · Source-material terms