R-426: volume-persistence decoys - the injected-prober suite run from here, and a dead runtime end to end

test_gate_decoys.py runs test_check_volume_persistence.py (the blind and
crying-wolf probers refused rc=3, `wrote nothing` never CLEAN, the papra
signature convicted) and requires it green, so COVERS is a fact; and runs
the working-tree gate in a scratch catalog with PATH = ONLY a stub docker
that fails every call: a runtime that answers nothing, no docker, nothing
to judge are each HARNESS REFUSED rc=3, never 0. An always-succeeding stub
is deliberately not used - it would walk the prober into the host
filesystem. COVERS gains "volume-persistence".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-06 01:40:43 +02:00
parent 31d4f4e6de
commit 979ababb8f
+71
View File
@@ -47,6 +47,7 @@ ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Read by felhom.eu/scripts/decoy_coverage_gate.py, which AST-parses this literal. A gate named here
# MUST have a decoy below that has been seen to fail.
COVERS = {
"volume-persistence": "the classifier and the self-test via the injected-prober suite scripts/test_check_volume_persistence.py, RUN FROM HERE and required green (a blind prober and a crying-wolf prober are refused rc=3; `wrote nothing`, a container not running, a path token alone, an unresolved suspect are UNDETERMINED or clean, never a false CLEAN/BROKEN; the papra signature convicts); and END TO END with a PATH-STUB docker that fails every call, no docker at all, nothing to judge - each HARNESS REFUSED rc=3, never 0 (R-426)",
"image-resolvable": "END TO END through the gate's own `docker manifest inspect` call, with a PATH-STUB docker (PATH holds ONLY the stub, so the real runtime is unreachable): the label of success without the fact - rc=0 carrying a throttle or any error text, a docker that resolves EVERYTHING incl. the .invalid canary, no docker at all, nothing to judge - each INCONCLUSIVE or HARNESS REFUSED, never 0; the cry-wolf direction - a throttle or an unrecognised error on rc=1 is never an accusation; vs a registry that positively says `manifest unknown` (convicted, naming the app) and a clean run (R-426)",
"image-pins": "the pin's LABEL without the pin: a registry PORT (`:5000`) read as a tag, `@sha256:` with no digest behind it, a QUOTED `\"image\":` key, an interpolated `${APP_IMAGE:-nginx}`, `:LATEST`/`:latest` in quotes - vs the inert shapes that must pass (a commented `# image: nginx`, an `x-image:` extension field, a README line) and the genuine pins (a tag, a real 64-hex digest, `:latest@sha256:` pinned by its digest, a port with a tag) (R-426)",
"engine-major": "the major moved in a comment/env var/README/app image, not on an engine's image: line",
@@ -836,6 +837,75 @@ def image_resolvable_cases():
shutil.rmtree(ws, ignore_errors=True)
FAIL_DOCKER = """#!%s
# PATH-stub docker for the volume-persistence decoys: a host whose runtime answers nothing. Every call fails.
import sys
sys.stderr.write("Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?\\n")
sys.exit(1)
"""
def volume_persistence_cases():
"""check-volume-persistence.py (R-426). Two halves.
1. Its classifier and self-test are pure and already fixture-tested with an INJECTED prober — the blind prober,
the crying-wolf prober, `wrote nothing`, the papra signature. Those ARE decoys; this suite runs that file and
requires it green, so the COVERS line above is a fact and not a label (felhom.eu's guide-quote precedent).
2. End to end, the working-tree script copied into a scratch catalog and run with PATH = ONLY a stub docker. The
stub FAILS every call, so the gate stops at its canary build and nothing — no compose, no container, no
volume — is ever created; an always-succeeding stub is deliberately NOT used, because it would walk the
prober into the host filesystem. The real docker acts on DooPlex and cannot be reached from here.
"""
global ran
ran += 1
r = subprocess.run([sys.executable, os.path.join(ROOT, "scripts", "test_check_volume_persistence.py")],
cwd=ROOT, capture_output=True, text=True, input="")
tail = (r.stdout + r.stderr).strip().splitlines()
if r.returncode != 0:
fails.append("volume-persistence: its injected-prober decoy suite FAILED rc=%d\n%s"
% (r.returncode, "\n".join(tail[-25:])))
else:
print(" ok %-52s %s" % ("volume-persistence: injected-prober suite", tail[-1] if tail else "?"))
ws = tempfile.mkdtemp(prefix="catalog-volpersist-")
try:
stub = os.path.join(ws, "stubbin")
os.makedirs(stub)
io.open(os.path.join(stub, "docker"), "w", encoding="utf-8").write(FAIL_DOCKER % sys.executable)
os.chmod(os.path.join(stub, "docker"), 0o755)
empty = os.path.join(ws, "nobin")
os.makedirs(empty)
def run(name, expect_rc, must=(), path=stub, templates=True):
global ran
cat = os.path.join(ws, "cat")
shutil.rmtree(cat, ignore_errors=True)
os.makedirs(os.path.join(cat, "scripts"))
shutil.copy(os.path.join(ROOT, "scripts", "check-volume-persistence.py"), os.path.join(cat, "scripts"))
if templates:
d = os.path.join(cat, "templates", "demo")
os.makedirs(d)
io.open(os.path.join(d, "docker-compose.yml"), "w", encoding="utf-8").write(
"services:\n demo:\n image: example.org/demo:1.0\n volumes:\n - demo_data:/data\n"
"volumes:\n demo_data:\n")
r = subprocess.run([sys.executable, os.path.join(cat, "scripts", "check-volume-persistence.py")],
cwd=cat, env={"PATH": path}, capture_output=True, text=True, input="", timeout=300)
out = r.stdout + r.stderr
ran += 1
miss = [m for m in must if m not in out]
if r.returncode == expect_rc and not miss:
print(" ok %-52s rc=%d (expected %d)" % ("volume-persistence: " + name, r.returncode, expect_rc))
else:
fails.append("volume-persistence: %s: rc=%d expected %d%s; missing %s\n%s" % (
name, r.returncode, expect_rc, " - LIVE HOLE" if r.returncode == 0 else "", miss, out[-600:]))
run("LABEL: a runtime that answers nothing", 3, ("HARNESS REFUSED", "failed its canary"))
run("LABEL: no docker at all", 3, ("HARNESS REFUSED",), path=empty)
run("LABEL: nothing to judge", 3, ("HARNESS REFUSED",), templates=False)
finally:
shutil.rmtree(ws, ignore_errors=True)
def mem_sum_cases():
"""check-mem-limit-sum.py reads FILES: templates/*/docker-compose.yml + .felhom.yml, via --root (R-758)."""
global ran
@@ -1461,6 +1531,7 @@ i18n:
image_pins_cases()
image_resolvable_cases()
volume_persistence_cases()
onboarding_cases()
family_gate_cases()
mem_sum_cases()