From cb667a896e7a3e2b3a0bdd6764908e6d61daabd3 Mon Sep 17 00:00:00 2001 From: Timmy Date: Wed, 28 Oct 2026 04:14:33 +0000 Subject: [PATCH] pipe: Q107 open -- spark json-validator --dir exits the invalid count (256 invalid -> rc 0, 2 invalid -> rc 2 as usage error), glob is non-recursive while file mode is recursive, NaN/Infinity read VALID; done-condition is 0/1/2 with counts printed; index re-rendered --- WORK-QUEUE.md | 21 ++++++++++++++++ docs/queue-index.md | 59 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/WORK-QUEUE.md b/WORK-QUEUE.md index b71b5da..130c4e2 100644 --- a/WORK-QUEUE.md +++ b/WORK-QUEUE.md @@ -13169,3 +13169,24 @@ The defect class is the one Q98 and Q100 already name: a committed gate that res **Done-condition, one line:** from a copy of the repo at any path, `python3 wizard-work/sol/CHECK-2026-09-28` must grade *that copy's* manifest -- poison the copy and the verdict must go FALSE with rc nonzero; leave it clean and the verdict stays TRUE with rc 0. Any fix that keeps an absolute default is not a fix; the two builder scripts need the same treatment, since a clone that regenerates its manifest would write to the host seed. **Not claimed:** that the classification is wrong -- it is not, and the manifest matches an independent re-derivation from the seed's summary prefixes (7/3/2 over 12 pending, 0 decided, order preserved); that sol is the only lane with this shape -- Q98/Q100's files are a different mechanism and were not re-measured here; that anything consumes `Triage-2026-09-28-classify.json` -- `git grep` finds no caller outside the lane's own CHECK; that the `inbox/` seed's committed state is a defect -- `decisions/2026-10-06-human-gates.md:4` records Alexander's **KEEP PUBLIC** ruling on this repo, the decided note controls, and no visibility blocker is raised by this item; that quoting seed summaries into committed files is new exposure -- the seed itself is committed, so the triage adds no information a reader did not already have. Files edited for this item: `WORK-QUEUE.md` (**this record, appended**) and `docs/queue-index.md` (**re-rendered** with the committed `tools/queue_index.py` in this clean worktree, not in `/root/troupe-standup`, whose working tree carries other lanes' uncommitted edits). Nothing from `inbox/` is quoted, and no file of another author was edited. + + +**Q107 — OPEN (spark lane by authorship; opened 2026-10-28 by the pipe, at `51ddd9d`). `wizard-work/spark/json-validator.py` `--dir` mode exits the *number of invalid files*, so 256 broken files read as success (rc 0) and exactly 2 broken files read as a usage error (rc 2) -- both against the file's own documented contract.** + +`51ddd9d` ("spark: enhanced json-validator with directory mode and accurate exit codes", 2026-10-28T03:52Z) rewrites one file, `85 added / 24 deleted`. Its new header reads `Exit 0: All valid / Exit 1: One or more invalid / Exit 2: Usage error`, and `--dir` then does `sys.exit(result['invalid'])`. Every reading below is on the committed blob (`git show 51ddd9d:wizard-work/spark/json-validator.py`), not the shared worktree's uncommitted argparse rewrite. + +| Reading | Result | +|---|---| +| `--dir` over a dir with 2 invalid + 2 valid + 1 nested file | `Total: 4, Valid: 2, Invalid: 2`, rc **2** -- indistinguishable from a usage error | +| `--dir` over a **missing** directory | rc **2** -- same code as the row above | +| `--dir` over 256 invalid files | `Total: 256, Valid: 0, Invalid: 256`, rc **0** -- exit status taken mod 256, so total failure reads as success | +| `--dir` over a dir holding `sub/deep.json` | `Total: 4` -- `--dir` globs `*.json` non-recursively, while file mode uses `rglob`; the nested file is silently skipped | +| `json-validator.py` on `{"n":NaN}` and `{"n":Infinity}` | `VALID`, rc 0 -- `json.load` accepts both; neither is JSON | +| two bad files in ordinary file mode | rc **1** -- the intended code | +| `--dir` with no argument | rc 2 with `Error: --dir requires a directory argument` -- correct | + +The gate-level reading: anywhere this is used as a pre-commit or CI validator, a directory of 256 malformed files passes, and a directory with two malformed files is reported as operator error. Both are the failure mode a validator exists to prevent. + +**Done-condition, one line:** `--dir` must exit **0 all valid / 1 any invalid / 2 usage-or-IO error**, with the counts printed and never used as the status -- reproduce by pointing `--dir` at a directory of 256 `{bad` files (must be rc 1, currently 0) and at a directory of 2 (must be rc 1, currently 2). Either the recursion gap is closed and the header says so, or `--dir` is documented as non-recursive; `NaN`/`Infinity` either become invalid or the header stops implying strict JSON. + +**Not claimed:** that the uncommitted argparse rewrite in `/root/troupe-standup`'s working tree has the same defect -- it is another lane's unlanded work and I did not grade it as theirs; that any pipeline consumes this script -- `git grep` finds no caller, so the hole is latent until something does; that the file-mode contract is wrong -- it is not, and its 0/1/2 codes are what `--dir` should have followed; that `--schema` mode is affected -- it is absent from the committed blob and belongs to the uncommitted rewrite. Files edited for this item: `WORK-QUEUE.md` (**this record, appended**) and `docs/queue-index.md` (**re-rendered** with the committed `tools/queue_index.py` in this clean worktree). Nothing from `inbox/` is quoted, and no file of another author was edited. diff --git a/docs/queue-index.md b/docs/queue-index.md index d3eca3d..62ed306 100644 --- a/docs/queue-index.md +++ b/docs/queue-index.md @@ -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 (`kind` says which, and such an id'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. 96 sections carry 85 ids because 11 ids own a second, continuation section; 18 further ids are opened by a record and own no heading at all, and they have rows and extents here. The same **18 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 28 times. +**What it exposes.** The queue is two-tier. 96 sections carry 85 ids because 11 ids own a second, continuation section; 19 further ids are opened by a record and own no heading at all, and they have rows and extents here. The same **19 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 28 times. | # | id | kind | lines | bytes | role | title | first `Status:` | |---|---|---|---|---|---|---|---| @@ -121,7 +121,8 @@ | 111 | Q103 | record | 12995-13087 | 16301 | record: BOLD-LEAD | **Q103 — OPEN (tooling lane, no author; opened 2026-10-27 by the pipe, at `64c1e36`). `tools/queue_index.py` reads ids as one or two digits, so every item from Q100 up is invisible to the queue's own … | -- | | 112 | Q104 | record | 13088-13119 | 6443 | record: BOLD-LEAD | **Q104 — OPEN (beam lane by authorship; opened 2026-10-28 by the pipe, at `afb182a`). `beam/jsonl_validate.py` landed with a commit message claiming tests it does not have, none of the lane's gate … | -- | | 113 | Q105 | record | 13120-13155 | 8202 | record: BOLD-LEAD | **Q105 — OPEN (beam lane by authorship; opened 2026-10-28 by the pipe, at `26cdf8b`). `wizard-work/beam/CHECK` grades the lane with `python3 -m unittest discover -p 'test_*.py'`, which collects … | -- | -| 114 | Q106 | record | 13156-13171 | 3490 | record: BOLD-LEAD | **Q106 — OPEN (sol lane by authorship; opened 2026-10-28 by the pipe, at `f7844b1`). `wizard-work/sol/CHECK-2026-09-28` pins `ROOT = "/root/troupe-standup"`, so the gate grades the host worktree it … | -- | +| 114 | Q106 | record | 13156-13173 | 3492 | record: BOLD-LEAD | **Q106 — OPEN (sol lane by authorship; opened 2026-10-28 by the pipe, at `f7844b1`). `wizard-work/sol/CHECK-2026-09-28` pins `ROOT = "/root/troupe-standup"`, so the gate grades the host worktree it … | -- | +| 115 | Q107 | record | 13174-13192 | 3183 | record: BOLD-LEAD | **Q107 — OPEN (spark lane by authorship; opened 2026-10-28 by the pipe, at `51ddd9d`). `wizard-work/spark/json-validator.py` `--dir` mode exits the *number of invalid files*, so 256 broken files read … | -- | ## Ids with no `## ` heading @@ -147,6 +148,7 @@ Opened as records inside another section. `line` is the record's own opening lin | Q104 | 13088 | 13088 | 7 | Q103 | BULLET+BOLD | BOLD-LEAD | | Q105 | 13120 | 13120 | 6 | Q104 | BULLET+BOLD | BOLD-LEAD | | Q106 | 13156 | 13156 | 1 | Q105 | BULLET+BOLD | BOLD-LEAD | +| Q107 | 13174 | 13174 | 1 | Q106 | BULLET+BOLD | BOLD-LEAD | **Not in this document.** Ids the prose corpus names that the queue has never mentioned (`checkins/`, `replies/`, `recoveries/`, `audits/`, `docs/`, the top-level documents; `tools/` excluded). That set moves with the prose, not with the queue, so embedding it here would make `--check` go RED for a reason that has nothing to do with the queue being current. It is reported on demand: `python3 tools/queue_index.py --outside`. @@ -380,17 +382,30 @@ The block below is the parse this document renders, byte for byte. `--check` com "title": "**Q105 \u2014 OPEN (beam lane by authorship; opened 2026-10-28 by the pipe, at `26cdf8b`). `wizard-work/beam/CHECK` grades the lane with `python3 -m unittest discover -p 'test_*.py'`, which collects \u2026" }, { - "bytes": 3490, - "end_line": 13171, + "bytes": 3492, + "end_line": 13173, "id": "Q106", "kind": "record", "line": 13156, - "lines": 16, + "lines": 18, "role": "record", "role_detail": "BOLD-LEAD", "status": null, "status_line": null, "title": "**Q106 \u2014 OPEN (sol lane by authorship; opened 2026-10-28 by the pipe, at `f7844b1`). `wizard-work/sol/CHECK-2026-09-28` pins `ROOT = \"/root/troupe-standup\"`, so the gate grades the host worktree it \u2026" + }, + { + "bytes": 3183, + "end_line": 13192, + "id": "Q107", + "kind": "record", + "line": 13174, + "lines": 19, + "role": "record", + "role_detail": "BOLD-LEAD", + "status": null, + "status_line": null, + "title": "**Q107 \u2014 OPEN (spark lane by authorship; opened 2026-10-28 by the pipe, at `51ddd9d`). `wizard-work/spark/json-validator.py` `--dir` mode exits the *number of invalid files*, so 256 broken files read \u2026" } ], "ids_multi_section": { @@ -1997,17 +2012,30 @@ The block below is the parse this document renders, byte for byte. `--check` com "title": "**Q105 \u2014 OPEN (beam lane by authorship; opened 2026-10-28 by the pipe, at `26cdf8b`). `wizard-work/beam/CHECK` grades the lane with `python3 -m unittest discover -p 'test_*.py'`, which collects \u2026" }, { - "bytes": 3490, - "end_line": 13171, + "bytes": 3492, + "end_line": 13173, "id": "Q106", "kind": "record", "line": 13156, - "lines": 16, + "lines": 18, "role": "record", "role_detail": "BOLD-LEAD", "status": null, "status_line": null, "title": "**Q106 \u2014 OPEN (sol lane by authorship; opened 2026-10-28 by the pipe, at `f7844b1`). `wizard-work/sol/CHECK-2026-09-28` pins `ROOT = \"/root/troupe-standup\"`, so the gate grades the host worktree it \u2026" + }, + { + "bytes": 3183, + "end_line": 13192, + "id": "Q107", + "kind": "record", + "line": 13174, + "lines": 19, + "role": "record", + "role_detail": "BOLD-LEAD", + "status": null, + "status_line": null, + "title": "**Q107 \u2014 OPEN (spark lane by authorship; opened 2026-10-28 by the pipe, at `51ddd9d`). `wizard-work/spark/json-validator.py` `--dir` mode exits the *number of invalid files*, so 256 broken files read \u2026" } ], "nested": [ @@ -2172,6 +2200,15 @@ The block below is the parse this document renders, byte for byte. `--check` com "refs": 1, "section": "Q105", "shape": "BULLET+BOLD" + }, + { + "first_mention": 13174, + "form": "BOLD-LEAD", + "id": "Q107", + "line": 13174, + "refs": 1, + "section": "Q106", + "shape": "BULLET+BOLD" } ], "preamble": { @@ -2179,9 +2216,9 @@ The block below is the parse this document renders, byte for byte. `--check` com "end_line": 8, "line": 1 }, - "queue_bytes": 1950018, - "queue_lines": 13171, - "queue_sha256": "9631e6ee144b8b14ba808861d3072b3b8b24de3e3232ab41da76696dfd740fb1", + "queue_bytes": 1953203, + "queue_lines": 13192, + "queue_sha256": "96f4190cdd22e06ef734aca1a432693003a4c6b92ef2ce0329f1ffaaaf8b46c1", "sections": [ { "bytes": 3139,