# nb-22 solutions ## 1. Optional premise, then and now `cause = some repeat_inquirer` in `RepeatFee`: the generated rule carries `if some cause as g { when g(subject); }`, so without a `repeat_inquirer` fact the premise is unsatisfied and the rule cannot fire — `callback_fee` is NEITHER, exactly what `fee needs the repeat record` asserts. `cause = none` in `FirstNotice`: the optional premise vanishes, so `inquiry_filed` alone suffices and `callback_notice` is TRUE_ONLY. If you predicted NEITHER for the fee, you read the option correctly; if you predicted FALSE_ONLY, re-read nb-01 — an unsatisfied premise is silence, not a refusal. ## 2. Surcharge explanation steps `DeskSurcharge/applicable` (the generated defeasible rule, named by the `self/applicable` stable identifier), the `insp` case assertion (`inspects_at`), and the `open` case assertion (`desk_open`). The waiver defeater `DeskSurcharge/excluded/Waiver/excludes` does not appear: no `waived_case` fact is present, so it never fires. A miss here usually means naming the template (`inspection`) instead of the instance rule. ## 3. Two cheapest flips Two solutions — `...#add-i6a` and `...#add-i6b` — each at cost `1`, with `"cutoffCost":"1"` and two candidates checked. `--verify` over the two-candidate result reports `{"kind":"counterfactual-verification",...,"valid":true}` for result id `...#FlipInquiryInput02/result`. If you predicted one solution, you assumed the solver breaks ties; it does not — every cheapest patch is listed. ## 4. Removed spellings The two migration probes are now rejection cases. Use `` `relation … kind institutional` `` for relations and `` `unless` `` for exceptions. The earlier `LDC-E1328` warning followed by `check OK` is a historical observation from engine `law 0.1.0`; neither spelling is accepted by the current compiler. ## 5. Which edit moves the hash Re-indenting and the metadata note leave `programHash` at `sha256:cfe2fcb8…` — canonicalization ignores byte layout and `metadata` is outside the semantic preimage. Only the `50` → `51` literal moves it (`sha256:8b4127d7…`). The stale `--verify` then fails with `COUNTERFACTUAL_PROGRAM_HASH_MISMATCH`, exit 1, naming both hashes; a renewed input with the old result fails the second layer instead (`COUNTERFACTUAL_CERTIFICATE_INVALID`). Re-obtaining the certificate finds `add-i6` at cost 1 again and verifies `valid:true`. If you predicted that any byte change moves the hash, re-read [§4](/tutorials/northbridge/solutions/nb-04-solutions/#4-matchedcount18--value-and-what-does-it-say) — the hash is semantic, not textual.