volt: Q63 census reads CHECK-<slug> gates, and a census row may not tolerate its own rot
This commit is contained in:
1 parent
c2aff3c8f2
commit
b168ba701c
3 files changed
+152
-14
No files matched your search
@@ -31,6 +31,11 @@
|
||||
# `inert` on forge/verify_chunker_refactor.py, whose rc moves at 3 of its 11
|
||||
# sites (L123, L139, L142) that the sample did not pick.
|
||||
#
|
||||
# The census instrument's own cells gate this lane since 2026-11-02 (14 cells,
|
||||
# run before its verdict): a pathspec that cannot see a committed gate is a
|
||||
# blindness the scan's grading mode reads as clean, because the census row it
|
||||
# wrote for the file tolerates the class it no longer measures.
|
||||
#
|
||||
# The root is resolved from $0, not written down. A gate that `cd`s to an
|
||||
# absolute host path grades THAT tree from whatever checkout invokes it: at
|
||||
# `66e5be1`, a clone with one verifier deleted printed `0 unclassed of 88` and
|
||||
@@ -49,6 +54,13 @@ cd "$ROOT" || exit 2
|
||||
|
||||
python3 wizard-work/volt/q65_runner.py --selftest || exit 1
|
||||
python3 wizard-work/volt/q65_runner.py --check --class gate-run,undeclared || exit 1
|
||||
# The census instrument's own cells, before its verdict is trusted. Measured
|
||||
# 2026-11-02: the pathspecs could not read a root `CHECK-<slug>` gate, so a
|
||||
# verifier a committed gate execs measured `undeclared` and its own census row
|
||||
# tolerated the reading -- grading mode alone read 0 faults either way. The
|
||||
# selftest cell fails on that pathspec, and cell 13 faults a row whose claimed
|
||||
# wiring is gone, so the repair is what reds this leg, not a comment saying so.
|
||||
python3 wizard-work/volt/q63_verify_scan.py --selftest || exit 1
|
||||
python3 wizard-work/volt/q63_verify_scan.py --repo . >/dev/null || exit 1
|
||||
python3 wizard-work/volt/q65_no_verdict.py --selftest >/dev/null || exit 1
|
||||
python3 wizard-work/volt/q65_no_verdict.py --repo . --check >/dev/null || exit 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Q63 verifier census -- one row per COMMITTED verify_*.py at the rev the
|
||||
# scan read, class plus the evidence the class rests on.
|
||||
# rev: fe23317 (the tree these classes were read at)
|
||||
# rev: 4306881 (the tree these classes were read at)
|
||||
# row: <class> TAB <path> TAB <evidence> (three tab-separated columns)
|
||||
# class gate-run = q65_runner.py executed it and recorded an rc (Q65);
|
||||
# class wired-invoke = a committed line invokes it (the ref is the evidence);
|
||||
@@ -63,8 +63,9 @@ wired-invoke wizard-work/ledger/2026-10-29-jsonplaceholder-census/verify_predict
|
||||
wired-invoke wizard-work/ledger/2026-10-31-ledger-inventory/verify_ledger_inventory.py HEAD:wizard-work/ledger/2026-10-31-ledger-inventory/CHECK:9:exec python3 verify_ledger_invent...
|
||||
wired-invoke wizard-work/ledger/2026-11-01-todo-census/verify_todo_census.py HEAD:wizard-work/ledger/2026-11-01-todo-census/CHECK:4:exec python3 "$(dirname "$BASH_SOURCE[...
|
||||
wired-invoke wizard-work/ledger/2026-11-01-users-census/verify_users.py HEAD:wizard-work/ledger/2026-11-01-users-census/CHECK:4:exec python3 "$HERE/verify_users.py"
|
||||
gate-run wizard-work/ledger/verify_2026_11_02_openmeteo_summary.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_albums_photo_counts.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_artifact.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_artifact.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_arxiv_csai.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_arxiv_csai_fresh.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_arxiv_csv.py q65:PASS
|
||||
@@ -73,6 +74,7 @@ gate-run wizard-work/ledger/verify_arxiv_llm_agents_top15.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_catalog.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_census.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_commits_by_author_day.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_commits_census.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_commits_check.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_commits_table.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_dates.py q65:PASS
|
||||
@@ -85,19 +87,22 @@ gate-run wizard-work/ledger/verify_gitea_repos.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_github_python_repos.py q65:FAIL
|
||||
declared-one-off wizard-work/ledger/verify_github_repos.py in-file declaration
|
||||
gate-run wizard-work/ledger/verify_issues.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_issues_csv.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_ledger_census.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_ledger_dir_census.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_ledger_dir_census_2026_11_01.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_profile_census.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_python_org_repos.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_replies_catalog.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_replies_index_2026-11-02.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_reply_volume_census.py q65:FAIL
|
||||
gate-run wizard-work/ledger/verify_skill_catalog.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_stackchain_catalog.py q65:FAIL
|
||||
wired-invoke wizard-work/ledger/verify_tree_census.py HEAD:wizard-work/ledger/verify.sh:5:exec python3 wizard-work/ledger/verify_tree_census.py
|
||||
gate-run wizard-work/ledger/verify_users.py q65:PASS
|
||||
gate-run wizard-work/ledger/verify_wizard_roster_2026-10-29.py q65:PASS
|
||||
wired-invoke wizard-work/ledger/verify_wizards.py HEAD:wizard-work/ledger/verify_wizards.sh:9:exec python3 "$OUT/verify_wizards.py" "$@"
|
||||
wired-invoke wizard-work/ledger/verify_wizard_work_census_2026_11_02.py HEAD:wizard-work/ledger/CHECK:6:exec python3 verify_wizard_work_census_2026_11_02.py
|
||||
wired-invoke wizard-work/ledger/verify_wizards.py HEAD:wizard-work/ledger/CHECK-wizards:15:python3 "$HERE/verify_wizards.py" "$@"
|
||||
gate-run wizard-work/ledger/verify_workflow.py q65:FAIL
|
||||
wired-invoke wizard-work/ledger/workqueue-census/verify_workqueue_census.py HEAD:wizard-work/ledger/workqueue-census/CHECK:37:python3 "$HERE/verify_workqueue_census.py" ...
|
||||
gate-run wizard-work/null/artifact-seal/verify_artifact_seal_oracle.py q65:PASS
|
||||
@@ -106,11 +111,14 @@ gate-run wizard-work/null/satkit-2026-10-26/verify_satkit.py q65:PASS
|
||||
gate-run wizard-work/quill/verify_draft_compliance.py q65:FAIL
|
||||
gate-run wizard-work/quill/verify_placeholder_ids.py q65:PASS
|
||||
gate-run wizard-work/quill/verify_standup_draft.py q65:FAIL
|
||||
gate-run wizard-work/quill/verify_summary.py q65:FAIL
|
||||
gate-run wizard-work/sol/class-triage-2026-10-31/verify_class_triage.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_classify_audit.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_daily_ledger_triage_check.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_daily_triage_2026-10-27.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_demands_class_triage_2026_10_31.py q65:PASS
|
||||
wired-invoke wizard-work/sol/verify_independent_2026-11-02.py HEAD:wizard-work/sol/CHECK-sol-profile-triage-2026-11-02.sh:7:exec python3 verify_independent...
|
||||
gate-run wizard-work/sol/verify_fleet_classify.py q65:FAIL
|
||||
wired-invoke wizard-work/sol/verify_independent_2026-11-02.py HEAD:CHECK-sol-profile-triage-2026-11-02:15:exec python3 wizard-work/sol/verify_independent_2...
|
||||
gate-run wizard-work/sol/verify_pending_request_triage.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_probe_retire_trip_2026_10_31.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_probe_set_2026_10_31.py q65:FAIL
|
||||
@@ -118,9 +126,12 @@ gate-run wizard-work/sol/verify_register.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_reverify.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_sol_daily_ledger_triage_check.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_sol_lane_triage.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_sol_lane_triage_2026_11_01.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_sol_lane_triage_2026_11_02.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_sol_profile_file_class.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_sol_profile_file_class_2026-10-28.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_sol_profile_file_class_2026_10_31.py q65:FAIL
|
||||
wired-invoke wizard-work/sol/verify_sol_profile_file_class_2026_11_02.py HEAD:wizard-work/sol/CHECK-sol-profile-file-class-2026-11-02.sh:13:exec python3 wizard-work/s...
|
||||
wired-invoke wizard-work/sol/verify_sol_profile_triage.py HEAD:wizard-work/sol/gen_and_verify.sh:20:python3 verify_sol_profile_triage.py
|
||||
gate-run wizard-work/sol/verify_sol_profile_triage_2026_10_31.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_sol_profile_triage_check.py q65:PASS
|
||||
@@ -142,8 +153,11 @@ gate-run wizard-work/sol/verify_triage_queue.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_triage_review.py q65:PASS
|
||||
declared-one-off wizard-work/sol/verify_troupe_sol_health.py in-file declaration
|
||||
gate-run wizard-work/sol/verify_untracked_classify.py q65:FAIL
|
||||
wired-invoke wizard-work/sol/verify_untracked_classify_2026_11_02.py HEAD:CHECK-2026-11-02-untracked-classify:10:exec python3 wizard-work/sol/verify_untracked_cla...
|
||||
gate-run wizard-work/sol/verify_untracked_triad_2026_11_01.py q65:FAIL
|
||||
gate-run wizard-work/sol/verify_untracked_triad_2026_11_02.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_untracked_triage_2026_11_01.py q65:PASS
|
||||
gate-run wizard-work/sol/verify_working_tree_triage_2026_11_02.py q65:PASS
|
||||
gate-run wizard-work/spark/verify_all.py q65:PASS
|
||||
gate-run wizard-work/spark/verify_analyzer.py q65:PASS
|
||||
gate-run wizard-work/spark/verify_artifact.py q65:PASS
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 48 and column 92.
|
@@ -48,15 +48,24 @@ WHY THIS EXISTS
|
||||
otherwise). A NEW unwired file the ledger does not name is
|
||||
rc 1 the moment it lands -- the same rule checkin_baseline.tsv
|
||||
and reply_baseline.tsv already use, where a row is a stated
|
||||
tolerance and not an exemption.
|
||||
tolerance and not an exemption. Only an `undeclared` row is a
|
||||
tolerance: a row that says `gate-run`, `wired-invoke` or
|
||||
`declared-one-off` is a measurement, and a file that measures
|
||||
`undeclared` today is CLASS_REGRESSED, rc 1, even though its
|
||||
path is in the ledger. Without that rule the row absorbs the
|
||||
loss of the very wiring it recorded -- measured 2026-11-02 at
|
||||
`9466cd7`, where a CHECK-<slug> blind spot turned one wired
|
||||
file `undeclared` and the scan still read 0 faults.
|
||||
|
||||
WHAT IT PRINTS
|
||||
per-file rows only with --verbose; always the two counts, the tolerated rows,
|
||||
and the command behind each figure.
|
||||
|
||||
EXIT CODES
|
||||
0 no stripped-assert verifier; no unwired verifier outside the ledger
|
||||
1 a fault: new stripped-assert file, or a new unwired file the ledger omits
|
||||
0 no stripped-assert verifier; no unwired verifier outside the ledger; no
|
||||
census row whose measured class regressed to `undeclared`
|
||||
1 a fault: new stripped-assert file, a new unwired file the ledger omits, or
|
||||
a ledger row claiming a class the tree no longer holds
|
||||
2 could not grade (bad rev, git failure) -- outranks 1
|
||||
|
||||
Usage:
|
||||
@@ -100,7 +109,7 @@ EXIT_RE = re.compile(r"\b(?:sys\.)?exit\(\s*([^)]*?)\s*\)")
|
||||
# `unittest discover -p 'test_*.py'`). The defect was latent, not academic:
|
||||
# a nested CHECK that ran a verifier would have been read as not running it.
|
||||
CODE_PATHSPECS = ["*.py", "*.sh", ":(glob)**/CHECK", ":(glob)**/CHECK.txt",
|
||||
"*.yml", "*.yaml"]
|
||||
":(glob)**/CHECK*", "*.yml", "*.yaml"]
|
||||
# `CHECK.txt` was the second half of the same defect, measured 2026-10-25 at
|
||||
# `30653c6`: sphinx's `archive-agentic-memory-5paper-dossier-2026-10-25/CHECK.txt`
|
||||
# is one line, `python3 "$(dirname "$0")/verify_claims.py"`, and the file sat in
|
||||
@@ -110,6 +119,19 @@ CODE_PATHSPECS = ["*.py", "*.sh", ":(glob)**/CHECK", ":(glob)**/CHECK.txt",
|
||||
# one file that moves being exactly that verifier. A pathspec is a claim about
|
||||
# where a runner may live; leaving a gate filename out of it files a false
|
||||
# fault against the lane that wrote the gate.
|
||||
# The third half, measured 2026-11-02 at `c1497ef`: `CHECK`, `CHECK.txt` and
|
||||
# `*.sh` still do not name the gate shape this tree actually uses most -- a
|
||||
# root file called `CHECK-<slug>` or `CHECK-<date>-<slug>`, 25 of them at that
|
||||
# rev, 11 of which `exec python3 wizard-work/...:N`. `CHECK-2026-11-02-
|
||||
# untracked-classify:10` execs `wizard-work/sol/verify_untracked_classify_
|
||||
# 2026_11_02.py`, and the census called that verifier `undeclared` -- the Q65
|
||||
# residual, "no committed gate invokes" -- on the strength of a grep that could
|
||||
# not read the invoker. `:(glob)**/CHECK*` covers the shape at the root and
|
||||
# under a lane, and subsumes both earlier entries (kept: their histories are
|
||||
# measured and a duplicate pathspec costs nothing). The blind spot was visible
|
||||
# on exactly one file because the other 10 CHECK-* invokers also carry a
|
||||
# q65_runner row, and a graded row wires a file whether the grep sees the gate
|
||||
# or not -- a second instrument was covering for the first.
|
||||
DECLARED_RE = re.compile(r"Q63", re.I)
|
||||
DECLARED_PHRASE = "no committed gate invokes"
|
||||
# The measuring instruments name every file in the class; naming is not running.
|
||||
@@ -367,13 +389,35 @@ def read_gate(path):
|
||||
return gate, ungraded
|
||||
|
||||
|
||||
def current_class(r, gate=None):
|
||||
"""The class the tree holds NOW for one row (precedence: emit_baseline's)."""
|
||||
gate = gate or {}
|
||||
if r["path"] in gate:
|
||||
return "gate-run"
|
||||
if r["wired_refs"]:
|
||||
return "wired-invoke"
|
||||
if r["declared_one_off"]:
|
||||
return "declared-one-off"
|
||||
return "undeclared"
|
||||
|
||||
|
||||
def grade(rows, ledger, gate=None):
|
||||
gate = gate or {}
|
||||
stripped = [r for r in rows if "STRIPPED_ASSERT" in r["faults"]]
|
||||
unwired = [r for r in rows if not r["wired_refs"] and r["path"] not in gate]
|
||||
new_unwired = [r for r in unwired if r["path"] not in ledger]
|
||||
stale = [p for p in ledger if p not in {r["path"] for r in rows}]
|
||||
return stripped, unwired, new_unwired, stale
|
||||
# A census row is a MEASUREMENT, not an exemption: `wired-invoke` says a
|
||||
# committed line runs this file. Tolerance keyed on the path alone let that
|
||||
# measurement rot silently -- at `9466cd7` the pathspecs could not read a
|
||||
# root `CHECK-<slug>`, so a wired file measured `undeclared`, was tolerated
|
||||
# by its own row, and the scan read 0 faults. Only `undeclared` rows are
|
||||
# tolerances; a row that claims a runner, an invocation or a declaration and
|
||||
# measures `undeclared` today is a fault the census itself can name.
|
||||
regressed = [r for r in rows if r["path"] in ledger
|
||||
and ledger[r["path"]] != "undeclared"
|
||||
and current_class(r, gate) == "undeclared"]
|
||||
return stripped, unwired, new_unwired, stale, regressed
|
||||
|
||||
|
||||
def report(rows, ledger, rev, verbose=False, gate=None, ungraded=None):
|
||||
@@ -389,7 +433,7 @@ def report(rows, ledger, rev, verbose=False, gate=None, ungraded=None):
|
||||
for r in rows:
|
||||
tag = ",".join(r["faults"]) or ("wired" if r["wired_refs"] else ledger.get(r["path"], "NEW-UNWIRED"))
|
||||
print(f" {'FAULT ' if r['faults'] else 'ok '}{r['asserts']:2d} assert {tag:18s} {r['path']}")
|
||||
stripped, unwired, new_unwired, stale = grade(rows, ledger, gate)
|
||||
stripped, unwired, new_unwired, stale, regressed = grade(rows, ledger, gate)
|
||||
ran = [r for r in rows if r["path"] in gate and not r["wired_refs"]]
|
||||
by_verdict = {}
|
||||
for r in ran:
|
||||
@@ -427,9 +471,13 @@ def report(rows, ledger, rev, verbose=False, gate=None, ungraded=None):
|
||||
print(" unwired, NEW (fault) : %d" % len(new_unwired))
|
||||
for r in new_unwired:
|
||||
print(f" NEW_UNWIRED {r['path']}")
|
||||
print(" census class regressed : %d (row claims a runner/invocation/declaration; tree says undeclared)"
|
||||
% len(regressed))
|
||||
for r in regressed:
|
||||
print(f" CLASS_REGRESSED {r['path']} (census: {ledger[r['path']]})")
|
||||
if stale:
|
||||
print(" stale ledger rows : %d (advisory): %s" % (len(stale), ", ".join(stale[:5])))
|
||||
faults = len(stripped) + len(new_unwired)
|
||||
faults = len(stripped) + len(new_unwired) + len(regressed)
|
||||
print(f"q63: {faults} fault(s)")
|
||||
return faults
|
||||
|
||||
@@ -491,7 +539,9 @@ def emit_baseline(rows, path, gate=None, rev=None):
|
||||
|
||||
|
||||
def selftest():
|
||||
"""Four cells on a throwaway repo: the two fault classes, and the ledger rule."""
|
||||
"""Cells on a throwaway repo: both fault classes, the ledger rule, the
|
||||
pathspec blind spots (Q150 root files, Q63 CHECK-<slug> gates) and the
|
||||
class-regression rule."""
|
||||
import tempfile
|
||||
d = tempfile.mkdtemp(prefix="q63-selftest-")
|
||||
env = dict(os.environ, GIT_AUTHOR_NAME="t", GIT_AUTHOR_EMAIL="t@t",
|
||||
@@ -607,6 +657,58 @@ def selftest():
|
||||
cells.append(("a repo-root verifier is in the population",
|
||||
len(roots) == 1 and roots[0]["lane"] == "(root)"))
|
||||
|
||||
# (12) the gate shape this tree actually uses: a root file called
|
||||
# `CHECK-<slug>`. At `c1497ef` the pathspecs named `CHECK`, `CHECK.txt`
|
||||
# and `*.sh` -- none of them match `CHECK-2026-11-02-untracked-classify`
|
||||
# -- so the census called a verifier that gate execs `undeclared`.
|
||||
# The control is the same fixture under a name the glob cannot match:
|
||||
# if that one also reads wired, the cell is not testing the pathspec.
|
||||
put("wizard-work/x/verify_gateform.py", "import sys\nsys.exit(0)\n")
|
||||
put("wizard-work/x/verify_nowire.py", "import sys\nsys.exit(0)\n")
|
||||
put("CHECK-q999", "exec python3 wizard-work/x/verify_gateform.py\n")
|
||||
put("XCHECK-q999", "exec python3 wizard-work/x/verify_nowire.py\n")
|
||||
commit("c12")
|
||||
rows = scan(d, "HEAD")
|
||||
by = {r["path"]: r for r in rows}
|
||||
cells.append(("a root CHECK-<slug> gate wires the verifier it execs",
|
||||
len(by["wizard-work/x/verify_gateform.py"]["wired_refs"]) == 1
|
||||
and by["wizard-work/x/verify_nowire.py"]["wired_refs"] == []))
|
||||
|
||||
# (13) a census row is a measurement, not an exemption. A file rowed
|
||||
# `wired-invoke` and then unwired in a later commit must fault, or the
|
||||
# row tolerates its own rot -- exactly how the CHECK-<slug> blind spot
|
||||
# survived: the row for `verify_untracked_classify_2026_11_02.py` said
|
||||
# wired-invoke, the pathspec-less scan measured `undeclared`, and
|
||||
# presence of the path alone was enough to read clean. The control is
|
||||
# the same file rowed `undeclared`: then the row IS the tolerance and
|
||||
# the scan must stay clean.
|
||||
put("wizard-work/x/verify_regress.py", "import sys\nsys.exit(0)\n")
|
||||
put("CHECK-q998", "exec python3 wizard-work/x/verify_regress.py\n")
|
||||
commit("c13")
|
||||
rows = scan(d, "HEAD")
|
||||
led = {r["path"]: "wired-invoke" for r in rows
|
||||
if r["path"].endswith("verify_regress.py")}
|
||||
before = grade(rows, led)[4]
|
||||
os.remove(os.path.join(d, "CHECK-q998"))
|
||||
commit("c14")
|
||||
rows = scan(d, "HEAD")
|
||||
after = [r["path"] for r in grade(rows, led)[4]]
|
||||
tol = grade(rows, {"wizard-work/x/verify_regress.py": "undeclared"})[4]
|
||||
cells.append(("a row that claims wiring faults when the wiring is gone",
|
||||
before == [] and after == ["wizard-work/x/verify_regress.py"]
|
||||
and tol == []))
|
||||
|
||||
# (14) a missing gate ledger is rc 2 (could not grade), not rc 0. Without
|
||||
# the guard, read_gate returns {} and every `gate-run` row measures
|
||||
# `undeclared` -- the scan's own control run in this tick printed 175
|
||||
# faults against a tree that has 0, which is the loudest possible way
|
||||
# to be wrong. An absent instrument is neither a pass nor a fault.
|
||||
p = subprocess.run([sys.executable, os.path.abspath(__file__), "--repo", d,
|
||||
"--gate", os.path.join(d, "no-such-gate.tsv")],
|
||||
capture_output=True, text=True)
|
||||
cells.append(("a missing gate ledger is ungradable (rc 2), not clean",
|
||||
p.returncode == 2 and "cannot grade" in (p.stdout + p.stderr)))
|
||||
|
||||
for name, passed in cells:
|
||||
print(f" {'PASS' if passed else 'FAIL'} {name}")
|
||||
ok &= passed
|
||||
@@ -630,6 +732,15 @@ def main():
|
||||
a = ap.parse_args()
|
||||
if a.selftest:
|
||||
return selftest()
|
||||
if not os.path.isfile(a.gate):
|
||||
# Measured 2026-11-02 while building the CHECK-<slug> control: a copy of
|
||||
# this file run from outside its lane resolved DEFAULT_GATE to a path
|
||||
# that does not exist, read_gate returned {}, every `gate-run` row
|
||||
# measured `undeclared`, and the scan reported 175 faults against a
|
||||
# tree that has 0. A missing ledger is not a clean ledger and not a
|
||||
# fault either -- it is a missing instrument, which is rc 2.
|
||||
print(f"q63_verify_scan: cannot grade: gate ledger is missing: {a.gate}")
|
||||
return 2
|
||||
try:
|
||||
rows = scan(a.repo, a.rev)
|
||||
except RuntimeError as e:
|
||||
@@ -656,11 +767,12 @@ def main():
|
||||
for ln in r["mention_refs"][:3]:
|
||||
print(f" mention {ln[:150]}")
|
||||
if a.json:
|
||||
stripped, unwired, new_unwired, stale = grade(rows, read_baseline(a.baseline))
|
||||
stripped, unwired, new_unwired, stale, regressed = grade(rows, read_baseline(a.baseline), gate)
|
||||
with open(a.json, "w", encoding="utf-8") as f:
|
||||
json.dump({"rev": a.rev, "verifiers": len(rows), "rows": rows,
|
||||
"stripped_assert": len(stripped), "unwired": len(unwired),
|
||||
"new_unwired": len(new_unwired), "stale": stale}, f, indent=1)
|
||||
"new_unwired": len(new_unwired), "stale": stale,
|
||||
"class_regressed": [r["path"] for r in regressed]}, f, indent=1)
|
||||
return 0 if faults == 0 else 1
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user