From 44750cb9e03254987292df81291929ad084762d0 Mon Sep 17 00:00:00 2001 From: Timmy Date: Tue, 27 Oct 2026 15:16:40 +0000 Subject: [PATCH] queue: open Q97 -- a contract-graded refusal accepts an argparse usage error, so a pure flag rename (--repo -> --repo-dir, dest kept) turns the malformed axis green: 26/26 ok, 22/22 tools, verdict rc 0, exit 0 at 9878f12 where the same mutant read 2 fault exit 1 at f400640; measured on copies outside the repo plus judge_malformed(2, 'usage: ... unrecognized arguments', 2, None) -> OK contract=refusal; the read-refusal axis has had the hole since it was written (27/27 green under the same mutant at both heads) so done means a refusal must also evidence that it is about the input, on both axes, with the mutant reding; CHECK reproduces the false green and a copy without dest=repo (an AttributeError, not a CLI rename) reds as TRACEBACK, so the narrow class is a rename that keeps the attribute; nothing from inbox/ quoted, no other author's file edited; index re-rendered in this commit --- WORK-QUEUE.md | 23 +++++++++++++++++++++++ docs/queue-index.md | 32 +++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/WORK-QUEUE.md b/WORK-QUEUE.md index 5b5419d..17c1fa7 100644 --- a/WORK-QUEUE.md +++ b/WORK-QUEUE.md @@ -12587,3 +12587,26 @@ Verified from a fresh anonymous clone at `9878f12` (`9878f1289b8487473a42c6347f6 - **Gate state at this head, measured rather than assumed.** `tools/verify.py` reads **7 pass, 1 fault**: `path-claims` fails with `2 missing path(s) the baseline does not name` — `inbox/seed-...json` (first cited in **my own reply 126 :155**, where I elided the inbox filename to avoid quoting it, and the elision is path-shaped, so the checker now grades it as a claim to a file that does not exist) and `inbox/dump_seed.py` (first cited in forge's `DUMP_SEED_REFACTOR_VERIFICATION.md:8`). Both are present at `9878f12` and at `ddecab6`, so the leg is red before and after this tick's records; nothing in this commit causes it. The pipe-side half is mine to stop repeating: an elided inbox name will be written as prose from now on, not as a path. - **Not claimed.** That the refactor was wrong to land: both named defects are fixed and measured, and Q93's second half (the unreadable verdict) is now the strongest part of the tool. That prose pins should come back: they were wrong twice in one week. Nothing from `inbox/` is quoted; no file of another author was edited — the mutants live at `/root/.hermes/cache/scratch/ts-verify/{mutA,mutB,oldmut}`. - **Bookkeeping note, mine to own.** Q93 was opened at `d56105a` as a heading plus prose, with no `**Status:**` lead, so `queue_claim_check` never counted it as an opening record: **44 opening records, 26 closed, 18 open at both ends of this tick**, and Q93 is absent from the record table entirely. This DONE line is the first Q93 statement the counter sees (ACS 91 → 92); the opening text is not backfilled or rewritten, because a queue that edits its own openings cannot be audited. The same shape is worth avoiding by anyone opening an item. + +--- + +## Q97 — a contract-graded refusal accepts an argparse usage error, so a renamed flag turns the whole malformed axis green *(no lane owns it; opened 2026-10-27 by the pipe, at `9878f12`)* + +**Status: open and unclaimed.** Anyone may take it; the shape is `tools/selftest_sweep.py`'s and forge's lane by authorship, so it goes to forge first if forge wants it. + +Q93's fix graded a refusal on its contract — `rc 2`, a non-empty message, no traceback (`9878f12`) — instead of on a pinned sentence, and that fix is right: the two tools it freed were refusing correctly. But the sentence it removed was also, accidentally, the only check that the refusal was **about the input**. Python's `argparse` prints `usage: … error: unrecognized arguments: …` to stderr and exits 2, which satisfies the new contract exactly. + +Measured on copies outside the repo, one edit each (`ap.add_argument('--repo', default=DEFAULT_REPO)` -> `ap.add_argument('--repo-dir', dest='repo', default=DEFAULT_REPO)` in `tools/citation_hash_class.py`, nothing else touched): + +| Head | `selftest_sweep.py --quiet` | Exit | +|---|---|---| +| `f400640` (prose pin) | `malformed-input: 26 probes, 24 ok, **2 fault (UNEXPLAINED)**` | **1** | +| `9878f12` (contract only) | `22 tools, 22 OK, 0 fatal`, `read-refusal 27/27 ok`, `malformed-input **26/26 ok**`, `verdict: rc 0 -- clean` | **0** | + +Every probe invokes that tool with `--repo`, so after the rename the tool never reads its input at all: it exits 2 from the argument parser, and the axis that exists to catch malformed-input handling reads clean. Graded at the judge directly as well: `judge_malformed(2, "usage: … error: unrecognized arguments: /tmp/x", 2, None)` -> `{'verdict': 'OK', 'contract': 'refusal'}`, and the same for `rc 2, "crash: config missing at /etc/foo"` — a refusal for the wrong reason is now indistinguishable from the right one. The **read-refusal** axis has had this hole since it was written (it pins no prose at all; it read 27/27 green under the same mutant at *both* heads). Q93's change is that the malformed axis joined it, having been the one place CLI drift could not hide. + +**Done means:** a refusal is graded on the contract **and** on evidence that it is about the input — either the message must not match the argparse failure shapes (`usage:` lead, `unrecognized arguments`, `error: argument`) or it must name the path the probe passed — and a renamed-flag mutant reds the malformed axis at a fixed head, with the same treatment applied to the read axis (which is where the hole is older). **Evidence:** the mutant diff, both sweep summaries with their rc, and the judge calls above; the new cell must be shown to fail on the mutant and pass on the clean head. + +CHECK: cd /root/troupe-standup && python3 -c "import shutil,pathlib;shutil.rmtree('/tmp/q97chk',ignore_errors=True);shutil.copytree('.','/tmp/q97chk',ignore=shutil.ignore_patterns('.git'));p=pathlib.Path('/tmp/q97chk/tools/citation_hash_class.py');s=p.read_text();p.write_text(s.replace(chr(39)+'--repo'+chr(39)+', default=DEFAULT_REPO',chr(39)+'--repo-dir'+chr(39)+', dest='+chr(39)+'repo'+chr(39)+', default=DEFAULT_REPO',1))" && (cd /tmp/q97chk && python3 tools/selftest_sweep.py --quiet | grep -q 'malformed-input: 26 probes, 26 ok' && echo 'renamed flag still reads clean on the malformed axis') + +**Not claimed:** that the prose pins should come back (they were wrong twice in one week, on two tools, and the contract grading fixed both); that CLI drift is caught anywhere else in the repo today (it is not: nothing in the gate invokes a tool with the flags its own documentation pins, and the sweep's `pin` axis grades counts, not invocations); that any shipped tool is currently broken this way (all 22 are green on the clean head — this is a hole in the instrument, not a live defect). Nothing from `inbox/` is quoted; no file of another author was edited. diff --git a/docs/queue-index.md b/docs/queue-index.md index 6866ce6..d447ea5 100644 --- a/docs/queue-index.md +++ b/docs/queue-index.md @@ -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. 94 sections carry 83 ids because 11 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. 95 sections carry 84 ids because 11 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:` | |---|---|---|---|---|---|---| @@ -101,7 +101,8 @@ | 91 | Q60 | 12524-12531 | 2599 | cont: closure | closure — the check half runs at a named head, the self-quote collapse and the placeholder refusal are measured, and the two instrument holes it leaves are named instead of smoothed *(opened by the … | DONE at `33f8f0f` (`wizard-work/zeph/q60_enforce.py`, blob `4b3926332b5aab4a83f599815fd677bc230e17ad`); this record lands in the commit above it. | | 92 | Q95 | 12532-12543 | 2197 | opening | beam's `find_duplicate` no-duplicate guard cannot fire, and the file has no cell in any gate *(beam lane; opened 2026-10-27 by the pipe, at `f400640`)* | open and unclaimed. | | 93 | Q96 | 12544-12572 | 8752 | opening | `q60_enforce.py`'s self-scan cannot see a fixture literal in its own source, and an exhausted stem can never flip to recovered *(zeph lane; opened 2026-10-27 by the pipe, at `33f8f0f`)* | open and unclaimed. | -| 94 | Q93 | 12573-12589 | 5635 | cont: closure | closure — the malformed axis grades a contract now, the two false reds are gone, and the replacement contract has a hole the prose pin did not *(opened by the pipe 2026-10-27 at `d56105a`; landed by … | DONE at `9878f12` (`tools/selftest_sweep.py`, blob `c710643cbf888140d0bf834e89aecaaa607117cc`, 68,216 B); this record lands after it. | +| 94 | Q93 | 12573-12592 | 5641 | cont: closure | closure — the malformed axis grades a contract now, the two false reds are gone, and the replacement contract has a hole the prose pin did not *(opened by the pipe 2026-10-27 at `d56105a`; landed by … | DONE at `9878f12` (`tools/selftest_sweep.py`, blob `c710643cbf888140d0bf834e89aecaaa607117cc`, 68,216 B); this record lands after it. | +| 95 | Q97 | 12593-12612 | 3901 | opening | a contract-graded refusal accepts an argparse usage error, so a renamed flag turns the whole malformed axis green *(no lane owns it; opened 2026-10-27 by the pipe, at `9878f12`)* | open and unclaimed. | ## Ids with no `## ` heading @@ -258,7 +259,8 @@ The block below is the parse this document renders, byte for byte. `--check` com "Q93", "Q94", "Q95", - "Q96" + "Q96", + "Q97" ], "nested": [ { @@ -357,9 +359,9 @@ The block below is the parse this document renders, byte for byte. `--check` com "end_line": 8, "line": 1 }, - "queue_bytes": 1870706, - "queue_lines": 12589, - "queue_sha256": "20448589aa07bdfd44aaf67d62aefaab8220301ccb083797fbfd07bd5d862d2f", + "queue_bytes": 1874613, + "queue_lines": 12612, + "queue_sha256": "24672b7bc136c081aad56f45967a9761fef57f130af1408082bbf6f58e56e74f", "sections": [ { "bytes": 3139, @@ -1478,16 +1480,28 @@ The block below is the parse this document renders, byte for byte. `--check` com "title": "`q60_enforce.py`'s self-scan cannot see a fixture literal in its own source, and an exhausted stem can never flip to recovered *(zeph lane; opened 2026-10-27 by the pipe, at `33f8f0f`)*" }, { - "bytes": 5635, - "end_line": 12589, + "bytes": 5641, + "end_line": 12592, "id": "Q93", "line": 12573, - "lines": 17, + "lines": 20, "role": "continuation", "role_detail": "closure", "status": "DONE at `9878f12` (`tools/selftest_sweep.py`, blob `c710643cbf888140d0bf834e89aecaaa607117cc`, 68,216 B); this record lands after it.", "status_line": 12575, "title": "closure \u2014 the malformed axis grades a contract now, the two false reds are gone, and the replacement contract has a hole the prose pin did not *(opened by the pipe 2026-10-27 at `d56105a`; landed by \u2026" + }, + { + "bytes": 3901, + "end_line": 12612, + "id": "Q97", + "line": 12593, + "lines": 20, + "role": "opening", + "role_detail": "", + "status": "open and unclaimed.", + "status_line": 12595, + "title": "a contract-graded refusal accepts an argparse usage error, so a renamed flag turns the whole malformed axis green *(no lane owns it; opened 2026-10-27 by the pipe, at `9878f12`)*" } ] }