[HARDENING] PENDING-126 + PENDING-122 Amendment 2 — what inducing red revealed, and REVIEWED-102..105 placed

All three findings came from contact while building a red fixture for the
REVIEWED-103 acceptance. None was sought; the search for a control that worked is
what exposed them.

The fleet already violates the condition REVIEWED-104 attached to the NEW
live-binding assertion, on a dependency the ruling did not consider. Three suites
crash on a gitignored corpus/index.db with a raw sqlite traceback, and run-fleet
reports FLEET RED indistinguishably from a code defect — while store.py rebuilds
that file in 0.628 seconds and the clone then runs 7/7 green. So the condition is
retroactive, not prospective. And test_retrieve.py already detects the absence and
skips with a named reason, which makes PENDING-124 recommendation (d) concrete: the
honest third state exists in this fleet, in one suite, and three others lack it.

R0's section_end bound is unguarded. Removing it leaves 31/31 passing. That is the
rule R0 was created to establish after two consumers disagreed on 3 of 253 patterns
with neither right — asserted in prose, correct-but-inert on the live corpus, and
therefore invisible to every test.

test_navigate crashes with StopIteration rather than naming a failure. The exit code
was always right; the legibility is missing — REVIEWED-100's own distinction,
recurring where its fix does not reach.

Also commits REVIEWED-102 through -105, placed by the steward and left uncommitted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A35wiD55yRHj5U1ECZAX4t
This commit is contained in:
David F Glidden
2026-08-08 18:15:20 +02:00
co-authored by Claude Opus 5
parent 448ce373ca
commit 2472ed8e88
3 changed files with 214 additions and 2 deletions
+56
View File
@@ -1897,6 +1897,32 @@ The `0 of 17` → `0 of 14` figure the jurist saw is a **secondary** paragraph o
---
### AMENDMENT 2 — 2026-08-08, the condition is ALREADY VIOLATED, by a dependency the ruling did not consider
*Found by contact while running REVIEWED-103's acceptance in a fresh clone — not sought.*
**REVIEWED-104 §1 conditioned the NEW live-binding assertion on three states**, reasoning that *"red on absent trains people to discount fleet red, which is the worst possible outcome for this particular thread."* **That outcome is already the present state**, on a different dependency, with nothing to do with `chamber-library`.
**Measured 2026-08-08 in a fresh `git clone`:**
| suite | with `corpus/index.db` absent |
|---|---|
| `test_ground.py` | **crashes** — raw `sqlite3.OperationalError: unable to open database file` |
| `test_navigate.py` | **crashes** — same |
| `test_reading_index.py` | **crashes** — same |
| `test_retrieve.py` | ✅ **skips, with a named reason** |
| `test_fidelity_v3` · `test_ingest_gate` · `test_verify_quote` | pass (no dependency) |
`run-fleet.sh` reports **FLEET RED**, indistinguishable from a code defect.
**`corpus/index.db` is gitignored on purpose** — the engine's first law is that *the files are authoritative; every index is derived, subordinate, and disposable.* And the disposal is real: **`python3 engine/store.py build` rebuilt it in 0.628 s**, after which the clone ran **7/7 green**. So this red is a **0.6-second-avoidable environment condition, reported as a failure.**
**Three consequences.** **(1)** The condition ruled here is **retroactive, not prospective** — three suites need `bound`/`drifted`/`cannot-assess` today, before any live-binding assertion exists. **(2)** ⚠ **The honest third state ALREADY EXISTS IN THIS FLEET, in one suite:** `test_retrieve.py` detects the absence and skips with a named reason. **That is PENDING-124 recommendation (d) with a live in-repo precedent** — generalize what is implemented rather than mint doctrine beside it. **(3)** **A crash is not a third state.** REVIEWED-100 made every suite name its failures in the summary; an uncaught traceback bypasses that, so these three are invisible to the improvement meant to cover them.
**Files affected (revised):** three suites gain the detect-and-report shape `test_retrieve.py` already has; `scripts/run-fleet.sh` must render `cannot-assess` distinguishably from red.
---
## PENDING-123 — The pre-commit hook cannot distinguish "nothing to check" from "I am disarmed"
**Date:** 2026-08-08
@@ -2046,3 +2072,33 @@ Three cases, all discriminated: a rule ran → existing output already says so,
**Awaiting:** Steward authorization (D-1 lane).
---
## PENDING-126 — Two holes in the fleet, found by inducing red against it: an untested load-bearing rule, and a suite that crashes instead of failing
**Date:** 2026-08-08
**Tag:** [HARDENING]
**Related:** REVIEWED-103 (whose acceptance surfaced both) · REVIEWED-100 (the failure-naming improvement hole 2 bypasses) · `studium-engine/docs/spec/r0-reading-index-contract.md` §3 · PENDING-122 Amendment 2 (same act, third finding).
**Provenance:** neither was sought. Both surfaced while trying to build a red fixture the fleet would catch — **the search for a working control is what exposed them**, the discrimination gate doing its job one level out.
**Hole 1 — R0's `section_end` bound is not covered by any test, and it is the rule R0 exists for.** `engine/reading_index.py:123` reads `it["line_end"] = min(nxt, section_end) if end is None else min(end, section_end)`. **Removing the `section_end` bound entirely leaves `tests/test_reading_index.py` at 31/31 passing** and the whole fleet green. That bound is not incidental: R0 was created because `measure_rerank.py` and `navigate.py` had each grown their own reader and **disagreed on 3 of 253 Alexander patterns with neither right** — one ran a pattern into the next group, the other into ACKNOWLEDGMENTS. The derived rule *"end = min(next sibling's start − 1, containing section's end)"* is the fix. **It is asserted in prose and unguarded in code.** ⚠ Likely cause: the live corpus never exercises the branch, so the bound is **correct-but-inert**, and a regression would surface only on a corpus shape we do not yet hold.
**Hole 2 — `test_navigate.py` crashes rather than naming a failure.** Forcing `citable = False` at `engine/navigate.py:189` produces an uncaught `StopIteration` at `tests/test_navigate.py:116`. Exit is non-zero, so the fleet correctly goes red and the commit is correctly refused — **but the failure is a traceback, not a named check.** REVIEWED-100's improvement was that *"all seven suites now name failures in the summary"*; a crash bypasses the summary entirely. ⚠ **The exit code was always right; the legibility is what is missing** — the same distinction REVIEWED-100 drew, recurring where its fix does not reach.
**Rationale.** Both holes are invisible to a green fleet by construction, and the trigger landed today makes the fleet the gate on every `engine/` and `tests/` commit. **A gate is only as good as the suites behind it**, and these are two measured ways those suites say less than their green implies — the PENDING-96 family, now inside the fleet rather than around it.
**Options.**
- **(a) Fix both.** A fixture exercising the `section_end` bound (necessarily synthetic — the branch has no live instance), and a guarded lookup in `test_navigate.py` that fails by name instead of raising.
- **(b) Fix hole 2 only.** Cheaper; leaves a load-bearing derived rule unguarded.
- **(c) Census first.** ⚠ Neither hole was sought, so **the base rate is unknown** — how many other asserted-in-prose rules are unguarded, and how many suites crash rather than name?
**Recommendation: (a), then (c) as a bounded sweep.** (a) closes what is measured; (c) is the honest follow-on because **two holes found without looking is not a base rate**, and the census is bounded (7 suites; the contracts are enumerable).
**Check that it worked — both directions required.** Hole 1: the new fixture must go **red** with the bound removed and **green** with it restored — the removal is already proven invisible, so that is the discriminating negative, real and available. Hole 2: the induced citability break must produce a **named** failure in the summary and still exit non-zero; the restore must return 34/34.
**⚠ What this does not establish.** Fixing these two says nothing about the class (option c). And hole 1's fixture is necessarily **synthetic** — the live corpus has no instance of the shape, which is exactly why the gap survived.
**Files affected:** `~/_Dev/studium-engine/tests/test_reading_index.py`, `~/_Dev/studium-engine/tests/test_navigate.py`.
**Awaiting:** Steward authorization (D-1 lane).
---