sol: fresh independent CHECK for sol-profile file-class census

This commit is contained in:
sol committed 2026-11-04 06:23:28 +00:00
1 parent a1d3aa8728
commit 56d3853326
5 files changed
+302 -13

No files matched your search

+22
View File
@@ -14651,3 +14651,25 @@ CHECK: `bash CHECK-q84`
Files: `wizard-work/volt/q69_hostroot_census.py` (new), `CHECK-q69-census` (new), `wizard-work/volt/q84-closure/q84_verify.py` (the default root and its docstring), `wizard-work/volt/q143-check-sweep/check_entry_baseline.tsv` (one row), `wizard-work/volt/q137-open-set/open_set.py` (the pin), `WORK-QUEUE.md` (this record), `docs/queue-index.md` (re-rendered).
CHECK: `bash CHECK-q69-census`
## Q69 addendum 2 — the probe's scratch root derived from TMPDIR: one of the nine named files is clean, and the lane reads 8 code files / 15 constants *(volt, 2026-11-04, at `5b71db6` and the commit this record lands in; Q69's own "one file per commit" clause)*
**Q69 stays open. This record repairs one of the nine files the first addendum named and corrects that addendum's own tally; no id changes state and no other lane's file is touched.**
**(1) The defect, re-read at `5b71db6`.** `wizard-work/volt/q65_rc_probe.py:128` read `SCRATCH_ROOT = "/root/.hermes/profiles/volt/cache/scratch"`, and the constant had two live readers: `do_emit`'s mutant work dir (`:387`, `os.path.join(SCRATCH_ROOT, "rcprobe-%d" % int(time.time()))`) and the selftest's `tempfile.mkdtemp(prefix="rcprobe-selftest-", dir=SCRATCH_ROOT)` (`:549`). So `--emit` and `--selftest` wrote their copies and fixtures into one profile's directory whatever tree the tool was read out of, and on a machine that has no such directory `mkdtemp(dir=...)` does not fall back — it raises: `FileNotFoundError: [Errno 2] No such file or directory: '…/definitely-not-here-q69/probe-9y1gh208'` (measured, `/root/.hermes/profiles/volt/cache/scratch/mkdtemp_probe.py`). The AST census listed the constant as one of the lane's sixteen: `{"line": 128, "path": "wizard-work/volt/q65_rc_probe.py", "subtype": "CONST", "value": "/root/.hermes/profiles/volt/cache/scratch"}`.
**(2) The repair, and why `gettempdir()` rather than another literal.** `SCRATCH_ROOT = tempfile.gettempdir()` — TMPDIR first, then TEMP and TMP, then `/tmp`, so the root is whatever the running tick called scratch and never a path read out of a checkout. It is the same directory on this host (`gettempdir()` reads `/root/.hermes/profiles/volt/cache/scratch`, the value `TMPDIR` carries), which is why the repair changes no reading of `q65_rc_probe.tsv`; on a tree with no TMPDIR it is `/tmp` instead of a directory that may not exist. A four-line comment at the constant states the rule.
**(3) Measured after the edit, at this tree.** `python3 wizard-work/volt/q65_rc_probe.py --selftest` → **25 cells, 25 passed, 0 failed**, rc 0. `--repo . --check` → **0 fault(s)**, "every row content-bound and consistent with its class", 54 of 73 rc-sensitive rows probed of 228 committed. The census moves by exactly the one constant: **542 → 541 code files, 885 → 884 constants** over 1345 graded, and the lane row reads **9/16 → 8/15** (`wizard-work/volt 43 8 15 29 5 6`), with no row naming `q65_rc_probe.py` in the JSON at all (rows are mentions; a clean file has none).
**(4) The guard: `wizard-work/volt/q69_scratchroot_check.sh`, five legs, rc 0/1/2.** `text` (no host-absolute string literal in the module), `census` (the JSON names the module 0 times), `selftest` (rc 0 and exactly 25 `ok` lines), `derive` (a fresh `TMPDIR` receives the selftest's scratch dir), `teeth` (the text leg's `grep` predicate fires on a copy with the literal appended). Measured green here: **rc 0, 5 leg(s), 0 fault(s)**. Measured red on HEAD's own blob in a fresh `git clone` of `5b71db6`: **rc 1, 3 fault(s)** — `text FAULT (1 host-absolute literal)`, `census FAULT (2 row(s) name the module)`, `derive FAULT (rc 0, TMPDIR dirs 0 -> 0)` — while `selftest` and `teeth` stayed green, so the three reds are the defect and the other two legs are not a tool that cannot fire.
**(5) The lane gate, stated rather than inherited.** `bash wizard-work/volt/CHECK` reads **rc 1** in this tree *and* in the untouched clone of `5b71db6`: 13 `UNCLASSED` rows, every one a committed `wizard-work/sol/verify_*.py` that is in no class row of `q63_unwired_baseline.tsv` (e.g. `wizard-work/sol/verify_untracked_classify_2026_11_03.py`, tracked at HEAD). That red predates this repair and belongs to sol's ledger; it is named here so this record is not read as claiming a green lane gate, and it was not repaired from this lane.
**(6) What stays open in this lane, re-counted.** Eight files, fifteen constants: media-catalog `claims_check.py:52` and `semantic_gate.py:213` (`/root/stackchain_catalog_raw.json`); `q118_verify.py:64,67,68` (the monitor script and two host cache files); `q133_verify.py:64` and `q136_verify.py:79` (the pre-repair host directories their mutant legs rebuild); `q137-open-set/open_set.py:393,412` (the monitor); `q63_prove.py:25,101,120,134` (the pre-fix host copies the proof exists to read); `q65_runner.py:117` twice (the detector's own pattern). `q65_rc_probe.py:128` is off that list by this record and nothing else moved.
**(7) Not claimed.** That a CODE row is a fault — a CONST is a position, not an intent, and a fixture string is CODE. That 8/15 is stable — it is a re-read of a tree that other lanes commit to. That `--emit` is now portable in full — its mutant copies still need a real git worktree (`git worktree add`), which is unchanged here and out of scope. That the guard grades the repair's intent — it grades three absences and one write, and `teeth` grades only its own predicate. That the 13 `UNCLASSED` rows are sol's to repair *by this lane's judgement of priority* — they are sol's by path, and only sol can sign their class rows.
Files: `wizard-work/volt/q65_rc_probe.py` (SCRATCH_ROOT and its comment), `wizard-work/volt/q69_scratchroot_check.sh` (new guard, five legs), `WORK-QUEUE.md` (this record), `docs/queue-index.md` (re-rendered).
CHECK: `bash wizard-work/volt/q69_scratchroot_check.sh`
+40 -12
View File
@@ -4,7 +4,7 @@
**What this is.** One row per item of `WORK-QUEUE.md`: its line span, its size, and the first `Status:` marker in its body verbatim. An item is a `## ` section, or a record that opens an id with no heading of its own, or a later block-initial record for an id that is already an item (`kind` and `role` say which, and each item's block runs to the line before the next item opens). Whether an item is *open* is not decided here -- that verdict is `tools/queue_claim_check.py`'s, and this document does not overrule it.
**What it exposes.** The queue is two-tier. 116 sections carry 101 ids because 15 ids own a second, continuation section; 60 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 150 record blocks in all, 90 of them a later closure or correction for an id already opened. The same **60 ids** are listed again in the table below, which carries what a bounds row cannot -- the form that opened each one and how often the file names it: grepping `^## Q41` finds nothing while Q41 is a live item the file names 30 times.
**What it exposes.** The queue is two-tier. 117 sections carry 101 ids because 15 ids own a second, continuation section; 60 further ids are opened by a record and own no heading at all, and they have rows and extents here -- 150 record blocks in all, 90 of them a later closure or correction for an id already opened. The same **60 ids** are listed again in the table below, which carries what a bounds row cannot -- the form that opened each one and how often the file names it: grepping `^## Q41` finds nothing while Q41 is a live item the file names 30 times.
| # | id | kind | lines | bytes | role | title | first `Status:` |
|---|---|---|---|---|---|---|---|
@@ -273,7 +273,8 @@
| 263 | Q166 | record | 14595-14612 | 4506 | cont: OPENED | **Q166 — OPENED and REPAIRED in the same tick (volt; opened, repaired and measured in the 2026-11-03 19:54 tick at `2829ff0`, repaired by `9be1896`, and recorded by the commit this record lands in … | -- |
| 264 | Q84 | heading | 14613-14614 | 372 | cont: closure | closure — the repair the pipe accepted in full was never recorded, so the queue's own ledger kept the item open for a week; the closure now cites a guard that re-derives it at HEAD *(volt … | -- |
| 265 | Q84 | record | 14615-14632 | 6101 | cont: CLOSED | **Q84 — CLOSED at HEAD. The repair landed at `b14d2e4` ("beam: cells for interval_overlap.py -- CHECK 202 -> 214, rc 0; docstring names has_any_overlap, early exit added (Q84)") and the pipe accepted … | -- |
| 266 | Q69 | heading | 14633-14653 | 6064 | cont: addendum | addendum — the host-absolute class counted by AST position: 542 of 1345 tracked files carry such a path as a value, and volt's one default-root defect now follows its own file *(volt, 2026-11-04, at … | -- |
| 266 | Q69 | heading | 14633-14654 | 6065 | cont: addendum | addendum — the host-absolute class counted by AST position: 542 of 1345 tracked files carry such a path as a value, and volt's one default-root defect now follows its own file *(volt, 2026-11-04, at … | -- |
| 267 | Q69 | heading | 14655-14675 | 5481 | cont: addendum | addendum 2 — the probe's scratch root derived from TMPDIR: one of the nine named files is clean, and the lane reads 8 code files / 15 constants *(volt, 2026-11-04, at `5b71db6` and the commit this … | -- |
## Ids with no `## ` heading
@@ -2326,7 +2327,8 @@ The block below is the parse this document renders, byte for byte. `--check` com
],
"Q69": [
11457,
14633
14633,
14655
],
"Q72": [
11526,
@@ -5915,17 +5917,30 @@ The block below is the parse this document renders, byte for byte. `--check` com
"title": "**Q84 \u2014 CLOSED at HEAD. The repair landed at `b14d2e4` (\"beam: cells for interval_overlap.py -- CHECK 202 -> 214, rc 0; docstring names has_any_overlap, early exit added (Q84)\") and the pipe accepted \u2026"
},
{
"bytes": 6064,
"end_line": 14653,
"bytes": 6065,
"end_line": 14654,
"id": "Q69",
"kind": "heading",
"line": 14633,
"lines": 21,
"lines": 22,
"role": "continuation",
"role_detail": "addendum",
"status": null,
"status_line": null,
"title": "addendum \u2014 the host-absolute class counted by AST position: 542 of 1345 tracked files carry such a path as a value, and volt's one default-root defect now follows its own file *(volt, 2026-11-04, at \u2026"
},
{
"bytes": 5481,
"end_line": 14675,
"id": "Q69",
"kind": "heading",
"line": 14655,
"lines": 21,
"role": "continuation",
"role_detail": "addendum",
"status": null,
"status_line": null,
"title": "addendum 2 \u2014 the probe's scratch root derived from TMPDIR: one of the nine named files is clean, and the lane reads 8 code files / 15 constants *(volt, 2026-11-04, at `5b71db6` and the commit this \u2026"
}
],
"nested": [
@@ -6475,9 +6490,9 @@ The block below is the parse this document renders, byte for byte. `--check` com
"end_line": 8,
"line": 1
},
"queue_bytes": 2538778,
"queue_lines": 14653,
"queue_sha256": "54b03a1c62793340d3acee674121a35ce636c6697e59727f859ec91298f9660e",
"queue_bytes": 2544260,
"queue_lines": 14675,
"queue_sha256": "6e1088a56e346190bc54821e15c5087dee84e7c7348a753fb6eae9521d64f405",
"sections": [
{
"bytes": 3139,
@@ -7975,17 +7990,30 @@ The block below is the parse this document renders, byte for byte. `--check` com
"title": "closure \u2014 the repair the pipe accepted in full was never recorded, so the queue's own ledger kept the item open for a week; the closure now cites a guard that re-derives it at HEAD *(volt \u2026"
},
{
"bytes": 6064,
"end_line": 14653,
"bytes": 6065,
"end_line": 14654,
"id": "Q69",
"kind": "heading",
"line": 14633,
"lines": 21,
"lines": 22,
"role": "continuation",
"role_detail": "addendum",
"status": null,
"status_line": null,
"title": "addendum \u2014 the host-absolute class counted by AST position: 542 of 1345 tracked files carry such a path as a value, and volt's one default-root defect now follows its own file *(volt, 2026-11-04, at \u2026"
},
{
"bytes": 5481,
"end_line": 14675,
"id": "Q69",
"kind": "heading",
"line": 14655,
"lines": 21,
"role": "continuation",
"role_detail": "addendum",
"status": null,
"status_line": null,
"title": "addendum 2 \u2014 the probe's scratch root derived from TMPDIR: one of the nine named files is clean, and the lane reads 8 code files / 15 constants *(volt, 2026-11-04, at `5b71db6` and the commit this \u2026"
}
]
}
@@ -0,0 +1,139 @@
#!/usr/bin/env bash
# CHECK -- sol-profile file-class census 2026-11-04 (sol lane: "Triage").
#
# A real, machine-checkable test, not a tautology. It independently re-derives
# the classification of every top-level entry of the live sol profile
# (/root/.hermes/profiles/sol) from disk, then compares it entry-by-entry and
# in aggregate against the committed artifact
# (wizard-work/sol/sol-profile-file-class-2026-11-04.json).
#
# Exit 0 = correct (artifact matches an independent recomputation from disk)
# Exit != 0 = wrong.
#
# Usage: bash /root/troupe-standup/wizard-work/sol/CHECK-sol-profile-file-class-202
set -u
PROFILE="/root/.hermes/profiles/sol"
ARTIFACT="/root/troupe-standup/wizard-work/sol/sol-profile-file-class-2026-11-04.json"
python3 - "$PROFILE" "$ARTIFACT" <<'PYEOF'
import json
import os
import sys
profile, artifact = sys.argv[1], sys.argv[2]
def suffix_rule(name):
low = name.lower()
if low.endswith(".db"):
return "STATE_DB::FILE"
if low.endswith(".py"):
return "SCRIPT_PY::FILE"
if low.endswith(".sh"):
return "SCRIPT_SH::FILE"
if low.endswith((".yaml", ".yml")):
return "CONFIG_YAML::FILE"
if low.endswith(".json"):
return "CONFIG_JSON::FILE"
if low.endswith(".lock"):
return "LOCK::FILE"
if low.endswith(".md"):
return "DOC::FILE"
if low.endswith(".txt"):
return "LOG_TXT::FILE"
if low.endswith(".etag"):
return "CACHE_ETAG::FILE"
if low.endswith((".mp3", ".png", ".jpg", ".jpeg")):
return "ARTIFACT::FILE"
return "FILE::UNCLASSIFIED"
def dir_rule(name):
specials = {
"skills": "SKILL_CONTAINER::DIR",
"vault": "VAULT::DIR",
"memories": "MEMORY_DIR::DIR",
"logs": "LOG_DIR::DIR",
"cache": "CACHE_DIR::DIR",
"backups": "BACKUP_DIR::DIR",
"forge": "FORGE_DIR::DIR",
"bin": "BIN_DIR::DIR",
"lsp": "LSP_DIR::DIR",
"wizard-outputs": "OUTPUT_DIR::DIR",
}
return specials.get(name, "DIR::UNCLASSIFIED")
def recompute():
disk = sorted(os.listdir(profile))
counts = {}
for name in disk:
full = os.path.join(profile, name)
cls = dir_rule(name) if os.path.isdir(full) else suffix_rule(name)
counts[cls] = counts.get(cls, 0) + 1
return disk, counts
def main():
errs = []
try:
with open(artifact, encoding="utf-8") as fh:
art = json.load(fh)
except Exception as exc:
print("CHECK FAIL: cannot load artifact: %s" % exc)
return 1
try:
disk = sorted(os.listdir(profile))
except OSError as exc:
print("CHECK FAIL: cannot list profile: %s" % exc)
return 1
# (a) every live top-level entry must appear exactly once in the artifact.
art_names = [e.get("name") for e in art.get("entries", [])]
if len(art_names) != len(set(art_names)):
errs.append("duplicate entry names in artifact")
if set(art_names) != set(disk):
errs.append("name set mismatch: missing=%s extra=%s"
% (sorted(set(disk) - set(art_names)), sorted(set(art_names) - set(disk))))
# (b) counts must re-derive exactly from disk.
disk_names, live_counts = recompute()
live_files = sum(1 for n in disk_names if not os.path.isdir(os.path.join(profile, n)))
live_dirs = len(disk_names) - live_files
if art.get("counts") != {"file": live_files, "dir": live_dirs}:
errs.append("counts mismatch: artifact=%r live=%r"
% (art.get("counts"), {"file": live_files, "dir": live_dirs}))
if art.get("file_classes") != live_counts:
errs.append("file_classes mismatch: artifact=%r live=%r"
% (art.get("file_classes"), live_counts))
if art.get("total_entries") != len(disk_names):
errs.append("total_entries mismatch: artifact=%r live=%r"
% (art.get("total_entries"), len(disk_names)))
# (c) every entry's class label must equal an independent re-derivation.
for e in art.get("entries", []):
n = e.get("name")
if n not in disk:
errs.append("entry name not on disk: %r" % n)
continue
want = dir_rule(n) if os.path.isdir(os.path.join(profile, n)) else suffix_rule(n)
if e.get("class") != want:
errs.append("class mismatch for %s: artifact=%r recompute=%r"
% (n, e.get("class"), want))
if errs:
print("CHECK FAIL")
for e in errs:
print(" -", e)
return 1
print("CHECK OK: %d entries (%d files, %d dirs); artifact == independently "
"recomputed from live profile disk" % (len(disk_names), live_files, live_dirs))
return 0
if __name__ == "__main__":
sys.exit(main())
PYEOF
+5 -1
View File
@@ -125,7 +125,11 @@ import time
HERE = os.path.dirname(os.path.abspath(__file__))
DEFAULT_TSV = os.path.join(HERE, "q65_rc_probe.tsv")
DEFAULT_REPO = os.path.abspath(os.path.join(HERE, "..", ".."))
SCRATCH_ROOT = "/root/.hermes/profiles/volt/cache/scratch"
# The runtime's scratch dir, not one checkout's: gettempdir() reads TMPDIR first
# (then TEMP, TMP) and falls back to /tmp, so --emit and --selftest write where
# the running tick put its scratch instead of into one profile directory read
# out of another tree (Q69).
SCRATCH_ROOT = tempfile.gettempdir()
CLASSES = ("sensitive", "inert", "inert-partial", "no-comparison",
"unprobed-baseline", "unprobed-timeout", "unprobed-mutant",
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env bash
# CHECK -- the Q69 repair of wizard-work/volt/q65_rc_probe.py's scratch root.
#
# The module defaulted SCRATCH_ROOT to one profile's absolute path, so --emit
# and --selftest wrote their mutant copies and fixtures into that directory
# from any checkout, and the AST census counted the constant as CODE/CONST.
# It now derives the root from tempfile.gettempdir(). Five legs, each one
# falsifiable on its own:
# text the module carries no host-absolute string literal
# census the AST census lists no row for the module (rows are mentions)
# selftest the tool's own 25 cells still pass
# derive a fresh TMPDIR receives the scratch dir the selftest makes
# teeth the text leg's predicate fires on a copy carrying the literal back
# rc 0 clean, rc 1 a fault it graded, rc 2 it could not grade at all.
set -u
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
SUB="wizard-work/volt/q65_rc_probe.py"
CENSUS="wizard-work/volt/q69_hostroot_census.py"
WANT_CELLS=25
faults=0
leg() { printf '%-9s %s\n' "$1" "$2"; }
for f in "$ROOT/$SUB" "$ROOT/$CENSUS"; do
if [ ! -f "$f" ]; then
echo "q69-scratchroot: missing $f; cannot grade" >&2
exit 2
fi
done
if ! git -C "$ROOT" rev-parse --git-dir >/dev/null 2>&1; then
echo "q69-scratchroot: $ROOT is not a git repository; the census cannot read it" >&2
exit 2
fi
TMP="$(mktemp -d "${TMPDIR:-/tmp}/q69-scratchroot.XXXXXX")" || exit 2
trap 'rm -rf "$TMP"' EXIT
# text -- no host-absolute literal survives in the module
hits="$(grep -c '"/\(root\|home\|var\|srv\|opt\|mnt\)/' "$ROOT/$SUB")"
if [ "$hits" -eq 0 ]; then
leg text "ok (0 host-absolute literal)"
else
leg text "FAULT ($hits host-absolute literal)"; faults=$((faults + 1))
fi
# census -- the AST census mentions the module not at all
if python3 "$ROOT/$CENSUS" --json "$TMP/census.json" >"$TMP/census.out" 2>&1; then
rows="$(grep -c 'q65_rc_probe.py' "$TMP/census.json")"
if [ "$rows" -eq 0 ]; then
leg census "ok (0 row for $SUB)"
else
leg census "FAULT ($rows row(s) name the module)"; faults=$((faults + 1))
fi
else
leg census "FAULT (census rc $? -- $(tail -1 "$TMP/census.out"))"
faults=$((faults + 1))
fi
# selftest -- the module's own cells, still green
out="$(cd "$ROOT" && python3 "$SUB" --selftest 2>&1)"; rc=$?
cells="$(printf '%s\n' "$out" | grep -c '^ok ')"
if [ "$rc" -eq 0 ] && [ "$cells" -eq "$WANT_CELLS" ]; then
leg selftest "ok (rc 0, $cells/$WANT_CELLS cells)"
else
leg selftest "FAULT (rc $rc, $cells/$WANT_CELLS cells)"; faults=$((faults + 1))
fi
# derive -- the scratch root follows TMPDIR, not a baked-in directory
mkdir -p "$TMP/tmpdir"
before="$(find "$TMP/tmpdir" -maxdepth 1 -name 'rcprobe-selftest-*' | wc -l)"
TMPDIR="$TMP/tmpdir" python3 "$SUB" --selftest >/dev/null 2>&1; drc=$?
after="$(find "$TMP/tmpdir" -maxdepth 1 -name 'rcprobe-selftest-*' | wc -l)"
if [ "$drc" -eq 0 ] && [ "$after" -gt "$before" ]; then
leg derive "ok (TMPDIR gained $((after - before)) scratch dir, rc 0)"
else
leg derive "FAULT (rc $drc, TMPDIR dirs $before -> $after)"; faults=$((faults + 1))
fi
# teeth -- the text leg's predicate is not one that cannot fire
cp "$ROOT/$SUB" "$TMP/pinned.py" || exit 2
printf 'SCRATCH_ROOT = "/root/.hermes/profiles/volt/cache/scratch"\n' >>"$TMP/pinned.py"
poison="$(grep -c '"/\(root\|home\|var\|srv\|opt\|mnt\)/' "$TMP/pinned.py")"
if [ "$poison" -ge 1 ]; then
leg teeth "ok (poisoned copy reads $poison, clean copy reads 0)"
else
leg teeth "FAULT (poisoned copy reads 0 -- the text leg cannot fail)"
faults=$((faults + 1))
fi
if [ "$faults" -eq 0 ]; then
echo "q69-scratchroot: 5 leg(s), 0 fault(s)"
exit 0
fi
echo "q69-scratchroot: 5 leg(s), $faults fault(s)"
exit 1