Markdown for LLMs
nb-21 — Positions live, files move, readings decide
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# nb-21 — Positions live, files move, readings decide
*Northbridge course, advanced ([nb-09](/tutorials/northbridge/nb-09-duties-powers/) →
[nb-10](/tutorials/northbridge/nb-10-parallel-procedure/) → [nb-11](/tutorials/northbridge/nb-11-appeal/) →
[nb-12](/tutorials/northbridge/nb-12-allocation-rounds/) →
[nb-21](/tutorials/northbridge/nb-21-positions-procedures-precedent/)).
All law is fictional: every stall, applicant, notice, score and reading
below is synthetic and unofficial. Northbridge is an invented town used
only to teach Law DSL. No real municipal deployment or legal-validity
claims. Engine `law 0.1.0`, semantics `law.core/0.2`.*
## 1. Situation
On 1 May 2026, Ann files an application for a night-market stall. That
single filing sets several directed relations in motion at once. The
permit office owes her a decision within thirty days. Ann must keep her
pitch safe through May, and the office must serve no eviction on her
through May. She must not sublet the stall.
If she sublets anyway, the office may revoke her permit by sending a
revocation notice — and only then. If the office refuses her outright,
she may object during May. And while she displays the permit, she is
shielded from eviction.
Her file moves as well: from `Draft` to `Filed`, then into a review
with two regions that must both accept before the join approves the
file. Two disputes need a reader. Does a stall permit cover overnight
storage — the narrow or the broad reading? Does the night warden show
mercy? An earlier pitch-keeping case guides the overnight question
without dictating it. Separately, repair slots are granted in two
frozen rounds.
One case, three lenses. **Positions** track who owes what — kept,
broken or still open. **Procedure and stage** track how files advance
and how rounds freeze. **Readings** settle which interpretation holds,
whose judgment counts and which precedent applies. Positions are
lifecycle states, procedures are event automata, stages are round
folds — and none of them decides a dispute by itself.
## 2. Prerequisites
[nb-01: First permit: facts, a rule and a question](/tutorials/northbridge/nb-01-first-permit/): facts, strict rules,
`law test` as the way to check a claim.
[nb-02: Why a missing fact is not a refusal](/tutorials/northbridge/nb-02-missing-fact/):
the four truth statuses — `NEITHER` below means "no conclusion either
way", never a refusal.
[nb-03: Exceptions and conflicting rules](/tutorials/northbridge/nb-03-exceptions/): strict
rules and conflict resolution.
[nb-09: From permit to duties and powers](/tutorials/northbridge/nb-09-duties-powers/): the
five positions and their lifecycle (`ACTIVE`, `SATISFIED`, `VIOLATED`,
`UNDETERMINED`).
[nb-10: A procedure with parallel checks](/tutorials/northbridge/nb-10-parallel-procedure/):
events, guards, regions, join.
[nb-11: Appeal: reading, judgment and precedent](/tutorials/northbridge/nb-11-appeal/): interpretation groups, judgment,
factors, precedent.
[nb-12: Allocation in rounds](/tutorials/northbridge/nb-12-allocation-rounds/): stages,
closed tours, `supported`, world separation.
Each new idea is explained where it first appears: the three goal forms
(**achievement**, **maintenance**, **forbearance**) with their short
spellings; the parties of each position (**bearer**/**beneficiary**,
**holder**/**over**, **holder**/**against**); power **exercise** with
**valid_when** and **effect** (and which effect forms execute);
**event history** as the procedure's memory; and the **exactly_one**
selection with what an unchosen reading leaves open.
## 3. Minimal example
All fragments are excerpts from
`packs/examples/language-demo/lifecycle/package.law` (identifiers as
written; header, imports, neighbouring declarations cut), except the
last two, which are excerpts from
`packs/examples/language-demo/lifecycle_stages/package.law`.
Excerpt 1 — the office's duty to decide (lines 41–54). The office owes
Ann a decision, so the duty names a bearer (who owes — the office), a
beneficiary (to whom it is owed — Ann) and a goal. Watch the goal
block: a full `goal achievement` means the condition must become true
at least once inside the window.
```law
rule FileDecisionDuty strict {
for a: Applicant;
for o: Office;
for on, due: Date;
when demo.northbridge.vocabulary::application_filed(a, on) and decision_due(a, due) and demo.northbridge.vocabulary::permit_office(o);
then duty DecideStall {
bearer o;
beneficiary a;
goal achievement {
condition demo.northbridge.vocabulary::decision_notified(a);
window [on, due];
}
};
}
```
One idea: an achievement goal with a computed window. Look at the
`window [on, due]` line: the due date comes from the `DecisionDue`
rule (thirty calendar days after filing), not from a literal date.
Excerpt 2 — the upkeep duty (lines 56–66). Ann must keep her pitch
safe for the whole of May. The short spelling `maintain F during W`
is the same goal as a full `goal maintenance` block: the condition
must hold for the whole window, not just once.
```law
rule KeepPitchSafe strict {
for a: Applicant;
for o: Office;
for s: Stall;
when stall_holder(s, a) and demo.northbridge.vocabulary::permit_office(o);
then duty MaintainSafety {
bearer a;
beneficiary o;
maintain safety_clear(s) during [@2026-05-01, @2026-05-31];
};
}
```
One idea: maintenance reads the world continuously. A single
accepted counterexample — the pitch is not clear on some day in May —
violates the whole duty.
Excerpt 3 — the no-eviction duty (lines 68–81). Now the office owes
Ann restraint: a **forbearance** goal forbids an action for a window.
It desugars to maintaining the absence of the action, and the
`action` field is kept for explanations.
```law
rule NoEviction strict {
for a: Applicant;
for o: Office;
for s: Stall;
when stall_holder(s, a) and demo.northbridge.vocabulary::permit_office(o);
then duty SpareEviction {
bearer o;
beneficiary a;
goal forbearance {
action eviction_served(o, a);
window [@2026-05-01, @2026-05-31];
}
};
}
```
One idea: the third goal form — the office owes *not acting*.
Watch the `action` line: a served eviction is the counterexample that
would violate this duty.
Excerpt 4 — the sublet ban (lines 83–93). Ann must not sublet her
stall in May. A **prohibition** names a bearer, a beneficiary, the
forbidden action and a window — the same party shape as a duty.
```law
rule SubletBan strict {
for a: Applicant;
for o: Office;
when stall_permit_open(a) and demo.northbridge.vocabulary::permit_office(o);
then prohibition NoSublet {
bearer a;
beneficiary o;
action stall_sublets(a);
window [@2026-05-01, @2026-05-31];
};
}
```
One idea: prohibitions also have parties. Ann owes the office her
restraint, inside the May window.
Excerpt 5 — the revocation power (lines 102–113). If Ann sublets, the
office may revoke her permit by sending a revocation notice. A
**power** names a holder, the party it is over, the **exercise**
event, the **valid_when** gate and the **effect**. The exercise event
alone creates nothing: the engine checks the gate, and only then does
the constitutive step create the effect.
```law
rule StallRevocation strict {
for a: Applicant;
for o: Office;
when demo.northbridge.vocabulary::permit_office(o) and stall_permit_open(a);
then power RevokeStall {
holder o;
over a;
exercise revocation_notice(o, a);
valid_when (stall_sublets(a));
effect create(stall_revoked(a));
};
}
```
One idea: valid exercise is a two-step run. Watch the `exercise`
line together with the `valid_when` line: the notice plus the sublet
gate, ending in a created fact.
Excerpt 6 — the sealing power (lines 115–126). Same shape, different
effect form: `terminate` instead of `create`. The grammar accepts it;
the 0.1 executable subset does not (see Limits).
```law
rule StallSealing strict {
for a: Applicant;
for o: Office;
when demo.northbridge.vocabulary::permit_office(o) and stall_permit_open(a);
then power SealStall {
holder o;
over a;
exercise sealing_order(o, a);
valid_when (stall_sublets(a));
effect terminate(stall_permit_open(a));
};
}
```
One idea: the boundary inside the pair. `SealStall` passes its
gate and still creates nothing — the test pins the
`NON_EXECUTABLE_RULE` warning to prove it.
Excerpt 7 — the objection liberty (lines 128–138). If the office
refuses Ann outright, she may object during May. A **liberty** names
a holder, the party it is held against, the permitted action and a
window.
```law
rule ObjectRefusal strict {
for a: Applicant;
for o: Office;
when stall_refused(a, o);
then liberty MayObject {
holder a;
against o;
action objects(a, o);
window [@2026-05-01, @2026-05-31];
};
}
```
One idea: the mirror party pattern. Here Ann is the holder and
the office is the other side — the reverse of the revocation power.
Excerpt 8 — the calm-trading immunity (lines 140–150). While Ann
displays her permit, the office cannot evict her. An **immunity**
shields the holder: the other side cannot bring the protected effect
about.
```law
rule CalmTrading strict {
for a: Applicant;
for o: Office;
when stall_displayed(a, o);
then immunity StallCalm {
holder a;
against o;
protected_effect eviction_served(o, a);
window [@2026-05-01, @2026-05-31];
};
}
```
One idea: five positions, five party shapes. Duties and the
prohibition use bearer/beneficiary, the power uses holder/over, and
liberty and immunity use holder/against.
Excerpt 9 — the parallel review (lines 179–198). Ann's filed
application is checked for documents and for safety side by side.
Two **regions** run in parallel; `join all` means the review leaves
only when every region is terminal. The safety region carries a
guard: acceptance needs the certificate.
```law
region Docs {
state DocsPending initial;
state DocsOk terminal;
transition DocsAccept {
from DocsPending;
to DocsOk;
on DocsFiled;
}
}
region Safety {
state SafetyPending initial;
state SafetyOk terminal;
transition SafetyAccept {
from SafetyPending;
to SafetyOk;
on SafetyPassed;
when safety_certificate(s);
}
}
join all;
```
(Cut: the `state Review parallel {` opener on line 178, the
surrounding states and the outer transitions.) One idea: guards live
on transitions. The `when` line on `SafetyAccept` blocks that region
alone, and the join — not any single region — releases the review.
Excerpt 10 — filing and deciding (lines 200–216). The outer
transitions move Ann's file: filing is guarded by a complete pitch,
and deciding follows the joined review with no further guard.
```law
state Approved terminal;
transition File {
from Draft;
to Filed;
on StallFiled;
when pitch_complete(s);
}
transition StartReview {
from Filed;
to Review;
on ReviewStarted;
}
transition Decide {
from Review;
to Approved;
on ReviewComplete;
}
```
One idea: **event history** is the procedure's memory. The tests
record `attempted_transition` facts; the engine replays the attempts
and projects `current_state` from them.
Excerpt 11 — the competing readings (lines 222–238). Does Ann's stall
permit cover overnight storage? Two **interpretations** answer: the
narrow one refuses, the broad one covers permit holders.
```law
interpretation Narrow {
status reviewed;
rule NarrowReading strict {
for a: Applicant;
when overnight_storage(a);
then not storage_covered(a);
}
}
interpretation Broad {
status reviewed;
rule BroadReading strict {
for a: Applicant;
when overnight_storage(a) and stall_permit_open(a);
then storage_covered(a);
}
}
```
One idea: readings are ordinary rules wrapped in a named choice.
The group below (lines 240–243, `alternatives Narrow, Broad;
selection exactly_one`) forces the case to pick one — with no pick,
the question stays open.
Excerpt 12 — the warden's judgment (lines 245–256). Ann applied for
her stall; whether the night warden shows mercy is a question only a
person can decide. An **external judgment** relation names its
**authority**; the rule still needs an adjudicated assertion before
it fires.
```law
relation applied_for_stall(a: Applicant) kind empirical;
relation mercy_granted(a: Applicant) kind institutional;
external judgment relation warden_mercy(a: Applicant) {
authority NightWarden;
}
rule MercyWaiver strict {
for a: Applicant;
when applied_for_stall(a) and warden_mercy(a);
then mercy_granted(a);
}
```
One idea: authority versus judgment. The warden's title routes
the request, but only the rendered judgment (origin `adjudicated`)
lets the rule fire.
Excerpt 13 — the pitch precedent (lines 262–281, shown in two
parts: first the factors frame and the distinguishing rule, lines
262–274; then the precedent, lines 276–281). An earlier
pitch-keeping case guides Ann's overnight question.
```law
factors PitchLine {
for a: Applicant;
domain keeps_pitch(a);
plaintiff keeps_pitch;
defendant sublets_pitch;
courts HIGH; LOW;
}
rule SubletsLoseOvernight strict {
for a: Applicant;
when sublets_pitch(a);
then not overnight_right(a);
}
```
One idea: **factors** sort the facts into sides. Watch the
`plaintiff`/`defendant` lines in the frame: the distinguishing rule
below fires on the defendant fact alone.
Excerpt 14 — the precedent itself (lines 276–281). The high-court
case kept a pitch and won; Ann, who only keeps hers, follows it.
```law
precedent PNight of PitchLine {
court HIGH;
decided @2021-04-01;
plaintiff keeps_pitch;
outcome overnight_right(a);
}
```
One idea: **following** versus **distinguishing**. The precedent
covers the plaintiff-facts case, while Bob (who also sublets) is
decided by the distinguishing rule instead.
Excerpt 15 — the repair-slot stage
(`packs/examples/language-demo/lifecycle_stages/package.law`, lines 15–19).
Repair slots are granted in two rounds. A **stage** names the frozen
round order: tour counter 1 to 2, both relations tour-bound.
```law
stage GrantRounds {
index round: Integer from 1 to 2;
bind nominated index 2;
bind granted index 2;
}
```
One idea: the same stratification as the allotment in
[nb-12: Allocation in rounds](/tutorials/northbridge/nb-12-allocation-rounds/) — in a
world with no procedure anywhere (transitively).
Excerpt 16 — round 2 and the close
(`packs/examples/language-demo/lifecycle_stages/package.law`, lines 35–48).
Urgent nominations become grants in round 2, then the slots close.
`supported` reads the closed tour; the close reads the closed grant —
never the case input.
```law
rule Grant strict {
for a: Applicant;
for p: Integer;
for r: Integer;
when supported(nominated(a, r)) and r < 2 and urgency(a, p) and p >= MIN_URGENCY;
then granted(a, r + 1);
}
rule CloseSlots strict {
for a: Applicant;
for r: Integer;
when supported(granted(a, r));
then slots_closed();
}
```
(Cut: the `Seed` rule, lines 29–33, which nominates at tour 1 from
the repair request.) One idea: later reads see frozen rounds only.
Urgency qualifies a nomination — it never creates one.
## 4. Command and result
Run the lifecycle suite from the repository root:
```sh
law test packs/examples/language-demo/lifecycle
```
Observed result (tool `law 0.1.0`):
```text
law test demo.northbridge.lifecycle: мир demo.northbridge.lifecycle, demo.northbridge.vocabulary
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / duty and prohibition active
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / duty satisfied
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / duty violated
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / outcome unknown — no violation
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / maintenance holds while the window is open
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / maintenance violated by counterexample
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / forbearance holds while nobody acts
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / forbearance violated by eviction
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / prohibition violated by subletting
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / power exercised lawfully
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / power without grounds does not operate
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / terminate effect is not executable
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / liberty and immunity
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / filing with a complete pitch
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / without the pitch the case stands still
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / both regions ready — stall approved
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / join waits for both regions
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / broad reading covers storage
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / narrow reading refuses storage
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / no selection — storage stays open
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / main route needs no reading
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / judgment not yet rendered
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / judgment rendered
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / precedent followed
ok [demo.northbridge.lifecycle] tests/lifecycle.lawtest / precedent distinguished
итого: 25 проверено, 25 прошли, 0 не прошли, 0 не исполнены; код 0
```
All 25 tests pass: every `ok` line means the answer matched its
expectation. A passing test is not a ruling for Ann — it confirms the
machine behaves as the test declares. The final Russian line reads
"итого: 25 проверено, 25 прошли, 0 не прошли, 0 не исполнены; код 0":
25 checked, 25 passed, 0 failed, 0 unexecuted, exit code 0.
The rounds live in their own world, so they run as a separate suite:
```sh
law test packs/examples/language-demo/lifecycle_stages
```
```text
law test demo.northbridge.lifecycle_stages: мир demo.northbridge.lifecycle_stages, demo.northbridge.vocabulary
ok [demo.northbridge.lifecycle_stages] tests/rounds.lawtest / round 1 nominates from requests
ok [demo.northbridge.lifecycle_stages] tests/rounds.lawtest / rounds are empty without a request
ok [demo.northbridge.lifecycle_stages] tests/rounds.lawtest / round 2 grants by urgency
ok [demo.northbridge.lifecycle_stages] tests/rounds.lawtest / low urgency — no slot granted
ok [demo.northbridge.lifecycle_stages] tests/rounds.lawtest / closed total reads after the rounds
итого: 5 проверено, 5 прошли, 0 не прошли, 0 не исполнены; код 0
```
Again all green — 5 checked, 5 passed, exit code 0. The round
tests confirm that nominations appear only from repair requests, that
urgency decides the round-2 grant, and that the close reads the
finished rounds.
Both packages also pass the static check:
```sh
law engine check packs/examples/language-demo/lifecycle/package.law
law engine check packs/examples/language-demo/lifecycle_stages/package.law
```
```text
check OK: packs/examples/language-demo/lifecycle/package.law
check OK: packs/examples/language-demo/lifecycle_stages/package.law
```
`check OK` for both files means the packages compile cleanly
before any test runs. The table below reads the decisive tests as
pairs: what each setup varies and what each outcome establishes. The
output block above pins the rest.
| Test | Setup | Expects |
|---|---|---|
| `duty satisfied` / `violated` / `outcome unknown` | notified / denied / silent, 10 June | SATISFIED / VIOLATED / UNDETERMINED |
| `power exercised lawfully` / `without grounds` | notice ± sublet | TRUE_ONLY / NEITHER |
| `terminate effect is not executable` | sublet + sealing order | permit open (TRUE_ONLY) + `NON_EXECUTABLE_RULE` |
| `both regions ready` / `join waits` | docs+safety / docs only | `Approved` TRUE_ONLY / NEITHER |
| `broad` / `narrow` / `no selection` | Broad / Narrow / none | TRUE_ONLY / FALSE_ONLY / `INTERPRETATION_REQUIRED` |
| `main route needs no reading` | none selected | `DecideStall` ACTIVE anyway |
| `judgment not yet rendered` / `rendered` | silent / adjudicated | `REQUIRES_JUDGMENT` / TRUE_ONLY |
| `precedent followed` / `distinguished` | keeps / keeps + sublets | TRUE_ONLY / FALSE_ONLY |
| stages: `grants` / `low urgency` / `closed total` | urgency 9 / 2 | TRUE_ONLY / NEITHER / `slots_closed()` |
## 5. Why this construct
Ann's case runs through three lenses that must not leak into each
other: lifecycle states for obligations, an event automaton for the
file, frozen rounds for the slots, and chosen readings for the
disputes. Each lens earns its place by reporting something the others
cannot.
Only `positions()` reports the lifecycle. `truth()` can say the
notice was sent, but only `DecideStall` SATISFIED says the duty is
thereby discharged. The four statuses (plus the open-window ACTIVE)
are the proof the construct acts: notify, silence and deny flip one
duty through three of them.
Only the automaton remembers attempts. The guard blocks the filing
and the join blocks the decision. No rule chain records "tried but
guard failed" the way `current_state` does.
Only the stage closes a tour: `Grant` provably reads the finished
round 1. Rules derive, procedures advance, stages stratify — the
division of labour from
[nb-12: Allocation in rounds](/tutorials/northbridge/nb-12-allocation-rounds/).
Readings handle disputes by refusing to guess. Two lawful answers
means the package answers neither unasked
(`INTERPRETATION_REQUIRED`). No answer yet means the engine names the
cause (`REQUIRES_JUDGMENT`). The precedent guides where its facts fit
and yields where the defendant fact appears.
<details>
<summary>Why not a simpler rule?</summary>
A strict rule could derive `stall_revoked` directly — but the gate
and the two-step exercise would be hand-simulated, not
machine-checked. A defeasible rule could mimic readings — but it
would pick a winner silently instead of demanding `exactly_one`
selection.
</details>
The proof is the thirty executed tests above, not prose: the same
notice revokes with the sublet and does nothing without it. What the
tests do not prove is that thirty days, the May windows or urgency 5
are fair or lawful. They prove the machine enforces the declared
relations; no test blesses Northbridge's policy.
## 6. Changed condition
Take `power exercised lawfully` and change one condition: keep the
revocation notice, drop the sublet fact. Everything else stays
identical — same office, same open permit, same dates. That is
exactly the `power without grounds does not operate` test.
With the sublet, the `valid_when (stall_sublets(a))` gate holds, the
constitutive step runs, and `truth(stall_revoked(ann))` is TRUE_ONLY.
Without it, the exercise event is still accepted and stored, but the
gate fails and no effect is created, so the same query is NEITHER.
An exercise without grounds is recorded history, never an operation.
The mirror case is `terminate effect is not executable`: there the
gate passes and still nothing is created — because the effect *form*
is the boundary, not the gate.
## 7. Typical mistake
The mistake is capitalising the party field: `Bearer o;` instead
of `bearer o;`. The field keyword is lowercase, so the parser reads
`Bearer o` as a term followed by an interval. The observable
consequence is a triple diagnostic, not a duty:
```text
error LDC-E0201: ожидалось `,` в интервале, найдено `]`
error LDC-E1305: duty "DecideStall" без bearer (§123)
warning LDC-E1305: поле "Bearer" нормы "DecideStall" вне DutyPayload-среза (§123); опущено
```
The duty is never created: no bearer, no position, and every
lifecycle test about it goes NEITHER. The fix is mechanical — spell
party fields lowercase (`bearer`, `beneficiary`, `holder`, `over`,
`against`). A capitalised one is silently not-a-field, and the check
output tells you so: read the warning, not just the errors.
A second, semantic mistake is asserting the exercise event and
expecting the effect without the gate — "the notice was sent, surely
the permit is revoked." It is not. `power without grounds does not
operate` asserts exactly that notice and still returns NEITHER.
Exercise is an attempt; `valid_when` is the permission.
## 8. Limits
The 0.1 subset executes one effect form: `create` with an
after-literal. `terminate` (also `modify`, `opaque`) parses but never
materialises. Each gated attempt warns `NON_EXECUTABLE_RULE` (once
per position–event pair), the event is kept, `invalidly_exercised`
is not produced, and the position stays available. The `SealStall`
test pins this boundary: the gate passes, the permit stays open,
and the warning is issued.
A stage and a procedure never share a world. A scratch program
combining a stage with a minimal procedure is refused at check time:
```sh
law engine check packs/examples/language-demo/lifecycle/evidence/snippets/stage-procedure.law.txt
```
```text
error LDC-E4126: STAGE_PROCEDURE_UNSUPPORTED: процедура §159 "Filing" и исполняемый stage "Rounds" в одной программе — свёртка §161.1 по турам не определена (§111.2 п. 6)
```
(exit 1). Hence two packages: the `lifecycle` world holds positions,
procedure and readings, while the `lifecycle_stages` world holds the
stage. Each world's `law.toml` pins exactly its members, with no
direct or transitive dependency between them.
Readings stay chosen. The main route (duties, procedure) never reads
`storage_covered`: `main route needs no reading` derives `DecideStall`
ACTIVE with no interpretation selected, while the storage question
without a selection yields `INTERPRETATION_REQUIRED`, not a default
answer.
Judgment is routed, not derived. `warden_mercy` names its authority
(`NightWarden`), but no rule manufactures the warden's answer:
silence gives NEITHER with `REQUIRES_JUDGMENT`, and only an
`adjudicated` assertion decides.
Tool version (`law 0.1.0`, from `law --version`), language version
(`law.core` version `0.2`, the header line), semantics (`law.core/0.2`,
reported by the same command), implementation support (the `terminate`
warning and the `LDC-E4126` refusal are facts about this engine
profile), and the observed runs (25/25, 5/5) are five separate claims.
A newer tool could keep the language version and still change what
executes — re-run before assuming otherwise.
Verified profile: tool `law 0.1.0`, semantics `law.core/0.2`. The goal
forms (`achievement`, the `maintain` shorthand, `forbearance`), the
`create` effect, tour reads and the refusal codes are facts about this
profile's implementation, never claims about the language in general.
Recurring goals exist in the language, but this article uses none —
nothing here proves anything about them.
## 9. Exercise
Predict each answer without running the engine, then check with
`law test`:
1. In `power exercised lawfully`, which single asserted fact, if
removed, turns `stall_revoked(ann)` from TRUE_ONLY to NEITHER —
and which test already proves that outcome?
2. In `terminate effect is not executable`, the gate passes yet the
permit stays open. Which token in the `SealStall` power is the
reason, what warning does the run record, and what would change
(if anything) if the sealing order were sent twice?
3. In `no selection — storage stays open`, why does the engine
report `INTERPRETATION_REQUIRED` rather than NEITHER — and which
test proves the main route is unaffected by the missing choice?
4. Bob keeps his pitch and sublets it. Which rule decides
`overnight_right(bob)`, what is the outcome, and why does the
`PNight` precedent not cover him?
5. What happens if you add a `procedure` block to the stages
package — at which command does it fail, and with which error
code?
Write down each prediction first, run the suites, and explain any
miss in one sentence. Checkable solution:
[full solution with checkable answers](/tutorials/northbridge/solutions/nb-21-solutions/).
## 10. Sources
- Source: `packs/examples/language-demo/lifecycle/package.law`
(duties `DecideStall`, `MaintainSafety`, `SpareEviction`,
prohibition `NoSublet`, powers `RevokeStall`/`SealStall`, liberty
`MayObject`, immunity `StallCalm`, procedure `StallApproval`,
readings `Narrow`/`Broad`, judgment `warden_mercy`, factors
`PitchLine`, precedent `PNight`)
- Rounds: `packs/examples/language-demo/lifecycle_stages/package.law`
(stage `GrantRounds`, rules `Seed`, `Grant`, `CloseSlots`)
- Tests: `packs/examples/language-demo/lifecycle/tests/lifecycle.lawtest`
(the 25 position/procedure/reading tests),
`packs/examples/language-demo/lifecycle_stages/tests/rounds.lawtest`
(the five round/close tests)
- Refusal probe:
`packs/examples/language-demo/lifecycle/evidence/snippets/stage-procedure.law.txt`
(`LDC-E4126`, exit 1)
- Suite tour: `packs/examples/language-demo/lifecycle/README.md`;
world pins: `packs/examples/language-demo/lifecycle/law.toml`,
`packs/examples/language-demo/lifecycle_stages/law.toml`
- Language reference: `docs/language/08-cheat-sheet.law.md`
(the `Duties, prohibitions, powers` section: five positions, goal
blocks), `docs/language/09-advanced-cheat-sheet.law.md` (the
`Liberties and immunities`, `Questions only a person can decide`,
`Competing readings`, `Procedures`, `Stages` and `Precedents`
sections), `docs/language/06-testing-a-package.law.md` (the
`law test` reference)
- Prerequisite:
[nb-09: From permit to duties and powers](/tutorials/northbridge/nb-09-duties-powers/);
see also:
[nb-10: A procedure with parallel checks](/tutorials/northbridge/nb-10-parallel-procedure/)
(procedures in full),
[nb-11: Appeal: reading, judgment and precedent](/tutorials/northbridge/nb-11-appeal/) (readings in full),
[nb-12: Allocation in rounds](/tutorials/northbridge/nb-12-allocation-rounds/) (stages in
full)
Three levels:
1. **Northbridge use** (this article): one stall file through duties,
a guarded two-region procedure, a disputed storage question, a
warden judgment, a pitch precedent and frozen repair rounds —
verified by the thirty tests above.
2. **Domain template:** whenever one case needs obligations, motion
and judgment together, model each lens with its own construct
(positions for who owes what, a procedure for file motion, a stage
for frozen rounds, readings for disputes). Gate every power with
`valid_when`; keep `create` the only relied-upon effect form;
never let the main route read an unchosen interpretation; keep
stages and procedures in separate worlds.
3. **Confirmed examples elsewhere:** the permits package, where the
same five positions govern parking (verified by
`law test packs/examples/language-demo/permits`, 28/28, including
`power exercised lawfully` and `liberty and immunity`); the
appeals package, where the same reading machinery decides second
permits (broad/narrow, judgment pending/rendered, precedent
followed/distinguished); the allocation package, where the same
tour machinery allots market seats in two rounds. Positions recur,
procedures advance, stages freeze, readings decide — in each
package alike.
4. **Confirmed external formalization (corpus):** the Lefkowitz
advertisement-as-offer holding (US case law) — package
`us.caselaw.advertisement_offers`,
`corpus/laws/us/caselaw-advertisement-offers/03-lefkowitz.law:31-41`:
`precedent Lefkowitz of OfferFactors` with court, mandatory
decided date, outcome, a ratio that is a subset of the
plaintiff-side factors, and `prefer over` beating a named general
defeasible rule of the statutory line. Evidence:
`docs/research/constructs/25-argue-precedent/corpus-forms.en.md` [§2](/tutorials/northbridge/nb-01-first-permit/#2-prerequisites)
(rated exemplary). Limit of verification: presence of the named
construct at the cited lines only, confirmed by direct file read;
no claim about deployment, runtime behaviour, or legal
correctness.