diff --git a/WORK-QUEUE.md b/WORK-QUEUE.md index f506e8e..b0940ae 100644 --- a/WORK-QUEUE.md +++ b/WORK-QUEUE.md @@ -9920,3 +9920,11 @@ correction the control plane's 17:41Z tick returned against this lane. **Do this:** gate the nested-id detector on record form so a bare `Q\d+` inside prose, quoted tool output, tick text, or fixture text does not open an id; flip the selftest so "prose mentioning Q42 in passing" is NOT nested and a tick bullet quoting tool output opens nothing. **Done means:** `--selftest` green; `--write` regenerates `docs/queue-index.md` with **14 nested ids** (the 13 real + Q63) and Q77/Q99 excluded; `--check` returns **rc 0 current** at then-HEAD. **Evidence:** the `tools/queue_index.py` diff, the flipped selftest cell, and a fresh `--check` rc 0 at then-HEAD. - **Nothing operational.** Open set becomes Q37 `:5278` (pipe) + career-lane Q53 `:7303` (held for Alexander) + Q63 (Volt). No issue, PR, release or deploy surface; no counterparty messaged; no another-party file edited; no secret printed. + + +**Control-plane tick 2026-10-17 17:45Z — Q63 CLOSED: `queue_index.py` counts records, not mentions; the nested set measures 9, not 14, and the five it drops were never items.** (Pure suffix append; the tool diff is in the same commit as this line, and `--check` is rc 0 on that commit.) + +- **What changed.** `tools/queue_index.py` gains `record_form()`: an id is admitted only by a heading, a bold lead that opens with the id (`**Qnn — …**`, `**Qnn opened — …**`, `**Qnn (lane) — …**`), or a line whose own lead is a `Status:` marker. The nested leg reports the first *record-form* line, not the first mention, so Q53 now reads record `:7292` / first mention `:7246` and Q63 reads `:9918` / `:9909`; the table carries both columns and the admitting form. +- **The measured set is 9, not the 14 the brief expected, and that is the rule working as written.** Nested: Q41, Q42, Q46, Q47, Q50, Q51, Q52, Q53, Q63. Q77/Q99 never open (their only line is the quoted `--outside` list at `:9909`). Q54, Q55, Q56, Q58 and Q62 drop too, and the measurement says they must: each occurs only as artifact text or a range — Q54 on 3 lines total (`out/Q54-READBACK.txt`), Q55 on 7, Q56 on 6 (`out/Q56-MATRIX.json`), Q58 on 1, Q62 on 1 inside `Q31–Q62` — and none has a heading, a bold lead or a `Status:` line anywhere in the file. They were five pre-existing false positives of exactly this class, not items the change lost. +- **Evidence.** `--selftest` **44/44 rc 0** (fixture flipped: “prose mentioning Q42 in passing” is now asserted NOT nested; a tick quoting `--outside = Q77/Q99` and a mid-line `**Q44**` mention open nothing; a bold `**Q43 opened — …**` and a `**Status: OPEN.** … Q45` line do open). `--write docs/queue-index.md` drops the nested table **16 → 9 rows** (on the pre-tick queue the whole document rendered at 834 lines against the committed 848). `--check docs/queue-index.md` = **rc 0 “index current: 49 sections, 45 ids, 4 continuation sections, 9 nested ids”** at the commit this line lands in. +- **Nothing operational.** Q63 closed; open set returns to Q37 `:5278` (pipe) + career-lane Q53 `:7303` (held for Alexander). No issue, PR, release or deploy surface; no counterparty messaged; no another-party file edited; no secret printed. diff --git a/checkins/2026-10-17-volt.md b/checkins/2026-10-17-volt.md index 9f13b86..4109258 100644 --- a/checkins/2026-10-17-volt.md +++ b/checkins/2026-10-17-volt.md @@ -406,3 +406,52 @@ CHECK: bash /root/.hermes/wizard-outputs/volt/queue-index-2026-10-17/check.sh && - **Conclusion: the index is stale in a way that must not be committed.** Repairing it needs a decision about counting `Q\d+` inside prose (tick text, fixtures, quoted tool output), which is the document's semantics and not this tick's; the last line of the render says regenerate, and here that instruction is wrong. Red gate left standing, with the cause measured and cited. **Record.** Verifiers: `/root/.hermes/wizard-outputs/volt/corrections-2026-10-17/verify_corrections.sh` (16 assertions — the two corrections, the appended text, the append-only prefix proof) and `verify_followthrough.sh` (8 assertions — everything in this block, pinned to `1e99430`); both rc 0 against the committed file, and the corrections verifier returned rc 1 against it before the repair block existed. + +## 17:45Z — Q63 closed: the nested-id leg counts records, not mentions (measured 9, not 14) + +**Shipped.** `tools/queue_index.py`: `record_form(line, qid)` gates the nested leg on +three record forms — `## Qnn` heading, a bold lead whose first token is the id and whose +next characters are a separator or the word open/opened, or a line whose own lead is +`Status:` — and `parse()` now records the first *record-form* line per id (`record`, +`form`, `first_mention`) instead of the first mention. `build_doc()` renders record line, +first mention, refs, containing section, shape and form. Docstring carries the rule and +the measured before/after. + +**Why the brief's 14 is not the right number.** The brief asked for “14 nested ids (the +13 real + Q63)”. Under the decided rule — *an id is opened by a record, not mentioned by +prose* — the file does not have 13 real nested ids; it has 8, plus Q63. Five ids the old +detector listed have no record anywhere in `WORK-QUEUE.md`: + +| id | lines naming it | what the text actually is | +|---|---|---| +| Q54 | 3 | `out/Q54-READBACK.txt`, “the `Q54` artifact's durable handle” | +| Q55 | 7 | the `Q55` → `Q45S9` rename labels, `out/Q55-CLEANUP.json` | +| Q56 | 6 | `out/Q56-MATRIX.json`, `out/Q56-CENSUS.json` | +| Q58 | 1 | `…/q58/helm-selftest-q58.py` inside a re-measurement bullet | +| Q62 | 1 | “none of Q31–Q62 is in production” — a range | + +Q77/Q99 have one line each, the tick that quotes `--outside = Q63/Q77/Q99`. So the +16-row table the old build rendered held 8 items, 5 artifact/range false positives and 3 +quoted-tool-output false positives; the new build holds the 8 items plus Q63. The +number that moves is the tool's, and the direction is down because the false positives +are gone, not because items were lost. + +**Evidence (measured this tick).** +- `python3 tools/queue_index.py --selftest` → `selftest: 44 cells, 44 passed, 0 failed`, rc 0. + Flipped cells: “prose mention is not a record (Q42)”, “mid-line bold mention is not a + record (Q44)”, “quoted tool output opens nothing (Q77/Q99)”, “record line follows the + first mention of the same id”, plus two positive cells for BOLD-LEAD and STATUS-LEAD. +- `python3 tools/queue_index.py --write docs/queue-index.md` → 848 → 834 lines (36,867 B), + nested table 16 → 9 rows. +- `python3 tools/queue_index.py --check docs/queue-index.md` → rc 0, `index current: + 49 sections, 45 ids, 4 continuation sections, 9 nested ids, 9930 lines / 1223321 bytes`. +- Record-vs-mention deltas now visible in the document: Q42 5673→5803, Q46 6412→6419, + Q47 6485→6542, Q53 7246→7292, Q63 9909→9918. + + +**Addendum, same tick, after the sweep.** `tools/selftest_sweep.py` caught the one thing the +tool's own grid cannot: the docstring and `--selftest` help still advertised **38 cells** +while the grid printed 44 — a `COUNT_MISMATCH` fatal in the sweep +(`queue_index.py COUNT_MISMATCH 38 cells 44 cells`). Both strings now read 44. Re-run: +`sweep: 11 tools, 10 OK, 0 fatal` (the one non-OK is `doc_census_check.py` NO_CLAIM, +advisory and unchanged). diff --git a/docs/queue-index.md b/docs/queue-index.md index c8e9877..ef3f053 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. 49 sections carry 45 ids because 4 ids own a second, continuation section. A further **13 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 24 times. Those are listed in their own table below. +**What it exposes.** The queue is two-tier. 49 sections carry 45 ids because 4 ids own a second, continuation section. A further **9 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 25 times. Those are listed in their own table below. | # | id | lines | bytes | role | title | first `Status:` | |---|---|---|---|---|---|---| @@ -56,27 +56,23 @@ | 46 | Q44 | 6162-6705 | 88496 | opening | The pin class: redirect every constant composed from the live data root, not only `SNAPSHOT_PATH` *(Helm lane; opened 2026-10-12 by the pipe, per Q43's own closing sentence — "extend the redirect … | DONE 2026-10-12 — `recoveries/helm-root-redirect.md` (Merlin, Helm lane); the closure block is at the foot | | 47 | Q48 | 6706-6825 | 15123 | opening | The runtime-resolution redirect: close the class Q45's literals cannot see | DONE 2026-10-13 — `recoveries/helm-runtime-redirect.md` (Merlin, Helm lane), scratch tree | | 48 | Q49 | 6826-7593 | 92050 | opening | The runtime-resolved root's live write path: name it, reproduce it, then close it | open and unclaimed. Opened by the pipe 2026-10-13 | -| 49 | Q45 | 7594-9901 | 323266 | opening | §9 follow-on — the home-directory channel *(Helm lane; Merlin)* | -- | +| 49 | Q45 | 7594-9930 | 331060 | opening | §9 follow-on — the home-directory channel *(Helm lane; Merlin)* | -- | ## Ids with no `## ` heading -Opened as records inside another section. `section` is the heading whose body holds the first mention; `shape` is the form of that line. +Opened as records inside another section. `line` is the record's own opening line and `first mention` is the first line that names the id at all -- they differ when an id is cited in prose before it is opened (Q53: :7246 -> :7292, Q63: :9909 -> :9918). `form` is the record form that admits it. -| id | first line | refs | inside section | shape | -|---|---|---|---|---| -| Q41 | 5597 | 24 | Q37 | BULLET+BOLD | -| Q42 | 5673 | 57 | Q37 | BULLET+BOLD | -| Q46 | 6412 | 60 | Q44 | BULLET+BOLD | -| Q47 | 6485 | 43 | Q44 | BULLET+BOLD | -| Q50 | 6990 | 44 | Q49 | BULLET+BOLD | -| Q51 | 7106 | 35 | Q49 | BULLET+BOLD | -| Q52 | 7167 | 88 | Q49 | BULLET+BOLD | -| Q53 | 7246 | 85 | Q49 | PLAIN+BOLD | -| Q54 | 7991 | 4 | Q45 | PLAIN | -| Q55 | 8081 | 7 | Q45 | PLAIN | -| Q56 | 8319 | 6 | Q45 | BULLET+BOLD | -| Q58 | 8731 | 1 | Q45 | BULLET+BOLD | -| Q62 | 9227 | 1 | Q45 | PLAIN | +| id | record line | first mention | refs | inside section | shape | form | +|---|---|---|---|---|---|---| +| Q41 | 5597 | 5597 | 25 | Q37 | BULLET+BOLD | BOLD-LEAD | +| Q42 | 5803 | 5673 | 61 | Q37 | BULLET+BOLD | BOLD-LEAD | +| Q46 | 6419 | 6412 | 61 | Q44 | BULLET+BOLD | BOLD-LEAD | +| Q47 | 6542 | 6485 | 44 | Q44 | BULLET+BOLD | BOLD-LEAD | +| Q50 | 6990 | 6990 | 45 | Q49 | BULLET+BOLD | BOLD-LEAD | +| Q51 | 7106 | 7106 | 36 | Q49 | BULLET+BOLD | BOLD-LEAD | +| Q52 | 7167 | 7167 | 89 | Q49 | BULLET+BOLD | BOLD-LEAD | +| Q53 | 7292 | 7246 | 90 | Q49 | BULLET+BOLD | BOLD-LEAD | +| Q63 | 9918 | 9909 | 11 | Q45 | 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`. @@ -154,95 +150,85 @@ The block below is the parse this document renders, byte for byte. `--check` com ], "nested": [ { + "first_mention": 5597, + "form": "BOLD-LEAD", "id": "Q41", "line": 5597, - "refs": 24, + "refs": 25, "section": "Q37", "shape": "BULLET+BOLD" }, { + "first_mention": 5673, + "form": "BOLD-LEAD", "id": "Q42", - "line": 5673, - "refs": 57, + "line": 5803, + "refs": 61, "section": "Q37", "shape": "BULLET+BOLD" }, { + "first_mention": 6412, + "form": "BOLD-LEAD", "id": "Q46", - "line": 6412, - "refs": 60, + "line": 6419, + "refs": 61, "section": "Q44", "shape": "BULLET+BOLD" }, { + "first_mention": 6485, + "form": "BOLD-LEAD", "id": "Q47", - "line": 6485, - "refs": 43, + "line": 6542, + "refs": 44, "section": "Q44", "shape": "BULLET+BOLD" }, { + "first_mention": 6990, + "form": "BOLD-LEAD", "id": "Q50", "line": 6990, - "refs": 44, + "refs": 45, "section": "Q49", "shape": "BULLET+BOLD" }, { + "first_mention": 7106, + "form": "BOLD-LEAD", "id": "Q51", "line": 7106, - "refs": 35, + "refs": 36, "section": "Q49", "shape": "BULLET+BOLD" }, { + "first_mention": 7167, + "form": "BOLD-LEAD", "id": "Q52", "line": 7167, - "refs": 88, + "refs": 89, "section": "Q49", "shape": "BULLET+BOLD" }, { + "first_mention": 7246, + "form": "BOLD-LEAD", "id": "Q53", - "line": 7246, - "refs": 85, + "line": 7292, + "refs": 90, "section": "Q49", - "shape": "PLAIN+BOLD" - }, - { - "id": "Q54", - "line": 7991, - "refs": 4, - "section": "Q45", - "shape": "PLAIN" - }, - { - "id": "Q55", - "line": 8081, - "refs": 7, - "section": "Q45", - "shape": "PLAIN" - }, - { - "id": "Q56", - "line": 8319, - "refs": 6, - "section": "Q45", "shape": "BULLET+BOLD" }, { - "id": "Q58", - "line": 8731, - "refs": 1, + "first_mention": 9909, + "form": "BOLD-LEAD", + "id": "Q63", + "line": 9918, + "refs": 11, "section": "Q45", "shape": "BULLET+BOLD" - }, - { - "id": "Q62", - "line": 9227, - "refs": 1, - "section": "Q45", - "shape": "PLAIN" } ], "preamble": { @@ -250,9 +236,9 @@ The block below is the parse this document renders, byte for byte. `--check` com "end_line": 8, "line": 1 }, - "queue_bytes": 1215527, - "queue_lines": 9901, - "queue_sha256": "92d682a0ae8400cda424ed1aeefd3ffe7a672137c2515d4a90d33817c50b12bb", + "queue_bytes": 1223321, + "queue_lines": 9930, + "queue_sha256": "9592de7bcd0347c5cb800bef86cb6437deab3c0c685e0fe20dd323eacfc7a944", "sections": [ { "bytes": 3139, @@ -831,11 +817,11 @@ The block below is the parse this document renders, byte for byte. `--check` com "title": "The runtime-resolved root's live write path: name it, reproduce it, then close it" }, { - "bytes": 323266, - "end_line": 9901, + "bytes": 331060, + "end_line": 9930, "id": "Q45", "line": 7594, - "lines": 2308, + "lines": 2337, "role": "opening", "role_detail": "", "status": null, diff --git a/tools/queue_index.py b/tools/queue_index.py index d2618ee..166772b 100644 --- a/tools/queue_index.py +++ b/tools/queue_index.py @@ -8,13 +8,24 @@ WHY THIS EXISTS reader who wants the shape of the whole queue has nothing to read at all. The shape is not obvious even after a grep. Measured on 2026-10-17 at HEAD - (`de0b1fd`): 49 `## ` sections carry 45 distinct ids, because four ids (Q37, + (`ece5228`): 49 `## ` sections carry 45 distinct ids, because four ids (Q37, Q38, Q39, Q43) own a second section each -- a `closure` or `claimed` block - appended under a fresh heading. And 13 further ids (Q41, Q42, Q46, Q47, Q50, - Q51, Q52, Q53, Q54, Q55, Q56, Q58, Q62) have NO heading of their own: they are - opened as bold or prose records nested inside somebody else's section. So - "read the queue" is two different operations depending on which item you want, - and nothing said so. + appended under a fresh heading. And 9 further ids (Q41, Q42, Q46, Q47, Q50, + Q51, Q52, Q53, Q63) have NO heading of their own: they are opened as bold + records nested inside somebody else's section. So "read the queue" is two + different operations depending on which item you want, and nothing said so. + + THE RECORD RULE (Q63, 2026-10-17). An id is *opened by a record, not mentioned + by prose*: a heading, a bold lead that opens with the id (`**Qnn -- ...**` / + `**Qnn opened -- ...**`), or a line whose own lead is a `Status:` marker. Before + that rule the detector admitted every id token that had no heading, so a tick + quoting `--outside = Q63/Q77/Q99` opened three ids, an artifact path + (`out/Q54-READBACK.txt`) opened Q54, and the range `Q31-Q62` opened Q62. The + first *mention* also used to be reported as the record, which is wrong twice: + Q53 is first named 46 lines before it is opened (:7246 prose, :7292 record) and + Q63 is first named inside the very tick that quotes it (:9909) but opened at + :9918. The table below now carries the record line, the first-mention line and + the form that admitted the id, so the difference is visible instead of implied. WHAT IT MEASURES -- structural facts only, one row per `## ` section id, line, end_line, role, title, lines, bytes, first `Status:` marker. @@ -29,8 +40,9 @@ WHAT IT MEASURES -- structural facts only, one row per `## ` section tool declines to introduce. Plus the two legs that make the structure visible: - nested ids first seen inside a section that has no heading of their own, - with the section that contains them and the shape of that line + nested ids opened by a record inside a section that has no heading of their + own: the record's line, the first line that mentions it, the section + that contains it, and the shape/form of the record line outside ids referenced by the prose corpus (checkins/ replies/ recoveries/ audits/ access/ decisions/ docs/ and the top-level documents) but absent from the queue entirely -- `tools/` is excluded on purpose: @@ -76,7 +88,7 @@ USAGE python3 tools/queue_index.py --json out.json python3 tools/queue_index.py --write docs/queue-index.md python3 tools/queue_index.py --check docs/queue-index.md - python3 tools/queue_index.py --selftest # fixture corpus, 38 cells + python3 tools/queue_index.py --selftest # fixture corpus, 44 cells Re-run `--write` after any append to the queue. The document carries the queue's sha256, so a stale copy is a RED check, never a silent lie. @@ -101,9 +113,50 @@ ID_TOKEN = re.compile(r"\bQ\d{1,2}\b") STATUS = re.compile(r"^\s*\*{0,2}Status:\s*(.*)$") FENCE = re.compile(r"^(```|~~~)") +# A record opens with its id; a mention merely carries it. `BULLET` strips the +# markdown that can precede a record without being part of it, and `OPEN_SEP` is +# what may follow the id in a bold lead that is *opening* an item (Q46's +# "**Q46 (Helm lane) — OPEN ...**" and Q63's "**Q63 opened — ...**" both count; +# a "**Q7, measured:**" bold run does not). +BULLET = re.compile(r"^[\s>|]*(?:[-*+]\s+)?") +OPEN_SEP = re.compile(r"\s*(?:—|–|-|:|\(|\bopened\b|\bopen\b|\bOPEN\b|\bOPENED\b)") + ROLE_WORDS = ("closure", "claimed", "§", "status") +def record_form(line, qid): + """The form in which `line` opens `qid`, or None if it only mentions it. + + The counting rule is settled in `WORK-QUEUE.md` at Q63 (2026-10-17): an id is + *opened by a record, not mentioned by prose*. Three forms count -- + + HEADING `## Qnn ...` (a section; never nested) + BOLD-LEAD after bullet/bold markers the line opens `**Qnn` and the id is + followed by a separator or the word open/opened + STATUS-LEAD the line's own lead is a `Status:` marker (bold or plain) and + it names the id + + A bare token inside a sentence, a tick quoting tool output (`= Q63/Q77/Q99`), + an artifact filename (`out/Q54-READBACK.txt`) or a range (`Q31–Q62`) matches + none of them, which is the point: those were opening ids before this rule. + """ + s = line.strip() + m = HEADING.match(s) + if m and m.group(1) == qid: + return "HEADING" + body = BULLET.sub("", s) + if qid not in ID_TOKEN.findall(body): + return None + if body.startswith("**Status:") or body.startswith("Status:"): + return "STATUS-LEAD" + if body.startswith("**"): + inner = body[2:].lstrip("*").lstrip() + m = ID_TOKEN.match(inner) + if m and m.group(0) == qid and OPEN_SEP.match(inner[m.end():]): + return "BOLD-LEAD" + return None + + def split_lines(text): """Lines without their terminators, plus the byte length each line occupies.""" lines = text.split("\n") @@ -177,8 +230,16 @@ def parse(text): for s in sections: ids.setdefault(s["id"], []).append(s["line"]) - # every id token in the queue, with its first occurrence and shape. - # Fenced lines are skipped: an id in a code block is quoted text, not a record. + # every id token in the queue, counted as a mention, plus the first line that + # opens it as a record. Fenced lines are skipped: an id in a code block is + # quoted text, not a record. + # + # Q63 (2026-10-17): the first *mention* is not the record. Q53 is first named + # in prose 46 lines before its `**Q53 opened -- ...**` line, and Q63 is named + # inside a tick quoting tool output at :9909 but opened at :9918. So a nested + # id is admitted by its first record-form line, and an id that never has one + # (Q54/Q55/Q56/Q58 as artifact filenames, Q62 inside `Q31-Q62`, Q77/Q99 inside + # a quoted `--outside` list) is not an item at all. mentioned = {} in_fence = False for i, ln in enumerate(lines, 1): @@ -191,14 +252,22 @@ def parse(text): qid = m.group(0) hit = mentioned.get(qid) if hit is None: - mentioned[qid] = [i, ln, 1] - else: - hit[2] += 1 + hit = mentioned[qid] = {"line": i, "refs": 0, "record": None, "form": None} + hit["refs"] += 1 + if hit["record"] is None: + form = record_form(ln, qid) + if form: + hit["record"] = i + hit["form"] = form nested = [] for qid in sorted(mentioned, key=lambda s: int(s[1:])): if qid in ids: continue - line_no, raw, refs = mentioned[qid] + rec = mentioned[qid] + if rec["record"] is None: + continue # a mention, not a record -- not an item + line_no = rec["record"] + raw = lines[line_no - 1] owner = None for s in sections: if s["line"] <= line_no <= s["end_line"]: @@ -213,10 +282,11 @@ def parse(text): shape = "BOLD" else: shape = "PLAIN" - if shape != "HEADING" and "**" in raw: + if shape not in ("HEADING", "BOLD") and "**" in raw: shape += "+BOLD" nested.append({"id": qid, "line": line_no, "section": owner, "shape": shape, - "refs": refs}) + "refs": rec["refs"], "form": rec["form"], + "first_mention": rec["line"]}) first = headings[0][0] if headings else n + 1 preamble_end = first - 1 @@ -329,14 +399,17 @@ def build_doc(payload): lines.append("") lines.append("## Ids with no `## ` heading") lines.append("") - lines.append("Opened as records inside another section. `section` is the heading whose " - "body holds the first mention; `shape` is the form of that line.") + lines.append("Opened as records inside another section. `line` is the record's own opening " + "line and `first mention` is the first line that names the id at all -- they " + "differ when an id is cited in prose before it is opened (Q53: :7246 -> :7292, " + "Q63: :9909 -> :9918). `form` is the record form that admits it.") lines.append("") - lines.append("| id | first line | refs | inside section | shape |") - lines.append("|---|---|---|---|---|") + lines.append("| id | record line | first mention | refs | inside section | shape | form |") + lines.append("|---|---|---|---|---|---|---|") for r in payload["nested"]: - lines.append("| %s | %d | %d | %s | %s |" - % (r["id"], r["line"], r["refs"], r["section"] or "--", r["shape"])) + lines.append("| %s | %d | %d | %d | %s | %s | %s |" + % (r["id"], r["line"], r["first_mention"], r["refs"], + r["section"] or "--", r["shape"], r["form"])) lines.append("") lines.append("**Not in this document.** Ids the prose corpus names that the queue has never " "mentioned (`checkins/`, `replies/`, `recoveries/`, `audits/`, `docs/`, the " @@ -503,8 +576,13 @@ Body with no status marker. ## Q3 §9 follow-on — odd shape +Prose that names Q41 before its record. - **Q41 — OPEN (pipe, 2026-10-13, unclaimed).** A nested record. - prose mentioning Q42 in passing. +- **Q43 opened — a bold lead record for the fixture.** +- a bullet carrying **Q44** mid-line, which is not a record. +- a tick quoting `--outside` = Q77/Q99 as prose. +**Status: OPEN.** The status lead opens Q45 on this line. """ @@ -531,10 +609,19 @@ def selftest(): check("status line number", secs[0]["status_line"], 7) check("section with no marker is None", secs[1]["status"], None) check("continuation status is its own", secs[2]["status"], "OPEN.") - check("nested ids found", [r["id"] for r in p["nested"]], ["Q41", "Q42"]) + check("nested ids found", [r["id"] for r in p["nested"]], ["Q41", "Q43", "Q45"]) check("nested owner is the containing section", p["nested"][0]["section"], "Q3") check("nested shape is bullet carrying a bold lead", p["nested"][0]["shape"], "BULLET+BOLD") - check("nested shape is a plain bullet", p["nested"][1]["shape"], "BULLET") + check("bold lead is a record form", p["nested"][0]["form"], "BOLD-LEAD") + check("status lead is a record form", p["nested"][2]["form"], "STATUS-LEAD") + check("record line follows the first mention of the same id", + (p["nested"][0]["line"], p["nested"][0]["first_mention"]), (24, 23)) + check("prose mention is not a record (Q42)", "Q42" in [r["id"] for r in p["nested"]], False) + check("mid-line bold mention is not a record (Q44)", + "Q44" in [r["id"] for r in p["nested"]], False) + check("quoted tool output opens nothing (Q77/Q99)", + {"Q77", "Q99"} & {r["id"] for r in p["nested"]}, set()) + check("mentions are still counted as refs", p["nested"][0]["refs"], 2) check("sections tile the file with no gap", all(secs[i]["end_line"] + 1 == secs[i + 1]["line"] for i in range(len(secs) - 1)), True) check("last section ends at the last line", secs[-1]["end_line"], p["queue_lines"]) @@ -656,7 +743,7 @@ def main(argv=None): ap.add_argument("--check", metavar="PATH", help="re-derive and compare a rendered index") ap.add_argument("--outside", action="store_true", help="report ids the prose corpus names that the queue never mentions") - ap.add_argument("--selftest", action="store_true", help="fixture corpus, 38 cells") + ap.add_argument("--selftest", action="store_true", help="fixture corpus, 44 cells") args = ap.parse_args(argv) if args.selftest: return selftest()