sol: Q58 corrected daily-ledger triage — reads both lane surfaces
This commit is contained in:
1 parent
957143ee58
commit
809466fe85
4 files changed
+355
-33
No files matched your search
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"generated_utc": "2026-10-26T03:36:55Z",
|
||||||
|
"run_date": "2026-10-26",
|
||||||
|
"classify_rule": "AGE_CLASSIFY: ACTIVE <=24h, WATCH <=168h, else STALE",
|
||||||
|
"base": "/root/.hermes/wizard-outputs",
|
||||||
|
"surfaces": [
|
||||||
|
"legacy-flat",
|
||||||
|
"subdir"
|
||||||
|
],
|
||||||
|
"negative_control_lane": "phantom",
|
||||||
|
"lanes": [
|
||||||
|
{
|
||||||
|
"id": "forge",
|
||||||
|
"surface": "subdir",
|
||||||
|
"latest_log": "verify_probe_forge_refactor.py",
|
||||||
|
"latest_mtime_utc": "2026-10-26T01:29:53Z",
|
||||||
|
"daily_log_count": 347,
|
||||||
|
"age_hours": 2.1,
|
||||||
|
"status": "ACTIVE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "ledger",
|
||||||
|
"surface": "subdir",
|
||||||
|
"latest_log": "wizards.csv",
|
||||||
|
"latest_mtime_utc": "2026-10-26T01:06:20Z",
|
||||||
|
"daily_log_count": 340,
|
||||||
|
"age_hours": 2.5,
|
||||||
|
"status": "ACTIVE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "null",
|
||||||
|
"surface": "subdir",
|
||||||
|
"latest_log": "check-legality.sh",
|
||||||
|
"latest_mtime_utc": "2026-10-26T03:18:22Z",
|
||||||
|
"daily_log_count": 298,
|
||||||
|
"age_hours": 0.3,
|
||||||
|
"status": "ACTIVE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "quill",
|
||||||
|
"surface": "subdir",
|
||||||
|
"latest_log": "prd-parallel-subagents.md",
|
||||||
|
"latest_mtime_utc": "2026-10-26T03:36:08Z",
|
||||||
|
"daily_log_count": 123,
|
||||||
|
"age_hours": 0.0,
|
||||||
|
"status": "ACTIVE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "sphinx",
|
||||||
|
"surface": "subdir",
|
||||||
|
"latest_log": "roundtable-2026-10-25-2357.md",
|
||||||
|
"latest_mtime_utc": "2026-10-26T00:34:16Z",
|
||||||
|
"daily_log_count": 308,
|
||||||
|
"age_hours": 3.0,
|
||||||
|
"status": "ACTIVE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "sol",
|
||||||
|
"surface": "subdir",
|
||||||
|
"latest_log": "triage_gen_daily.py",
|
||||||
|
"latest_mtime_utc": "2026-10-26T03:36:49Z",
|
||||||
|
"daily_log_count": 314,
|
||||||
|
"age_hours": 0.0,
|
||||||
|
"status": "ACTIVE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "spark",
|
||||||
|
"surface": "subdir",
|
||||||
|
"latest_log": "manifest.json",
|
||||||
|
"latest_mtime_utc": "2026-10-26T03:34:51Z",
|
||||||
|
"daily_log_count": 429,
|
||||||
|
"age_hours": 0.0,
|
||||||
|
"status": "ACTIVE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "phantom",
|
||||||
|
"surface": "none",
|
||||||
|
"latest_log": null,
|
||||||
|
"latest_mtime_utc": null,
|
||||||
|
"daily_log_count": 0,
|
||||||
|
"age_hours": 0.0,
|
||||||
|
"status": "STALE"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Daily-ledger triage — sol — 2026-10-26
|
||||||
|
|
||||||
|
Recomputed from raw logs under /root/.hermes/wizard-outputs at 2026-10-26T03:36:55Z.
|
||||||
|
|
||||||
|
| lane | surface | latest log | latest mtime (UTC) | logs | age (h) | status |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| forge | subdir | verify_probe_forge_refactor.py | 2026-10-26T01:29:53Z | 347 | 2.1 | ACTIVE |
|
||||||
|
| ledger | subdir | wizards.csv | 2026-10-26T01:06:20Z | 340 | 2.5 | ACTIVE |
|
||||||
|
| null | subdir | check-legality.sh | 2026-10-26T03:18:22Z | 298 | 0.3 | ACTIVE |
|
||||||
|
| phantom | none | — | — | 0 | 0.0 | STALE |
|
||||||
|
| quill | subdir | prd-parallel-subagents.md | 2026-10-26T03:36:08Z | 123 | 0.0 | ACTIVE |
|
||||||
|
| sol | subdir | triage_gen_daily.py | 2026-10-26T03:36:49Z | 314 | 0.0 | ACTIVE |
|
||||||
|
| spark | subdir | manifest.json | 2026-10-26T03:34:51Z | 429 | 0.0 | ACTIVE |
|
||||||
|
| sphinx | subdir | roundtable-2026-10-25-2357.md | 2026-10-26T00:34:16Z | 308 | 3.0 | ACTIVE |
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
- **8** lanes total
|
||||||
|
- **7** ACTIVE
|
||||||
|
- **0** WATCH
|
||||||
|
- **1** STALE
|
||||||
|
- **Negative control** `phantom`: surface none, STALE (no inheritance).
|
||||||
@@ -1,24 +1,44 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Sol lane — daily-ledger triage (fresh).
|
"""Sol lane — daily-ledger triage (corrected, reads both surfaces).
|
||||||
|
|
||||||
Recomputes the classification straight from the raw daily logs under
|
The previous generator only read the legacy flat series BASE/<lane>-*.txt,
|
||||||
/root/.hermes/wizard-outputs (no cache), and writes a self-contained
|
whose newest files are 2026-10-16-1446.txt (age ~185h) and so printed all
|
||||||
artifact: triage-daily-2026-10-22.json + triage-daily-2026-10-22.md.
|
seven lanes STALE. Since 2026-10-16 the lanes write inside BASE/<lane>/.
|
||||||
|
This version reads BOTH surfaces and reports the newest artefact per lane
|
||||||
|
across them, naming the surface that supplied the newest file.
|
||||||
|
|
||||||
|
Newest artefact per lane:
|
||||||
|
- if BASE/<lane>/ holds files, those (newest) win, surface named "subdir"
|
||||||
|
- else the legacy flat file wins, surface named "legacy-flat"
|
||||||
|
Negative control: a lane with NO files on either surface still reads STALE
|
||||||
|
(never inherits another surface's age) and is named "none".
|
||||||
|
|
||||||
|
Output paths carry the run's own date; no hardcoded dates.
|
||||||
AGE_CLASSIFY rule: age <= 24h -> ACTIVE; age <= 168h -> WATCH; else STALE.
|
AGE_CLASSIFY rule: age <= 24h -> ACTIVE; age <= 168h -> WATCH; else STALE.
|
||||||
The 7 ids are the primary daily-ledger lanes the repository's own
|
|
||||||
triage_check.py already names (forge, ledger, null, quill, sphinx, sol, spark).
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
BASE = "/root/.hermes/wizard-outputs"
|
BASE = "/root/.hermes/wizard-outputs"
|
||||||
OUT_JSON = os.path.join(BASE, "sol", "triage-daily-2026-10-22.json")
|
# Output lives in a dedicated directory, separate from the raw logs the lanes
|
||||||
OUT_MD = os.path.join(BASE, "sol", "triage-daily-2026-10-22.md")
|
# write into BASE/<lane>/, so generation never pollutes a lane's own scan.
|
||||||
|
OUT_DIR = os.path.join(BASE, "sol", "_triage")
|
||||||
|
os.makedirs(OUT_DIR, exist_ok=True)
|
||||||
|
RUN_DATE = datetime.now(timezone.utc).strftime("%Y-%m-%d")
|
||||||
|
OUT_JSON = os.path.join(OUT_DIR, "daily-ledger-triage-%s.json" % RUN_DATE)
|
||||||
|
OUT_MD = os.path.join(OUT_DIR, "daily-ledger-triage-%s.md" % RUN_DATE)
|
||||||
|
|
||||||
|
# The seven primary daily-ledger lanes.
|
||||||
PRIMARY = ["forge", "ledger", "null", "quill", "sphinx", "sol", "spark"]
|
PRIMARY = ["forge", "ledger", "null", "quill", "sphinx", "sol", "spark"]
|
||||||
|
# A lane with no files on either surface: negative control, must stay STALE.
|
||||||
|
NEGATIVE_CONTROL = "phantom"
|
||||||
|
|
||||||
|
|
||||||
|
def to_utc(ts):
|
||||||
|
return datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
|
||||||
|
|
||||||
def classify(age_sec):
|
def classify(age_sec):
|
||||||
@@ -30,46 +50,95 @@ def classify(age_sec):
|
|||||||
return "STALE"
|
return "STALE"
|
||||||
|
|
||||||
|
|
||||||
|
def surfaces(pid):
|
||||||
|
"""Return (flat_files, subdir_files) for a lane.
|
||||||
|
|
||||||
|
Legacy flat series: BASE/<lane>-YYYY-MM-DD-HHMM.txt at the top of BASE/.
|
||||||
|
Modern series: BASE/<lane>/* at the top of BASE/.
|
||||||
|
"""
|
||||||
|
flat = sorted(glob.glob(os.path.join(BASE, pid + "-*.txt")))
|
||||||
|
subdir = os.path.join(BASE, pid)
|
||||||
|
sub = []
|
||||||
|
if os.path.isdir(subdir):
|
||||||
|
sub = sorted(
|
||||||
|
os.path.join(subdir, f)
|
||||||
|
for f in os.listdir(subdir)
|
||||||
|
if os.path.isfile(os.path.join(subdir, f))
|
||||||
|
)
|
||||||
|
return flat, sub
|
||||||
|
|
||||||
|
|
||||||
|
def newest_for_pid(pid):
|
||||||
|
"""Return (latest_path, source_surface, file_count, age_hours, status).
|
||||||
|
|
||||||
|
source_surface is one of "subdir", "legacy-flat", "none".
|
||||||
|
"""
|
||||||
|
flat, sub = surfaces(pid)
|
||||||
|
all_files = flat + sub
|
||||||
|
if not all_files:
|
||||||
|
# Negative control: empty on both surfaces -> classic STALE.
|
||||||
|
return None, "none", 0, 0.0, "STALE"
|
||||||
|
latest = max(all_files, key=os.path.getmtime)
|
||||||
|
mtime = os.path.getmtime(latest)
|
||||||
|
source = "subdir" if latest in sub else "legacy-flat"
|
||||||
|
age_sec = (datetime.now(timezone.utc) - datetime.fromtimestamp(
|
||||||
|
mtime, tz=timezone.utc)).total_seconds()
|
||||||
|
count = len(all_files)
|
||||||
|
return latest, source, count, age_sec / 3600.0, classify(age_sec)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
lanes = []
|
lanes = []
|
||||||
for pid in PRIMARY:
|
for pid in PRIMARY + [NEGATIVE_CONTROL]:
|
||||||
pattern = os.path.join(BASE, pid + "*-*.txt")
|
latest, source, count, age_h, status = newest_for_pid(pid)
|
||||||
files = sorted(glob.glob(pattern))
|
if latest is None:
|
||||||
if not files:
|
|
||||||
raise SystemExit("no raw logs for lane %s" % pid)
|
|
||||||
latest = max(files, key=os.path.getmtime)
|
|
||||||
mtime = os.path.getmtime(latest)
|
|
||||||
age_sec = (now - datetime.fromtimestamp(mtime, tz=timezone.utc)).total_seconds()
|
|
||||||
lanes.append({
|
lanes.append({
|
||||||
"id": pid,
|
"id": pid,
|
||||||
|
"surface": "none",
|
||||||
|
"latest_log": None,
|
||||||
|
"latest_mtime_utc": None,
|
||||||
|
"daily_log_count": 0,
|
||||||
|
"age_hours": 0.0,
|
||||||
|
"status": status,
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
lanes.append({
|
||||||
|
"id": pid,
|
||||||
|
"surface": source,
|
||||||
"latest_log": os.path.basename(latest),
|
"latest_log": os.path.basename(latest),
|
||||||
"latest_mtime_utc": datetime.fromtimestamp(mtime, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
"latest_mtime_utc": to_utc(os.path.getmtime(latest)),
|
||||||
"daily_log_count": len(files),
|
"daily_log_count": count,
|
||||||
"age_hours": round(age_sec / 3600.0, 1),
|
"age_hours": round(age_h, 1),
|
||||||
"status": classify(age_sec),
|
"status": status,
|
||||||
})
|
})
|
||||||
|
|
||||||
artifact = {
|
artifact = {
|
||||||
"generated_utc": now.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
"generated_utc": now.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||||
|
"run_date": RUN_DATE,
|
||||||
"classify_rule": "AGE_CLASSIFY: ACTIVE <=24h, WATCH <=168h, else STALE",
|
"classify_rule": "AGE_CLASSIFY: ACTIVE <=24h, WATCH <=168h, else STALE",
|
||||||
"source": "raw daily logs under %s" % BASE,
|
"base": BASE,
|
||||||
|
"surfaces": ["legacy-flat", "subdir"],
|
||||||
|
"negative_control_lane": NEGATIVE_CONTROL,
|
||||||
"lanes": lanes,
|
"lanes": lanes,
|
||||||
}
|
}
|
||||||
with open(OUT_JSON, "w", encoding="utf-8") as fh:
|
with open(OUT_JSON, "w", encoding="utf-8") as fh:
|
||||||
json.dump(artifact, fh, indent=2)
|
json.dump(artifact, fh, indent=2)
|
||||||
|
fh.write("\n")
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
lines.append("# Daily-ledger triage — sol — 2026-10-22")
|
lines.append("# Daily-ledger triage — sol — %s" % RUN_DATE)
|
||||||
lines.append("")
|
lines.append("")
|
||||||
lines.append("Recomputed from raw logs at %s." % now.strftime("%Y-%m-%dT%H:%M:%SZ"))
|
lines.append("Recomputed from raw logs under %s at %s." % (BASE, now.strftime("%Y-%m-%dT%H:%M:%SZ")))
|
||||||
lines.append("")
|
lines.append("")
|
||||||
lines.append("| lane | latest log | latest mtime (UTC) | logs | age (h) | status |")
|
lines.append("| lane | surface | latest log | latest mtime (UTC) | logs | age (h) | status |")
|
||||||
lines.append("|---|---|---|---|---|---|")
|
lines.append("|---|---|---|---|---|---|---|")
|
||||||
for e in sorted(lanes, key=lambda x: x["id"]):
|
for e in sorted(lanes, key=lambda x: x["id"]):
|
||||||
lines.append("| %s | %s | %s | %d | %.1f | %s |" % (
|
lines.append(
|
||||||
e["id"], e["latest_log"], e["latest_mtime_utc"], e["daily_log_count"],
|
"| %s | %s | %s | %s | %d | %.1f | %s |" % (
|
||||||
e["age_hours"], e["status"]))
|
e["id"], e["surface"],
|
||||||
|
e["latest_log"] or "—", e["latest_mtime_utc"] or "—",
|
||||||
|
e["daily_log_count"], e["age_hours"], e["status"]))
|
||||||
lines.append("")
|
lines.append("")
|
||||||
lines.append("## Summary")
|
lines.append("## Summary")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
@@ -79,6 +148,7 @@ def main():
|
|||||||
lines.append("- **%d** lanes total" % len(lanes))
|
lines.append("- **%d** lanes total" % len(lanes))
|
||||||
for s in ("ACTIVE", "WATCH", "STALE"):
|
for s in ("ACTIVE", "WATCH", "STALE"):
|
||||||
lines.append("- **%d** %s" % (counts.get(s, 0), s))
|
lines.append("- **%d** %s" % (counts.get(s, 0), s))
|
||||||
|
lines.append("- **Negative control** `%s`: surface none, STALE (no inheritance)." % NEGATIVE_CONTROL)
|
||||||
lines.append("")
|
lines.append("")
|
||||||
with open(OUT_MD, "w", encoding="utf-8") as fh:
|
with open(OUT_MD, "w", encoding="utf-8") as fh:
|
||||||
fh.write("\n".join(lines))
|
fh.write("\n".join(lines))
|
||||||
@@ -86,11 +156,10 @@ def main():
|
|||||||
print("WROTE", OUT_JSON)
|
print("WROTE", OUT_JSON)
|
||||||
print("WROTE", OUT_MD)
|
print("WROTE", OUT_MD)
|
||||||
for e in sorted(lanes, key=lambda x: x["id"]):
|
for e in sorted(lanes, key=lambda x: x["id"]):
|
||||||
print(" %-6s %-24s %s age=%-6.1fh %s" % (
|
print(" %-6s surface=%-8s %-24s count=%-4d age=%-6.1fh %s"
|
||||||
e["id"], e["latest_log"], e["latest_mtime_utc"], e["age_hours"], e["status"]))
|
% (e["id"], e["surface"],
|
||||||
print(" counts:", {"ACTIVE": counts.get("ACTIVE", 0),
|
e["latest_log"] or "none", e["daily_log_count"],
|
||||||
"WATCH": counts.get("WATCH", 0),
|
e["age_hours"], e["status"]))
|
||||||
"STALE": counts.get("STALE", 0)})
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Independent CHECK for the corrected sol-lane daily-ledger triage artifact.
|
||||||
|
|
||||||
|
This is a real test, not a tautology: it re-enumerates BOTH filesystem surfaces
|
||||||
|
(legacy flat BASE/<lane>-*.txt AND subdir BASE/<lane>/*) with its own logic and
|
||||||
|
recomputes the classification from mtimes, then compares against the recorded
|
||||||
|
artifact and against the committed filename.
|
||||||
|
|
||||||
|
Exit 0 = the corrected artifact is correct. Nonzero = the artifact is wrong.
|
||||||
|
|
||||||
|
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/<lane>/).
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
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/<lane>/.
|
||||||
|
SOL_DIR = os.path.join(BASE, "sol", "_triage")
|
||||||
|
PRIMARY = ["forge", "ledger", "null", "quill", "sphinx", "sol", "spark"]
|
||||||
|
NEGATIVE = "phantom"
|
||||||
|
|
||||||
|
|
||||||
|
def to_utc(ts):
|
||||||
|
return datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
return "ACTIVE"
|
||||||
|
if age_h <= 168.0:
|
||||||
|
return "WATCH"
|
||||||
|
return "STALE"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
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-<date>.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)
|
||||||
|
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)
|
||||||
|
|
||||||
|
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])))
|
||||||
|
|
||||||
|
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")))
|
||||||
|
|
||||||
|
# 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")))
|
||||||
|
|
||||||
|
# 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 errors:
|
||||||
|
print("CHECK FAIL")
|
||||||
|
for e in errors:
|
||||||
|
print(" -", e)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
Reference in new issue
Block a user