  ok  FACT: docmost-postgres major + 1 (read from the clone) rc=1 (expected 1)
  ok  FACT: docmost-postgres major + 1, alone              rc=1 (expected 1)
  ok  FACT: kimai-db 11.6 -> 12.3 BUNDLED with the kimai app bump rc=1 (expected 1)
  ok  FACT: kimai-db mariadb:11.6 -> mariadb:lts (major unreadable) rc=2 (expected 2)
  ok  GENUINE: kimai-db mariadb:11.x -> 11.99 (within major) rc=0 (expected 0)
  ok  GENUINE: kimai-db mariadb:11.6 -> 12.3 ALONE (the R-469 lift) rc=0 (expected 0)
  ok  GENUINE: docmost-postgres major+1 ALONE with its proven two-venue MARKED entry rc=0 (expected 0)
  ok  DECOY: the entry is proven on both venues but carries NO conversion mark rc=1 (expected 1)
  ok  DECOY: the marked entry cites ONE venue only (no box_evidence) rc=1 (expected 1)
  ok  DECOY: the mark sits in a COMMENT, the entry has none rc=1 (expected 1)
  ok  DECOY: the marked entry, but the move is BUNDLED with the app's own bump rc=1 (expected 1)
  ok  FACT: adventurelog's postgis 16 -> 17 (the postgis family was never judged before) rc=1 (expected 1)
  ok  DECOY: major moves only in a comment + serverVersion env rc=0 (expected 0)
  ok  DECOY: the APP image crosses a major (kimai 2.57 -> 3.0) rc=0 (expected 0)
  ok  DECOY: 'mariadb:12.3' lands in README.md, not a template rc=0 (expected 0)
  ok  FACT: kimai image moves, catalog_since untouched     rc=1 (expected 1)
  ok  FACT: kimai image moves, catalog_since set to a FUTURE year rc=1 (expected 1)
  ok  GENUINE: kimai image moves AND catalog_since = today rc=0 (expected 0)
  ok  DECOY: image moves; today's date lands in a COMMENT and README, the field stays rc=1 (expected 1)
  ok  DECOY: only a comment + env line change, images untouched, date untouched rc=0 (expected 0)
  ok  FACT: a Hungarian byte changed in a frozen string    rc=1 (expected 1)
  ok  FACT: an em dash in a Hungarian string (R-932)       rc=1 (expected 1)
  ok  FACT: a Hungarian first_step removed                 rc=1 (expected 1)
  ok  FACT: a NEW app is not in the freeze                 rc=1 (expected 1)
  ok  FACT: an unknown key inside the English block        rc=1 (expected 1)
  ok  FACT: an English deploy field with no Hungarian twin rc=1 (expected 1)
  ok  FACT: an accented Hungarian letter left in the English rc=1 (expected 1)
  ok  FACT: ASCII-only Hungarian left in the English (no accent to find) rc=1 (expected 1)
  ok  FACT: the product begs ("please")                    rc=1 (expected 1)
  ok  FACT: an English retrieval promise the Hungarian never made rc=1 (expected 1)
  ok  GENUINE: a REGISTERED true retrieval promise passes  rc=0 (expected 0)
  ok  FACT: registered for ANOTHER app - the promise still convicts, the entry is stale rc=1 (expected 1)
  ok  FACT: registered on the path, but the sentence was rewritten (match gone) rc=1 (expected 1)
  ok  FACT: a STALE entry - nothing in the English promises it any more rc=1 (expected 1)
  ok  FACT: a registered promise with a two-word reason    rc=1 (expected 1)
  ok  FACT: a credential token rewritten in translation    rc=1 (expected 1)
  ok  FACT: a credential value reworded in translation (one digit added) rc=1 (expected 1)
  ok  FACT: an i18n block for a language the controller does not render rc=1 (expected 1)
  ok  FACT: an English list with a different number of steps rc=1 (expected 1)
  ok  FACT: ratchet — fewer strings translated than the ceiling records rc=1 (expected 1)
  ok  FACT: ratchet — more translated than the ceiling records rc=1 (expected 1)
  ok  GENUINE: a correct English block on privatebin       rc=0 (expected 0)
  ok  GENUINE: naming an app does not change the coverage count rc=0 (expected 0)
  ok  FACT(no-yaml): a Hungarian byte changed in a frozen string rc=1 (expected 1)
  ok  FACT(no-yaml): a frozen Hungarian line deleted       rc=1 (expected 1)
  ok  FACT(no-yaml): a NEW app is not in the freeze        rc=1 (expected 1)
  ok  GENUINE(no-yaml): the untouched tree passes, and SAYS what it did not check rc=0 (expected 0)
  ok  GENUINE(no-yaml): romm's escaped-quote help_texts are still found rc=0 (expected 0)
  ok  DECOY: Hungarian rewritten inside a YAML COMMENT     rc=0 (expected 0)
  ok  DECOY: a frozen Hungarian sentence pasted into README.md rc=0 (expected 0)
  ok  DECOY: display_name changed - a NAME, never copy     rc=0 (expected 0)
  ok  DECOY: docs_url changed - configuration, never copy  rc=0 (expected 0)
  ok  DECOY: Hungarian text added to a docker-compose.yml  rc=0 (expected 0)

-- probe-matches-compose: the facts (each MUST be refused)
  ok  FACT: tandoor's real R-618 port fault, re-introduced rc=1 (expected 1)
  ok  FACT: wger's real R-618 port fault, re-introduced    rc=1 (expected 1)
  ok  FACT: zipline's real R-618 path fault, re-introduced rc=1 (expected 1)
  ok  GENUINE: the fixed tree passes                       rc=0 (expected 0)
  ok  FACT: a clean app given a wrong probe port           rc=1 (expected 1)
  ok  FACT: api+expect probe given a path the app does not answer rc=1 (expected 1)
-- probe-matches-compose: the decoys (the label moves, the fact does not)
  ok  DECOY: the port moves in a COMMENT in .felhom.yml    rc=0 (expected 0)
  ok  DECOY: traefik loadbalancer.server.port changed      rc=0 (expected 0)
  ok  DECOY: a published `ports:` mapping changed          rc=0 (expected 0)
  ok  DECOY: a NON-probed sidecar's healthcheck port changed rc=0 (expected 0)
  ok  DECOY: path mismatch on a probe that CANNOT fail on it -> WARN, not FAIL rc=0 (expected 0)
-- probe-matches-compose: the DEGRADED mode CI actually runs (no PyYAML)
  ok  DEGRADED: the fixed tree passes, and SAYS it is degraded rc=0 (expected 0)
  ok  DEGRADED FACT: tandoor's port fault still refused    rc=1 (expected 1)
  ok  DEGRADED FACT: wger's port fault still refused       rc=1 (expected 1)
  ok  DEGRADED FACT: zipline's path fault still refused    rc=1 (expected 1)
  ok  DEGRADED DECOY: traefik label moves, the fact does not rc=0 (expected 0)
-- probe-matches-compose: the probe TARGET (R-630)
  ok  FACT: paperless-ngx without its explicit container is refused rc=1 (expected 1)
  ok  FACT: immich's FOUR prefix candidates are an ambiguity, not a pick rc=1 (expected 1)
  ok  FACT: an explicit container no service declares is refused rc=1 (expected 1)
  ok  GENUINE: both explicit containers resolve            rc=0 (expected 0)
  ok  DECOY: the container name moves in a COMMENT, not the field rc=0 (expected 0)
  ok  DECOY: a UNIQUE prefix still resolves without the field rc=0 (expected 0)
  ok  DEGRADED: the explicit container is read without PyYAML too rc=0 (expected 0)
  ok  DEGRADED FACT: removing it still refuses             rc=1 (expected 1)
-- test-record-move: an image move needs its own proven record
  ok  FACT: a bare image move, no entry                    rc=1 (expected 1)
  ok  GENUINE: a proven entry whose digest the registry serves rc=0 (expected 0)
  ok  FACT: the entry's verdict is failed                  rc=1 (expected 1)
  ok  FACT: the registry now serves another digest         rc=1 (expected 1)
  ok  INCONCLUSIVE: the registry cannot be asked           rc=2 (expected 2)
  ok  DECOY: the entry only in a COMMENT under update_ladder rc=1 (expected 1)
  ok  DECOY: the entry only in README.md                   rc=1 (expected 1)
  ok  FACT: a new move carrying a BACKFILLED entry         rc=1 (expected 1)
  ok  FACT: memory_tight and the limit did not move        rc=1 (expected 1)
  ok  GENUINE: memory_tight WITH the limit raised          rc=0 (expected 0)
  ok  DECOY: a ref moves in a compose COMMENT only         rc=0 (expected 0)
-- test-record (static): the newest step IS the compose
  ok  GENUINE: a ladder whose head is the compose          rc=0 (expected 0)
  ok  FACT: the compose moved past the ladder's head       rc=1 (expected 1)
  ok  FACT: a line that is not one JSON entry              rc=1 (expected 1)
  ok  FACT: a gap between steps                            rc=1 (expected 1)
  ok  FACT: a failed verdict sits in the ladder            rc=1 (expected 1)
-- test-record (static): every intermediate step carries its own definition
  ok  FACT: a two-step ladder with NO steps/ file for the first step rc=1 (expected 1)
  ok  GENUINE: a two-step ladder whose first step carries its definition rc=0 (expected 0)
  ok  DECOY: the steps/ file has the right NAME and names the head's image rc=1 (expected 1)
  ok  DECOY: the step's definition sits beside the template under another name rc=1 (expected 1)
  ok  FACT: the step has its compose but no .felhom.yml    rc=1 (expected 1)
  ok  DECOY: the step's .felhom.yml exists by NAME and holds no healthcheck rc=1 (expected 1)
-- test-record: a same-tag re-test (decision 52)
  ok  GENUINE: head + a re-test from its digest, both venues rc=0 (expected 0)
  ok  FACT: a re-test with NO new digest                   rc=1 (expected 1)
  ok  FACT: a re-test without the box venue                rc=1 (expected 1)
  ok  FACT: a re-test FROM a digest the previous entry never tested rc=1 (expected 1)
  ok  DECOY: a re-test that names digest_from only in its evidence text rc=1 (expected 1)
  ok  GENUINE: a re-test whose digest the registry serves now rc=0 (expected 0)
  ok  FACT: a re-test whose digest the registry no longer serves rc=1 (expected 1)
  ok  FACT: a re-test with no new digest reaches the move gate too rc=1 (expected 1)
  ok  probe-measured: genuine komga note passes            rc=0 (expected 0)
  ok  probe-measured: note moved into the TAGLINE          rc=1 (expected 1)
  ok  probe-measured: date but no before/after             rc=1 (expected 1)
  ok  probe-measured: before/after but no date             rc=1 (expected 1)
  ok  probe-measured: 'read upstream' is not a measurement rc=1 (expected 1)

-- copy-i18n: the user guide (each FACT must be refused, naming the key)
  ok  GENUINE: a full Hungarian guide with its English overlay rc=0 (expected 0)
  ok  FACT: guide strings that are not in the freeze       rc=1 (expected 1)
  ok  FACT: checked_version in the English block           rc=1 (expected 1)
  ok  FACT: a section with an empty steps list             rc=1 (expected 1)
  ok  FACT: an FAQ entry with a question and no answer     rc=1 (expected 1)
  ok  FACT: an unquoted checked_version (YAML reads 4.10 as 4.1) rc=1 (expected 1)
  ok  FACT: more English sections than Hungarian           rc=1 (expected 1)
  ok  FACT: an English section with a different step count rc=1 (expected 1)
  ok  FACT: an English guide with no Hungarian guide       rc=1 (expected 1)
  ok  FACT: a tracker named in an English step             rc=1 (expected 1)
  ok  FACT: a tracker named in a Hungarian answer (folded, any case) rc=1 (expected 1)
  ok  DECOY: a tracker named only in a YAML comment        rc=0 (expected 0)
  ok  DECOY: a source-like word only in docs_url (configuration) rc=0 (expected 0)

-- guide-version (ADVISORY: WARN on the fact, silent on the label, exit 0 always)
  ok  FACT: the app's image moved off the checked tag (4.0.20 -> 4.0.21) rc=0 (advisory)
  ok  GENUINE: the guide is current                        rc=0 (advisory)
  ok  DECOY: the checked tag survives only on a SIDECAR    rc=0 (advisory)
  ok  DECOY: checked_version only in a COMMENT             rc=0 (advisory)
  ok  DECOY: checked_version only inside the English block rc=0 (advisory)
  ok  FACT: an empty checked_version is HIDDEN and named   rc=0 (advisory)
  ok  image-pins: FACT: untagged                           rc=1 (expected 1)
  ok  image-pins: FACT: a registry PORT is not a tag       rc=1 (expected 1)
  ok  image-pins: FACT: quoted :latest                     rc=1 (expected 1)
  ok  image-pins: FACT: :LATEST in capitals                rc=1 (expected 1)
  ok  image-pins: FACT: a floating alias (:edge)           rc=1 (expected 1)
  ok  image-pins: FACT: untagged with a comment saying pinned rc=1 (expected 1)
  ok  image-pins: FACT: a QUOTED key is the same field     rc=1 (expected 1)
  ok  image-pins: FACT: an interpolated ref cannot be read rc=1 (expected 1)
  ok  image-pins: FACT: @sha256: with no digest behind it  rc=1 (expected 1)
  ok  image-pins: INERT: a commented-out untagged image    rc=0 (expected 0)
  ok  image-pins: INERT: an x- extension field (Compose ignores it) rc=0 (expected 0)
  ok  image-pins: INERT: an untagged image in README.md    rc=0 (expected 0)
  ok  image-pins: GENUINE: a concrete tag                  rc=0 (expected 0)
  ok  image-pins: GENUINE: a registry port WITH a tag      rc=0 (expected 0)
  ok  image-pins: GENUINE: a real digest                   rc=0 (expected 0)
  ok  image-pins: GENUINE: :latest pinned by its digest    rc=0 (expected 0)
  ok  image-pins: GENUINE: the real catalog                rc=0 (expected 0)
  ok  image-resolvable: GENUINE: every pin resolves        rc=0 (expected 0)
  ok  image-resolvable: FACT: the registry says one pin is gone rc=1 (expected 1)
  ok  image-resolvable: LABEL: rc=0 carrying a throttle message rc=2 (expected 2)
  ok  image-resolvable: LABEL: rc=0 carrying any error text rc=2 (expected 2)
  ok  image-resolvable: CRY-WOLF: a throttle on rc=1 is not an accusation rc=2 (expected 2)
  ok  image-resolvable: CRY-WOLF: an unrecognised failure is not an accusation rc=2 (expected 2)
  ok  image-resolvable: LABEL: a docker that resolves EVERYTHING, the canary too rc=3 (expected 3)
  ok  image-resolvable: LABEL: no docker at all            rc=2 (expected 2)
  ok  image-resolvable: LABEL: nothing to judge            rc=3 (expected 3)
  ok  volume-persistence: injected-prober suite            OK
  ok  volume-persistence: LABEL: a runtime that answers nothing rc=3 (expected 3)
  ok  volume-persistence: LABEL: no docker at all          rc=3 (expected 3)
  ok  volume-persistence: LABEL: nothing to judge          rc=3 (expected 3)
  ok  volume-persistence: LABEL: not a scratch host        rc=3 (expected 3)

-- onboarding: the facts (each MUST be refused)
  ok  FACT: a new template with NO record                  rc=1 (expected 1)
  ok  FACT: a record missing id 1.4                        rc=1 (expected 1)
  ok  FACT: 1.4 answered only inside an HTML comment       rc=1 (expected 1)
  ok  FACT: done with a path that does not exist           rc=1 (expected 1)
  ok  FACT: done with an EMPTY directory (the mkdir shape) rc=1 (expected 1)
  ok  FACT: done naming an absent file in the sibling repo rc=1 (expected 1)
  ok  FACT: n/a with an EMPTY reason                       rc=1 (expected 1)
  ok  FACT: n/a with a two-word reason                     rc=1 (expected 1)
  ok  FACT: an OPEN row                                    rc=1 (expected 1)
  ok  FACT: opened: backdated before the checklist         rc=1 (expected 1)
  ok  FACT: a checklist id the template a new app copies lacks rc=1 (expected 1)
  ok  FACT: an exempt app's record with a done that points nowhere rc=1 (expected 1)
-- onboarding: the genuine articles (each MUST pass)
  ok  GENUINE: a complete record (catalog + sibling evidence) rc=0 (expected 0)
  ok  GENUINE: an id added AFTER opened: does not bind     rc=0 (expected 0)
  ok  GENUINE: an exempt app's record may say open         rc=0 (expected 0)
  ok  STATED SKIP: sibling repo absent (the CI shape) - printed, not checked rc=0 (expected 0)

-- family-gate: genuine and decoys
  ok  GENUINE: a family app, literal exceptions, min 0.287.0, golden 0.287.0 rc=0 (expected 0)
  ok  DECOY: family_gate only in a COMMENT -> not gated, nothing owed        rc=0 (expected 0)
  ok  DECOY: no sibling -> rule 3 stated NOT CHECKED                         rc=0 (expected 0)
-- family-gate: the facts (each MUST be refused)
  ok  FACT: an exception that is a regex                                     rc=1 (expected 1)
  ok  FACT: the exception '/' (the whole app)                                rc=1 (expected 1)
  ok  FACT: an exception with '..'                                           rc=1 (expected 1)
  ok  FACT: an exception list with no gate                                   rc=1 (expected 1)
  ok  FACT: min_controller only in a comment                                 rc=1 (expected 1)
  ok  FACT: min_controller below the release                                 rc=1 (expected 1)
  ok  FACT: newest baked golden below the release                            rc=1 (expected 1)
  ok  FACT: a golden DIRECTORY 0.287.0 with no bake log (a name is not a bake) rc=1 (expected 1)
  ok  FACT: glance (ruled family-gated, decision 221) without family_gate    rc=1 (expected 1)
  ok  FACT: glance with family_gate only in a COMMENT (the label without the fact) rc=1 (expected 1)
  ok  FACT: grimmory (ruled, decisions 63/64) with family_gate: false        rc=1 (expected 1)
  ok  GENUINE: glance gated, no exceptions                                   rc=0 (expected 0)

-- mem-limit-sum: genuine and decoys
  ok  GENUINE: 384+256 = 640M, the field says 640M                           rc=0 (expected 0)
  ok  GENUINE: 1G is 1024M (1G + 256M = 1280M)                               rc=0 (expected 0)
  ok  DECOY: a steps/ file with an old figure is not judged                  rc=0 (expected 0)
-- mem-limit-sum: the facts (each MUST be refused)
  ok  FACT: the field under the sum; the right figure only in comments       rc=1 (expected 1)
  ok  FACT: reservations: memory makes nothing a limit (service w/o limit)   rc=1 (expected 1)
  ok  FACT: mem_limit only OUTSIDE resources: (top level) is no declaration  rc=1 (expected 1)
  ok  FACT: an unreadable size is INCONCLUSIVE, never a pass                 rc=2 (expected 2)

-- db-credentials: genuine and decoys
  ok  GENUINE + DECOYS: comment, app-service ref, redis, literal - all not judged rc=0 (expected 0)
-- db-credentials: the facts (each MUST be refused)
  ok  FACT: list form, the variable has no deploy field                      rc=1 (expected 1)
  ok  FACT: list form, fed by a `type: password` field                       rc=1 (expected 1)
  ok  FACT: map form, the variable has no deploy field                       rc=1 (expected 1)

-- data-key: genuine and decoys
  ok  GENUINE: a flagged *_ENCRYPTION_KEY; a signing key labelled 'Encryption key' unflagged; bookstack registered rc=0 (expected 0)
-- data-key: the facts (each MUST be refused)
  ok  FACT: the flag only in a COMMENT                                       rc=1 (expected 1)
  ok  FACT: the flag only inside the i18n: block                             rc=1 (expected 1)
  ok  FACT: a REGISTERED data key unflagged (bookstack APP_KEY)              rc=1 (expected 1)
  ok  FACT: an unexplained flag (a signing key flagged)                      rc=1 (expected 1)
  ok  FACT: a stale REGISTRY entry (bookstack has no APP_KEY any more)       rc=1 (expected 1)
  ok  FACT: a non-boolean flag is INCONCLUSIVE                               rc=2 (expected 2)

-- unclean-boot-images: genuine and decoys
  ok  GENUINE: the block lists the server's image                            rc=0 (expected 0)
  ok  GENUINE: bumped AND the list updated (flow list)                       rc=0 (expected 0)
  ok  GENUINE: bumped AND the list updated (block list)                      rc=0 (expected 0)
  ok  DECOY: the new image only in a compose COMMENT                         rc=0 (expected 0)
  ok  DECOY: ANOTHER service bumped (machine-learning)                       rc=0 (expected 0)
  ok  DECOY: the block COMMENTED OUT, server bumped (no block, nothing owed) rc=0 (expected 0)
  ok  DECOY: a template with no block                                        rc=0 (expected 0)
-- unclean-boot-images: the facts (each MUST be refused)
  ok  FACT: the server bumped, the list unchanged                            rc=1 (expected 1)
  ok  FACT: the same in a steps/ file (the ladder)                           rc=1 (expected 1)
  ok  FACT: the block names a service the compose does not run               rc=1 (expected 1)
  ok  FACT: the block lists no images                                        rc=1 (expected 1)

-- login-kind: genuine and decoys
  ok  GENUINE: login_kind first_visit                                        rc=0 (expected 0)
  ok  GENUINE: login_kind email                                              rc=0 (expected 0)
  ok  GENUINE: login_kind none                                               rc=0 (expected 0)
  ok  GENUINE: quoted value                                                  rc=0 (expected 0)
  ok  DECOY: a bad value only in a COMMENT                                   rc=0 (expected 0)
  ok  DECOY: a bad value only in the English block                           rc=0 (expected 0)
  ok  DECOY: the key under ANOTHER mapping                                   rc=0 (expected 0)
-- login-kind: the facts (each MUST be refused)
  ok  FACT: an unknown value                                                 rc=1 (expected 1)
  ok  FACT: a wrong case                                                     rc=1 (expected 1)
  ok  FACT: the key twice                                                    rc=1 (expected 1)
  ok  FACT: no templates/ at all (nothing to judge)                          rc=3 (expected 3)

-- image-volumes: genuine
  ok  GENUINE: a named volume AT /romm/assets                                rc=0 (expected 0)
  ok  GENUINE: a bind AT /romm/assets, quoted                                rc=0 (expected 0)
  ok  GENUINE: an image not in the registry is not judged                    rc=0 (expected 0)
-- image-volumes: decoys and facts (each MUST be refused)
  ok  DECOY: the mount only in a COMMENT                                     rc=1 (expected 1)
  ok  DECOY: the mount on ANOTHER service                                    rc=1 (expected 1)
  ok  DECOY: the PARENT /romm mounted                                        rc=1 (expected 1)
  ok  DECOY: a CHILD /romm/assets/x mounted                                  rc=1 (expected 1)
  ok  DECOY: only a top-level volume, never mounted                          rc=1 (expected 1)
  ok  FACT: a steps/ file without it                                         rc=1 (expected 1)
  ok  FACT: no templates/ at all (nothing to judge)                          rc=3 (expected 3)

-- redis-persistence: genuine and decoys (each passes)
  ok  GENUINE: --appendonly no                                               rc=0 (expected 0)
  ok  GENUINE: no command (the image default is RDB)                         rc=0 (expected 0)
  ok  DECOY: --appendonly yes only in a COMMENT                              rc=0 (expected 0)
  ok  DECOY: AOF only in a steps/ file (a tested step, not judged)           rc=0 (expected 0)
-- redis-persistence: the facts (each MUST be refused)
  ok  FACT: AOF in string form                                               rc=1 (expected 1)
  ok  FACT: AOF in a flow list                                               rc=1 (expected 1)
  ok  FACT: AOF in a block list                                              rc=1 (expected 1)
  ok  FACT: AOF on a valkey image                                            rc=1 (expected 1)
  ok  FACT: no templates/ at all (nothing to judge)                          rc=3 (expected 3)

catalog gate decoys OK — 252 case(s), every label judged on its fact (R-421)
rc=0
