R-444: hub half — the System page shows each box's last disk trim

sysfacts reads the agent's top-level guest_disk_trim stanza (schedule + per-guest
last attempt: vmid, last_attempt_at, ok, bytes_trimmed, mounts, duration_seconds,
last_ok_at, error) into a field-by-field mirror. The System page's new 'Last disk
trim' column shows the last successful trim and the GiB it freed; amber when the
newest attempt failed (error shown) or last_ok_at is older than 14 days (judged on
the success time, never the attempt time); '—' when the agent sends no stanza.
wire_contract_gate: SUBTREE_MIRRORS checks guest_disk_trim field by field BOTH
ways against sysfacts.DiskTrim; decoys (ok renamed, last_ok_at dropped) in
test_gate_decoys.py. Decision 139.

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 11:28:20 +02:00
parent 9d39faabf8
commit a411cde7c4
7 changed files with 303 additions and 13 deletions
+44 -1
View File
@@ -63,7 +63,9 @@ COVERS = {
"must convict (it passed for months as `language` did); the genuine article — the same "
"name in a struct tag beside a `//` inside a string literal — must pass; and R-315: the "
"agent RENAMING its mirror's `superseded_at` tag (the old name still occurs as a local-API "
"map key) must convict on the field-by-field mirror check"),
"map key) must convict on the field-by-field mirror check; and R-444: the agent renaming "
"`guest_disk_trim.guests.ok` to `succeeded` (a name the hub carries elsewhere) or DROPPING `last_ok_at` (a field the "
"hub reads and would show as never-ok for ever) must convict on the subtree mirror"),
"stands": ("R-819: a stand citing a register id that exists in NEITHER register, and a stand "
"marked 'walked' whose only source is a register row (a green dot from a label); "
"plus the genuine article — a stand citing only a CLOSED row, which must PASS"),
@@ -750,6 +752,47 @@ for _mode, _want in (("renamed", 10), ("genuine", 0)):
print(" ok %-20s %s" % ("wire-mirror/" + _mode,
"decoy rejected" if _want else "genuine accepted"))
# ── wire-contract subtree mirror (R-444) ─────────────────────────────────────────────────────────
#
# `guest_disk_trim` is checked field by field BOTH ways against hub sysfacts.DiskTrim. Two decoys on the agent's parsed
# GuestDiskTrim body (no tree copy): `ok` renamed to `succeeded` — the name check passes it, since `succeeded` occurs in the hub — and
# `last_ok_at` dropped, which only the reverse direction can see. The genuine article must pass.
_WCS = r"""
import os, sys
sys.path.insert(0, "scripts")
import wire_contract_gate as g
mode = sys.argv[1]
orig, agent = g.build_index, os.path.abspath(g.REPOS["agent"])
def patched(root):
by_dir, by_name = orig(root)
if mode != "genuine" and os.path.abspath(root) == agent:
k = ("internal/hub", "GuestDiskTrim")
b = by_dir[k]
if mode == "renamed":
assert 'json:"ok"' in b, "mutation target missing"
b = b.replace('json:"ok"', 'json:"succeeded"')
else:
assert 'json:"last_ok_at' in b, "mutation target missing"
b = "\n".join(l for l in b.split("\n") if 'json:"last_ok_at' not in l)
by_dir[k] = b
by_name["GuestDiskTrim"] = [(d, b if d == k[0] else x) for d, x in by_name["GuestDiskTrim"]]
return by_dir, by_name
g.build_index = patched
rc, conv = g.run(quiet=True)
want = {"renamed": "guest_disk_trim.guests.succeeded", "dropped": "guest_disk_trim.guests.last_ok_at"}.get(mode)
hit = any(d == want for _, _, m in conv for _, d in m)
print("rc=%d convicted=%s" % (rc, hit))
sys.exit(0 if rc == 0 else (10 if hit else 11))
"""
for _mode, _want in (("renamed", 10), ("dropped", 10), ("genuine", 0)):
ran += 1
_p = subprocess.run([sys.executable, "-c", _WCS, _mode], cwd=ROOT, capture_output=True, text=True)
if _p.returncode != _want:
fails.append("wire-trim/%s: rc=%d, want %d (10 = the mutated trim field convicted, 0 = passed)\n%s"
% (_mode, _p.returncode, _want, (_p.stdout + _p.stderr)[-500:]))
else:
print(" ok %-20s %s" % ("wire-trim/" + _mode, "decoy rejected" if _want else "genuine accepted"))
# ── stands (R-819) ───────────────────────────────────────────────────────────────────────────────
#
# check_stands.py was red and in no runner. Its decoys are stand files written as a session would write