sol: cron fleet state triage 2026-11-05
This commit is contained in:
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
@@ -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())
|
||||
Reference in new issue
Block a user