hub v0.137.0 source + burn-down round 2 in felhom.eu: R-277 R-581 R-600 R-544 R-855 R-134 R-92 R-292 R-599 R-725 R-728 (hub), R-819 R-857 R-555 R-364 R-587 (gates/tools), R-571 R-129 R-124-runbook (docs); 28 rows closed incl. catalog + agent v0.147.0 rows, R-350 merged into R-132, R-888 opened, R-887 mechanism (249 -> 222)
gates / gates (push) Successful in 2m3s
gates / gates (push) Successful in 2m3s
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:
@@ -280,6 +280,30 @@ ALLOWLIST = {
|
||||
"and a fact displayed with nothing to compare it to is decoration."),
|
||||
(_CH, "backup.last_db_dump"): _R264,
|
||||
(_CH, "backup.last_integrity_check"): _R264,
|
||||
|
||||
# ---- R-555 (2026-10-05): surfaced when comments stopped counting as receivers ----
|
||||
#
|
||||
# Each of these passed for months because its NAME occurred hub-side only in a comment. No hub struct
|
||||
# decodes any of them. Listed so the drop is visible; none is known to be needed by a hub surface.
|
||||
# **Delete an entry when a hub struct starts decoding the field.**
|
||||
(_AH, "audit_tail"): (
|
||||
"R-555: ignored on purpose — hub/internal/api/handler.go's hostReportPayload comment names it "
|
||||
"among the fields the hub does not decode (backups/restore_tests/pbs_snapshots/audit_tail)."),
|
||||
(_AH, "guests.spec"): (
|
||||
"R-555: the parent of guests.spec.disk_bytes / memory_bytes above — sizing is hub-owned intent, "
|
||||
"not mirrored reality, so the object is not decoded either."),
|
||||
(_CH, "backup.integrity_ok"): (
|
||||
"R-555 / R-331: no producer since disk-tier restic moved to the agent (slice 8C); the Backup card "
|
||||
"dropped it rather than re-sourcing it (hub/internal/web/backup_card.go)."),
|
||||
(_CH, "backup.repo_size_mb"): (
|
||||
"R-555 / R-331: no producer since slice 8C; the Backup card reads offsite.repo_size_bytes "
|
||||
"instead (hub/internal/web/backup_card.go)."),
|
||||
(_CH, "stacks.deployed"): (
|
||||
"R-555: surfaced 2026-10-05 — the hub decodes no deployed-app list from the report; whether a hub "
|
||||
"surface needs it is not decided. Filed as R-888 for the operator to decide."),
|
||||
(_CH, "storage.decommissioned"): (
|
||||
"R-555: surfaced 2026-10-05 — the hub decodes no per-drive decommissioned marker from the report; "
|
||||
"whether a hub surface needs it is not decided. Filed as R-888 for the operator to decide."),
|
||||
}
|
||||
|
||||
# A node whose IMMEDIATE CHILDREN are still checked but whose DEEPER descendants are not, because the
|
||||
@@ -446,6 +470,48 @@ def walk(by_dir, by_name, start_dir, start_type, seen=None, prefix=""):
|
||||
|
||||
|
||||
TOKEN_RE = re.compile(r"[A-Za-z0-9_]+")
|
||||
TEMPLATE_COMMENT_RE = re.compile(r"\{\{-?\s*/\*.*?\*/\s*-?\}\}", re.S)
|
||||
|
||||
|
||||
def strip_go_comments(src):
|
||||
"""Go source with every // and /* */ comment removed; string, raw-string and rune literals kept.
|
||||
|
||||
R-555: a field whose name appeared hub-side only in a COMMENT counted as received — `language`
|
||||
passed because configs.go said "this page's existing language". A comment is prose, not a decoder.
|
||||
A small lexer rather than a regex, because a regex cannot tell `//` in "http://…" or a backtick
|
||||
struct tag from a comment, and the struct tags are exactly what this gate reads.
|
||||
"""
|
||||
out, i, n = [], 0, len(src)
|
||||
while i < n:
|
||||
c = src[i]
|
||||
if c == "/" and i + 1 < n and src[i + 1] == "/":
|
||||
j = src.find("\n", i)
|
||||
i = n if j < 0 else j # keep the newline
|
||||
continue
|
||||
if c == "/" and i + 1 < n and src[i + 1] == "*":
|
||||
j = src.find("*/", i + 2)
|
||||
i = n if j < 0 else j + 2
|
||||
out.append(" ")
|
||||
continue
|
||||
if c in "\"'`":
|
||||
j = i + 1
|
||||
while j < n and src[j] != c:
|
||||
if c != "`" and src[j] == "\\":
|
||||
j += 1
|
||||
elif c != "`" and src[j] == "\n":
|
||||
break # an unterminated literal ends at the line
|
||||
j += 1
|
||||
out.append(src[i:j + 1])
|
||||
i = j + 1
|
||||
continue
|
||||
out.append(c)
|
||||
i += 1
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def strip_template_comments(src):
|
||||
"""An HTML template with every {{/* … */}} action removed (R-555)."""
|
||||
return TEMPLATE_COMMENT_RE.sub(" ", src)
|
||||
|
||||
|
||||
def receiver_tokens(repo_root):
|
||||
@@ -479,7 +545,10 @@ def receiver_tokens(repo_root):
|
||||
p = os.path.join(dp, f)
|
||||
try:
|
||||
with open(p, encoding="utf-8", errors="replace") as fh:
|
||||
toks.update(TOKEN_RE.findall(fh.read()))
|
||||
src = fh.read()
|
||||
# R-555: comments are stripped first — a name in prose is not a decoder.
|
||||
src = strip_go_comments(src) if f.endswith(".go") else strip_template_comments(src)
|
||||
toks.update(TOKEN_RE.findall(src))
|
||||
except OSError as e:
|
||||
# never swallowed: an unreadable source file makes the answer unknown, not "absent"
|
||||
die("wire-contract gate INCONCLUSIVE: cannot read %s: %s" % (p, e))
|
||||
|
||||
Reference in New Issue
Block a user