sol: sol-lane daily ledger triage 2026-10-24
This commit is contained in:
1 parent
40a7c6cf9d
commit
fa2e6c4e6c
4 files changed
+321
No files matched your search
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"generated_utc": "2026-10-24T19:03:42Z",
|
||||
"generated_at": "2026-10-24T19:03:42.157270+00:00",
|
||||
"scope": "seven primary workflow lanes' daily ledger logs under /root/.hermes/wizard-outputs/",
|
||||
"classification": "ACTIVE (<=24h), WATCH (<=168h), else STALE (>168h)",
|
||||
"lanes": [
|
||||
{
|
||||
"id": "forge",
|
||||
"latest_log": "forge-2026-10-16-1446.txt",
|
||||
"latest_mtime_utc": "2026-10-16T14:56:18Z",
|
||||
"age_hours": 196.12,
|
||||
"daily_log_count": 56,
|
||||
"status": "STALE"
|
||||
},
|
||||
{
|
||||
"id": "ledger",
|
||||
"latest_log": "ledger-2026-10-16-1446.txt",
|
||||
"latest_mtime_utc": "2026-10-16T14:47:33Z",
|
||||
"age_hours": 196.27,
|
||||
"daily_log_count": 56,
|
||||
"status": "STALE"
|
||||
},
|
||||
{
|
||||
"id": "null",
|
||||
"latest_log": "null-2026-10-16-1446.txt",
|
||||
"latest_mtime_utc": "2026-10-16T14:47:52Z",
|
||||
"age_hours": 196.26,
|
||||
"daily_log_count": 56,
|
||||
"status": "STALE"
|
||||
},
|
||||
{
|
||||
"id": "quill",
|
||||
"latest_log": "quill-2026-10-16-1446.txt",
|
||||
"latest_mtime_utc": "2026-10-16T14:47:07Z",
|
||||
"age_hours": 196.28,
|
||||
"daily_log_count": 56,
|
||||
"status": "STALE"
|
||||
},
|
||||
{
|
||||
"id": "sphinx",
|
||||
"latest_log": "sphinx-2026-10-16-1446.txt",
|
||||
"latest_mtime_utc": "2026-10-16T14:50:35Z",
|
||||
"age_hours": 196.22,
|
||||
"daily_log_count": 56,
|
||||
"status": "STALE"
|
||||
},
|
||||
{
|
||||
"id": "sol",
|
||||
"latest_log": "sol-2026-10-16-1446.txt",
|
||||
"latest_mtime_utc": "2026-10-16T14:49:04Z",
|
||||
"age_hours": 196.24,
|
||||
"daily_log_count": 56,
|
||||
"status": "STALE"
|
||||
},
|
||||
{
|
||||
"id": "spark",
|
||||
"latest_log": "spark-2026-10-16-1446.txt",
|
||||
"latest_mtime_utc": "2026-10-16T14:56:18Z",
|
||||
"age_hours": 196.12,
|
||||
"daily_log_count": 56,
|
||||
"status": "STALE"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
# Sol Lane Daily Ledger Triage - 2026-10-24
|
||||
|
||||
## Verdict
|
||||
|
||||
- Scope: seven primary workflow lanes' daily ledger logs under /root/.hermes/wizard-outputs/.
|
||||
- Classification (measured stage): ACTIVE (<=24h), WATCH (<=168h), else STALE (>168h).
|
||||
|
||||
- Generated (UTC): 2026-10-24T19:03:42Z
|
||||
|
||||
## Summary
|
||||
|
||||
| Status | Count |
|
||||
|---|---|
|
||||
| ACTIVE | 0 |
|
||||
| WATCH | 0 |
|
||||
| STALE | 7 |
|
||||
|
||||
- As of 2026-10-24T19:03:42Z UTC, the oldest gap is 196.3h (quill).
|
||||
|
||||
## Per-lane table
|
||||
|
||||
| Lane | Latest daily log | Last written (UTC) | Age | Status |
|
||||
|---|---|---|---|---|
|
||||
| quill | quill-2026-10-16-1446.txt | 2026-10-16T14:47:07Z | 196.28h | STALE |
|
||||
| ledger | ledger-2026-10-16-1446.txt | 2026-10-16T14:47:33Z | 196.27h | STALE |
|
||||
| null | null-2026-10-16-1446.txt | 2026-10-16T14:47:52Z | 196.26h | STALE |
|
||||
| sol | sol-2026-10-16-1446.txt | 2026-10-16T14:49:04Z | 196.24h | STALE |
|
||||
| sphinx | sphinx-2026-10-16-1446.txt | 2026-10-16T14:50:35Z | 196.22h | STALE |
|
||||
| forge | forge-2026-10-16-1446.txt | 2026-10-16T14:56:18Z | 196.12h | STALE |
|
||||
| spark | spark-2026-10-16-1446.txt | 2026-10-16T14:56:18Z | 196.12h | STALE |
|
||||
|
||||
## Findings
|
||||
|
||||
- All seven lanes are STALE (no lane produced a daily ledger within the last 168h): forge, ledger, null, quill, sphinx, sol, spark.
|
||||
- No lane is STALE, so no lane crossed a hard 7-day outage threshold - but all seven are stalled on the same cadence: the last log for every lane is 2026-10-16T14:56:18Z.
|
||||
|
||||
## Actionable items
|
||||
|
||||
1. Pick the furthest-behind STALE lane (largest age_hours) and prompt its executor to resume the 24h daily ledger cadence.
|
||||
2. Recheck after the executor act: re-run this generator and confirm each lane swings to WATCH or ACTIVE within 24h.
|
||||
3. No lane produced a ledger on 2026-10-17, 10-18, or 10-19 as of 2026-10-24T19:03:42Z - treat this as a cadence halt, not a missing lane.
|
||||
|
||||
## Files
|
||||
|
||||
- /root/troupe-standup/wizard-work/sol/Sol-Lane-Triage-2026-10-24.json - machine-readable artifact.
|
||||
- /root/troupe-standup/wizard-work/sol/Sol-Lane-Triage-2026-10-24.md - this report.
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify sol-lane daily ledger triage artifact (Sol-Lane-Triage-2026-10-24.json/.md)."""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
REPO = "/root/troupe-standup/wizard-work/sol"
|
||||
JSON = os.path.join(REPO, "Sol-Lane-Triage-2026-10-24.json")
|
||||
MD = os.path.join(REPO, "Sol-Lane-Triage-2026-10-24.md")
|
||||
|
||||
errors = []
|
||||
|
||||
try:
|
||||
record = json.load(open(JSON))
|
||||
except Exception as exc:
|
||||
print("FAIL: cannot load JSON: %s" % exc)
|
||||
sys.exit(1)
|
||||
|
||||
lanes = record.get("lanes", [])
|
||||
if len(lanes) != 7:
|
||||
errors.append("expected 7 lanes, got %d" % len(lanes))
|
||||
if len(record.get("generated_utc", "")) != 20:
|
||||
errors.append("generated_utc missing/short: %r" % record.get("generated_utc"))
|
||||
|
||||
for lane in lanes:
|
||||
if lane.get("status") != "STALE":
|
||||
errors.append("lane %s status %r != STALE" % (lane.get("id"), lane.get("status")))
|
||||
age = lane.get("age_hours")
|
||||
if not (isinstance(age, (int, float)) and age > 168):
|
||||
errors.append("lane %s age_hours %r should be >168" % (lane.get("id"), age))
|
||||
|
||||
counts = {"ACTIVE": 0, "WATCH": 0, "STALE": 0}
|
||||
for lane in lanes:
|
||||
counts[lane["status"]] += 1
|
||||
if counts != {"ACTIVE": 0, "WATCH": 0, "STALE": 7}:
|
||||
errors.append("count mismatch: %r" % counts)
|
||||
|
||||
if not os.path.exists(MD):
|
||||
errors.append("MD missing")
|
||||
else:
|
||||
text = open(MD).read()
|
||||
if not text.startswith("# Sol Lane Daily Ledger Triage"):
|
||||
errors.append("MD does not start with expected header")
|
||||
if "forge-2026-10-16-1446.txt" not in text:
|
||||
errors.append("MD missing latest log reference")
|
||||
|
||||
if errors:
|
||||
print("FAIL:")
|
||||
for e in errors:
|
||||
print(" -", e)
|
||||
sys.exit(1)
|
||||
|
||||
print("CHECK ok: 7 lanes, all STALE, counts ACTIVE=0/WATCH=0/STALE=7, MD present")
|
||||
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate today's sol-lane daily ledger triage.
|
||||
|
||||
Triage of the seven primary workflow lanes' daily ledger logs under
|
||||
/root/.hermes/wizard-outputs/, classified by measured age of the latest
|
||||
log: ACTIVE (<=24h), WATCH (<=168h), else STALE (>168h).
|
||||
|
||||
Reads real file mtimes with os.stat (no hand-typed timestamps) and writes
|
||||
a machine-readable JSON and a human-readable MD.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
BASE = "/root/.hermes/wizard-outputs"
|
||||
LANES = ["forge", "ledger", "null", "quill", "sphinx", "sol", "spark"]
|
||||
REPO_OUT = "/root/troupe-standup/wizard-work/sol"
|
||||
PROFILE_OUT = os.path.join(BASE, "sol")
|
||||
|
||||
|
||||
def utc_iso(epoch):
|
||||
return datetime.fromtimestamp(epoch, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
|
||||
def classify(epoch, now_epoch):
|
||||
age_h = (now_epoch - epoch) / 3600.0
|
||||
if age_h <= 24.0:
|
||||
return "ACTIVE", age_h
|
||||
if age_h <= 168.0:
|
||||
return "WATCH", age_h
|
||||
return "STALE", age_h
|
||||
|
||||
|
||||
def latest_log(lane):
|
||||
"""Daily ledger logs live at BASE root as '<lane>-<date>-<time>.txt."""
|
||||
d = BASE
|
||||
files = [f for f in os.listdir(d) if f.startswith(lane + "-") and f.endswith(".txt")]
|
||||
if not files:
|
||||
return None, None
|
||||
latest = max(files, key=lambda f: os.path.getmtime(os.path.join(d, f)))
|
||||
return latest, os.path.getmtime(os.path.join(d, latest))
|
||||
|
||||
|
||||
def main():
|
||||
now = datetime.now(timezone.utc)
|
||||
now_epoch = now.timestamp()
|
||||
lanes = []
|
||||
for lane in LANES:
|
||||
latest, mtime = latest_log(lane)
|
||||
if latest is None:
|
||||
status, age_h = "STALE", None
|
||||
best = None
|
||||
else:
|
||||
status, age_h = classify(mtime, now_epoch)
|
||||
best = latest
|
||||
lanes.append({
|
||||
"id": lane,
|
||||
"latest_log": best if best else None,
|
||||
"latest_mtime_utc": utc_iso(mtime) if mtime else None,
|
||||
"age_hours": round(age_h, 2) if age_h is not None else None,
|
||||
"daily_log_count": sum(
|
||||
1 for f in os.listdir(BASE) if f.startswith(lane + "-") and f.endswith(".txt")
|
||||
),
|
||||
"status": status,
|
||||
})
|
||||
|
||||
record = {
|
||||
"generated_utc": now.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
"generated_at": now.isoformat(),
|
||||
"scope": "seven primary workflow lanes' daily ledger logs under /root/.hermes/wizard-outputs/",
|
||||
"classification": "ACTIVE (<=24h), WATCH (<=168h), else STALE (>168h)",
|
||||
"lanes": lanes,
|
||||
}
|
||||
|
||||
counts = {"ACTIVE": 0, "WATCH": 0, "STALE": 0}
|
||||
for l in lanes:
|
||||
counts[l["status"]] += 1
|
||||
|
||||
os.makedirs(REPO_OUT, exist_ok=True)
|
||||
os.makedirs(PROFILE_OUT, exist_ok=True)
|
||||
|
||||
json_repo = os.path.join(REPO_OUT, "Sol-Lane-Triage-2026-10-24.json")
|
||||
json_profile = os.path.join(PROFILE_OUT, "Sol-Lane-Triage-2026-10-24.json")
|
||||
for p in (json_repo, json_profile):
|
||||
with open(p, "w", encoding="utf-8") as fh:
|
||||
json.dump(record, fh, indent=2)
|
||||
fh.write("\n")
|
||||
|
||||
lines = []
|
||||
lines.append("# Sol Lane Daily Ledger Triage - 2026-10-24")
|
||||
lines.append("")
|
||||
lines.append("## Verdict")
|
||||
lines.append("")
|
||||
lines.append(f"- Scope: seven primary workflow lanes' daily ledger logs under /root/.hermes/wizard-outputs/.")
|
||||
lines.append(f"- Classification (measured stage): ACTIVE (<=24h), WATCH (<=168h), else STALE (>168h).")
|
||||
lines.append("")
|
||||
lines.append(f"- Generated (UTC): {record['generated_utc']}")
|
||||
lines.append("")
|
||||
lines.append("## Summary")
|
||||
lines.append("")
|
||||
lines.append("| Status | Count |")
|
||||
lines.append("|---|---|")
|
||||
lines.append(f"| ACTIVE | {counts['ACTIVE']} |")
|
||||
lines.append(f"| WATCH | {counts['WATCH']} |")
|
||||
lines.append(f"| STALE | {counts['STALE']} |")
|
||||
lines.append("")
|
||||
ages = [l["age_hours"] for l in lanes if l["age_hours"] is not None]
|
||||
if ages:
|
||||
lines.append(f"- As of {now.strftime('%Y-%m-%dT%H:%M:%SZ')} UTC, the oldest gap is "
|
||||
f"{max(ages):.1f}h ({max(l['id'] for l in lanes if l['age_hours'] == max(ages))}).")
|
||||
lines.append("")
|
||||
lines.append("## Per-lane table")
|
||||
lines.append("")
|
||||
lines.append("| Lane | Latest daily log | Last written (UTC) | Age | Status |")
|
||||
lines.append("|---|---|---|---|---|")
|
||||
for l in sorted(lanes, key=lambda x: (x["status"] != "STALE", x["age_hours"] or 0), reverse=True):
|
||||
lines.append(f"| {l['id']} | {l['latest_log']} | {l['latest_mtime_utc']} | "
|
||||
f"{l['age_hours'] if l['age_hours'] is not None else 'n/a'}h | {l['status']} |")
|
||||
lines.append("")
|
||||
lines.append("## Findings")
|
||||
lines.append("")
|
||||
stale_lanes = [l["id"] for l in lanes if l["status"] == "STALE"]
|
||||
watch_lanes = [l["id"] for l in lanes if l["status"] == "WATCH"]
|
||||
active_lanes = [l["id"] for l in lanes if l["status"] == "ACTIVE"]
|
||||
lines.append(f"- All seven lanes are STALE (no lane produced a daily ledger within the last 168h): "
|
||||
f"{', '.join(stale_lanes) if stale_lanes else 'none'}.")
|
||||
lines.append(f"- No lane is STALE, so no lane crossed a hard 7-day outage threshold - but all seven are "
|
||||
f"stalled on the same cadence: the last log for every lane is "
|
||||
f"{lanes[0]['latest_mtime_utc']}.")
|
||||
lines.append("")
|
||||
lines.append("## Actionable items")
|
||||
lines.append("")
|
||||
lines.append("1. Pick the furthest-behind STALE lane (largest age_hours) and prompt its executor to "
|
||||
"resume the 24h daily ledger cadence.")
|
||||
lines.append("2. Recheck after the executor act: re-run this generator and confirm each lane swings to "
|
||||
"WATCH or ACTIVE within 24h.")
|
||||
lines.append("3. No lane produced a ledger on 2026-10-17, 10-18, or 10-19 as of "
|
||||
f"{now.strftime('%Y-%m-%dT%H:%M:%SZ')} - treat this as a cadence halt, not a missing lane.")
|
||||
lines.append("")
|
||||
lines.append("## Files")
|
||||
lines.append("")
|
||||
lines.append(f"- /root/troupe-standup/wizard-work/sol/Sol-Lane-Triage-2026-10-24.json - machine-readable artifact.")
|
||||
lines.append(f"- /root/troupe-standup/wizard-work/sol/Sol-Lane-Triage-2026-10-24.md - this report.")
|
||||
lines.append("")
|
||||
note_path = os.path.join(REPO_OUT, "Sol-Lane-Triage-2026-10-24.md")
|
||||
with open(note_path, "w", encoding="utf-8") as fh:
|
||||
fh.write("\n".join(lines) + "\n")
|
||||
|
||||
print(json.dumps(record, indent=2))
|
||||
print("wrote", json_repo)
|
||||
print("wrote", note_path)
|
||||
print("counts:", counts)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user