sol: cron fleet state triage 2026-11-05

This commit is contained in:
sol committed 2026-11-05 14:07:07 +00:00
1 parent 4efde57a9d
commit e9e466e8f4
3 files changed
+253

No files matched your search

@@ -0,0 +1,122 @@
{
"fleet": "cron",
"source": "/root/.hermes/cron/jobs.json",
"total": 103,
"classes": {
"attention_delivery": 1,
"attention_error": 14,
"attention_unknown": 1,
"completed": 5,
"paused": 51,
"scheduled": 31
},
"attention_total": 16,
"attention_jobs": [
{
"id": "e61f5ce71d8b",
"name": "Hourly Ops Pulse",
"state": "paused",
"last_status": "error"
},
{
"id": "cd8a31f5ff9f",
"name": "Evaluate every new Pi harness release",
"state": "paused",
"last_status": "error"
},
{
"id": "e267b564eb2d",
"name": "Stackchain Lab Daily Drop \u2014 Candidate Correction Pass",
"state": "paused",
"last_status": "error"
},
{
"id": "a348cb59a0c1",
"name": "Forge Human Value Brief \u2014 Top Repositories",
"state": "paused",
"last_status": "error"
},
{
"id": "a9226ea81409",
"name": "Sovereign Signal \u2014 Independent Film Retrospective",
"state": "paused",
"last_status": null
},
{
"id": "fee83aa9ed16",
"name": "[bot:timmy] Stackchain forge change triage",
"state": "paused",
"last_status": "delivery_failed"
},
{
"id": "cfb73a4cf7ad",
"name": "Repertoire \u2014 14:00 Sovereign Media Studio",
"state": "paused",
"last_status": "error"
},
{
"id": "ccd3a4141f52",
"name": "Repertoire \u2014 19:30 Visual Product Studio",
"state": "paused",
"last_status": "error"
},
{
"id": "6cf100cea5f5",
"name": "Email digest (pre-6am)",
"state": "scheduled",
"last_status": "error"
},
{
"id": "6a5db2fe8231",
"name": "Dream cycle 02 (10:30pm)",
"state": "paused",
"last_status": "error"
},
{
"id": "01442c7c6acc",
"name": "Dream cycle 04 (1:30am)",
"state": "paused",
"last_status": "error"
},
{
"id": "1d1cfcd3542b",
"name": "Dream cycle 05 (3am)",
"state": "paused",
"last_status": "error"
},
{
"id": "b6cb8c490e9f",
"name": "Volt workhorse (every 2h)",
"state": "scheduled",
"last_status": "error"
},
{
"id": "1ae8f67df4c8",
"name": "Beam Foundry (every 2h)",
"state": "paused",
"last_status": "error"
},
{
"id": "3ac2f4a3f546",
"name": "X follows pitch monitor",
"state": "scheduled",
"last_status": "error"
},
{
"id": "b5e9b0fd4f4f",
"name": "TM spectator commentary",
"state": "paused",
"last_status": "error"
}
],
"class_decisions": {
"attention_error": "investigate last_error; stop delivery; do not re-run until root cause is cleared",
"attention_delivery": "fix delivery target; re-attempt dispatch",
"attention_unknown": "last_status missing; confirm the job ran ok",
"paused": "resume or confirm hold with an operator",
"scheduled": "healthy scheduled run; no action",
"completed": "archive the finished run",
"unknown": "unclassifiable; escalate"
},
"generated_at": "2026-11-05T13:51:31.419305+00:00"
}
@@ -0,0 +1,33 @@
# Cron Fleet State Triage 2026-11-05
Classification of every cron job in `jobs.json`.
| Class | Count | Decision |
|---|---|---|
| attention_delivery | 1 | fix delivery target; re-attempt dispatch |
| attention_error | 14 | investigate last_error; stop delivery; do not re-run until root cause is cleared |
| attention_unknown | 1 | last_status missing; confirm the job ran ok |
| completed | 5 | archive the finished run |
| paused | 51 | resume or confirm hold with an operator |
| scheduled | 31 | healthy scheduled run; no action |
Attention jobs (need sign-off): 16 of 103
| id | name | state | last_status |
|---|---|---|---|
| e61f5ce71d8b | Hourly Ops Pulse | paused | error |
| cd8a31f5ff9f | Evaluate every new Pi harness release | paused | error |
| e267b564eb2d | Stackchain Lab Daily Drop — Candidate Correction Pass | paused | error |
| a348cb59a0c1 | Forge Human Value Brief — Top Repositories | paused | error |
| a9226ea81409 | Sovereign Signal — Independent Film Retrospective | paused | None |
| fee83aa9ed16 | [bot:timmy] Stackchain forge change triage | paused | delivery_failed |
| cfb73a4cf7ad | Repertoire — 14:00 Sovereign Media Studio | paused | error |
| ccd3a4141f52 | Repertoire — 19:30 Visual Product Studio | paused | error |
| 6cf100cea5f5 | Email digest (pre-6am) | scheduled | error |
| 6a5db2fe8231 | Dream cycle 02 (10:30pm) | paused | error |
| 01442c7c6acc | Dream cycle 04 (1:30am) | paused | error |
| 1d1cfcd3542b | Dream cycle 05 (3am) | paused | error |
| b6cb8c490e9f | Volt workhorse (every 2h) | scheduled | error |
| 1ae8f67df4c8 | Beam Foundry (every 2h) | paused | error |
| 3ac2f4a3f546 | X follows pitch monitor | scheduled | error |
| b5e9b0fd4f4f | TM spectator commentary | paused | error |
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env python3
"""Independent verifier for fleet-state-triage-2026-11-05.json.
Re-reads /root/.hermes/cron/jobs.json and re-derives every job's operational
class with the priority rule (a copy of the generator's rule, not an import).
Diffs the rollup against the committed artifact. Exit 0 iff identical.
"""
import json
import sys
from collections import Counter
REPO = "/root/troupe-standup"
ART_PATH = REPO + "/wizard-work/sol/fleet-state-triage-2026-11-05.json"
SRC = "/root/.hermes/cron/jobs.json"
DECISIONS = {
"attention_error": "investigate last_error; do not re-run until root cause is cleared",
"attention_delivery": "fix delivery target; re-attempt dispatch",
"attention_unknown": "last_status missing; confirm the job ran ok",
"paused": "resume or confirm hold with an operator",
"scheduled": "healthy scheduled run; no action",
"completed": "archive the finished run",
}
def classify(job):
ls = job.get("last_status")
st = job.get("state")
if ls == "error":
return "attention_error"
if ls == "delivery_failed":
return "attention_delivery"
if ls is None:
return "attention_unknown"
if st == "paused":
return "paused"
if st == "scheduled":
return "scheduled"
if st == "completed":
return "completed"
return "unknown"
def main():
try:
art = json.load(open(ART_PATH, encoding="utf-8"))
except Exception as exc:
print("FAIL: cannot read artifact %s: %s" % (ART_PATH, exc))
return 1
try:
jobs = json.load(open(SRC, encoding="utf-8"))["jobs"]
except Exception as exc:
print("FAIL: cannot read source %s: %s" % (SRC, exc))
return 1
expected_classes = Counter()
expected_attention = []
for j in jobs:
c = classify(j)
expected_classes[c] += 1
if c.startswith("attention"):
expected_attention.append({"id": j.get("id"), "name": j.get("name"),
"state": j.get("state"), "last_status": j.get("last_status")})
problems = []
# 1. headline numbers
if art.get("total") != len(jobs):
problems.append("total %r != %d" % (art.get("total"), len(jobs)))
if art.get("attention_total") != len(expected_attention):
problems.append("attention_total %r != %d" % (art.get("attention_total"), len(expected_attention)))
# 2. class rollup
exp = {k: int(v) for k, v in sorted(expected_classes.items())}
if art.get("classes") != exp:
problems.append("classes rolled up %r != %r" % (art.get("classes"), exp))
# 3. attention job ids (sorted, set-equal)
got_ids = sorted(i.get("id") for i in art.get("attention_jobs", []))
exp_ids = sorted(i["id"] for i in expected_attention)
if got_ids != exp_ids:
problems.append("attention job ids differ: %r != %r" % (got_ids, exp_ids))
# 4. artifact mentions the source and decisions map
if art.get("source") != SRC:
problems.append("source field mismatch")
if not isinstance(art.get("class_decisions"), dict) or not art["class_decisions"]:
problems.append("class_decisions missing/empty")
if problems:
print("FAIL: %d problem(s)" % len(problems))
for p in problems:
print(" -", p)
return 1
print("PASS: artifact re-derives %d jobs; classes=%s; attention=%d" % (len(jobs), exp, len(expected_attention)))
return 0
if __name__ == "__main__":
sys.exit(main())