R-404: the golden NOTICE, in the repo where the debt is created - NOT A RELEASE
gates / gates (push) Successful in 12s

No version heading on purpose. No Go code, no image, no version bump; giving this one would create
the exact golden debt the change is about.

Until today this repo - where a release actually happens - had NO golden-currency check at all,
while felhom.eu ran one on every push including documents-only ones that can neither create the
debt nor clear it. The person who could act heard nothing; the person who could not act was
blocked, thirteen --no-verify uses' worth.

golden_notice.py is ADVISORY IN EVERY CASE, and that is the only correct behaviour rather than
timidity: at the moment a release is committed the golden legitimately does not exist yet, so
blocking there would refuse the commit that STARTS the process - and blocking later is the mistake
being undone.

NO SECOND IMPLEMENTATION: it IMPORTS felhom.eu/scripts/golden_currency_gate.py and calls that
gate's own released_versions()/newest_baked(), so it is the same comparison read in the other
direction. Cross-repo shape copied from instructions_gate.py; never a copy of the script, because a
copy recreates the drift these gates exist to detect. An absent sibling clone is INCONCLUSIVE and
silent about currency - it never guesses.

controller_gates.py GAINED A FIFTH `blocking` FIELD. It could not express a reporting-only gate at
all before: every registered gate's non-zero exit failed the run, so the only way to add a notice
was to give it the power to refuse a push. The capability was added rather than the notice
compromised (R-420). False for exactly one gate, and test_golden_notice.py asserts it stays one.

Tests N1-N4 with a positive control that every other gate is still blocking. RED-PROOF RUN: making
the debt branch return 1 fails N1 - in production that would refuse the commit that starts a
release.
This commit is contained in:
2026-09-01 12:01:26 +02:00
parent a017367f9f
commit a4444088ad
6 changed files with 575 additions and 226 deletions
+39 -18
View File
@@ -52,28 +52,44 @@ SHARED_INSTRUCTIONS = os.path.join(
SHARED_OBSERVATIONS = os.path.join(
os.path.dirname(REPO), "felhom.eu", "scripts", "observations_gate.py")
# (label, absolute script path, args, fast)
# R-404 — the golden NOTICE. Lives here, beside the runner, because it is about THIS repo's
# releases; it imports the felhom.eu gate rather than copying its comparison.
GOLDEN_NOTICE = os.path.join(SCRIPTS, "golden_notice.py")
# (label, absolute script path, args, fast, blocking)
#
# `blocking` — R-404, 2026-09-01. FALSE means this gate REPORTS and never changes the runner's exit
# code. Before this the runner could not express such a gate at all: every registered gate's
# non-zero exit failed the run, so the only way to add a notice was to give it the power to refuse
# a push. That was the wrong trade for the golden notice, whose whole point is that it fires at the
# moment a release is committed — when the golden legitimately does not exist yet and refusing
# would be absurd. The capability was added rather than the notice compromised.
#
# It is FALSE for exactly one gate. Everything else blocks, as it always has.
GATES = [
("template-id", os.path.join(SCRIPTS, "template_id_gate.py"), [], True),
("emoji", os.path.join(SCRIPTS, "emoji_gate.py"), [], True),
("native-confirm", os.path.join(SCRIPTS, "native_confirm_gate.py"), [], True),
("offbox-rename", os.path.join(SCRIPTS, "offbox_rename_gate.py"), [], True),
("app-row-dedup", os.path.join(SCRIPTS, "app_row_dedup_gate.py"), [], True),
("mojibake", os.path.join(SCRIPTS, "mojibake_gate.py"), [], True),
("docker-v", os.path.join(SCRIPTS, "docker_run_volume_path_gate.py"), [], True),
("secret-markup", os.path.join(SCRIPTS, "secret_in_markup_gate.py"), [], True),
("retrieval-promise", os.path.join(SCRIPTS, "retrieval_promise_gate.py"), [], True),
("template-id", os.path.join(SCRIPTS, "template_id_gate.py"), [], True, True),
("emoji", os.path.join(SCRIPTS, "emoji_gate.py"), [], True, True),
("native-confirm", os.path.join(SCRIPTS, "native_confirm_gate.py"), [], True, True),
("offbox-rename", os.path.join(SCRIPTS, "offbox_rename_gate.py"), [], True, True),
("app-row-dedup", os.path.join(SCRIPTS, "app_row_dedup_gate.py"), [], True, True),
("mojibake", os.path.join(SCRIPTS, "mojibake_gate.py"), [], True, True),
("docker-v", os.path.join(SCRIPTS, "docker_run_volume_path_gate.py"), [], True, True),
("secret-markup", os.path.join(SCRIPTS, "secret_in_markup_gate.py"), [], True, True),
("retrieval-promise", os.path.join(SCRIPTS, "retrieval_promise_gate.py"), [], True, True),
# R-400 — every debug-page control resolves to a handler, and every handler is reachable.
# Registered AFTER the seven dead controls were implemented or deleted: a registered-but-failing
# gate refuses every push, so the order matters here exactly as it did for instructions_gate.
("debug-routes", os.path.join(SCRIPTS, "debug_route_gate.py"), [], True),
("reuse-refs", SHARED_REUSE, [REPO], True),
("instructions", SHARED_INSTRUCTIONS, [REPO], True),
("debug-routes", os.path.join(SCRIPTS, "debug_route_gate.py"), [], True, True),
("reuse-refs", SHARED_REUSE, [REPO], True, True),
("instructions", SHARED_INSTRUCTIONS, [REPO], True, True),
# R-389 — a REPORT.md observation with no register row behind it. Fast: stdlib file reads.
("observations", SHARED_OBSERVATIONS, [REPO], True),
("observations", SHARED_OBSERVATIONS, [REPO], True, True),
# R-404 — ADVISORY. Reports the golden debt where it is created; never refuses.
("golden-notice", GOLDEN_NOTICE, [REPO], True, False),
]
VERDICT = {0: "OK", 1: "FAILED", 2: "INCONCLUSIVE"}
ADVISORY = "ADVISORY" # R-404: a non-blocking gate — it reports, it never refuses
def hooks_armed_note(root):
@@ -124,21 +140,26 @@ def main(argv):
print(" --fast SKIPPED (deliberate periodic runs, never in a hook): %s" % ", ".join(skipped))
hooks_armed_note(REPO)
results = [(label, run_gate(label, path, args)) for label, path, args, _f in selected]
results = [(label, run_gate(label, path, args), blocking)
for label, path, args, _f, blocking in selected]
print("\n" + "=" * 78)
print("== summary")
print("=" * 78)
worst = 0
for label, rc in results:
for label, rc, blocking in results:
if not blocking:
# A non-blocking gate's exit code is INFORMATION, never a verdict on the push.
print(" %-18s %-13s (exit %d, advisory)" % (label, ADVISORY, rc))
continue
print(" %-18s %-13s (exit %d)" % (label, VERDICT.get(rc, "ERROR"), rc))
if rc != 0:
worst = 1 if rc == 1 or worst == 1 else 2
if worst == 0:
print("\nall controller gates OK")
return 0
convicted = [l for l, rc in results if rc == 1]
undecided = [l for l, rc in results if rc not in (0, 1)]
convicted = [l for l, rc, b in results if rc == 1 and b]
undecided = [l for l, rc, b in results if rc not in (0, 1) and b]
if convicted:
print("\nCONVICTED: %s" % ", ".join(convicted))
if undecided:
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""golden_notice.py — tell the repo that CREATES the golden debt, at the moment it creates it.
Usage: python3 scripts/golden_notice.py <repo-root>
Exit ALWAYS 0 when it can answer, 2 when it cannot. **NEVER 1. It cannot refuse a push.**
WHY THIS EXISTS (R-404, 2026-09-01).
The golden-currency check was pointed at the wrong repository. `felhom.eu` — which holds the bake
evidence, the register and the architecture — ran it on every push, including pushes that touch only
documents and therefore can neither create the debt nor clear it. `felhom-controller` — where a
release actually happens — **never checked at all.** So the person who could act heard nothing and
the person who could not act was blocked, and `--no-verify` was reached for thirteen times.
This is the other half of that correction: the notice belongs where the debt is born.
⚠ IT IS ADVISORY IN EVERY CASE, AND THAT IS NOT TIMIDITY — IT IS THE ONLY CORRECT BEHAVIOUR.
At the moment a release is committed the golden legitimately does NOT exist yet: you cannot bake a
golden for a version you have not pushed. Blocking here would refuse the very commit that starts the
process. And blocking LATER is the mistake this whole change is undoing. So it prints, and the
runner's exit code is untouched. `controller_gates.py` gained a `blocking` field to express that;
before this, that runner could not describe a gate that reports without refusing.
⚠ IT NEVER GUESSES. With no `felhom.eu` sibling clone it says INCONCLUSIVE and stays silent about
currency — an absent input is "I do not know", never "fine".
NO SECOND IMPLEMENTATION. It IMPORTS `felhom.eu/scripts/golden_currency_gate.py` and calls that
gate's own `released_versions()` and `newest_baked()`, so the comparison here is the SAME
comparison, read in the other direction. A private copy of "which version owes a golden" is a second
thing that can be wrong, and the two would drift. This follows `instructions_gate.py`'s cross-repo
pattern: the shared script lives in ONE repo and is invoked across the workspace, never copied.
"""
import importlib.util
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
CTRL = os.path.dirname(HERE)
REPO_DEFAULT = os.path.dirname(CTRL)
def load_gate(repo_root):
"""Import the sibling felhom.eu gate. Returns (module, tried_path) or (None, tried_path)."""
path = os.path.join(os.path.dirname(repo_root), "felhom.eu", "scripts",
"golden_currency_gate.py")
if not os.path.isfile(path):
return None, path
try:
spec = importlib.util.spec_from_file_location("golden_currency_gate", path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod, path
except Exception as e:
sys.stdout.write("golden-notice: the sibling gate could not be imported: %s\n" % e)
return None, path
def main(argv):
repo_root = os.path.abspath(argv[1]) if len(argv) > 1 else REPO_DEFAULT
gate, tried = load_gate(repo_root)
if gate is None:
print("golden-notice: INCONCLUSIVE — no felhom.eu sibling clone.")
print(" tried: %s" % tried)
print(" Nothing is claimed about golden currency. An absent input is 'I do not know',")
print(" never 'fine'. This is still NOT a refusal — it never blocks a push.")
return 2
try:
released = gate.released_versions()
baked = gate.newest_baked()
except Exception as e:
print("golden-notice: INCONCLUSIVE — the sibling gate raised %s" % e)
return 2
# `released_versions()` returns newest-first; `newest_baked()` returns the newest bake.
newest_rel = released[0] if released else None
newest_bake = baked[0] if isinstance(baked, tuple) else baked
if newest_rel is None:
print("golden-notice: INCONCLUSIVE — could not read a released version from CHANGELOG.md.")
return 2
rel_s = gate.vstr(newest_rel)
bake_s = gate.vstr(newest_bake) if newest_bake else "none"
if newest_bake and tuple(newest_bake) >= tuple(newest_rel):
print("golden-notice: OK — v%s is released and a golden carries it (newest bake %s)."
% (rel_s, bake_s))
return 0
# The debt exists. Say so plainly, and say what clears it.
print("=" * 78)
print("NOTICE — v%s OWES A GOLDEN. (this NEVER blocks; see the docstring)" % rel_s)
print("=" * 78)
print(" newest released controller : %s (this repo's CHANGELOG.md)" % rel_s)
print(" newest golden baked : %s (felhom.eu documentation/tests/)" % bake_s)
print("")
print(" A machine installed right now would receive %s, not %s." % (bake_s, rel_s))
print("")
print(" This is a REMINDER AT THE ONE MOMENT IT IS USEFUL — you are in the repo where the")
print(" release happens. It does not block, and must not: at the moment a release is")
print(" committed the golden cannot exist yet.")
print("")
print(" WHAT CLEARS IT: bake a golden (felhom.eu documentation/runbooks/RUNBOOK-manual-build.md")
print(" section 4.1), then vouch it — a THREE-field change: golden_version + agent_version +")
print(" min_agent. The bake record lands in felhom.eu documentation/tests/golden-<ver>-<date>/.")
print("")
print(" If this release deliberately needs no golden, record a waiver row in")
print(" felhom.eu documentation/backlog/OPEN-ITEMS.md — never a habit of bypassing.")
print("=" * 78)
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))
+157
View File
@@ -0,0 +1,157 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""test_golden_notice.py — the notice REPORTS and never REFUSES (R-404).
N1 IS THE LOAD-BEARING CASE. The notice's value depends entirely on it being harmless: it fires at
the moment a release is committed, when the golden legitimately cannot exist yet. A notice that
blocked there would refuse the very commit that starts the process, and would be disabled within a
day. Its red-proof is written out below and was run.
Run from `controller/`: python3 scripts/test_golden_notice.py
Exit 0 all pass · 1 a case failed.
"""
import io
import os
import shutil
import subprocess
import sys
import tempfile
HERE = os.path.dirname(os.path.abspath(__file__))
CTRL = os.path.dirname(HERE)
REPO = os.path.dirname(CTRL)
NOTICE = os.path.join(HERE, "golden_notice.py")
SHA = "9287f7cef5f13166276e8406005e3f28004004510c5184f1c1c7377f7aafad2e"
def run(repo_root):
p = subprocess.run([sys.executable, NOTICE, repo_root], capture_output=True, text=True)
return p.returncode, p.stdout + p.stderr
def fake_workspace(tmp, released, baked):
"""A miniature workspace: <tmp>/felhom-controller + <tmp>/felhom.eu, only what the gate reads."""
ctrl = os.path.join(tmp, "felhom-controller")
eu = os.path.join(tmp, "felhom.eu")
os.makedirs(ctrl)
os.makedirs(os.path.join(eu, "scripts"))
tests = os.path.join(eu, "documentation", "tests")
os.makedirs(tests)
with io.open(os.path.join(ctrl, "CHANGELOG.md"), "w", encoding="utf-8") as fh:
fh.write(u"# changelog\n\n## v%s — a release\n\nstuff\n" % released)
# the real gate, copied in so the notice imports a genuine one
shutil.copy(os.path.join(os.path.dirname(REPO), "felhom.eu", "scripts",
"golden_currency_gate.py"),
os.path.join(eu, "scripts", "golden_currency_gate.py"))
if baked:
d = os.path.join(tests, "golden-%s-2026-01-01" % baked)
os.makedirs(d)
with io.open(os.path.join(d, "bake.log"), "w", encoding="utf-8") as fh:
fh.write(u"[golden] upload OK\nGOLDEN_VERSION=%s\nGOLDEN_SHA256=%s\n" % (baked, SHA))
return ctrl
def main():
fails = []
# --- N1: a version with no golden -> the notice PRINTS, exit code UNCHANGED (0) -----------
# RED-PROOF (run 2026-09-01, recorded in REPORT.md): changing the debt branch's `return 0` to
# `return 1` makes this fail — and in production would refuse the commit that starts a release.
tmp = tempfile.mkdtemp(prefix="gnotice-")
try:
ctrl = fake_workspace(tmp, "0.240.0", "0.230.0")
rc, out = run(ctrl)
if rc != 0:
fails.append("N1: a debt must NOT change the exit code — the notice fires when the "
"golden cannot exist yet, so blocking there refuses the commit that "
"starts the release. Got exit %d" % rc)
elif "0.240.0" not in out or "OWES A GOLDEN" not in out:
fails.append("N1: the notice must NAME the version that owes a golden; got:\n%s" % out)
elif "0.230.0" not in out:
fails.append("N1: the notice must also say which golden IS current; got:\n%s" % out)
else:
print("N1 ok: debt named (0.240.0 owes; newest bake 0.230.0), exit 0 - never blocks")
finally:
shutil.rmtree(tmp, ignore_errors=True)
# --- N2: sibling clone absent -> INCONCLUSIVE, silent about currency, still non-blocking ---
tmp = tempfile.mkdtemp(prefix="gnotice-")
try:
lonely = os.path.join(tmp, "felhom-controller")
os.makedirs(lonely)
rc, out = run(lonely)
if rc != 2:
fails.append("N2: an absent sibling must be INCONCLUSIVE (exit 2), never a pass and "
"never a conviction; got %d" % rc)
elif "OWES A GOLDEN" in out or "OK —" in out:
fails.append("N2: with no sibling it must stay SILENT about currency; got:\n%s" % out)
elif "INCONCLUSIVE" not in out:
fails.append("N2: it must say INCONCLUSIVE out loud; got:\n%s" % out)
else:
print("N2 ok: absent sibling -> INCONCLUSIVE, silent about currency, exit 2")
# and exit 2 must still not fail the runner, because the gate is registered non-blocking
import importlib.util
spec = importlib.util.spec_from_file_location(
"cg", os.path.join(HERE, "controller_gates.py"))
cg = importlib.util.module_from_spec(spec)
spec.loader.exec_module(cg)
row = [g for g in cg.GATES if g[0] == "golden-notice"]
if not row:
fails.append("N2: golden-notice is not registered in controller_gates.py at all")
elif row[0][4] is not False:
fails.append("N2: golden-notice must be registered NON-BLOCKING (5th field False); "
"got %r" % (row[0][4],))
else:
print("N2 ok: registered non-blocking, so exit 2 cannot fail the runner")
# POSITIVE CONTROL: every OTHER gate must still be blocking, or this proves nothing.
nonblocking = [g[0] for g in cg.GATES if g[4] is False]
if nonblocking != ["golden-notice"]:
fails.append("N2 CONTROL: exactly ONE gate may be non-blocking; got %r" % nonblocking)
else:
print("N2 ok (control): golden-notice is the ONLY non-blocking gate")
finally:
shutil.rmtree(tmp, ignore_errors=True)
# --- N3: currency fine -> nothing beyond the ordinary line --------------------------------
tmp = tempfile.mkdtemp(prefix="gnotice-")
try:
ctrl = fake_workspace(tmp, "0.230.0", "0.230.0")
rc, out = run(ctrl)
if rc != 0:
fails.append("N3: a current golden must exit 0; got %d" % rc)
elif "OWES A GOLDEN" in out:
fails.append("N3: it must not cry wolf when the golden is current; got:\n%s" % out)
elif len([l for l in out.splitlines() if l.strip()]) != 1:
fails.append("N3: a healthy check must be ONE line — a gate that prints a paragraph "
"every run is one people stop reading; got:\n%s" % out)
else:
print("N3 ok: current golden -> one quiet line, exit 0")
# NEGATIVE CONTROL: a string that cannot be there.
if "ZZZ-NOT-IN-THE-OUTPUT" in out:
fails.append("N3: negative control matched — the search is not discriminating")
finally:
shutil.rmtree(tmp, ignore_errors=True)
# --- N4: a golden AHEAD of the record is not reported as a debt ----------------------------
tmp = tempfile.mkdtemp(prefix="gnotice-")
try:
ctrl = fake_workspace(tmp, "0.230.0", "0.240.0")
rc, out = run(ctrl)
if "OWES A GOLDEN" in out:
fails.append("N4: a golden AHEAD of the newest release is not a missing golden; that "
"is R-385's direction and belongs to the felhom.eu gate, not here")
else:
print("N4 ok: a golden ahead of the record is not reported here as a debt")
finally:
shutil.rmtree(tmp, ignore_errors=True)
if fails:
print()
for f in fails:
print("FAIL: %s" % f)
return 1
print("\ngolden-notice tests OK — it reports, it never refuses")
return 0
sys.exit(main())