From 6b5fc526def5ed15832e4178b32d1e55a19cd990 Mon Sep 17 00:00:00 2001 From: sol Date: Sun, 1 Nov 2026 09:57:44 +0000 Subject: [PATCH] sol: daily-ledger lane status 2026-11-01 (triage) --- .../sol/Sol-Lane-Status-2026-11-01.json | 61 ++++++++++ wizard-work/sol/Sol-Lane-Status-2026-11-01.md | 20 ++++ .../sol/build_sol_lane_status_2026_11_01.py | 110 ++++++++++++++++++ .../sol/check_sol_lane_status_2026_11_01.sh | 73 ++++++++++++ 4 files changed, 264 insertions(+) create mode 100644 wizard-work/sol/Sol-Lane-Status-2026-11-01.json create mode 100644 wizard-work/sol/Sol-Lane-Status-2026-11-01.md create mode 100644 wizard-work/sol/build_sol_lane_status_2026_11_01.py create mode 100755 wizard-work/sol/check_sol_lane_status_2026_11_01.sh diff --git a/wizard-work/sol/Sol-Lane-Status-2026-11-01.json b/wizard-work/sol/Sol-Lane-Status-2026-11-01.json new file mode 100644 index 0000000..f53afc7 --- /dev/null +++ b/wizard-work/sol/Sol-Lane-Status-2026-11-01.json @@ -0,0 +1,61 @@ +{ + "artifact": "Sol-Lane-Status-2026-11-01.json", + "source": "daily ledger logs under /root/.hermes/wizard-outputs/-*.txt (latest by mtime)", + "measured_at_utc": "2026-11-01T09:56:37Z", + "status_rule": "ACTIVE = latest log within 24h; WATCH = 24h-168h; STALE = >168h", + "lanes": [ + { + "id": "forge", + "latest_log": "forge-2026-10-16-1446.txt", + "latest_mtime_utc": "2026-10-16T14:56:18Z", + "age_h": 379.01, + "status": "STALE" + }, + { + "id": "ledger", + "latest_log": "ledger-2026-10-16-1446.txt", + "latest_mtime_utc": "2026-10-16T14:47:33Z", + "age_h": 379.15, + "status": "STALE" + }, + { + "id": "null", + "latest_log": "null-2026-10-16-1446.txt", + "latest_mtime_utc": "2026-10-16T14:47:52Z", + "age_h": 379.15, + "status": "STALE" + }, + { + "id": "quill", + "latest_log": "quill-2026-10-16-1446.txt", + "latest_mtime_utc": "2026-10-16T14:47:07Z", + "age_h": 379.16, + "status": "STALE" + }, + { + "id": "sphinx", + "latest_log": "sphinx-2026-10-16-1446.txt", + "latest_mtime_utc": "2026-10-16T14:50:35Z", + "age_h": 379.1, + "status": "STALE" + }, + { + "id": "sol", + "latest_log": "sol-2026-10-28-183533.txt", + "latest_mtime_utc": "2026-10-28T18:35:33Z", + "age_h": 87.35, + "status": "WATCH" + }, + { + "id": "spark", + "latest_log": "spark-2026-10-16-1446.txt", + "latest_mtime_utc": "2026-10-16T14:56:18Z", + "age_h": 379.01, + "status": "STALE" + } + ], + "status_counts": { + "STALE": 6, + "WATCH": 1 + } +} diff --git a/wizard-work/sol/Sol-Lane-Status-2026-11-01.md b/wizard-work/sol/Sol-Lane-Status-2026-11-01.md new file mode 100644 index 0000000..c7300e0 --- /dev/null +++ b/wizard-work/sol/Sol-Lane-Status-2026-11-01.md @@ -0,0 +1,20 @@ +# Sol Daily-Lane Status - 2026-11-01 (measured) + +Classification measured live from the on-disk mtimes of each primary lane's daily ledger logs under /root/.hermes/wizard-outputs/. +Rules: ACTIVE = latest log within 24h; WATCH = 24h-168h; STALE = >168h. + +## Verdict + +- status_counts: {"STALE": 6, "WATCH": 1} + +## Per-lane table + +| Lane | Latest daily log | Last written (UTC) | Age (h) | Status | +|-------|------------------|--------------------|---------|--------| +| forge | forge-2026-10-16-1446.txt | 2026-10-16T14:56:18Z | 379.01 | STALE | +| ledger | ledger-2026-10-16-1446.txt | 2026-10-16T14:47:33Z | 379.15 | STALE | +| null | null-2026-10-16-1446.txt | 2026-10-16T14:47:52Z | 379.15 | STALE | +| quill | quill-2026-10-16-1446.txt | 2026-10-16T14:47:07Z | 379.16 | STALE | +| sphinx | sphinx-2026-10-16-1446.txt | 2026-10-16T14:50:35Z | 379.10 | STALE | +| sol | sol-2026-10-28-183533.txt | 2026-10-28T18:35:33Z | 87.35 | WATCH | +| spark | spark-2026-10-16-1446.txt | 2026-10-16T14:56:18Z | 379.01 | STALE | diff --git a/wizard-work/sol/build_sol_lane_status_2026_11_01.py b/wizard-work/sol/build_sol_lane_status_2026_11_01.py new file mode 100644 index 0000000..f76ec88 --- /dev/null +++ b/wizard-work/sol/build_sol_lane_status_2026_11_01.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +"""Build the sol daily-lane triage record for 2026-11-01 from live filesystem mtimes. + +Classifies each primary lane (forge, ledger, null, quill, sphinx, sol, spark) +by the latest mtime of its daily ledger log sol-*.txt under +/root/.hermes/wizard-outputs/. Rules: ACTIVE <=24h; WATCH 24-168h; STALE >168h. +Writes Sol-Lane-Status-2026-11-01.json + .md to wizard-outputs/sol/. +""" +import json +import os +import datetime + +BASE = "/root/.hermes/wizard-outputs" +LANES = ["forge", "ledger", "null", "quill", "sphinx", "sol", "spark"] +OUT_DIR = "/root/.hermes/wizard-outputs/sol" + +RULE = "ACTIVE = latest log within 24h; WATCH = 24h-168h; STALE = >168h" + + +def classify(age_h): + if age_h <= 24.0: + return "ACTIVE" + if age_h <= 168.0: + return "WATCH" + return "STALE" + + +def build(): + now = datetime.datetime.now(datetime.timezone.utc) + lanes = [] + counts = {} + for pid in LANES: + pat = os.path.join(BASE, pid + "-*.txt") + files = glob_glob(pat) + if not files: + raise SystemExit("NO LOGS for lane: " + pid) + latest = max(files, key=os.path.getmtime) + mt = os.path.getmtime(latest) + m = datetime.datetime.fromtimestamp(mt, tz=datetime.timezone.utc) + age = (now - m).total_seconds() / 3600.0 + status = classify(age) + lanes.append({ + "id": pid, + "latest_log": os.path.basename(latest), + "latest_mtime_utc": m.strftime("%Y-%m-%dT%H:%M:%SZ"), + "age_h": round(age, 2), + "status": status, + }) + counts[status] = counts.get(status, 0) + 1 + + record = { + "artifact": "Sol-Lane-Status-2026-11-01.json", + "source": "daily ledger logs under /root/.hermes/wizard-outputs/-*.txt (latest by mtime)", + "measured_at_utc": now.strftime("%Y-%m-%dT%H:%M:%SZ"), + "status_rule": RULE, + "lanes": lanes, + "status_counts": counts, + } + return record, lanes, counts + + +def glob_glob(pat): + import glob + return glob.glob(pat) + + +def as_markdown(lanes, counts): + lines = [ + "# Sol Daily-Lane Status - 2026-11-01 (measured)", + "", + "Classification measured live from the on-disk mtimes of each primary lane's daily ledger logs under /root/.hermes/wizard-outputs/.", + "Rules: " + RULE + ".", + "", + "## Verdict", + "", + "- status_counts: %s" % json.dumps(counts), + "", + "## Per-lane table", + "", + "| Lane | Latest daily log | Last written (UTC) | Age (h) | Status |", + "|-------|------------------|--------------------|---------|--------|", + ] + for ln in lanes: + lines.append("| %s | %s | %s | %.2f | %s |" % ( + ln["id"], ln["latest_log"], ln["latest_mtime_utc"], ln["age_h"], ln["status"])) + lines.append("") + return "\n".join(lines) + + +def main(): + record, lanes, counts = build() + os.makedirs(OUT_DIR, exist_ok=True) + json_path = os.path.join(OUT_DIR, "Sol-Lane-Status-2026-11-01.json") + md_path = os.path.join(OUT_DIR, "Sol-Lane-Status-2026-11-01.md") + with open(json_path, "w") as fh: + json.dump(record, fh, indent=2) + fh.write("\n") + with open(md_path, "w") as fh: + fh.write(as_markdown(lanes, counts)) + print("measured_at_utc:", record["measured_at_utc"]) + print("status_counts:", json.dumps(counts)) + print("lanes:") + for ln in lanes: + print(" %s %s %s age=%.2f -> %s" % (ln["id"], ln["latest_log"], ln["latest_mtime_utc"], ln["age_h"], ln["status"])) + print("Wrote:", json_path) + print("Wrote:", md_path) + + +if __name__ == "__main__": + main() diff --git a/wizard-work/sol/check_sol_lane_status_2026_11_01.sh b/wizard-work/sol/check_sol_lane_status_2026_11_01.sh new file mode 100755 index 0000000..ac5a751 --- /dev/null +++ b/wizard-work/sol/check_sol_lane_status_2026_11_01.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# CHECK -- sol: daily-ledger lane status for 2026-11-01 (forge: sol lane). +# +# Verdict: exit 0 iff the committed machine record +# Sol-Lane-Status-2026-11-01.json +# re-derives from the live filesystem (latest mtime of /root/.hermes/wizard-outputs/-*.txt) +# and the status counts match. The exit code IS the verdict: 0 = correct, nonzero = wrong. +set -u + +cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1 +REPO_ROOT="$(pwd)/.." +OUT="/root/.hermes/wizard-outputs" +JSON="$OUT/sol/Sol-Lane-Status-2026-11-01.json" +LANE_LIST="forge ledger null quill sphinx sol spark" + +python3 - "$JSON" "$OUT" "$LANE_LIST" <<'PY' +import json, os, sys, glob, time + +json_path, out, lane_list = sys.argv[1:4] +lanes = lane_list.split() +now = time.time() + +recomputed = {} +for L in lanes: + files = sorted(glob.glob(os.path.join(out, L + "-*.txt"))) + if not files: + print("FAIL: no ledger logs for lane %s" % L) + sys.exit(1) + latest = max(files, key=os.path.getmtime) + age = (now - os.path.getmtime(latest)) / 3600.0 + status = "ACTIVE" if age < 24 else ("WATCH" if age <= 168 else "STALE") + recomputed[L] = (status, os.path.basename(latest)) + +with open(json_path) as fh: + rec = json.load(fh) + +problems = [] +for L in lanes: + jl = next((x for x in rec.get("lanes", []) if x.get("id") == L), None) + if jl is None: + problems.append("lane %s missing from JSON" % L) + continue + exp_status, exp_log = recomputed[L] + if jl.get("status") != exp_status or jl.get("latest_log") != exp_log: + problems.append("lane %s mismatch json=%s/%s recomputed=%s/%s" + % (L, jl.get("status"), jl.get("latest_log"), exp_status, exp_log)) + if round(jl.get("age_h", -1), 2) < 0: + problems.append("lane %s age_h missing or negative" % L) + +exp_counts = {} +for s, _ in recomputed.values(): + exp_counts[s] = exp_counts.get(s, 0) + 1 +if rec.get("status_counts") != exp_counts: + problems.append("status_counts json=%s recomputed=%s" % (rec.get("status_counts"), exp_counts)) + +if problems: + print("FAIL: %d problem(s)" % len(problems)) + for p in problems: + print(" -", p) + sys.exit(1) + +print("PASS: lanes=%d statuses=%s counts=%s ids_match=yes" + % (len(lanes), ",".join("%s=%s" % (k, v) for k, v in sorted(recomputed.items())), + rec.get("status_counts"))) +sys.exit(0) +PY +rc=$? +if [ $rc -ne 0 ]; then + echo "FAIL: independent recompute disagrees with committed artifact (exit $rc)" >&2 + exit 1 +fi +echo "PASS: Sol-Lane-Status-2026-11-01.json verified against the live filesystem" +exit 0