Markdown for LLMs
nb-18 solutions — Vocabulary and package composition
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# nb-18 solutions — Vocabulary and package composition *Checkable against `law test packs/examples/language-demo/composition` (10 checked, 10 passed), `law engine check packs/examples/language-demo/composition` (`check OK`), `law fix imports ./packs/examples/language-demo/composition` (canonical), the frozen exhibits `packs/examples/language-demo/composition/evidence/ev-use-self.txt` (E1116) and `evidence/ev-private.txt` (E1105), and the scratch replays below (copies under `/tmp`, repo suite untouched). Tool `law 0.1.0`, language `0.2`, semantics `law.core/0.2`, std `0.2.0`. Identifiers and code as written.* ## 1. `counter_ready` without the exported facts **Answer: NEITHER. The resident half holds; the counter half has no support, so the conjunction never fires.** `CounterReady` needs both `resident(a)` (vocabulary, asserted in the test's `given`) and `counter_open(c)` (composition, fed only by `CounterFacts`). Remove the facts group on a scratch copy and the first suite test fails exactly this way: `truth_status == TRUE_ONLY: в документе NEITHER`, suite `9 прошли, 1 не прошли`, exit 1 — every other test still ok. The export is load-bearing, not decorative: without it the counter side of the conjunction is silence, and silence is NEITHER, not false. ## 2. The desk assert written twice **Answer: nothing changes — `shift_ok()` stays TRUE_ONLY, suite stays 10/10.** Executed on a scratch copy with the `shift_posted(open)` assert doubled under two ids: `10 проверено, 10 прошли, 0 не прошли`. Asserts feed a set of facts, not a multiset of derivations: the second identical assert adds no new ground, `ShiftOk` fires once, and the status is unchanged. If duplication changed answers, `CounterFacts`-style package facts plus a same-content `given` would double-fire everywhere — the suite shows they do not. ## 3. `Applicant` declared, `resident_seen` left out **Answer: still refused. The next diagnostic quotes `` `resident_seen` ``.** Executed on a scratch copy (`Applicant` added to the `use self` block, probe rule kept): `law test` fails the whole run with `LDC-E1116`, this time `` `resident_seen` объявлена в файле ... package.law и не заявлена в `use self` файла ... desk.law `` (@27:10). The block rule is one gap at a time and fail-fast for the whole run: each fix only promotes the next undeclared name into the diagnostic. Declare both and the probe builds (at which point the rule is ordinary package logic again). ## 4. Consumer probe over the `pub` relation **Answer: builds clean — and fires as soon as its premise holds.** Executed: the scratch consumer rewritten over `demo.northbridge.composition::resident_seen` (same manifest, same world) builds with no E1105, and with `demo.northbridge.vocabulary::resident(ann)` asserted in its `given` the probe evaluates `TRUE_ONLY` (`1 проверено, 1 прошли`). What makes it fire is the cross-package chain working end to end: vocabulary fact → composition's `ResidentSeen` → `resident_seen(a)` → consumer's `ProbeHit`. Visibility is the only gate: `pub` names compose across packages, the private note does not, and nothing else about the rule had to change. ## 5. `months: "12"` — text where an integer belongs **Answer: `TYPE_ERROR`, same as the missing field — suite exits nonzero.** Executed on a scratch copy: the record test FAILs with `truth_status == TRUE_ONLY: в документе NEITHER` and `evaluation_status == COMPUTED: в документе TYPE_ERROR` (`9 прошли, 1 не прошли`, exit 1) — byte for byte the same shape as the dropped-field mistake in the article. The field is declared `months: Integer`, so a `Text` literal is ill-typed at evaluation: the assert contributes no usable `Slip`, the rule never opens. Of the three candidates, only the two loud ones occur here, and both fail the suite — silent `NEITHER` with `COMPUTED` is reserved for well-typed absences (short slip, busy desk, missing role), never for ill-typed literals.