Gate rollout 2026-09-29 afternoon: 32/34 gated, sign-up blocks (decision 47 + CC mechanism), R-713; R-707/R-711/R-713 closed, R-714..R-716 opened; STATUS, CONTEXT, report
gates / gates (push) Successful in 27s

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-09-29 11:25:14 +02:00
parent fd9c77b92e
commit 1749e73e50
83 changed files with 1303 additions and 21 deletions
@@ -0,0 +1,30 @@
# Adds setup_gate (+ optional probe / signup_block / add_people) to catalog templates. argv[1] = repo root, argv[2] = JSON spec file.
# spec: {app: {"probe": {"url","field","done","why"} | null, "signup_block": "<matcher>" | null,
# "add_people": {"hu": "...", "en": "..."} | null, "why": "<one line>"}}
import json, os, re, sys
R, spec = sys.argv[1], json.load(open(sys.argv[2]))
for app, sp in spec.items():
p = os.path.join(R, "templates", app, ".felhom.yml")
s = open(p).read()
if "\nsetup_gate:" in s:
# replace the whole managed block
s = re.sub(r"\n# --- The setup gate \(controller.*?(?=\n# --- App info|\napp_info:)", "", s, flags=re.S)
block = ["", "# --- The setup gate (controller >= 0.281.0, `09` §3 decisions 46-47) ---",
"# " + sp.get("why", "The first visitor would create the admin; a fresh install is closed to everyone but the household until the first setup is done."),
"setup_gate: true"]
pr = sp.get("probe")
if pr:
block += ["# " + pr["why"], "setup_done_probe:", f" url: {pr['url']}", f" field: {pr['field']}", f" done: \"{pr['done']}\""]
if sp.get("signup_block"):
block += ["# Decision 47: the app's own sign-up address is closed once the gate opens (" + sp.get("signup_why", "measured on 9202 2026-09-29") + ").",
"signup_block: \"" + sp["signup_block"].replace('"', '\\"') + "\""]
i = s.index("\n# --- App info") if "\n# --- App info" in s else s.index("\napp_info:")
s = s[:i] + "\n".join(block) + "\n" + s[i:]
ap = sp.get("add_people")
if ap:
# Hungarian: into app_info (after docs_url or default_creds or tagline line); English: into i18n.en.app_info
s = re.sub(r"(\napp_info:\n(?: [^\n]*\n)*? tagline: [^\n]*\n)", lambda m: m.group(1) + " add_people: " + json.dumps(ap["hu"], ensure_ascii=False) + "\n", s, count=1)
s = re.sub(r"(\n en:\n(?: [^\n]*\n)*? app_info:\n tagline: [^\n]*\n)", lambda m: m.group(1) + " add_people: " + json.dumps(ap["en"], ensure_ascii=False) + "\n", s, count=1)
assert s.count("add_people:") == 2, app
open(p, "w").write(s)
print("patched", len(spec), "apps in", R)