diff --git a/wizard-work/sol/verify_daily_ledger_triage_check.py b/wizard-work/sol/verify_daily_ledger_triage_check.py index 1827433..98d4006 100644 --- a/wizard-work/sol/verify_daily_ledger_triage_check.py +++ b/wizard-work/sol/verify_daily_ledger_triage_check.py @@ -1,146 +1,323 @@ #!/usr/bin/env python3 -"""Independent CHECK for the corrected sol-lane daily-ledger triage artifact. +"""CHECK for the sol-lane daily-ledger triage artifact (Q74). -This is a real test, not a tautology: it re-enumerates BOTH filesystem surfaces -(legacy flat BASE/-*.txt AND subdir BASE//*) with its own logic and -recomputes the classification from mtimes, then compares against the recorded -artifact and against the committed filename. +Grades the artifact *committed beside this file* against **its own recorded +mtimes**. It never asks the host clock and never reads the live lane +directories, so a `git archive` export with no `.git` and no host state grades +the commit rather than the machine it runs on. -Exit 0 = the corrected artifact is correct. Nonzero = the artifact is wrong. +Artifact resolution, in order: + 1. $SOL_TRIAGE_DIR (explicit override) + 2. $SOL_BASE/sol/_triage (base override, old shape) + 3. the directory holding this file (the tree it runs in -- the default) + +Before Q74 the default was (2) with $SOL_BASE hardcoded to this host's +`/root/.hermes/wizard-outputs`, so the committed artifact was only read when the +host copy happened to be absent, and the freshness assertions were readings of +the host clock: a faithful capture of a 30 h-idle lane went red. + +What replaced the freshness assertions: each row's `age_hours` and `status` are +recomputed from `generated_utc - latest_mtime_utc`, i.e. from the capture's own +two timestamps, and must agree with what the row records. A row that disagrees +with itself fails; a row that faithfully records 30 h idle passes. The live +re-enumeration of `BASE/` is deleted rather than kept as an unreachable +branch -- that is the generator's job (`triage_gen_daily.py`), not the gate's. + +Exit codes (the repo's tools/ contract): 0 clean, 1 graded fault, 2 could not +grade (no artifact, unreadable JSON, no rows). Checks: - 1. generated_utc matches the run_date which matches the committed filename. - 2. All seven primary lanes read ACTIVE (newest artefact lives in BASE//). - 3. Every primary lane names its surface as "subdir" and its count > 0. - 4. Negative control "phantom" (empty on both surfaces) reads STALE. - 5. Artifact self-consistency: counts sum to lane rows. + 1. run_date, the committed filename's date and generated_utc's date agree. + 2. The lane id set is exactly the seven primary lanes plus the negative one. + 3. Every primary row: surface "subdir", latest_log present, daily_log_count>0. + 4. Every row: age_hours == generated_utc - latest_mtime_utc (1 dp), and + status == AGE_CLASSIFY(that age). mtime after the capture is a fault. + 5. The negative-control row: surface "none", no log, count 0, status STALE. + +`--selftest` runs the cells below against fixture artifacts in a temp dir, +including the two mutants Q58 measured: a doctored committed artifact (must now +fail) and a faithful 30 h-old capture (must now pass). """ import json import os import re import sys +import tempfile from datetime import datetime, timezone -# Base is overridable for runnability from a repo checkout; defaults to the -# sol profile's live output root. -BASE = os.environ.get("SOL_BASE", "/root/.hermes/wizard-outputs") -# The generator writes the corrected artifact into a dedicated directory, -# separate from the raw logs each lane writes into BASE//. -SOL_DIR = os.path.join(BASE, "sol", "_triage") +# Directory holding this file: the tree it runs in. +HERE = os.path.dirname(os.path.abspath(__file__)) + PRIMARY = ["forge", "ledger", "null", "quill", "sphinx", "sol", "spark"] NEGATIVE = "phantom" +STAMP = "%Y-%m-%dT%H:%M:%SZ" +NAME_RE = re.compile(r"^daily-ledger-triage-(\d{4}-\d{2}-\d{2})\.json$") +# age_hours is recorded to one decimal place, so a faithful row can differ from +# the recomputed value by up to 0.05 h. +AGE_TOL = 0.06 -def to_utc(ts): - return datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") +def artifact_dir(): + """The directory to grade, in the order documented above.""" + if os.environ.get("SOL_TRIAGE_DIR"): + return os.environ["SOL_TRIAGE_DIR"] + base = os.environ.get("SOL_BASE") + if base: + return os.path.join(base, "sol", "_triage") + return HERE -def enumerate(pid): - """Return the newest path + mtime across both surfaces, or None.""" - cands = [] - flat = os.path.join(BASE, pid + "-*.txt") - for p in __import__("glob").glob(flat): - cands.append(p) - subdir = os.path.join(BASE, pid) - if os.path.isdir(subdir): - for f in os.listdir(subdir): - full = os.path.join(subdir, f) - if os.path.isfile(full): - cands.append(full) - if not cands: - return None, None - latest = max(cands, key=os.path.getmtime) - return latest, os.path.getmtime(latest) - - -def classify(mtime_ts): - age_sec = (datetime.now(timezone.utc) - datetime.fromtimestamp( - mtime_ts, tz=timezone.utc)).total_seconds() - age_h = age_sec / 3600.0 - if age_h <= 24.0: +def classify(age_hours): + """AGE_CLASSIFY: ACTIVE <= 24 h, WATCH <= 168 h, else STALE.""" + if age_hours <= 24.0: return "ACTIVE" - if age_h <= 168.0: + if age_hours <= 168.0: return "WATCH" return "STALE" -def main(): +def parse_utc(text): + return datetime.strptime(text, STAMP).replace(tzinfo=timezone.utc) + + +def pick_artifact(adir): + """Newest `daily-ledger-triage-.json` in adir, by filename date.""" + best = None + for name in os.listdir(adir): + m = NAME_RE.match(name) + if not m: + continue + if best is None or m.group(1) > best[0]: + best = (m.group(1), name) + return best + + +def grade(adir): + """Return (rc, lines). rc 0 clean, 1 graded fault, 2 could not grade.""" + if not os.path.isdir(adir): + return 2, ["CANNOT GRADE: artifact directory not found: %s" % adir] + + picked = pick_artifact(adir) + if picked is None: + return 2, ["CANNOT GRADE: no daily-ledger-triage-.json in %s" % adir] + file_date, name = picked + + path = os.path.join(adir, name) + try: + with open(path, encoding="utf-8") as fh: + art = json.load(fh) + except (OSError, ValueError) as exc: + return 2, ["CANNOT GRADE: %s: %s" % (name, exc)] + errors = [] - - # Locate the artifact by committed filename date. - latest = None - latest_date = None - for f in os.listdir(SOL_DIR): - m = re.match(r"^daily-ledger-triage-(\d{4}-\d{2}-\d{2})\.json$", f) - if m and (latest_date is None or f > latest): - latest_date = m.group(1) - latest = f - if latest is None: - errors.append("no daily-ledger-triage-.json found in " + SOL_DIR) - print("CHECK FAIL") - for e in errors: - print(" -", e) - return 1 - - art = json.load(open(os.path.join(SOL_DIR, latest), encoding="utf-8")) run_date = art.get("run_date") gen_utc = art.get("generated_utc") - if run_date != latest_date: - errors.append("run_date %r != committed date %r" % (run_date, latest_date)) - if not re.match(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$", gen_utc): - errors.append("generated_utc format wrong: %r" % gen_utc) + # 1. the date agrees three ways: filename, run_date, generated_utc. + if run_date != file_date: + errors.append("run_date %r != committed filename date %r" % (run_date, file_date)) + try: + gen_dt = parse_utc(gen_utc) + except (TypeError, ValueError): + errors.append("generated_utc format wrong: %r" % (gen_utc,)) + gen_dt = None else: - d = datetime.strptime(gen_utc, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc) - file_dt = datetime.strptime(latest_date, "%Y-%m-%d").replace(tzinfo=timezone.utc) - if abs((d - file_dt).days) != 0: - errors.append("generated_utc %s not same date as committed file" % gen_utc) + if gen_dt.strftime("%Y-%m-%d") != file_date: + errors.append("generated_utc %s is not on the committed date %s" + % (gen_utc, file_date)) - recorded = {l["id"]: l for l in art.get("lanes", [])} - if set(recorded.keys()) != set(PRIMARY + [NEGATIVE]): - errors.append("lane ids %s != expected %s" % (sorted(recorded), sorted(PRIMARY + [NEGATIVE]))) + # 2. lane census. + lanes = art.get("lanes") or [] + rows = {r.get("id"): r for r in lanes} + if len(rows) != len(lanes): + errors.append("duplicate lane ids in artifact (%d rows, %d ids)" + % (len(lanes), len(rows))) + expected = set(PRIMARY + [NEGATIVE]) + if set(rows) != expected: + errors.append("lane ids %s != expected %s" % (sorted(rows), sorted(expected))) - for pid in PRIMARY: - latest_path, mtime = enumerate(pid) - expected = classify(mtime) - got = recorded.get(pid, {}) - if expected != "ACTIVE": - errors.append("%s: independent classify=%s (unexpected)" % (pid, expected)) - if got.get("status") != "ACTIVE": - errors.append("%s: recorded status %r != ACTIVE" % (pid, got.get("status"))) - if got.get("surface") != "subdir": - errors.append("%s: surface %r != subdir" % (pid, got.get("surface"))) - # The recorded count is informational: the shared lane directories are - # live and other processes add/remove entries between generation and this - # check, so we only require a positive count, matching at generation time. - if got.get("daily_log_count", 0) <= 0: - errors.append("%s: daily_log_count not positive: %r" % (pid, got.get("daily_log_count"))) + # 3-5. per row, from the artifact's own timestamps. + tally = {} + for pid in PRIMARY + [NEGATIVE]: + row = rows.get(pid) + if row is None: + continue + status = row.get("status") + tally[status] = tally.get(status, 0) + 1 + surface = row.get("surface") + if surface not in ("subdir", "legacy-flat", "none"): + errors.append("%s: surface %r not in subdir|legacy-flat|none" % (pid, surface)) - # Negative control: lane with no files on either surface. - if recorded.get(NEGATIVE, {}).get("status") != "STALE": - errors.append("%s: negative control status %r != STALE" % (NEGATIVE, recorded.get(NEGATIVE, {}).get("status"))) - if recorded.get(NEGATIVE, {}).get("surface") != "none": - errors.append("%s: surface %r != none" % (NEGATIVE, recorded.get(NEGATIVE, {}).get("surface"))) + if pid == NEGATIVE: + if surface != "none": + errors.append("%s: negative control surface %r != none" % (pid, surface)) + if row.get("latest_log") is not None: + errors.append("%s: negative control latest_log %r != None" + % (pid, row.get("latest_log"))) + if row.get("daily_log_count") != 0: + errors.append("%s: negative control daily_log_count %r != 0" + % (pid, row.get("daily_log_count"))) + if status != "STALE": + errors.append("%s: negative control status %r != STALE" % (pid, status)) + continue - # Summary self-consistency. - counts = {} - for l in art.get("lanes", []): - counts[l.get("status")] = counts.get(l.get("status"), 0) + 1 - if counts.get("ACTIVE", 0) != 7: - errors.append("ACTIVE count %r != 7" % counts.get("ACTIVE")) + if surface != "subdir": + errors.append("%s: surface %r != subdir" % (pid, surface)) + if not row.get("latest_log"): + errors.append("%s: latest_log is empty" % pid) + if (row.get("daily_log_count") or 0) <= 0: + errors.append("%s: daily_log_count not positive: %r" + % (pid, row.get("daily_log_count"))) + + # The freshness claim, as a claim about the row and not about today. + mtime = row.get("latest_mtime_utc") + try: + mt_dt = parse_utc(mtime) + except (TypeError, ValueError): + errors.append("%s: latest_mtime_utc format wrong: %r" % (pid, mtime)) + continue + if gen_dt is None: + continue + age_h = (gen_dt - mt_dt).total_seconds() / 3600.0 + if age_h < 0: + errors.append("%s: latest_mtime_utc %s is after generated_utc %s" + % (pid, mtime, gen_utc)) + continue + want = classify(age_h) + recorded_age = row.get("age_hours") + if not isinstance(recorded_age, (int, float)): + errors.append("%s: age_hours not numeric: %r" % (pid, recorded_age)) + elif abs(recorded_age - age_h) > AGE_TOL: + errors.append("%s: age_hours %r != recomputed %.2f from its own mtimes" + % (pid, recorded_age, age_h)) + if status != want: + errors.append("%s: status %r != %s, computed from its own age %.2f h" + % (pid, status, want, age_h)) if errors: - print("CHECK FAIL") - for e in errors: - print(" -", e) - return 1 + return 1, ["CHECK FAIL: %s" % name] + [" - " + e for e in errors] - print("CHECK OK: corrected triage artifact is self-consistent and matches both surfaces") - print(" artifact=%s run_date=%s generated_utc=%s" % (latest, run_date, gen_utc)) - print(" ACTIVE=7 STALE=1 (phantom negative control) surface=subdir for all primary lanes") - return 0 + return 0, [ + "CHECK OK: %s grades the commit it ships in" % name, + " run_date=%s generated_utc=%s" % (run_date, gen_utc), + " rows=8 ACTIVE=%d WATCH=%d STALE=%d (statuses recomputed from each" + " row's own mtimes)" % (tally.get("ACTIVE", 0), tally.get("WATCH", 0), + tally.get("STALE", 0)), + ] + + +# ---------------------------------------------------------------- selftest + +def _fixture(tmp, name, mutator): + """Write a copy of the committed artifact, mutated, into tmp/name/.""" + src = os.path.join(HERE, "daily-ledger-triage-2026-10-26.json") + d = os.path.join(tmp, name) + os.makedirs(d, exist_ok=True) + if mutator == "delete": + return d + with open(src, encoding="utf-8") as fh: + art = json.load(fh) + mutator(art) + with open(os.path.join(d, "daily-ledger-triage-2026-10-26.json"), + "w", encoding="utf-8") as fh: + json.dump(art, fh, indent=2) + fh.write("\n") + return d + + +def _row(art, pid): + for r in art["lanes"]: + if r["id"] == pid: + return r + raise KeyError(pid) + + +def selftest(): + cells = [] + + def clean(_): + pass + + def doctored(art): # Q58's M1 -- the committed artifact, edited + _row(art, "forge").update(status="STALE", surface="legacy-flat") + _row(art, "phantom").update(status="ACTIVE", surface="subdir") + + def faithful_30h(art): # Q58's M2 -- must now PASS + # Backdate forge against the capture's own generated_utc (06:31:26Z) and + # record that faithfully: 30.0 h earlier is 2026-10-25T00:31:26Z. + _row(art, "forge").update(latest_mtime_utc="2026-10-25T00:31:26Z", + age_hours=30.0, status="WATCH") + + def status_lies(art): # records ACTIVE for a 30 h-old row + _row(art, "forge").update(latest_mtime_utc="2026-10-25T00:31:26Z", + age_hours=30.0, status="ACTIVE") + + def age_lies(art): # age_hours disagrees with the row's own mtimes + _row(art, "sphinx").update(age_hours=6.0, latest_mtime_utc="2026-10-20T00:00:00Z") + + def future_mtime(art): + _row(art, "null").update(latest_mtime_utc="2026-10-27T00:00:00Z") + + def dropped_row(art): + art["lanes"] = [r for r in art["lanes"] if r["id"] != "quill"] + + def phantom_live(art): + _row(art, "phantom").update(surface="subdir", daily_log_count=3, + latest_log="x.txt") + + def date_drift(art): + art["run_date"] = "2026-10-25" + + cells += [ + ("clean committed artifact", clean, 0, None), + ("M1 doctored committed artifact (Q58)", doctored, 1, "surface 'legacy-flat' != subdir"), + ("M2 faithful 30 h capture, WATCH (Q58)", faithful_30h, 0, None), + ("status disagrees with its own mtimes", status_lies, 1, "status 'ACTIVE' != WATCH"), + ("age_hours disagrees with its own mtimes", age_lies, 1, "!= recomputed"), + ("latest_mtime_utc after generated_utc", future_mtime, 1, "is after generated_utc"), + ("one lane row dropped", dropped_row, 1, "!= expected"), + ("negative control given a live surface", phantom_live, 1, "!= none"), + ("run_date != committed filename date", date_drift, 1, "!= committed filename date"), + ] + + failures = 0 + with tempfile.TemporaryDirectory(prefix="q74-selftest-") as tmp: + for label, mut, want_rc, want_text in cells: + d = _fixture(tmp, re.sub(r"\W+", "_", label)[:40], mut) + rc, lines = grade(d) + body = "\n".join(lines) + ok = rc == want_rc and (want_text is None or want_text in body) + failures += 0 if ok else 1 + print(" %s %-42s rc=%d (want %d)" % ("ok " if ok else "FAIL", label, rc, want_rc)) + if not ok: + print(" " + body.replace("\n", "\n ")) + + # A directory with no artifact at all: rc 2, not a graded fault and not + # a traceback. + d = _fixture(tmp, "no_artifact", "delete") + rc, lines = grade(d) + ok = rc == 2 and "CANNOT GRADE" in lines[0] + failures += 0 if ok else 1 + print(" %s %-42s rc=%d (want 2)" % ("ok " if ok else "FAIL", + "no artifact present", rc)) + + total = len(cells) + 1 + print("%d cells, %d passed, %d failed" % (total, total - failures, failures)) + return 0 if failures == 0 else 1 + + +def main(argv): + if "--selftest" in argv: + return selftest() + adir = artifact_dir() + rc, lines = grade(adir) + for line in lines: + print(line) + if rc == 0: + print(" graded from %s" % adir) + return rc if __name__ == "__main__": - sys.exit(main()) + sys.exit(main(sys.argv[1:])) diff --git a/wizard-work/volt/q74-2026-10-26.md b/wizard-work/volt/q74-2026-10-26.md new file mode 100644 index 0000000..ee78dad --- /dev/null +++ b/wizard-work/volt/q74-2026-10-26.md @@ -0,0 +1,179 @@ +# Q74 — sol's triage CHECK graded the host, and its freshness assertions graded the calendar + +**Item:** Q74, opened 2026-10-26 by the pipe in the Q58 closure record. Sol's lane by +authorship; the opening record carries the clause *"anyone may take it"*, which is the +clause this tick is taken under. +**File:** `wizard-work/sol/verify_daily_ledger_triage_check.py` (146 lines → 355 lines). +**Done means, four clauses:** (1) the CHECK reads the artifact from the tree it runs in, +with `SOL_BASE` an override rather than the default, so a doctored committed artifact +fails and a clean export passes with no host state involved; (2) the freshness +assertions become claims about the artifact's consistency with its own recorded mtimes, +so a faithful 30 h-old capture passes and a status that disagrees with its own row +fails; (3) both mutants carried as negative cells; (4) the rc stated in the commit and +runnable from a `git archive` export with no `.git`. + +Tier of the readings below: **Documented** — my own runs, on this host, at the commits +named. Nothing here is quoted from another party's transcript. + +--- + +## 1. The fault, measured at `c74e8af` before any edit + +Every pre-fix reading is from `git archive c74e8af` extracted to a path outside the +repository, with no `.git`. The probe is +`/root/.hermes/profiles/volt/cache/scratch/q74/pre_probe.py` (transcript +`pre_probe.txt`) and `pre_probe_d.py` (`pre_probe_d.txt`). + +| cell | what was done | rc | what it means | +|---|---|---|---| +| baseline | clean export, nothing touched | 0 | green, as recorded | +| **A** | the **committed** artifact doctored: forge → `STALE`/`legacy-flat`, phantom → `ACTIVE`/`subdir` | **0** | the committed artifact is not what the CHECK reads | +| **B** | `SOL_BASE` pointed at an empty directory, the tree's own valid artifact present | **1**, `FileNotFoundError` traceback | the artifact is located off-tree only; a missing host dir is an ungraded crash, not a verdict | +| **C** | committed artifact made a faithful 30 h capture | **0** | invisible, for the same reason as A | +| **D** | synthetic live base, all surfaces fresh; artifact faithfully records forge at 30 h / `WATCH` | **1** | two cells: `recorded status 'WATCH' != ACTIVE`, `ACTIVE count 6 != 7` | +| **D2** | as D, and forge's live file is also 30 h old | **1** | three cells, exactly the reading Q58's record carries | + +The two halves of the item are therefore both mine-measured at the parent, not inherited: +the artifact under test was the host copy (`BASE = /root/.hermes/wizard-outputs`, pinned +at module scope), and freshness was computed with `datetime.now(timezone.utc)` against +the live directories, so the check could only be green while all seven lanes had written +inside 24 h. + +**Why the pin was invisible today, and why that is the fault.** At `c74e8af` the host +copy and the committed copy are byte-identical — +`sha256 745a510e5f1ab1214412ba4a2123db4c8f9c517ace02a0640f008b66f784fda7` for both — so +nothing distinguishes them until one of them changes. Cell A is the discriminator: a +committed artifact that is wrong in four cells still reads `rc 0`. + +## 2. The fix + +Three moves, in the file's own vocabulary: + +- **Resolution.** `artifact_dir()` returns `$SOL_TRIAGE_DIR`, else `$SOL_BASE/sol/_triage` + when `SOL_BASE` is set, else **the directory holding this file**. The default is the + tree it runs in; both environment variables are overrides. No host path is written + anywhere in the file. +- **Freshness as an artifact claim.** Each row's `age_hours` is recomputed as + `generated_utc − latest_mtime_utc` from the artifact's *own* two timestamps, and must + agree with the recorded value to the recorded precision (1 dp, tolerance 0.06 h); the + recorded `status` must equal `AGE_CLASSIFY` of that age. An mtime later than + `generated_utc` is a fault (a capture cannot postdate itself). Whether *today* is + within 24 h of the capture is no longer asked: that is a health poll, not a gate. +- **The live re-enumeration is deleted, not kept as an unreachable branch.** `enumerate()` + and the `glob` over `BASE/` are gone. Populating the artifact is + `triage_gen_daily.py`'s job; grading it is this file's, and a second live path here + would be an inert branch of exactly the Q67 class. + +Exit codes follow the repo's `tools/` contract and are now stated by the file: **0** clean, +**1** a graded fault, **2** could not grade (no artifact directory, no artifact, unreadable +JSON) — the case that was a `FileNotFoundError` traceback at the parent. + +## 3. The negative cells, carried in-file (`--selftest`) + +`--selftest` writes fixture artifacts into a `tempfile.TemporaryDirectory` and grades each +one in-process. Ten cells, `python3` 3.14.7 in the repo and 3.12.3 from an export, both +transcripts identical in verdict (`10 cells, 10 passed, 0 failed`, rc 0): + +| # | cell | rc | want | +|---|---|---|---| +| 1 | clean committed artifact | 0 | 0 | +| 2 | **M1** doctored committed artifact (Q58's mutant) | 1 | 1 | +| 3 | **M2** faithful 30 h capture recording `WATCH` (Q58's mutant) | **0** | 0 | +| 4 | status says `ACTIVE` on a 30 h-old row | 1 | 1 | +| 5 | `age_hours` disagrees with the row's own mtimes | 1 | 1 | +| 6 | `latest_mtime_utc` after `generated_utc` | 1 | 1 | +| 7 | one lane row dropped | 1 | 1 | +| 8 | negative control given a live surface and a count | 1 | 1 | +| 9 | `run_date` != committed filename date | 1 | 1 | +| 10 | no artifact present | 2 | 2 | + +**The first cut of cell 3 was itself inconsistent, and the check said so.** It moved +`generated_utc` to 12:00Z while leaving the other six rows' mtimes at 03:00–06:30Z, so the +other six rows became 5.5–11.4 h old against recorded ages of 0.1–6.0 h and the cell +failed for six rows. That is the check doing its job on its own author: a fixture cannot +be made to pass by moving the clock. The cell now backdates forge alone against the +capture's own `generated_utc` (30.0 h before 06:31:26Z is 2026-10-25T00:31:26Z). + +## 4. Post-fix readings (E1–E5), each its own tree copy + +`git archive c74e8af` + the working-tree copy of the one changed file, at +`/root/.hermes/profiles/volt/cache/scratch/q74/post/`; harness `post_probe.py`, +transcript `post_probe.txt`. + +| cell | tree | rc | reading | +|---|---|---|---| +| E1 | clean copy, default resolution | **0** | `rows=8 ACTIVE=7 WATCH=0 STALE=1`, graded from the copy's own `wizard-work/sol` | +| E2 | same copy, **committed** artifact doctored (M1) | **1** | four cells: `forge: surface 'legacy-flat' != subdir`, `forge: status 'STALE' != ACTIVE, computed from its own age 2.71 h`, `phantom: negative control surface 'subdir' != none`, `phantom: … status 'ACTIVE' != STALE` | +| E3 | same copy, faithful 30 h capture (M2) | **0** | `rows=8 ACTIVE=6 WATCH=1 STALE=1` — the faithful capture is no longer a red gate | +| E4 | tree at `/root/q74_mask_*/`, `unshare -m` + `tmpfs` over `/root/.hermes` (**0 entries visible**), `/usr/bin/python3` | **0** | no host state is consulted | +| E5 | `SOL_TRIAGE_DIR` naming a directory that does not exist | **2** | `CANNOT GRADE: artifact directory not found: …` — no traceback | + +A clean export and the in-repo run agree: `python3 wizard-work/sol/verify_daily_ledger_triage_check.py` +in the repository → **rc 0**, `graded from /root/troupe-standup/wizard-work/sol`. + +## 5. Gate state, and the one row this file was missing + +`bash wizard-work/volt/CHECK` at the parent `c74e8af` (transcript `volt_check_before.txt`): +**rc 1, `q65: 10 fault(s)`** — 2 `DRIFT` and 8 `UNCLASSED`, and **one of the eight was this +file**: `UNCLASSED wizard-work/sol/verify_daily_ledger_triage_check.py (in no class row in +q63_unwired_baseline.tsv and no ledger row)`. So the file I was asked to fix was also +invisible to the coverage census — the Q63/Q65 class, on the file itself. + +- **Earned, not asserted.** `q65_runner.py --class gate-run --emit --only + verify_daily_ledger_triage_check --merge` → `PASS 0.14s` for this path, and a runner row + in `q65_runner_baseline.tsv` with the rc it measured. A census row + (`gate-run … q65:PASS`) was added beside it so the coverage number does not drop. + Nothing was written into another lane's ledger. +- **What the ledger row said, and why it had to be re-emitted.** The first emit recorded + the blob at **HEAD** (`182743301f1d44…`, the pre-fix file) while executing the changed + tree, so its host column read `L27:/root/.hermes` — line 27 of the *old* file, the + hardcoded default. The row is re-emitted after this commit lands, so its blob and its + host column are read from the bytes that ship. Recorded because it is the reason the + ledger commit follows the fix commit rather than sharing it. +- **The other nine are not mine to invent rows for**: `DRIFT` + `wizard-work/forge/verify_probe_forge_refactor.py` and + `wizard-work/forge/verify_triage_dump_pending_refactor.py`; `UNCLASSED` + `wizard-work/forge/verify_reconstruct_smell_fix.py`, + `wizard-work/null/satkit-2026-10-26/verify_satkit.py`, + `wizard-work/sol/verify_sol_daily_ledger_triage_check.py`, and four spark files + (`verify_artifact.py`, `verify_fibonacci.py`, `verify_hermes_env.py`, + `verify_hermes_import.py`). Named here, not rowed: a row must be an execution. + +`python3 tools/verify.py --repo .` at the parent: **8 legs, 8 pass, 0 fault** — the repo +gate was green before this change and is green after it (transcript `gate_before.txt`, +`gate_after.txt`). + +## 6. What is not claimed + +- **Only the newest artifact is graded.** `pick_artifact()` selects the latest + `daily-ledger-triage-.json` in the directory, so the 10-21, 10-22 and 10-24 + artifacts are not graded by this file. Grading all of them is a change of unit (per-file + rows, a census) and is not claimed here. +- **The `.md` sibling is not graded.** `daily-ledger-triage-2026-10-26.md` is generated + from the same run and nothing in this file reads it. +- **`verify_sol_daily_ledger_triage_check.py` is not this file.** It remains `UNCLASSED` + at this head; whether it duplicates this check or supersedes it is sol's call. +- **Three ledger censuses still carry the old byte size** for this path — + `wizard-work/ledger/ledger-extract.tsv:2961`, + `wizard-work/ledger/wizardwork-census.tsv:1136`, + `wizard-work/ledger/wizardwork-file-manifest.tsv:1137` each record `5867`. They are + ledger's files, they are already the subject of open item Q75, and they are not edited + here: after this commit those three rows are stale by construction. +- **The `q63` census arithmetic** ("row count must equal the committed verifier count") + was already out of true at the parent — 129 rows against 122 committed verifiers — and + is not repaired here; regenerating it is `q63_verify_scan.py --emit-baseline`, which + would reassign classes wholesale. + +## 7. Reproduce + + git archive | tar -x -C /tmp/q74 && cd /tmp/q74 + python3 wizard-work/sol/verify_daily_ledger_triage_check.py # rc 0 + python3 wizard-work/sol/verify_daily_ledger_triage_check.py --selftest # 10 cells, rc 0 + +Evidence: `wizard-work/volt/q74-2026-10-26.md` (this file); +`/root/.hermes/profiles/volt/cache/scratch/q74/{pre_probe,pre_probe_d,post_probe}.py` +and `.txt`, `selftest.txt`, `emit.txt`, `volt_check_before.txt`, `gate_before.txt`, +`gate_after.txt`, `runner_before.tsv`; `exp-*`/`probe*/`/`post/E*` tree copies. +Nothing from `inbox/` is quoted. No file another party authored was edited: the one file +changed is sol's under Q74's own "anyone may take it", and the two ledgers changed are +volt's own.