nb-11 — Appeal: reading, judgment and precedent
Northbridge is fictional. Every applicant, hearing officer, precedent
and court cited here is synthetic and unofficial. Northbridge is a
training story, not a real deployment, and nothing here is
legal-validity advice. Verified profile: law 0.1.0, law.core/0.2.
Situation
Section titled “Situation”Ann owns a second car and asks the permit office for a second parking
permit. The clerk refuses: under the office’s working reading, one
household gets one permit, so second_permit(ann) is false. Ann
appeals. At the hearing, three questions land on the table. First,
which reading governs — the clerk’s narrow one, or Ann’s broad one
under which an otherwise eligible resident gets the second permit?
Second, Ann pleads hardship — a question nobody at the desk can answer;
only the hearing officer’s judgment settles it. Third, fellow appellant
Bob lives in the city but keeps a second home outside it, and an old
HIGH court decision on exactly that pattern is put on the table.
Eligibility rules (nb-01: First permit: facts, a rule and a question through nb-03: Exceptions and conflicting rules) answered “does the rule fire?”. Duties (nb-09: From permit to duties and powers) answered “who owes what once it fires?”. This article answers what happens when the answer is contested.
The three hearing questions map to five constructs. Rival readings are named as interpretations — one reading per container — and the closed list of rivals plus how one is chosen is an interpretation group. The hardship question marks the point where only a human decision can move the case: a judgment is a fact that only an authority’s decision can supply. The old HIGH court decision is reused without copying through its factors — the fact pattern it turned on — and the precedent itself, which the engine carries to new facts. Each construct is explained again where it first appears below.
Prerequisites
Section titled “Prerequisites”You need nb-01: First permit: facts, a rule and a question for facts,
strict rules, truth(...) queries and law test as the way to check
a claim; nb-02: Why a missing fact is not a refusal
for the four truth statuses, where NEITHER means “no conclusion
either way” and never a refusal; and
nb-03: Exceptions and conflicting rules for
strict rules and how conflicting conclusions resolve. Two issue flags
appear below: INTERPRETATION_REQUIRED (no reading chosen) and
REQUIRES_JUDGMENT (the authority has not spoken yet).
nb-09: From permit to duties and powers
showed duties and powers. Appeals resolve what is contested about
relations like those: the hearing in this article is where an
exercised objection — the MayObject power from
nb-09: From permit to duties and powers —
would be heard.
None of the five constructs decides a case by itself. The group selects the reading, the judgment supplies the missing fact, the precedent carries a past outcome to matching facts. Where any of the three is absent, the engine stops with a named issue instead of guessing. That stop is the limit of automatic decision, and it is the point of the design.
Minimal example
Section titled “Minimal example”All fragments are excerpts from
packs/examples/language-demo/appeals/package.law (identifiers as
written; package header, imports, type alias and unrelated relation
declarations cut). Each fragment is marked Excerpt.
Excerpt 1 — the narrow reading (lines 21–28). An interpretation is a named container for rules that belong to one reading of the law.
interpretation Narrow { status reviewed; rule NarrowReading strict { for a: Applicant; when second_vehicle(a); then not second_permit(a); }}Look at what the container holds: an ordinary strict rule. Under
Narrow, a second vehicle alone defeats the second permit — the
clerk’s reading, stated with no new rule machinery. The novelty is the
interpretation wrapper that names this reading as one rival among
several.
Excerpt 2 — the broad reading (lines 30–37). The rival container: eligibility carries over to the second vehicle.
interpretation Broad { status reviewed; rule BroadReading strict { for a: Applicant; when second_vehicle(a) and demo.northbridge.permits::permit_eligible(a); then second_permit(a); }}Look at the rule’s second premise: it reaches into the permits
package for permit_eligible, the relation derived in
nb-01: First permit: facts, a rule and a question. Under Broad, the same
second-vehicle fact plus eligibility yields the permit instead of
refusing it. Same fact, opposite conclusion — the reading decides.
Excerpt 3 — the group that chooses (lines 39–42). An
interpretation group lists the rival readings and declares how one
is picked; exactly_one means the context must select precisely one.
interpretation_group SecondVehicle { alternatives Narrow, Broad; selection exactly_one;}Look at the two lines inside the group: the closed list of rivals,
and selection exactly_one. The case context carries interpretation Broad (or Narrow); with no selection the question stays open by
construction, flagged INTERPRETATION_REQUIRED rather than defaulted.
Excerpt 4 — the judgment and the rule waiting on it (lines 44–52). A
judgment declares a relation whose instances only an authority’s
decision can supply — here hardship, vested in the HearingOfficer.
external judgment relation hardship(a: Applicant) { authority HearingOfficer;}rule HardshipWaiver strict { for a: Applicant; when applied_for_permit(a) and hardship(a); then hardship_waiver(a);}Look at the two parts together. The external judgment declaration
vests hardship in the HearingOfficer: only that authority’s
decision can supply the fact. HardshipWaiver is otherwise an
ordinary strict rule — but its hardship(a) premise is one no desk
fact can satisfy. Only an adjudicated judgment makes the waiver true.
Excerpt 5 — the fact pattern a past case turned on (lines 54–66). A
factors block names the domain predicate both sides share
(lives_in_city) and which side each distinguishing fact favors:
plaintiff facts favor following, defendant facts favor
distinguishing.
factors ResidencyLine { for a: Applicant; domain lives_in_city(a); plaintiff lives_in_city; defendant second_home; courts HIGH; LOW;}rule SecondHomeNotResident strict { for a: Applicant; when second_home(a); then not resident_for_permit(a);}Look at the side labels. lives_in_city is shared ground marked
plaintiff; second_home is the defendant fact that tells cases
apart. The pattern separates what Ann’s and Bob’s cases have in common
from the one fact that can distinguish them. The strict rule below the
block is the fallback: where the precedent is distinguished away, a
second home defeats residency.
Excerpt 6 — the past decision itself (lines 68–73). A precedent pins one decided instance of a factors pattern — court, date, winning side and outcome — so the engine can carry it to new facts.
precedent P1 of ResidencyLine { court HIGH; decided @2020-06-01; plaintiff lives_in_city; outcome resident_for_permit(a);}Look at the four pinned details: court, date, winning-side factors,
and outcome. P1 says the HIGH court granted resident_for_permit on
the city-living facts. A new case with the same factors follows it;
one with an extra defendant-side factor is distinguished back to the
general rule.
Command and result
Section titled “Command and result”Run the appeals suite:
law test packs/examples/language-demo/appealsObserved result (engine law 0.1.0) — all seven scenario lines plus
the summary:
law test demo.northbridge.appeals: мир demo.northbridge.appeals, demo.northbridge.calculations, demo.northbridge.permits, demo.northbridge.vocabulary ok [demo.northbridge.appeals] tests/appeals.lawtest / broad reading ok [demo.northbridge.appeals] tests/appeals.lawtest / narrow reading ok [demo.northbridge.appeals] tests/appeals.lawtest / no selection — open question ok [demo.northbridge.appeals] tests/appeals.lawtest / judgment not yet rendered ok [demo.northbridge.appeals] tests/appeals.lawtest / judgment rendered ok [demo.northbridge.appeals] tests/appeals.lawtest / precedent followed ok [demo.northbridge.appeals] tests/appeals.lawtest / precedent distinguishedитого: 7 проверено, 7 прошли, 0 не прошли, 0 не исполнены; код 0All seven tests pass: each answer matched its expectation. That says the machine selects, waits, follows and distinguishes as declared — it is not a ruling that Ann deserves the second permit. The first line names the world under test: the appeals package together with the calculations, permits and vocabulary packages it is evaluated with. The summary line is in Russian and says that 7 tests were checked, 7 passed, none failed and none were left unexecuted, with exit code 0.
The package also passes the static check:
law engine check packs/examples/language-demo/appeals/package.lawcheck OK: packs/examples/language-demo/appeals/package.lawcheck OK means the package file is well-formed; the suite run above
is what exercises its behavior.
What the decisive tests assert (all in
packs/examples/language-demo/appeals/tests/appeals.lawtest):
| Test | Setup | Expects |
|---|---|---|
broad reading | second_vehicle + resident + registered car, interpretation Broad | truth(second_permit(ann)) TRUE_ONLY |
narrow reading | second_vehicle only, interpretation Narrow | truth(second_permit(ann)) FALSE_ONLY |
no selection — open question | second_vehicle, no interpretation chosen | issue(INTERPRETATION_REQUIRED) |
judgment not yet rendered | applied for permit, no hardship on record | NEITHER + REQUIRES_JUDGMENT |
judgment rendered | applied + hardship with origin adjudicated | truth(hardship_waiver(ann)) TRUE_ONLY |
precedent followed | lives_in_city(ann) only, interpretation Broad | truth(resident_for_permit(ann)) TRUE_ONLY |
precedent distinguished | lives_in_city(bob) + second_home(bob) | truth(resident_for_permit(bob)) FALSE_ONLY |
Note what the Broad test carries that Narrow does not. The broad
rule needs permit_eligible, so its test asserts resident and vehicle
facts too. Selecting a reading selects what must be proven: Ann’s
permit under Broad stands or falls with her eligibility, while under
Narrow the second vehicle alone decides.
Why this construct
Section titled “Why this construct”The task is to decide a contested case where the rule itself is disputed, one premise needs an authority’s word, and a past decision constrains the outcome — and to show, for each open point, exactly what is missing. Each of the five constructs answers a different question the hearing officer actually asks. Interpretations: what are the rival readings. The group: which one governs this case. Judgment: who alone can supply this fact. Factors: what did the past case turn on. Precedent: what was decided there. One construct per question, no overloading.
A plain strict rule in the style of nb-01: First permit: facts, a rule and a question states either reading but cannot name the rivalry or demand a choice. A closure from nb-06: When the register may stay silent closes a register but cannot vest a fact in an authority. Copying P1’s outcome into a new rule freezes one answer where factors keep the follow-or-distinguish logic alive.
The proof is the seven tests above: both readings executed, the open
question flagged, both judgment states observed, and the precedent
pair — followed TRUE_ONLY, distinguished FALSE_ONLY — run by law test, not asserted in prose. What the tests do not prove is that
Broad should win, that Ann’s hardship is real, or that P1 was
rightly decided. The tests prove the machine selects, waits, follows
and distinguishes as declared; no test can prove the hearing officer
chose wisely. All cases are fictional data, not legal advice.
Changed condition
Section titled “Changed condition”Take precedent followed and add one fact: second_home(bob).
With city living only (Ann), truth(resident_for_permit(ann)) is
TRUE_ONLY — her factors match P1’s, so the holding carries over. With
the same city fact plus a second home (Bob), the same query is
FALSE_ONLY. The extra defendant-side factor distinguishes his case
back to the general SecondHomeNotResident rule. One condition, two
outcomes — and the difference is the distinguished factor, not a
different rule.
The same one-change logic governs readings. broad reading versus
narrow reading differ in the selected interpretation, plus the
eligibility facts that Broad’s premises require. Assert neither
selection and the third test reports INTERPRETATION_REQUIRED instead
of any truth value. The engine never silently defaults to a reading.
Typical mistake
Section titled “Typical mistake”A tempting assumption is that an unchosen reading defaults to
something — usually to the strict-looking one: “nobody selected Broad,
so Narrow applies and the permit is refused.” It does not. The no selection — open question test asserts second_vehicle with no
interpretation in context, and the engine answers with
issue(INTERPRETATION_REQUIRED), not FALSE_ONLY. exactly_one means
the choice is mandatory input, not an optional hint with a silent
fallback.
The fix is to treat the selected interpretation as part of the case —
like a fact. If a query returns INTERPRETATION_REQUIRED, add the
missing selection to the context, not more rules. If it returns
REQUIRES_JUDGMENT, the case waits on the authority, not on more desk
evidence.
Limits
Section titled “Limits”Automatic decision stops at named issues. INTERPRETATION_REQUIRED
and REQUIRES_JUDGMENT are the engine refusing to guess: no reading
chosen, no judgment on record. They mark work for a human — the
hearing officer — not engine failures.
A judgment fact needs its authority. The rendered test carries
hardship with origin adjudicated; desk assertions cannot stand in
for the vested authority’s word. A judgment relation is usable only
where its authority has spoken.
A precedent binds only inside its factors pattern. P1 moves
resident_for_permit for city-living facts and yields to the general
rule where a defendant factor appears. Outside the ResidencyLine
domain it says nothing at all.
Readings do not mix. Exactly one alternative governs per context; Broad’s eligibility premises never leak into a Narrow case. Rival readings coexist in the package but never fire together.
Verified profile: engine law 0.1.0, semantics law.core/0.2. The
selection discipline (exactly_one), the judgment gate
(REQUIRES_JUDGMENT) and the follow-or-distinguish behavior are facts
about this profile’s implementation, never claims about the language
in general.
Exercise
Section titled “Exercise”Without running the engine, predict, then check with law test:
- In
broad reading, which asserted facts satisfy Broad’s two premises, and which single premise would the clerk’s file (second vehicle only) fail? - In
no selection — open question, why does the engine report an issue rather than FALSE_ONLY — whose reading would FALSE_ONLY even be? - In
judgment not yet rendered, why is the status NEITHER rather than FALSE_ONLY — what is the case waiting for, and who supplies it? - In
precedent distinguished, name the shared domain fact and the distinguishing defendant fact, and say which rule decides Bob’s case once P1 is distinguished away.
Write down each prediction first; run the suite; explain any miss in one sentence. Checkable solution: full solution: predictions and checkable answers.
Sources
Section titled “Sources”- Source:
packs/examples/language-demo/appeals/package.law(readingsNarrow/Broad, groupSecondVehicle, judgmenthardship, ruleHardshipWaiver, factorsResidencyLine, ruleSecondHomeNotResident, precedentP1) - Tests:
packs/examples/language-demo/appeals/tests/appeals.lawtest(the seven reading, judgment and precedent tests) - Suite tour:
packs/examples/language-demo/appeals/README.md - Language reference:
docs/language/09-advanced-cheat-sheet.law.md(interpretations and advanced constructs),docs/language/06-testing-a-package.law.md(thelaw testreference) - Prerequisite: nb-09: From permit to duties and powers; next: nb-12: Allocation in rounds
Three levels:
- Northbridge use (this article): Ann’s second-permit appeal under rival readings, her hardship waiver waiting on the hearing officer, and Bob’s residency decided by precedent P1 — verified by the seven tests above.
- Domain template: whenever a decision is contested, put each
rival reading in its own interpretation, force the choice with an
exactly_onegroup, vest authority-only facts in judgment relations, and carry past decisions as precedents over explicit factors — so every open point surfaces as a named issue instead of a silent default. - Confirmed example elsewhere: the permits package, where the
eligibility rules that Broad builds on are exercised — verified by
law test packs/examples/language-demo/permits(28 checked, 28 passed, 0 failed). Confirmed external formalization: the Lefkowitz advertisement-as-offer holding (US case law) — packageus.caselaw.advertisement_offers,corpus/laws/us/caselaw-advertisement-offers/03-lefkowitz.law:31-41, constructprecedent ... of Factorswith court/decided/outcome/ ratio/prefer.
What the permits cross-check shows
The permits suite exercises resident with a car, fines refusal by
priority, and defeater without negation — including denial wins by priority (FALSE_ONLY where the refusal outranks eligibility).
Readings select the rule; eligibility rules do the proving.
Sources and scope of verification
The Lefkowitz precedent was decided @1957-12-20, with its ratio a
subset of the plaintiff-side factors and a prefer over
AdvertisementIsNotAnOffer. A past decision carried over explicit
factors with a named defeated rule — the same shape as precedent P1
deciding Bob’s case. Evidence:
docs/research/constructs/25-argue-precedent/corpus-forms.en.md,
section 2 (rated exemplary there). The recorded verification confirms
the construct’s presence at the cited lines only, by direct source
read; it makes no claim about deployment, runtime behavior, or legal
correctness.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.