# nb-25 — Capstone case: one file, five steps, three worlds Northbridge is fictional. Ann, her car, her two stamped filing copies, the hold on her file and every date in this article are synthetic and unofficial. Northbridge is not a deployed system, and nothing here is a claim about real law. Verified profile: tool `law 0.1.0`, language version `0.2`, semantics `law.core/0.2`, std `0.2.0`. ## 1. Situation Ann files for a twelve-month Northbridge permit on 1 March. Her file holds five items: her residency, her registered car, two stamped copies of the application dated 1 and 2 March that disagree with each other, a twelve-month term at 10 EUR a month, and — placed this morning by the night clerk — a hold. The office owes her a decision thirty days after filing. Your job is the whole course in one file. You will compose the packages her case needs, read what the file grants, change one circumstance at a time, predict each new outcome before running it, and finally name the smallest admissible change that flips the decision. A test pair that differs by exactly one admissible fact and records the flipped outcome is called a **counterfactual** here. The case grows in five steps. First the minimal file decides. Then a second stamped copy conflicts with the first. Then the night clerk places a hold. Then Ann seeks a second permit that two readings answer differently. Finally the same facts meet a new year and a late proof. Each step adds one circumstance the previous step's model cannot express. The five steps run in three separate evaluations. Each evaluation sees a closed set of packages — that closed set is what this article calls a **world**. Steps 1–3 share the capstone world: `capstone` composed with `permits`, `vocabulary` and `calculations`, pinned in `law.toml` and `law.lock`. These packages are **compatible**: they share the vocabulary entity `Applicant` and read only `pub` symbols across their boundaries. Step 4 lives in the appeals world and step 5 in the sourcetime world, so the case needs three commands. The runs are joined in prose below, never in one evaluation: | Step | New circumstance | World | Command | |---|---|---|---| | 1 | first filing decides | capstone + permits + vocabulary + calculations | `law test packs/examples/language-demo/capstone` | | 2 | conflicting copy | same capstone world | same command | | 3 | hold placed | same capstone world | same command | | 4 | second permit, two readings | appeals + permits + vocabulary + calculations | `law test packs/examples/language-demo/appeals` | | 5 | new year, late proof | sourcetime alone | `law test packs/examples/language-demo/sourcetime` | ## 2. Prerequisites You should be comfortable with facts, rules and truth statuses from [nb-01: First permit: facts, a rule and a question](/tutorials/northbridge/nb-01-first-permit/), including running suites with `law test`. The hold in step 3 is an `unless` defeater from [nb-03: Exceptions and conflicting rules](/tutorials/northbridge/nb-03-exceptions/), the fee reuses the monthly rate from [nb-04: The permit fee](/tutorials/northbridge/nb-04-permit-fee/), and the conflicting copies repeat the key conflict from [nb-06: When the register may stay silent](/tutorials/northbridge/nb-06-register-silence/). The remaining machinery comes from three advanced articles: [nb-18: Packages and composition](/tutorials/northbridge/nb-18-packages-composition/) for imports, `pub` and explicit packages, [nb-11: Appeal: reading, judgment and precedent](/tutorials/northbridge/nb-11-appeal/) for readings and the open question, and [nb-20: Sources, time and evidence](/tutorials/northbridge/nb-20-sources-time-evidence/) for editions, time axes and admission. Step by step, this case combines the neighbor drills from [nb-24: Neighbor constructs, nine mistakes and three decision tasks](/tutorials/northbridge/nb-24-neighbors-mistakes/). New here: composing four packages into one decided file, reading a grant through an upstream chain, the one-fact counterfactual, the visibility refusal on a non-`pub` symbol, and growing one file through five steps across three explicit world boundaries. ## 3. Minimal example Excerpts are byte-exact kept lines from the capstone package (new teaching package `demo.northbridge.capstone`); cut parts named per label. Excerpt 1 — the composed world (`demo.northbridge.capstone`, `packs/examples/language-demo/capstone/package.law`, lines 4–12; rules below cut). ```law language "law.core" version "0.2"; package demo.northbridge.capstone version "0.1.0"; namespace "urn:law:demo:northbridge:capstone"; import demo.northbridge.permits version "0.1.0"; import demo.northbridge.vocabulary version "0.1.0"; import demo.northbridge.calculations version "0.1.0"; type Applicant = demo.northbridge.vocabulary::Applicant; ``` Look at the three `import` lines: they pull the `permits`, `vocabulary` and `calculations` packages into one world. The `type Applicant = ...` line gives the shared vocabulary entity a local name, so every rule below writes `a: Applicant` while meaning the same kind of entity the upstream packages mean. Excerpt 2 — readiness through the upstream chain, grant with a hold (`demo.northbridge.capstone`, `packs/examples/language-demo/capstone/package.law`, lines 29–41; fee, track and deadline rules cut). ```law rule CapstoneReady strict { for a: Applicant; when demo.northbridge.permits::permit_eligible(a) and demo.northbridge.vocabulary::resident(a); then capstone_ready(a); } rule CapstoneGrant defeasible { for a: Applicant; when capstone_ready(a); then capstone_grant(a); unless capstone_hold(a); } ``` Read the two rules as one chain with two links. `CapstoneReady` derives local readiness from two upstream facts: eligibility from the permits package and residency from the vocabulary package. `CapstoneGrant` then reads only that local readiness — and its `unless` line names the hold as the one defeater that can block the grant without denying readiness. Excerpt 3 — fee and track (`demo.northbridge.capstone`, `packs/examples/language-demo/capstone/package.law`, lines 19–27; readiness rules below cut). ```law pub function capstone_fee(months: Integer) -> Money = months * demo.northbridge.calculations::MONTHLY_RATE; pub decision CapstoneTrack(months: Integer) -> Decimal { table hit first { when months >= 12 => 0.2; otherwise => 0.0; } } ``` The fee function multiplies the term by `MONTHLY_RATE` from the calculations package: the amount comes from one shared constant, not a number copied into this file. Below it, `CapstoneTrack` is a decision table in `hit first` mode — the first matching row wins — so a twelve-month term takes the `0.2` row and anything shorter falls to `otherwise`. Excerpt 4 — the thirty-day deadline (`demo.northbridge.capstone`, `packs/examples/language-demo/capstone/package.law`, lines 43–54; end of file). ```law deadline policy CAPSTONE_DAYS { start_count next_day; include_end true; roll no_roll; } rule CapstoneDeadline strict { for a: Applicant; for on: Date; when demo.northbridge.vocabulary::application_filed(a, on); then capstone_due(a, add_calendar_period(on, 30 calendar_day)); } ``` The policy block sets the three knobs every day-count needs: counting starts the day after filing, the end day counts, and the date never rolls to another day. The rule below binds the filing date `on` to a due date thirty calendar days later. For Ann's 1 March filing the suite derives 1 April; the test supplies this policy through its case context. Excerpt 5 — the granting test (`demo.northbridge.capstone`, `packs/examples/language-demo/capstone/tests/capstone.lawtest`, lines 5–13; the remaining suite cut). ```law test "resident driver is capstone-ready" { given { context { legal_time @2026-03-01; decision_time @2026-03-01T09:00:00Z; knowledge_time @2026-03-01T09:00:00Z; timezone "UTC"; } assert "resident-ann": demo.northbridge.vocabulary::resident(entity_ref("urn:demo:northbridge:ann")) { origin case_input; } assert "vehicle-ann": demo.northbridge.vocabulary::vehicle_registered(entity_ref("urn:demo:northbridge:ann")) { origin case_input; } } evaluate truth(capstone_ready(entity_ref("urn:demo:northbridge:ann"))); expect truth_status == TRUE_ONLY; } ``` This is the shape every later test follows. The `given` block fixes the three clocks and asserts Ann's two facts — residency and a registered car, each recorded as case input. The `evaluate` line asks whether she is capstone-ready, and the `expect` line states the answer: `TRUE_ONLY`, support with no denial. Excerpt 6 — the conflicting documents (`demo.northbridge.capstone`, `packs/examples/language-demo/capstone/tests/capstone.lawtest`, lines 69–78; neighboring tests cut). ```law test "two filing dates conflict on the key" { given { context { legal_time @2026-03-01; decision_time @2026-03-01T09:00:00Z; knowledge_time @2026-03-01T09:00:00Z; timezone "UTC"; } assert "filed-1": demo.northbridge.vocabulary::application_filed(entity_ref("urn:demo:northbridge:ann"), @2026-03-01) { origin case_input; } assert "filed-2": demo.northbridge.vocabulary::application_filed(entity_ref("urn:demo:northbridge:ann"), @2026-03-02) { origin case_input; } } evaluate truth(demo.northbridge.vocabulary::application_filed(entity_ref("urn:demo:northbridge:ann"), @2026-03-01)); expect truth_status == TRUE_ONLY; expect issue(KEY_CONFLICT); } ``` Two asserts file the same applicant under two dates — one key, two values. The test still expects the 1 March filing to stand (`TRUE_ONLY`) and additionally expects the `KEY_CONFLICT` issue. Watch that combination: the fact stands and the conflict is reported beside it, in one test. Excerpt 7a — the two readings (`demo.northbridge.appeals`, `packs/examples/language-demo/appeals/package.law`, lines 21–37; relations above and the group below cut). ```law interpretation Narrow { status reviewed; rule NarrowReading strict { for a: Applicant; when second_vehicle(a); then not second_permit(a); } } 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); } } ``` Compare the two `when` lines. Narrow reads only `second_vehicle(a)` and concludes `not second_permit(a)`: under this reading the second car alone decides against the permit. Broad adds upstream eligibility to the same vehicle fact and concludes the grant. Both readings are marked `reviewed`; nothing here says which one is right. Excerpt 7b — the group that refuses a silent default (`demo.northbridge.appeals`, `packs/examples/language-demo/appeals/package.law`, lines 39–42; readings above cut). ```law interpretation_group SecondVehicle { alternatives Narrow, Broad; selection exactly_one; } ``` The group names the two readings as alternatives and demands `exactly_one`. Each case must select one reading in its context — the engine never silently defaults to either. A case with no selection leaves the question open, as section 4 shows. Excerpt 8a — the year boundary as effective windows (`demo.northbridge.sourcetime`, `packs/examples/language-demo/sourcetime/package.law`, lines 163–177; references above and scopes below cut). ```law @source(PARKING_2025_ART2) rule OldResidencyNotice strict { effective [@2025-01-01, @2026-01-01); for a: Applicant; when resident(a); then residency_notice(a); } @source(PARKING_2026_ART2_EN) rule NewEligibilityNotice defeasible { effective [@2026-01-01, infinity); for a: Applicant; when resident(a) and vehicle_registered(a); then eligibility_notice(a); } ``` The `effective` lines draw the year boundary: the old rule holds only inside 2025, the new rule from 1 January 2026 on. Compare their `when` lines — the 2026 rule adds the vehicle registration the 2025 rule never asked for. The same facts therefore produce different notices depending on the legal date. Excerpt 8b — admission follows office knowledge (`demo.northbridge.sourcetime`, `packs/examples/language-demo/sourcetime/package.law`, lines 253–269; the `Accept` rule above cut). ```law evidence policy OfficeFilePolicy { profile "law.core.evidence-policy/0.1"; accepts accepted; protects residency_proof; input edge edge; input status evidence_status; input authentic authentic; input available available; input current current; rule Accept; } rule ProofAdmits strict { for a: Applicant; when residency_proof(a); then resident_admitted(a); } ``` The policy declares which proof it protects (`residency_proof`), which status counts as accepted, and which inputs feed its `Accept` rule. The rule below admits residency only from that protected proof. A proof the office does not yet know therefore yields no admission — not a denial, just silence until knowledge arrives.
The files behind the kept lines The kept lines above come from `package.law` and its test file. Each full package also pins its dependencies in `law.toml` and `law.lock`, and the appeals and sourcetime worlds each ship their own tests. Section 10 links every file.
## 4. Command and result The package checks clean at L0–L3: ```sh law engine check packs/examples/language-demo/capstone ``` Observed (exit 0): ```text check OK: packs/examples/language-demo/capstone ``` The check passes: `check OK` names the package and nothing else. The file is well-formed, so the suite below runs against a package the engine accepts. The whole file in one run: ```sh law test packs/examples/language-demo/capstone ``` Observed (exit 0, suite green): ```text law test demo.northbridge.capstone: мир demo.northbridge.capstone, demo.northbridge.calculations, demo.northbridge.permits, demo.northbridge.vocabulary ok [demo.northbridge.capstone] tests/capstone.lawtest / resident driver is capstone-ready ok [demo.northbridge.capstone] tests/capstone.lawtest / resident driver is granted without a hold ok [demo.northbridge.capstone] tests/capstone.lawtest / a hold defeats the grant ok [demo.northbridge.capstone] tests/capstone.lawtest / without a car nothing is ready ok [demo.northbridge.capstone] tests/capstone.lawtest / capstone fee for three months ok [demo.northbridge.capstone] tests/capstone.lawtest / capstone track rewards the long term ok [demo.northbridge.capstone] tests/capstone.lawtest / capstone track short term otherwise row ok [demo.northbridge.capstone] tests/capstone.lawtest / two filing dates conflict on the key ok [demo.northbridge.capstone] tests/capstone.lawtest / capstone deadline thirty days after filing итого: 9 проверено, 9 прошли, 0 не прошли, 0 не исполнены; код 0 ``` All nine tests pass: each `ok` line names one test whose answer matched its expectation. The summary line opens with the world the run saw — `мир` means "world", followed by the four composed packages. The `итого` line is the total: 9 checked, 9 passed, 0 failed, 0 unexecuted, exit code 0. A green suite is not a ruling for Ann. It says the file behaves as its tests expect — including the test where a hold defeats her grant. The appeal half of the case runs in its own world — Ann's second-permit reading under each interpretation: ```sh law test packs/examples/language-demo/appeals 2>&1 | grep -E "broad|narrow|open question|итого" ``` Observed (exit 0, suite green): ```text 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 итого: 7 проверено, 7 прошли, 0 не прошли, 0 не исполнены; код 0 ``` The command pipes the suite through `grep`, so only the reading tests and the total print; the four judgment and precedent tests run but stay hidden. All three visible lines pass: Broad grants, Narrow denies, and the unselected case stays an open question. The `итого` line counts the whole run — 7 checked, 7 passed — not just the three lines shown. The time boundary runs in the third world — the same facts under two editions and two states of office knowledge: ```sh law test packs/examples/language-demo/sourcetime 2>&1 | grep -E "2025 edition|2026 edition|before entry|late file|decision day|итого" ``` Observed (exit 0, suite green): ```text ok [demo.northbridge.sourcetime] tests/sourcetime.lawtest / 2025 edition: the old reading holds in its window ok [demo.northbridge.sourcetime] tests/sourcetime.lawtest / 2026 edition: the new reading holds ok [demo.northbridge.sourcetime] tests/sourcetime.lawtest / before entry into force the 2026 rule is silent ok [demo.northbridge.sourcetime] tests/sourcetime.lawtest / late file: unknown while the office has no knowledge ok [demo.northbridge.sourcetime] tests/sourcetime.lawtest / late file: admitted once the office knows it ok [demo.northbridge.sourcetime] tests/sourcetime.lawtest / decision day alone moves no law, 1 March ok [demo.northbridge.sourcetime] tests/sourcetime.lawtest / decision day alone moves no law, 6 March итого: 20 проверено, 20 прошли, 0 не прошли, 0 не исполнены; код 0 ``` Again the output is grep-filtered: seven lines print, covering both editions, the pre-entry silence, the late-file pair and the decision-day pair. Every printed line passes, and the `итого` line reports the full run — 20 checked, 20 passed, exit code 0. ## 5. Why this construct 1. Ann's file decides because its worlds are compatible: one shared entity, `pub`-only reads, no shared mutable state. Residency plus a registered car fires eligibility upstream, readiness follows locally, and the grant follows readiness. The vehicle conjunct carries readiness: without a car nothing is ready. This proves composition carries a whole file. It does NOT prove any three packages compose — only `pub` symbols cross the boundary, and the green run is the receipt for this world only. 2. The two stamped copies conflict, and the file reports that instead of denying either copy: each copy stands while the conflict is reported beside it, and the deadline still derives 1 April from the 1 March copy. The signature is the combination — standing fact plus reported conflict in one test. This does NOT prove conflicts never block. It proves this deadline rule reads the supported date through this conflict. 3. The night clerk's hold removes the grant's support without asserting a denial: the grant goes `TRUE_ONLY` → `NEITHER` while readiness stays `TRUE_ONLY`. The pair differs by exactly the hold assert — the one-fact counterfactual from Situation. It is a test pair, not certified counterfactual machinery: no solver runs, nothing is certified (boundary in Section 8). This does NOT prove holds never deny. It proves this `unless` gates one link and leaves no residue once lifted. 4. Ann's second permit waits on a choice the file cannot make for her. Once selected, the readings decide — Narrow denies, Broad with eligibility grants — and with no selection the question stays open. This does NOT prove Broad right. Both readings are reviewed, and the case selects. 5. The same facts meet two boundaries, each moving on its own axis: the windows select the norm by `legal_time`, and the policy admits the late proof only once office knowledge reaches it. The decision-day pair proves the negative — decision day alone moves no law. This does NOT prove other clocks never matter. It proves these two boundaries moved on their own axes here.
Tests and probes behind the five claims - Step 1: `resident driver is capstone-ready` (`TRUE_ONLY`) against `without a car nothing is ready` (`NEITHER`). - Step 2: `two filing dates conflict on the key`, plus two survival probes (deadline, second copy). - Step 3: `a hold defeats the grant`, plus the readiness probe. - Step 4: `broad reading` (`TRUE_ONLY`), `narrow reading` (`FALSE_ONLY`), `no selection — open question` (`INTERPRETATION_REQUIRED`). - Step 5: the seven printed sourcetime lines in Section 4 (editions, pre-entry silence, late-file and decision-day pairs). Six probes on a scratch copy under `/tmp` pin down what each step leaves standing: readiness survives the hold, the deadline and the second copy survive the conflict, the grant stays silent without a car, a single copy carries no conflict, and the empty file answers `NEITHER`. The scratch run reports 15 checked and 15 passed; the shipped suites stay untouched at 9, 7 and 20.
## 6. Changed condition Step 1 — the file decides. Change: from the empty file, where every question answers `NEITHER`, add residency and the registered car. Result: readiness and the grant derive `TRUE_ONLY`, the fee and the track route by term, and the deadline derives from the filing. Why: each link needs its own conjuncts — residency alone leaves the file silent, which proves a residency-only model forgets the vehicle conjunct. Then shorten the term from twelve months to three and predict before running. Change: the term only. Result: the fee becomes 30 EUR and the track `0.0`, while readiness and the grant do not move. Why: the fee and the track read only the term, never the grant — the suite holds tests on both sides of the table. The table mode stays as authored (`CapstoneTrack` hit first): no subject reason to change it. Step 2 — the second copy lands. Change: one added assert, the 2 March copy; the model is unchanged, because the key is already on the relation. Result: before, the single filing stands `TRUE_ONLY` with no issue and the deadline derives 1 April; after, each copy stands `TRUE_ONLY` with `KEY_CONFLICT`, and the deadline still derives 1 April. Why the key matters: a keyless model would silently keep both dates and let the deadline read either, while a denial model would deny a filing that plainly happened twice on paper. Step 3 — the hold is placed. Change: one added assert, `capstone_hold`; the model is unchanged, because the `unless` is already on the grant. Result: the grant goes `TRUE_ONLY` → `NEITHER` while readiness stays `TRUE_ONLY`. The naive variant — a strict rule deriving `not capstone_grant` from the hold — fires alone once the defeater has taken support away, reading `FALSE_ONLY` where the office means quiet `NEITHER`; Section 7 shows what breaks. Lift the hold and the grant flips back to `TRUE_ONLY`: the pair names the minimal admissible change that decides the file. Step 4 — the second vehicle, a new world. Change: move to the appeals world — the capstone world has no `second_permit` at all and answers bare `NEITHER`, unable even to name the disagreement. The appeals world adds the readings and the group. Result: before selection the question stays open (`INTERPRETATION_REQUIRED`); after selection Narrow denies (`FALSE_ONLY`) and Broad with eligibility grants (`TRUE_ONLY`). Why per question: the input delta is the `second_vehicle` assert, eligibility support for Broad, and the context's `interpretation` selection — or none. Step 5 — the year turns, the proof lands late. Change: move to the sourcetime world, whose paired tests differ by context dates only — zero fact changes. Result: on the legal axis, at `@2025-06-01` the old notice is `TRUE_ONLY` while the new notice is `NEITHER`, and at `@2026-03-01` the new notice is `TRUE_ONLY`; on the knowledge axis, the 1 February proof yields `NEITHER` at January office knowledge and `TRUE_ONLY` at March knowledge. Moving `decision_time` instead changes nothing: the decision-day pair executes the no-op. ## 7. Typical mistake One mistake per step, each with the run that exposes it. Mistake 1 — reading a non-`pub` symbol across the boundary. While writing the suite, the author tried to assert `demo.northbridge.permits::outstanding_fines` directly. Fines are an internal relation of the permits package, and the whole suite refused to lower (observed during authoring, stock CLI): ```text SKIP [demo.northbridge.capstone] tests/capstone.lawtest /Users/rifatjumagulov/Downloads/law-dsl/packs/examples/language-demo/capstone/tests/capstone.lawtest: тест не лоуверится (LDC-E1105: demo.northbridge.permits::outstanding_fines: символ не экспортирован пакетом (§24: межпакетные ссылки — только на `pub`-декларации; экспортировано: permit_eligible)) итого: 1 проверено, 0 прошли, 0 не прошли, 1 не исполнены; код 2 ``` The consequence lands on every test at once: one private read skips the entire suite instead of failing a single case. The refusal names the unexported symbol, cites [§24](https://github.com/arxohq/law/blob/master/spec/SPEC.ru/06-part-vi-package-and-module-system.ru.md#24-visibility) — cross-package references may only name `pub` declarations — lists what the package does export (`permit_eligible`), and totals 1 checked, 0 passed, 0 failed, 1 unexecuted, exit code 2. The fix is to route the case through the published `permit_eligible`, which the final file does. The boundary is load-bearing: it fails loudly at load time rather than leaking internals into the case. (The absolute path above is the author's checkout; on another machine the same refusal names that checkout's own path.) Mistake 2 — reading the conflict as denial. The mistake is to expect the conflicted filing to be `FALSE_ONLY` or `NEITHER`, or the deadline to break under the conflict. The engine does neither: each copy stands `TRUE_ONLY` with `KEY_CONFLICT` beside it, and the deadline rule reads through to 1 April (survival probes in Section 5). Support survives the key conflict; only the report grows. Expect standing fact plus reported conflict together — that combination is the signature. Mistake 3 — denying where the office means silence. Model the hold as strict denial (`then not capstone_grant`) and the quiet block becomes `FALSE_ONLY`. A scratch run proved it: with the naive rule added, the probe expecting `FALSE_ONLY` passes and the shipped `a hold defeats the grant` test fails — the experiment is meant to break the suite, and it does. The companion mistake is expecting readiness to fall with the grant. It does not: the `unless` gates one link while readiness stays `TRUE_ONLY`. Keep the hold as a defeater and the file lifts cleanly.
What the naive-denial scratch run reported With the strict denial added on a scratch copy, the new probe passes at `FALSE_ONLY` while the shipped hold test fails with `truth_status == NEITHER: в документе FALSE_ONLY` — expected `NEITHER`, found `FALSE_ONLY` in the document. The totals read 10 checked, 9 passed, 1 failed: the denial breaks exactly the test that pins the quiet block.
Mistake 4 — begging the appeal's question. Asserting `second_permit` directly as case input decides what the appeal exists to decide. The mirror mistake is expecting a default reading when none is selected — expecting what the engine refuses to give. `no selection — open question` keeps the question open with `INTERPRETATION_REQUIRED`: not a denial, not silence about the facts, but a named demand for the missing selection. The fix is the context's `interpretation` selection, one reading per case. Mistake 5 — moving the wrong clock. Move `decision_time` and expect a norm change, and nothing happens: the decision-day pair executes the no-op (1 March vs 6 March, identical outcomes). Or expect the late proof admitted before `knowledge_time` reaches its recording. Admission follows office knowledge, not the proof's own date — the late-file pair reads `NEITHER` at January knowledge and `TRUE_ONLY` at March knowledge. Move the axis the boundary actually reads: `legal_time` for the edition, `knowledge_time` for the proof. ## 8. Limits This article decides Ann's synthetic file and nothing else: no real applicant, no real fee, no real deadline. Its counterfactual is a one-fact test pair, not the cases package's replay-certified counterfactual machinery — no solver runs, nothing is certified. The appeal readings live in the appeals world and the time boundaries in the sourcetime world. The article runs three commands and joins them in prose, never in one evaluation: no test, probe or claim spans two worlds. The survival probes (claim `nb-25-step-probes`) run on a scratch copy under `/tmp`; the shipped suites stay untouched at 9/9, 7/7 and 20/20. Verified profile: `law 0.1.0`, `law.core/0.2`, std `0.2.0`. The refusals above — the `pub` visibility refusal, the open question without a selection — are implementation facts of this profile, never language-wide inability claims. ## 9. Exercise Work in three passes: warm up on a clean file, take one step at a time, then walk a single file through everything. Predict each value before running; confirm with the Section 4 commands. Solutions live ONLY in `solutions/nb-25-solutions.md`. **Pass A — warm-up.** Bob files: resident with a registered car, a twelve-month term, filed 1 March, no hold, a single filing copy. Predict five values: 1. `capstone_ready(Bob)` — truth status? 2. `capstone_grant(Bob)` — truth status? 3. `capstone_fee(12)` — amount? 4. `CapstoneTrack(12)` — discount? 5. `capstone_due` — date? Name all five first, then confirm them against the suite's analogues by running `law test packs/examples/language-demo/capstone`: 9 passed, 0 failed. **Pass B — one mini-exercise per step.** 1. Bob is resident, has no registered car, a twelve-month term, no hold. Predict `capstone_ready(Bob)` and `capstone_grant(Bob)` before running. 2. Carol files once, 1 March, a single copy. Predict the truth status and the issues for `application_filed(carol, @2026-03-01)`. 3. The hold on Ann's file is lifted; everything else stays. Predict `capstone_grant(Ann)`. 4. Ann is resident with a registered car and a second vehicle; the office selects Narrow. Predict `second_permit(Ann)`. 5. Same resident-plus-vehicle facts, `legal_time @2025-06-01`. Predict `eligibility_notice(ann)` in the sourcetime world. **Pass C — integrative.** Bob files as in pass A (resident, car, twelve months, 1 March, single copy, no hold). Then a second copy dated 2 March appears; a hold is placed, then lifted; Bob buys a second vehicle and the office hears the appeal under each reading; finally the same file is re-evaluated at legal time 2025, and the late proof arrives before office knowledge. Predict nine values, then confirm them with the three Section 4 commands: 1. `capstone_ready` at filing. 2. `capstone_grant` at filing. 3. Issues and truth status on the 1 March filing after the second copy. 4. The grant under the hold, with readiness beside it. 5. The grant after the hold is lifted. 6. `second_permit` under Narrow. 7. `second_permit` under Broad. 8. The 2025 `eligibility_notice`. 9. `resident_admitted` for the 1 February proof at January vs March office knowledge. Then name the construct for three new twists: (a) a suspension that blocks the grant while recorded and vanishes when cleared; (b) two offices reading one term differently, both defensibly; (c) a proof dated before the filing that arrives after the decision. The solution explains every model choice — not just the code. ## 10. Sources Northbridge role → domain template → confirmed external formalization. Full sources: the capstone [package.law](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/capstone/package.law), [law.toml](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/capstone/law.toml) and [tests](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/capstone/tests/capstone.lawtest); the upstream worlds [permits](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/permits/package.law), [vocabulary](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/vocabulary/package.law), [calculations](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/calculations/package.law) and [appeals](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/appeals/package.law); the time-boundary world [sourcetime](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/sourcetime/package.law) and [its tests](https://github.com/arxohq/law/blob/master/packs/examples/language-demo/sourcetime/tests/sourcetime.lawtest). - Ann's file, the hold, the conflicting copies and the deadline → `demo.northbridge.capstone` (this article's new template). - Upstream eligibility → `demo.northbridge.permits`; shared types → `demo.northbridge.vocabulary`; the rate constant → `demo.northbridge.calculations`; the Broad/Narrow appeal → `demo.northbridge.appeals`; editions, axes and admission → `demo.northbridge.sourcetime`. - No external formalization is claimed for the case: names, amounts and dates are synthetic, and this build executes the 0.2 line only.