Files
troupe-standup/wizard-work/ledger/grade_jobs_table.py
T
volt 82878043cb volt: Q161 -- jobs-table entry point is a bash wrapper over a grader that can say 'cannot grade'
wizard-work/ledger/CHECK-2026-11-02-jobs-table landed at 2e57e6b as a Python program with a python3 shebang, so `bash <path>` -- the invocation the q143 sweep, verify.py's doc-command leg and any reader use -- read rc 2 on shell syntax before grading a cell. Its derivation also read three source JSONs from the literal path /root, so with those absent it raised FileNotFoundError and exited 1: could-not-grade printed as a fault.

The grader moved to grade_jobs_table.py; the path keeps a bash wrapper. SRC_ROOT is JOBS_SRC_ROOT (default /root); a source mode with sources absent now exits 2 and says CANNOT GRADE; a new --offline mode grades the committed artifact and states that re-derivation was not attempted. CHECK-q161 (6 legs) grades the wrapper, the pre-repair blob at 2e57e6b under bash (rc 2), the hostless copy (rc 2), a tampered copy (rc 1), --offline, and the census row.
2026-11-03 05:52:58 +00:00

270 lines
10 KiB
Python

#!/usr/bin/env python3
"""grade_jobs_table.py -- the grader behind `CHECK-2026-11-02-jobs-table`.
WHY THIS FILE EXISTS (Q161, 2026-11-03)
The entry point at `wizard-work/ledger/CHECK-2026-11-02-jobs-table` used to be
this program with a `python3` shebang. Every caller in this tree invokes an
entry point with `bash` (the q143 sweep, `tools/verify.py`'s doc-command leg,
and any reader who types the path), so `bash CHECK-2026-11-02-jobs-table` read
rc 2 on shell syntax errors before grading a cell -- measured at `2e57e6b`:
`line 18: syntax error near unexpected token '('`. The grader moved here; the
path keeps a bash wrapper, which is the stable entry point.
Second defect, same record: the derivation read three source JSONs from the
literal host path `/root`. With those absent -- any clone, any other host --
the program died with `FileNotFoundError` and rc 1, i.e. "could not grade" was
reported as a fault. A missing source is not a failed artifact. It is now rc 2
and says so. The root is overridable with `JOBS_SRC_ROOT` so the absent case
can be exercised as a cell instead of argued about.
WHAT IT GRADES
default / --from-source the item's own claim: the committed `jobs.csv`
re-derives BYTE-FOR-BYTE from the source JSONs, and
its sha256 / row count / per-source counts /
fieldnames equal the frozen `manifest.json`. Plus the
required key fields are populated.
--offline the legs that do not need the sources: manifest
sha256 against the committed bytes, row count, header
vs manifest fieldnames, and each on-disk row's
required key fields non-empty. It says, in its own
output, that re-derivation was not attempted -- a
weaker reading is allowed, an unstated one is not.
EXIT CODES
0 every leg of the mode graded, all passed
1 a graded leg failed (drift, digest mismatch, empty required field)
2 could not grade: a source file is absent in a mode that needs it, a pinned
artifact is missing, or the manifest cannot be read. Never used for "the
artifact is wrong".
"""
import csv
import hashlib
import html
import io
import json
import os
import re
import sys
from typing import NoReturn
HERE = os.path.dirname(os.path.abspath(__file__))
MANIFEST = os.path.join(HERE, "manifest.json")
CSV = os.path.join(HERE, "jobs.csv")
# The three raw scrape files the table was built from. They are not tracked --
# they are the extraction lane's inputs -- so this path is a host fact, not a
# repository fact, and the check must be able to say it cannot grade without it.
SRC_FILES = {
"more_candidates.json": "more",
"ashby_candidates.json": "ashby",
"greenhouse_candidates.json": "greenhouse",
}
SRC_ROOT = os.environ.get("JOBS_SRC_ROOT", "/root")
TAG_RE = re.compile(r"<[^>]+>")
REQUIRED = ["source", "title", "job_url"]
def strip_html(s):
if not s:
return ""
s = html.unescape(s)
s = TAG_RE.sub(" ", s)
return " ".join(s.split())
def emp_of(rec):
for k in ("employmentType", "workplaceType"):
v = rec.get(k)
if v:
return v
return ""
def publish_at(rec):
return rec.get("publishedAt") or rec.get("updated_at") or ""
def desc_of(rec):
for k in ("descriptionPlain", "content", "descriptionHtml"):
v = rec.get(k)
if v:
return strip_html(v)[:220]
return ""
def build_expected_rows():
rows = []
counts = {}
for src_file, src_label in SRC_FILES.items():
path = os.path.join(SRC_ROOT, src_file)
with open(path) as fh:
data = json.load(fh)
counts[src_label] = 0
for rec in data:
rows.append({
"source": src_label,
"org": rec.get("org") or rec.get("board") or "",
"title": rec.get("title") or "",
"location": rec.get("location") or "",
"department": rec.get("department") or "",
"employment_type": emp_of(rec),
"job_url": rec.get("jobUrl") or rec.get("url") or "",
"apply_url": rec.get("applyUrl") or "",
"published_at": publish_at(rec),
"description": desc_of(rec),
})
counts[src_label] += 1
return rows, counts
def csv_bytes(rows):
buf = io.StringIO()
w = csv.DictWriter(buf, fieldnames=list(rows[0].keys()) if rows else [])
w.writeheader()
w.writerows(rows)
return buf.getvalue().encode("utf-8")
def cannot_grade(msg: str) -> NoReturn:
print("CANNOT GRADE: " + msg)
sys.exit(2)
def missing_sources():
return [f for f in SRC_FILES if not os.path.isfile(os.path.join(SRC_ROOT, f))]
def main(argv):
mode = "from-source"
for arg in argv:
if arg == "--offline":
mode = "offline"
elif arg in ("--from-source", "--default"):
mode = "from-source"
elif arg in ("-h", "--help"):
print(__doc__)
return 0
else:
print("unknown argument: %s" % arg)
return 2
if not os.path.isfile(MANIFEST):
cannot_grade("manifest.json is missing beside this grader")
if not os.path.isfile(CSV):
cannot_grade("jobs.csv is missing beside this grader")
try:
with open(MANIFEST) as fh:
manifest = json.load(fh)
except (ValueError, OSError) as ex:
cannot_grade("manifest.json is unreadable: %r" % ex)
if mode == "from-source":
absent = missing_sources()
if absent:
cannot_grade(
"source JSON(s) absent under %s: %s -- the byte-for-byte "
"re-derivation cannot be graded here; `--offline` grades the "
"committed artifact alone and says so"
% (SRC_ROOT, ", ".join(sorted(absent))))
ok = True
failures = []
with open(CSV, "rb") as fh:
on_disk_bytes = fh.read()
disk_sha = hashlib.sha256(on_disk_bytes).hexdigest()
text = on_disk_bytes.decode("utf-8", "surrogateescape")
n_data = text.count("\n") - 1 # minus header
# --- legs 1-3: the manifest's facts against the committed bytes ----------
sha_ok = disk_sha == manifest.get("sha256")
if not sha_ok:
ok = False
failures.append("sha256 mismatch: on-disk=%s manifest=%s"
% (disk_sha, manifest.get("sha256")))
count_ok = manifest.get("row_count") == n_data
if not count_ok:
ok = False
failures.append("row_count mismatch: manifest=%s ondisk_data=%s"
% (manifest.get("row_count"), n_data))
reader = csv.DictReader(io.StringIO(text))
fields = reader.fieldnames
fields_ok = fields == manifest.get("fieldnames")
if not fields_ok:
ok = False
failures.append("fieldnames mismatch: %s" % fields)
disk_rows = list(reader)
unreadable = [i for i, r in enumerate(disk_rows)
if r is None or any(not (r.get(k) or "").strip() for k in REQUIRED)]
if unreadable:
ok = False
failures.append("rows with empty required field: %s" % unreadable[:5])
derived_rows = None
deriv_ok = None
if mode == "from-source":
# --- legs 4-5: re-derivation from the pinned sources -----------------
derived_rows, derived_counts = build_expected_rows()
derived_bytes = csv_bytes(derived_rows)
deriv_ok = on_disk_bytes == derived_bytes
if not deriv_ok:
ok = False
failures.append(
"jobs.csv bytes differ from a fresh re-derivation from source "
"(on-disk %d bytes, derived %d bytes)"
% (len(on_disk_bytes), len(derived_bytes)))
o = text.splitlines()
e = derived_bytes.decode("utf-8", "surrogateescape").splitlines()
for i in range(max(len(o), len(e))):
a = o[i] if i < len(o) else "<missing>"
b = e[i] if i < len(e) else "<missing>"
if a != b:
failures.append("line %d: ondisk=%r derived=%r"
% (i, a[:60], b[:60]))
break
if derived_counts != manifest.get("counts"):
ok = False
failures.append("counts mismatch: manifest=%s derived=%s"
% (manifest.get("counts"), derived_counts))
if len(derived_rows) != n_data:
ok = False
failures.append("derived_rows %d != on-disk rows %d"
% (len(derived_rows), n_data))
# ---- measured report ----------------------------------------------------
print("CHECK-2026-11-02-jobs-table [%s]" % mode)
print(" source_root: %s%s"
% (SRC_ROOT, "" if mode == "from-source" else " (not read in this mode)"))
if mode == "from-source":
print(" source_files: %s"
% ", ".join("%s=%d" % kv for kv in sorted(derived_counts.items())))
print(" derived_rows: %d" % len(derived_rows))
print(" byte_identical: %s" % deriv_ok)
else:
print(" re_derivation: NOT ATTEMPTED (--offline: the sources are not read)")
print(" manifest.row_count: %s" % manifest.get("row_count"))
print(" on-disk_rows: %d" % n_data)
print(" sha256: %s" % disk_sha)
print(" csv_bytes: %d" % len(on_disk_bytes))
print(" fieldnames_match: %s" % fields_ok)
print(" required_fields_populated: %d/%d" % (len(disk_rows) - len(unreadable),
len(disk_rows)))
if ok:
print("VERDICT: PASS (%s)"
% ("jobs.csv re-derives from source and matches manifest"
if mode == "from-source"
else "committed artifact matches its manifest; source derivation not attempted"))
return 0
print("VERDICT: FAIL")
for f in failures:
print(" - " + f)
return 1
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))