Skip to content
docs
Arxo ↗

nb-09 — From permit to duties and powers

For LLMs10 sections
← Course mapChapter 09 / 25 · Intermediate

Northbridge course, intermediate (nb-05 → nb-06 → nb-07 → nb-08 → nb-09). All law is fictional; every office, notice, revocation and towing rule is synthetic and unofficial. No real municipal deployment or legal-validity claims. Engine law 0.1.0, semantics law.core/0.2.

Ann filed her parking-permit application on 1 March 2026. Filing is not the end of the story — it starts several directed relations at once. The permit office now owes Ann a decision within thirty days. Ann, once eligible, must not resell her permit to anyone during 2026.

If she does resell it, the office may revoke it by sending a revocation notice — and only then. If the office refuses her outright, she may object during March. And while she displays a valid permit, the office may not have her car towed.

The eligibility lessons answered “may Ann have a permit?”: nb-01: First permit: facts, a rule and a question, nb-02: Why a missing fact is not a refusal, nb-03: Exceptions and conflicting rules. This article answers what happens next: who owes what to whom, what counts as doing it or breaking it, and which acts change the legal state. Law DSL expresses those relations as five position constructs: duty, prohibition, power, liberty, and immunity, each shown with its meaning in place below.

nb-01: First permit: facts, a rule and a question: facts, strict rules, law test as the way to check a claim. nb-02: Why a missing fact is not a refusal: the four truth statuses — NEITHER below means “no conclusion either way”, never a refusal. nb-03: Exceptions and conflicting rules: strict rules and how conflicts resolve. nb-08: Which edition applies and when the term expires: the CALENDAR_DAYS deadline policy — the decision duty’s window end (due) is computed by the DecisionDeadline rule with that policy, and the duty tests set the policy in their context.

New here: positions are not truth claims. truth(...) says whether a proposition holds; positions() says what lifecycle state each duty, prohibition, power, liberty and immunity is in: ACTIVE (in force, outcome still open), SATISFIED (goal met), VIOLATED (goal failed), UNDETERMINED (too little known to say either).

All fragments are excerpts from packs/examples/language-demo/permits/package.law (identifiers as written; package header, imports and unrelated rules cut).

Excerpt 1 — the office’s duty to decide (lines 77–90). A duty names a bearer o (who owes), a beneficiary (to whom it is owed), and a goal: here an achievement goal with a condition and a window.

Arxo Law
rule DecisionDuty 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 NotifyDecision {
bearer o;
beneficiary a;
goal achievement {
condition demo.northbridge.vocabulary::decision_notified(a);
window [on, due];
}
};
}

One idea: an achievement goal is met when its condition becomes true at least once inside the window — notify Ann once before the due date and the duty is satisfied.

Excerpt 2 — Ann’s prohibition on resale (lines 92–102). A prohibition names a bearer a, a beneficiary, a forbidden action, and a window.

Arxo Law
rule NoResale strict {
for a: Applicant;
for o: Office;
when permit_eligible(a) and demo.northbridge.vocabulary::permit_office(o);
then prohibition NoPermitResale {
bearer a;
beneficiary o;
action demo.northbridge.vocabulary::resells_permit(a);
window [@2026-01-01, @2026-12-31];
};
}

One idea: the mirror image of a duty — instead of “bring about this condition”, “do not perform this action” for the whole of 2026.

Excerpt 3 — the maintenance duty (lines 149–162). Same parties shape, a different goal kind: maintenance must hold at every point of the window, not just once.

Arxo Law
rule MaintainEligibility strict {
for a: Applicant;
for o: Office;
for on: Date;
when demo.northbridge.vocabulary::application_filed(a, on) and demo.northbridge.vocabulary::permit_office(o);
then duty MaintainConditions {
bearer a;
beneficiary o;
goal maintenance {
condition permit_eligible(a);
window [@2026-01-01, @2026-12-31];
}
};
}

One idea: staying eligible all year is a duty too — one counterexample (fines on 1 June) violates it, while one good day proves nothing.

Excerpt 4 — the revocation power (lines 164–175). A power names a holder, the party it is over, the exercise act, the valid_when grounds, and the effect the exercise creates.

Arxo Law
rule RevocationPower strict {
for a: Applicant;
for o: Office;
when demo.northbridge.vocabulary::permit_office(o) and permit_eligible(a);
then power RevokePermit {
holder o;
over a;
exercise revocation_notice(o, a);
valid_when (demo.northbridge.vocabulary::resells_permit(a));
effect create(permit_revoked(a));
};
}

One idea: the notice is only an exercise — permit_revoked(a) appears solely when the grounds (resells_permit) hold too.

Excerpt 5 — the liberty to object (lines 177–187). A liberty names a holder, the party it is against, a permitted action, and a window.

Arxo Law
rule ObjectionRight strict {
for a: Applicant;
for o: Office;
when permit_refused(a, o);
then liberty MayObject {
holder a;
against o;
action objects(a, o);
window [@2026-03-01, @2026-03-31];
};
}

One idea: a refusal opens a one-month window in which objecting is permitted — the liberty exists only because the refusal happened.

Excerpt 6 — immunity against towing (lines 189–199). An immunity names a holder, the party it is against, a protected effect (something that must not be brought about against the holder), and a window.

Arxo Law
rule NoTowing strict {
for a: Applicant;
for o: Office;
when permit_displayed(a, o);
then immunity NoTowingWithPermit {
holder a;
against o;
protected_effect vehicle_towed(o, a);
window [@2026-01-01, @2026-12-31];
};
}

One idea: displaying the permit shields Ann from one specific effect — towing — without granting anything else.

Terminal
law test packs/examples/language-demo/permits

Observed result (engine law 0.1.0) — the ten position, power, liberty and immunity lines of the run plus its summary:

Output
ok [demo.northbridge.permits] tests/permits.lawtest / positions: duty and prohibition active
ok [demo.northbridge.permits] tests/permits.lawtest / duty satisfied
ok [demo.northbridge.permits] tests/permits.lawtest / duty violated
ok [demo.northbridge.permits] tests/permits.lawtest / outcome unknown — no violation
ok [demo.northbridge.permits] tests/permits.lawtest / maintenance holds while the window is open
ok [demo.northbridge.permits] tests/permits.lawtest / maintenance violated by counterexample
ok [demo.northbridge.permits] tests/permits.lawtest / without a certificate the post-window outcome is unknown
ok [demo.northbridge.permits] tests/permits.lawtest / power exercised lawfully
ok [demo.northbridge.permits] tests/permits.lawtest / power without grounds does not operate
ok [demo.northbridge.permits] tests/permits.lawtest / liberty and immunity
итого: 28 проверено, 28 прошли, 0 не прошли, 0 не исполнены; код 0

The package also passes the static check:

Terminal
law engine check packs/examples/language-demo/permits/package.law
Output
check OK: packs/examples/language-demo/permits/package.law

What the decisive tests assert (evaluate positions(), except the two power tests, which ask truth(permit_revoked(ann))):

TestSetupExpects
positions: duty and prohibition activefiled 1 March, office known, judged 5 MarchNotifyDecision ACTIVE, NoPermitResale ACTIVE
duty satisfiedfiled 2 March, notified, judged 10 AprilNotifyDecision SATISFIED
duty violatedfiled 2 March, explicitly not notified, judged 10 AprilNotifyDecision VIOLATED
outcome unknown — no violationfiled 2 March, notification neither asserted nor denied, judged 10 AprilNotifyDecision UNDETERMINED
maintenance holds while the window is openstill eligible, judged 1 JuneMaintainConditions ACTIVE
maintenance violated by counterexamplefines recorded, judged 1 JuneMaintainConditions VIOLATED
without a certificate the post-window outcome is unknownfiled 2 March, no certificate facts either way, judged 5 JanuaryMaintainConditions UNDETERMINED
power exercised lawfullynotice sent and resale recordedpermit_revoked TRUE_ONLY
power without grounds does not operatenotice sent, no resale recordedpermit_revoked NEITHER
liberty and immunityrefused and permit displayed, judged 10 MarchMayObject ACTIVE, NoTowingWithPermit ACTIVE

All 28 tests pass: each answer matched its expectation. A passing test is not a ruling in anyone’s favour — it only says the engine’s answer agreed with the test’s expect line. The summary is in Russian: итого: 28 проверено, 28 прошли, 0 не прошли, 0 не исполнены; код 0 — 28 checked, 28 passed, 0 failed, 0 skipped, exit code 0.

Note the dates doing work: the achievement duty is judged on 10 April, after the 30-day window from the 2 March filing has closed — so its outcome is decidable. The maintenance duty is judged on 1 June, mid-window — still open, hence ACTIVE while no counterexample exists.

The task is to turn “the office must decide, Ann must not resell, the office may revoke on resale, Ann may object, towing is off-limits” into machine-checkable relations with named parties and observable lifecycles.

Each of the five answers a different question the desk clerk actually asks. Duty and prohibition: who owes what to whom. Power: can this act change her legal state. Liberty: may she do this. Immunity: are we barred from doing that to her. One construct per question — no overloading.

The ten tests are the proof: every lifecycle state (ACTIVE, SATISFIED, VIOLATED, UNDETERMINED) and both power outcomes (TRUE_ONLY, NEITHER) are executed by law test, not asserted in prose.

What is not proven: that these are the right municipal rules. The tests prove the machine tracks the declared duties and powers; no test can prove Northbridge chose wisely. All acts are fictional data, not legal advice.

Why not eligibility rules or constraints?

Eligibility rules (nb-01: First permit: facts, a rule and a question, nb-02: Why a missing fact is not a refusal, nb-03: Exceptions and conflicting rules) can label someone “revocable” but cannot name the act, the grounds, or the effect. Constraints can flag “issued without fee” but carry no parties and no lifecycle. Positions keep parties, performance, violation and effect in one named unit.

Take the lawful revocation and remove one fact: resells_permit(ann).

With resale asserted (office, eligibility and the notice all present), truth(permit_revoked(ann)) is TRUE_ONLY — exercise plus grounds, so the create(permit_revoked(a)) effect fires. Without resale, everything else identical, the same query is NEITHER.

Why: the notice was still sent and the power still exists, but an exercise without valid_when grounds operates nothing. One condition, two outcomes — and the difference shows in the truth status, not in anyone’s intention.

The same one-change logic governs duties: duty satisfied versus duty violated differ only in whether decision_notified(ann) is asserted or explicitly denied on 10 April; assert neither and the third test reports UNDETERMINED. The engine never invents a violation from silence.

The mistake is treating the exercise act as the effect: “the office sent the notice, so the permit is revoked.”

It is not — the groundless-power test returns NEITHER with the notice on record. exercise names which act counts; valid_when decides whether it operates; only an operating exercise produces the effect.

The fix: a power needs three things at once — standing (office plus eligibility in the when), the exercise act, and true grounds. Remove any one and permit_revoked stays NEITHER. If you want revocation on notice alone, write valid_when that way — but then say so, because the test suite will hold you to it.

  • Positions are read through positions(). Truth queries see the power’s effect (permit_revoked), never the duty or liberty itself. Asking truth(NotifyDecision) is a category error — duties have lifecycle states, not truth values.
  • Windows bound everything. MayObject opens only for refusals inside 1–31 March; NoPermitResale covers only 2026. Outside its window a position is not violated — it simply does not apply.
  • UNDETERMINED is not VIOLATED. After the window closes with the outcome unrecorded (without a certificate ... unknown), the engine reports UNDETERMINED rather than guessing. Violation needs a witness: an explicit denial for achievement, a counterexample for maintenance.
  • Verified profile: engine law 0.1.0, semantics law.core/0.2. The lifecycle vocabulary (ACTIVE, SATISFIED, VIOLATED, UNDETERMINED, exercise / valid_when / effect) is a fact about this profile’s implementation, never a claim about the language in general.

Without running the engine, predict, then check with law test:

  1. In duty violated, which single change to the given facts flips NotifyDecision from VIOLATED to SATISFIED, and which flips it to UNDETERMINED?
  2. In maintenance violated by counterexample, why is the status VIOLATED rather than UNDETERMINED — what plays the witness role?
  3. In power without grounds does not operate, name the three ingredients (standing, exercise, grounds) and say which one is absent.
  4. In liberty and immunity, why is MayObject ACTIVE on 10 March but would not even apply to a refusal dated 15 April?

Write down each prediction first; run the suite; explain any miss in one sentence. Checkable solution: solutions/nb-09-solutions.md.

  • Source: packs/examples/language-demo/permits/package.law (rules DecisionDuty, NoResale, MaintainEligibility, RevocationPower, ObjectionRight, NoTowing)
  • Tests: packs/examples/language-demo/permits/tests/permits.lawtest (the ten position, power, liberty and immunity tests)
  • Suite tour: packs/examples/language-demo/README.md
  • Language reference: docs/language/09-advanced-cheat-sheet.law.md (positions and advanced constructs), docs/language/06-testing-a-package.law.md (the law test reference)
  • Prerequisite: nb-01: First permit: facts, a rule and a question; next: nb-10: A procedure with parallel checks

Three levels:

  1. Northbridge use (this article): office decision duty, resale prohibition, eligibility maintenance, revocation power, objection liberty, towing immunity — verified by the ten tests above.
  2. Domain template: whenever a regime says who must do what for whom, model each relation as one named position with explicit parties and a window; use achievement for one-off acts, maintenance for standing conditions; give every power named grounds plus a named effect, and read lifecycles only through positions().
  3. Confirmed example elsewhere: unit training readiness (US Army AR 350-1, para. 1-9a) — package us.army.training, corpus/laws/us/army-training/03-deontic.law:50-61, construct then duty with an addressed holder, a beneficiary, and an achieve-during window (UnitTrainingReadiness). Why this form fits: one named position with explicit parties and a window — this article’s domain template, outside civil law. Evidence: docs/research/constructs/10-duty/corpus-forms.en.md section 1 (rated exemplary there). Limit of verification: presence of the named construct at the cited lines only, confirmed by direct source read; no claim about deployment, runtime behavior, or legal correctness.
Where an exercised objection would be heard

The appeals package takes over where positions stop: readings are selected, judgments are rendered, precedents are followed or distinguished — verified by law test packs/examples/language-demo/appeals (7 checked, 7 passed, 0 failed), including judgment rendered (TRUE_ONLY once the hearing officer’s judgment is on record) and precedent distinguished (FALSE_ONLY where the defendant’s facts differ). Positions create the relations; appeals resolve what is contested about them — exactly as the limits say.

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

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