=== R-760 red-proof (2026-10-05T18:53:44+02:00) — catalog 29ac711 + working tree
--- UNDO: remove the R-760 '# No healthcheck' comment block from templates/vikunja/docker-compose.yml
$ python3 scripts/test_healthcheck_explained.py
+ [] : service(s) with no compose healthcheck and no '# No healthcheck' comment saying why: ['vikunja/vikunja']

----------------------------------------------------------------------
Ran 2 tests in 0.011s

FAILED (failures=1)
rc=1
--- RESTORE
$ python3 scripts/test_healthcheck_explained.py
Ran 2 tests in 0.011s

OK
rc=0

=== R-593 red-proof (2026-10-05T18:55:00+02:00) — catalog 29ac711 + working tree
--- UNDO: git show HEAD:templates/papra/.felhom.yml > templates/papra/.felhom.yml  (the pre-fix papra .felhom.yml)
$ python3 scripts/test_deploy_field_descriptions.py
- ['papra SUBDOMAIN has no description',
-  'papra AUTH_SECRET carries the subdomain sentence',
-  'papra SUBDOMAIN has no description'] : ['papra SUBDOMAIN has no description', 'papra AUTH_SECRET carries the subdomain sentence', 'papra SUBDOMAIN has no description']

----------------------------------------------------------------------
Ran 2 tests in 0.025s

FAILED (failures=1)
rc=1
--- RESTORE
$ python3 scripts/test_deploy_field_descriptions.py
Ran 2 tests in 0.025s

OK
rc=0

=== R-781 red-proof (2026-10-05T18:55:52+02:00) — catalog 29ac711 + working tree
--- UNDO: drop the isolate_onboarding_clone(cat) call in onboarding_cases (the pre-fix harness)
1
$ python3 <runner calling test_gate_decoys.onboarding_cases() only — the whole file also reaches a registry>
  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)
FAILS 4
FAIL: GENUINE: a complete record (catalog + sibling evidence): rc=1 expected 0; missing ['onboarding gate OK']
FAIL: GENUINE: an id added AFTER opened: does not bind: rc=1 expected 0; missing ['onboarding gate OK']
FAIL: GENUINE: an exempt app's record may say open: rc=1 expected 0; missing ['exempt app(s) with a record (shape-checked): wger']
FAIL: STATED SKIP: sibling repo absent (the CI shape) - printed, not checked: rc=0 expected 0; missing ['felhom.eu/documentation/audits/onb/
rc=1
--- RESTORE
  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)
FAILS 0
rc=0

=== R-806 red-proof (2026-10-05T18:56:53+02:00) — catalog 29ac711 + working tree
--- UNDO: exercise_argv back to the pre-fix shape (always http://, no -k) — the old inline argv
578:        pass  # red-proof: no -k
581:    return a + [f"http://{ip}:{port}{path}"]
$ python3 scripts/test_check_volume_persistence.py
FAIL: test_https_backend_gets_an_https_url_with_k (__main__.TestRoutedSchemes.test_https_backend_gets_an_https_url_with_k)
AssertionError: 'http://10.0.0.5:8443/' != 'https://10.0.0.5:8443/'
Ran 54 tests in 0.018s
FAILED (failures=1)
rc=1
--- RESTORE
Ran 54 tests in 0.018s

OK
rc=0

=== R-605 red-proof (2026-10-05T18:58:47+02:00) — catalog 29ac711 + working tree
--- UNDO: HARNESS_REFUSED = 2 in both gates (the pre-fix shared code); runner: rc 3 folded back into UNDETERMINED
scripts/check-image-resolvable.py:166:HARNESS_REFUSED = 2
scripts/check-volume-persistence.py:935:HARNESS_REFUSED = 2
124:VERDICT = {0: "OK", 1: "FAILED", 2: "INCONCLUSIVE"}
220:    refused = []  # red-proof
$ python3 scripts/test_check_volume_persistence.py
FAIL: test_canary_failure_prints_the_harness_refused_marker (__main__.TestCheckEntryPoint.test_canary_failure_prints_the_harness_refused_marker)
AssertionError: 2 != 3
Ran 55 tests in 0.017s
FAILED (failures=1)
rc=1
$ python3 scripts/test_check_image_resolvable.py
Ran 19 tests in 0.011s
OK
rc=0
$ python3 -m unittest scripts/test_catalog_gates.py SummaryTellsRefusedFromUndecided
FAIL: test_a_refused_harness_does_not_read_as_undetermined (test_catalog_gates.SummaryTellsRefusedFromUndecided.test_a_refused_harness_does_not_read_as_undetermined)
AssertionError: 'DID-NOT-RUN' not found in '\n==============================================================================\n== summary\n==============================================================================\n  image-pins           OK            (exit 0)\n  volume-persistence   ERROR         (exit 3)\nUNDETERMINED (it ran; some results could not be decided — never a pass): volume-persistence\n'
Ran 3 tests in 0.004s
FAILED (failures=1)
rc=1
--- RESTORE
$ python3 scripts/test_check_volume_persistence.py
Ran 55 tests in 0.018s
OK
rc=0
$ python3 scripts/test_check_image_resolvable.py
Ran 19 tests in 0.011s
OK
rc=0
Ran 3 tests in 0.003s
OK
rc=0

=== R-605 red-proof, image-resolvable leg re-run (2026-10-05T18:58:59+02:00) — the first run above passed because the test compared against the constant itself (tautology); the tests now pin the literal 3
--- UNDO: HARNESS_REFUSED = 2 in check-image-resolvable.py
$ python3 scripts/test_check_image_resolvable.py
FAIL: test_empty_catalog_is_an_error_not_a_pass (__main__.TestResolvabilityGate.test_empty_catalog_is_an_error_not_a_pass)
AssertionError: 2 != 3
FAIL: test_untrustworthy_resolver_refuses_to_report (__main__.TestResolvabilityGate.test_untrustworthy_resolver_refuses_to_report)
AssertionError: 2 != 3 : a resolver that resolves the canary must abort (3, the harness refused), not pass — and not 2, which reads as 'some pins were throttled' (R-605)
Ran 19 tests in 0.013s
FAILED (failures=2)
rc=1
--- RESTORE
Ran 19 tests in 0.012s
FAILED (failures=2)
rc=1

--- NOTE: the RESTORE above still failed because scripts/__pycache__ held the UNDONE module's bytecode: the undo
    (3 -> 2) kept the file's size and the restore landed in the same second, so Python's mtime+size cache check
    accepted the stale .pyc. Restored source confirmed HARNESS_REFUSED = 3; after `touch scripts/check-image-resolvable.py`:
$ python3 scripts/test_check_image_resolvable.py
Ran 19 tests in 0.011s
OK
rc=0
    (lesson for same-size red-proofs: run with PYTHONDONTWRITEBYTECODE=1 / clear __pycache__ between undo and restore)

=== R-594 red-proof (2026-10-05T19:01:53+02:00) — catalog 29ac711 + working tree (PYTHONDONTWRITEBYTECODE=1)
--- UNDO 1: the register is read but never consulted (reg = None) — the pre-fix gate's behaviour
1
$ python3 scripts/test_gate_decoys.py
  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: n/a with a two-word reason                     rc=1 (expected 1)
FAIL: GENUINE: a REGISTERED true retrieval promise passes: rc=1 expected 0; missing ['copy-i18n: OK', '1 registered retrieval promise(s) in ALLOWLIST_EN, 1 used
rc=1
--- UNDO 2: the STALE check removed (entries never judged live)
1
$ python3 scripts/test_gate_decoys.py
  ok  GENUINE: a REGISTERED true retrieval promise passes  rc=0 (expected 0)
  ok  FACT: a registered promise with a two-word reason    rc=1 (expected 1)
  ok  FACT: n/a with a two-word reason                     rc=1 (expected 1)
FAIL: FACT: registered for ANOTHER app - the promise still convicts, the entry is stale: rc=1 expected 1; missing ['STALE entry vaultwarden']
FAIL: FACT: registered on the path, but the sentence was rewritten (match gone): rc=1 expected 1; missing ['STALE entry privatebin']
FAIL: FACT: a STALE entry - nothing in the English promises it any more: rc=0 expected 1; missing ['STALE entry privatebin']
rc=1
--- RESTORE
$ python3 scripts/test_gate_decoys.py
  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: n/a with a two-word reason                     rc=1 (expected 1)
catalog gate decoys OK — 137 case(s), every label judged on its fact (R-421)
rc=0

