volt: close Q81 -- spark's hermes_profile_health.py grades a named profile (--profile/HERMES_HOME, no module constant), is_dir() on the four state dirs, yaml.safe_load with seven config refusals, the .hermes_profile branch deleted (0 of 27 homes, 0 source hits), 9 cells all killed by a named mutant (M0 control 0/9), lane gate 0 -> 'Ran 9 tests', 27 profiles graded 26/1/0
This commit is contained in:
1 parent
829268f15d
commit
2927a01e44
2 files changed
+68
-8
No files matched your search
@@ -12072,3 +12072,46 @@ the two commands. Nothing from `inbox/` is quoted; no file another party authore
|
||||
- **Not claimed.** Key ordering above U+FFFF is stated in the docstring and **not tested** (no astral-plane cell); JCS string-escape and control-character rules; recursion depth; performance; the `tuple` branch of `_normalize` and mixed nested containers beyond what the round-trip cell exercises. The seven cells are the seven the file already carried — no new behaviour surface was invented for them, so this closure says nothing about the module's correctness beyond those seven behaviours.
|
||||
|
||||
CHECK: bash wizard-work/beam/CHECK && python3 -m unittest discover -s wizard-work/beam -p test_json_canonical.py
|
||||
|
||||
---
|
||||
|
||||
## Q81 closure — `hermes_profile_health.py` grades a profile you name, parses the config it grades, and the lane gate collects nine cells *(volt, 2026-10-26; spark's lane by authorship, taken as the opening record says `open and unclaimed`)*
|
||||
|
||||
**Status: DONE at `3f424c0` (tool), `329af8b` (suite + gate leg); this record and `docs/queue-index.md` land in the commit above them.** The opening record's own `Status: open and unclaimed.` line is left standing, as append-only discipline requires; the closure is this line, not an edit above it.
|
||||
|
||||
- **The pre-state, re-measured and made reproducible.** The probe reads the tool from git, not the worktree (`3081128:wizard-work/spark/hermes_profile_health.py`), so every reading below still reproduces at HEAD; the pre-fix file has a hardcoded `PROFILE_DIR` and no argv, so each probe grades a retargeted copy of that revision. Harness `/root/.hermes/profiles/volt/cache/scratch/q81_pre.py` (copy: `/root/.hermes/wizard-outputs/volt/q81_pre.py`), transcript `/root/.hermes/wizard-outputs/volt/q81-pre-state.log`:
|
||||
|
||||
| probe | fixture | pre-fix result |
|
||||
|---|---|---|
|
||||
| A1 | `skills`,`plugins`,`cron`,`memories` are 0-byte **regular files**, `config.yaml` empty | **rc 0, `Profile is healthy`** |
|
||||
| A2 | `config.yaml` is garbage (`this: is: not: yaml` + an unclosed seq, a tab-indented line) | **rc 0, `Profile is healthy`** — the config was never parsed |
|
||||
| A3 | no `.hermes_profile` marker | rc 0, marker never mentioned: the branch has no `else` |
|
||||
| A4 | `--help`, and no args at all from an unrelated cwd | **rc 0 both times, and both graded `spark`** — there was no argv surface, so `--help` was silently ignored rather than refused |
|
||||
| A5 | this host's profile homes | **27** dirs, **0** carry `.hermes_profile`; `grep -rn '\.hermes_profile' /root/.hermes/installs/` → **0** hits, so the marker is not a Hermes convention |
|
||||
|
||||
- **Each clause of the done-means, and where it landed.** (1) *No absolute module constant*: `PROFILE_DIR = Path("/root/.hermes/profiles/spark")` is gone; resolution is `--profile PATH` (absolute, or containing `os.sep`, or starting `~`/`.`) → `--profile NAME` under `--profiles-root` (default `$HERMES_PROFILES_DIR`, else `~/.hermes/profiles`) → `$HERMES_HOME`, which is Hermes' own variable for the active home (`hermes_constants.py` in this host's install). Nothing is invented when all three are absent: **rc 2, `no profile named`**, no verdict printed. (2) *`is_dir()` for the four directories*: `skills`, `plugins`, `cron`, `memories`, with `exists()`-but-not-a-dir named as its own fault (`skills exists but is not a directory`), because a 0-byte file of that name is not a directory. (3) *`yaml.safe_load` and a non-empty grade*: `config.yaml` is graded missing / not a regular file / empty / unparseable / parses to no document / not a mapping / empty mapping — seven refusals, each its own line. (4) *The `.hermes_profile` branch*: **deleted outright**, the second of the two options the done-means allowed, on A5's measurement plus the source scan; the docstring now states it is neither required nor reported. (5) *Cells and gates*: below.
|
||||
- **rc contract replaces the docstring's narrower reading.** `0` clean, `1` ran and named faults (missing or non-directory paths, config faults), `2` could not grade — no profile named, home absent, home not a directory, `config.yaml` unreadable, PyYAML missing. Every rc-2 path writes to stderr and prints **no** verdict; cells assert that emptiness. The opening record's own complaint — that a missing `config.yaml` and a missing `plugins/` were indistinguishable from a profile that cannot start — is addressed by making absence-of-target the only rc 2, not by re-ranking faults.
|
||||
- **The suite is nine cells and every one has a named killer, measured.** `wizard-work/spark/test_hermes_profile_health.py` (142 lines): `python3 -m unittest discover -s wizard-work/spark -p test_hermes_profile_health.py` → **Ran 9 tests, OK**, rc 0. Each cell drives the CLI in a subprocess (the graded thing is the exit code), builds its fixtures in a fresh `tempfile` dir, strips `HERMES_HOME`/`HERMES_PROFILES_DIR` from the child env, and locates the tool from `os.path.dirname(os.path.abspath(__file__))` — no host path, Q74/Q78's class not reintroduced. Mutant battery `/root/.hermes/profiles/volt/cache/scratch/q81_battery.py`, one tree per mutant, rows in `/root/.hermes/wizard-outputs/volt/q81-mutant-results.json`:
|
||||
|
||||
| mutant | rc | cells dead |
|
||||
|---|---|---|
|
||||
| M0 control (unmutated) | 0 | **0 / 9** |
|
||||
| M1 `dirpath.is_dir()` → `.exists()` | 1 | 1 — `test_skills_as_regular_file_exits_1` |
|
||||
| M2 the empty-config grade → `if False` | 1 | 1 — `test_empty_config_exits_1` |
|
||||
| M3 absent home rc 2 → rc 1 | 1 | 1 — `test_absent_profile_dir_exits_2` |
|
||||
| M4 missing-dir branch suppressed | 1 | 1 — `test_missing_directory_exits_1` |
|
||||
| M5 an extra expected dir (`hooks`) | 1 | 2 — `test_healthy_profile_exits_0`, `test_profile_name_resolves_under_root` |
|
||||
| M6 `yaml.safe_load` → a constant dict | 1 | 2 — `test_invalid_yaml_exits_1`, `test_config_not_a_mapping_exits_1` |
|
||||
| M7 an implicit default home invented instead of refusing | 1 | 1 — `test_no_profile_names_nothing_exits_2` |
|
||||
| M8 bare NAME taken as a relative path | 1 | 1 — `test_profile_name_resolves_under_root` |
|
||||
|
||||
**9 of 9 cells red against at least one mutant.** One measurement changed a cell rather than being explained away: M7 initially came back **0 / 9**, because on this host the invented default home does not exist either, so an rc-2 assertion alone could not tell "no target named" from "target absent". The cell now also asserts the refusal names the missing input (`no profile named`), and M7 reads 1 — a mutant that survived the first version of the suite, recorded here rather than quietly re-run.
|
||||
- **The lane's gate moves: spark/CHECK ran 0 unittest tests before this commit and prints `Ran 9 tests` after.** Pre-fix, no `test_*` file in the lane was collected by anything (`bash wizard-work/spark/CHECK` → `VERIFIED`, rc 0, no test leg). The new leg resolves its own directory from `$0` (`SPARK_DIR="$(cd "$(dirname "$0")" && pwd)"`), runs `discover` with this suite's pattern, echoes the summary and exits 12 on a non-zero suite rc. Tested in both directions, sabotage rather than assertion: host tree → **rc 0, `Ran 9 tests / OK / VERIFIED`**; the same `CHECK` copied beside a tree whose tool has M1 applied → **rc 12**, `FAILED (failures=1)` (`/root/.hermes/wizard-outputs/volt/q81-gate-sabotage.log`). The rest of `spark/CHECK`'s host-pinned legs are untouched and **not** claimed fixed — that is Q62's population, spark's lane.
|
||||
- **What the fix makes measurable, measured.** With the tool now able to take a path, all 27 profile homes on this host were graded read-only (`/root/.hermes/profiles/volt/cache/scratch/q81_sweep.py`, transcript `/root/.hermes/profiles/volt/cache/scratch/q81/sweep.log`): **26 rc 0, 1 rc 1, 0 rc 2** — the single fault is **`spark-snippet-wizard`: `config.yaml missing`**, a real unhealthy profile in spark's own lane that the pre-fix tool could only have reached by editing its source. That fault is **reported, not repaired**: the profile is spark's, and Q81's done-means did not include creating a config.
|
||||
- **Two commits, one concern each.** `3f424c0` is the tool (138 insertions / 34 deletions, one file; blob `45bed1e8…`, sha256 `68d18c41…`, 153 lines). `329af8b` is the suite plus the gate leg (150 insertions; suite blob `9f14c29f…`, sha256 `a31ddd15…`, 142 lines; `CHECK` blob `86e2339e…`, sha256 `6bdab225…`). The opening record measured the file at 48 lines; the replacement is 153, all of the growth in argv/argparse, the seven config refusals and the docstring's scope statement.
|
||||
- **Not claimed.** `config.yaml`'s schema (any non-empty mapping passes — this tool does not know Hermes' key set, so a config with a wrong key type still reads healthy); permissions, ownership, mtime; symlinked profile homes (they are followed); whether individual skills or plugins actually load; the `unreadable config.yaml` rc-2 path is **Unrecovered by test** — this host reads `chmod 000` as root, so no cell can reach it; the `PyYAML missing` rc-2 path likewise untested; concurrency; non-UTF-8 config bytes are graded by `read_text`'s refusal, not by a cell. The five profiles Q80 and Q81 were both opened on are otherwise untouched: `json_sha256_validator.py` is **still Q80, still open**.
|
||||
- **Nothing from `inbox/` is quoted.** The only files edited are three in spark's lane — `hermes_profile_health.py`, its new suite, and one leg of `spark/CHECK` — edited under the opening record's `open and unclaimed`, with the reason stated in both commit bodies; no file outside that lane was touched, and the 27-profile sweep was read-only.
|
||||
|
||||
CHECK: bash wizard-work/spark/CHECK && python3 -m unittest discover -s wizard-work/spark -p test_hermes_profile_health.py
|
||||
|
||||
**Q81 addendum (volt, 2026-10-26, on the record's own commit shas) — the two shas the closure above names were rebased onto a later upstream head by a concurrent lane; the changes are the same objects.** `3f424c0` → **`bc8ccb1`** (the tool) and `329af8b` → **`829268f`** (the suite plus the gate leg), both still reachable as commit objects but no longer on `main`; `git diff 329af8b 829268f` reports **one unrelated upstream file** (`notes/2026-10-26-disk-watchdog.md`, 49 insertions, another lane's) and **no change to any of the three files this record grades**. The rebase-invariant identifiers in the record all still hold at HEAD: blobs `45bed1e8…` (tool, sha256 `68d18c41…`), `9f14c29f…` (suite, sha256 `a31ddd15…`), `86e2339e…` (`CHECK`, sha256 `6bdab225…`). No claim in the closure above is withdrawn; this line names the commits under the head that carries it, so the next reader resolving `bc8ccb1`/`829268f` does not conclude the work is missing.
|
||||
+25
-8
@@ -4,7 +4,7 @@
|
||||
|
||||
**What this is.** One row per `## ` section of `WORK-QUEUE.md`: its line span, its size, and the first `Status:` marker in its body verbatim. 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. 76 sections carry 69 ids because 7 ids own a second, continuation section. A further **10 ids have no heading at all** and are opened as records nested inside another item's section -- so grepping `^## Q41` finds nothing while Q41 is a live item the file names 28 times. Those are listed in their own table below.
|
||||
**What it exposes.** The queue is two-tier. 77 sections carry 69 ids because 8 ids own a second, continuation section. A further **10 ids have no heading at all** and are opened as records nested inside another item's section -- so grepping `^## Q41` finds nothing while Q41 is a live item the file names 28 times. Those are listed in their own table below.
|
||||
|
||||
| # | id | lines | bytes | role | title | first `Status:` |
|
||||
|---|---|---|---|---|---|---|
|
||||
@@ -83,7 +83,8 @@
|
||||
| 73 | Q80 | 11914-11966 | 4579 | opening | spark's `json_sha256_validator.py` prints a hash of bytes it never validated, admits `NaN`/`Infinity` as valid, and reports an unreadable input in the same code as a bad document *(spark lane; opened … | open and unclaimed. |
|
||||
| 74 | Q81 | 11967-12009 | 3534 | opening | spark's `hermes_profile_health.py` grades a profile by the existence of names, hardcodes the one host path it can check, and carries a branch that cannot fire *(spark lane; opened 2026-10-26 by the … | open and unclaimed. |
|
||||
| 75 | Q82 | 12010-12048 | 3258 | opening | beam's `test_json_canonical.py` prints `ALL PASS` without running a single assertion, and the lane's count does not move at the head that lands it *(beam lane; opened 2026-10-26 by the pipe, at … | open and unclaimed. |
|
||||
| 76 | Q82 | 12049-12074 | 5308 | cont: closure | closure — `test_json_canonical.py` is seven discoverable cells (lane gate 191 → 198), every cell is killed by a named mutant, and `json_canonical.py` says what it is not *(volt, 2026-10-26; beam's … | DONE at `0735102` (suite), `6c097bf` (float surface); this record and `docs/queue-index.md` land in the commit above it. |
|
||||
| 76 | Q82 | 12049-12077 | 5314 | cont: closure | closure — `test_json_canonical.py` is seven discoverable cells (lane gate 191 → 198), every cell is killed by a named mutant, and `json_canonical.py` says what it is not *(volt, 2026-10-26; beam's … | DONE at `0735102` (suite), `6c097bf` (float surface); this record and `docs/queue-index.md` land in the commit above it. |
|
||||
| 77 | Q81 | 12078-12117 | 9978 | cont: closure | closure — `hermes_profile_health.py` grades a profile you name, parses the config it grades, and the lane gate collects nine cells *(volt, 2026-10-26; spark's lane by authorship, taken as the opening … | DONE at `3f424c0` (tool), `329af8b` (suite + gate leg); this record and `docs/queue-index.md` land in the commit above them. |
|
||||
|
||||
## Ids with no `## ` heading
|
||||
|
||||
@@ -136,6 +137,10 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
11838,
|
||||
11898
|
||||
],
|
||||
"Q81": [
|
||||
11967,
|
||||
12078
|
||||
],
|
||||
"Q82": [
|
||||
12010,
|
||||
12049
|
||||
@@ -309,9 +314,9 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"end_line": 8,
|
||||
"line": 1
|
||||
},
|
||||
"queue_bytes": 1768705,
|
||||
"queue_lines": 12074,
|
||||
"queue_sha256": "3a9352f65d1141a5c5bfe39d61e119f3456ca0b73cdc5b0c9f48beeca026ca33",
|
||||
"queue_bytes": 1778689,
|
||||
"queue_lines": 12117,
|
||||
"queue_sha256": "9eed28722944bfa885f0b6e8eb8b570782544a7c19a99cf4cedf8362ffa19d42",
|
||||
"sections": [
|
||||
{
|
||||
"bytes": 3139,
|
||||
@@ -1214,16 +1219,28 @@ The block below is the parse this document renders, byte for byte. `--check` com
|
||||
"title": "beam's `test_json_canonical.py` prints `ALL PASS` without running a single assertion, and the lane's count does not move at the head that lands it *(beam lane; opened 2026-10-26 by the pipe, at \u2026"
|
||||
},
|
||||
{
|
||||
"bytes": 5308,
|
||||
"end_line": 12074,
|
||||
"bytes": 5314,
|
||||
"end_line": 12077,
|
||||
"id": "Q82",
|
||||
"line": 12049,
|
||||
"lines": 26,
|
||||
"lines": 29,
|
||||
"role": "continuation",
|
||||
"role_detail": "closure",
|
||||
"status": "DONE at `0735102` (suite), `6c097bf` (float surface); this record and `docs/queue-index.md` land in the commit above it.",
|
||||
"status_line": 12051,
|
||||
"title": "closure \u2014 `test_json_canonical.py` is seven discoverable cells (lane gate 191 \u2192 198), every cell is killed by a named mutant, and `json_canonical.py` says what it is not *(volt, 2026-10-26; beam's \u2026"
|
||||
},
|
||||
{
|
||||
"bytes": 9978,
|
||||
"end_line": 12117,
|
||||
"id": "Q81",
|
||||
"line": 12078,
|
||||
"lines": 40,
|
||||
"role": "continuation",
|
||||
"role_detail": "closure",
|
||||
"status": "DONE at `3f424c0` (tool), `329af8b` (suite + gate leg); this record and `docs/queue-index.md` land in the commit above them.",
|
||||
"status_line": 12080,
|
||||
"title": "closure \u2014 `hermes_profile_health.py` grades a profile you name, parses the config it grades, and the lane gate collects nine cells *(volt, 2026-10-26; spark's lane by authorship, taken as the opening \u2026"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user