session 2026-08-09: PENDING-129/130 filed → REVIEWED-113/114 placed; the V4 fixture was a 0-byte file

This commit is contained in:
David F Glidden
2026-08-09 21:27:53 +02:00
parent f530df6cde
commit 009359f64e
8 changed files with 571 additions and 7 deletions
+114
View File
@@ -2432,3 +2432,117 @@ else echo "INCOMPLETE — $old residual occurrence(s) of an old name"; fi
**§K — Recommended:** the jurist's offer to draft these as three lines under **REVIEWED-110 point 10** should be taken. They are conditions on a **placed** ruling, and per the REVIEWED-87 lesson an amendment **joins its record** rather than living as prose beside it. Steward's call; `~/REVIEWED.md` is their hand.
---
## PENDING-129 — `pattern_finder` silently discards a probed voice that has left the corpus, and its denominator hides the loss
**Date:** 2026-08-09
**Tag:** [HARDENING] — engine-side, D-1
**Related:** REVIEWED-104 / the ladder's **"Checks whose subject can be absent"** (the ratified three-outcome doctrine) · PENDING-124 (same collapse, *cross-repo*; this is the **same-repo** instance) · PENDING-122 (an aggregate that reports clean over an unassessed member) · Constitutional Constraint 4.
**Found by:** re-running the June Station-I pass on the steward's instruction, and reading the spec's probe keys against the harness's own voice list — not by reading the code.
**Summary.** `ground_primitive` iterates `sorted(station_voices(station))`, which is derived from **`corpus/manifest.yaml`**. The probes it runs come from the **spec JSON**. A voice the spec probes that is *not in the manifest* is therefore never iterated: it yields no citations, no silence, and **no mention anywhere in the output**. The report's spread line — `f"Instantiated in {voice_count} of {voice_count + len(silent)} voices"` — builds **both** halves of the fraction from the manifest, so the denominator cannot express the loss either.
**Measured, 2026-08-09, on the real spec and the live corpus.** `corpus/pattern-finder-station-i-pass1.json` probes **camus** in all three primitives (**19 distinct probes**). `camus-la-chute` has a sidecar but **no manifest entry**. The re-run printed **"Instantiated in 4 of 4 voices"** three times. The honest line is *4 of 5, fifth **not in corpus***. Nineteen probes were asked and the record shows no trace that they were asked.
**Why this is the ratified class and not a cosmetic gap.** The harness already models absence — it has a first-class `silence` with a `warranted` flag, and the charter (§VI) makes a warranted silence a *finding*. So the vocabulary exists; what is missing is that **`silence` means "the voice was searched and yielded nothing"** while this case is **"the voice was never searched."** Those are the two states REVIEWED-104 forbids merging, and merging them here is worse than the ordinary version: the missing voice does not even reach the aggregate as a member, so it cannot be counted as unassessed. ⚠ **Direction of the error is the dangerous one** — dropping a voice can only *raise* the apparent instantiation rate. A primitive that would have been silent in Camus reads as universally instantiated.
**Options.**
- **(a) Iterate the UNION of manifest voices and spec-probed voices; emit a third state `not-in-corpus` for the difference, excluded from the "of N" denominator and named on its own line.** The spec's probe list becomes evidence of what was *asked*, which is the only place that record exists.
- **(b) Refuse to run a spec naming an unmanifested voice** (fail-loud at load). ⚠ This makes every historical spec unrunnable the moment the corpus moves — destroying exactly the re-run capability that produced this finding.
- **(c) Warn at load, run anyway.** ⚠ A warning on stderr does not reach the report the steward reads; the false "4 of 4" still prints.
**Recommendation: (a).** A primitives spec is a **dated historical artifact** — this one is from June and the corpus has changed under it four times since. The harness's value is precisely that an old spec can be re-run against a new corpus; (b) trades that away to fix a reporting defect. (a) also puts the disclosure **in the artifact the human reads**, which (c) does not.
**Check that it worked — both directions.** Run the **unmodified June spec**: `camus` must appear as `not-in-corpus`, the spread line must read *4 of 5* (or equivalent) with the fifth named, and the four manifested voices' numbers must be **byte-identical to today's run**. Then run a spec naming **only manifested voices**: no `not-in-corpus` line may appear. ⚠ **A control built only from manifested voices cannot detect this defect** — it is the "control must sit at the layer the defect lives in" case, and the discriminating pair is the June spec against a manifest-only one, both real.
**⚠ What this does not establish.** Naming the dropped voice does nothing about whether the *remaining* grounding is true — see PENDING-130. It also does not check the inverse case (a manifested voice the spec never probes), which is silently untested today and is **not** proposed here.
**Files affected:** `~/_Dev/studium-engine/engine/pattern_finder.py` (`ground_primitive`, `render_report`); a suite — **`pattern_finder.py` has no test file at all**, which is itself the finding's context.
**Awaiting:** ~~Steward authorization (D-1 lane).~~ → **AUTHORIZED (a) by steward relay 2026-08-09; BUILT `6f6bac5`.** ⚠ **The corresponding `~/REVIEWED.md` entry is NOT placed** — the ruling exists as a relayed message only, and no `REVIEWED-N` is cited in the commit. Placement is owed and is the steward's hand.
---
### AMENDMENT 1 — 2026-08-09, built; and the fourth cell was a crash, not a collapse
**§A — The ruling's three refinements, all taken.** (1) Implemented as the **cross** — `voice_cross()` returns `assessed` / `not_in_corpus` / `not_probed` from (in manifest?) × (probed by spec?) — so closing the fourth cell later is a line, not a rewrite. (2) `not_assessed` is a **sibling of `by_voice`**, per REVIEWED-47 §1a quoted from the **placed** record: *"attested absence lives in its own honest top-level key … (not a verdict inside `source_verified:`)"* — stronger than the relay's *"named on its own line."* (3) Both cells carry `kind: environment`, and the fraction now reads *"of N voices **searched**"* so a reader who skips the block still cannot read it as coverage.
**§B — ⚠ THE FOURTH CELL DOES NOT COLLAPSE INTO `silence`. IT RAISES `KeyError`.** The ruling flagged its own table as *"inference, not reading"* and invited the check. Driven: `v_probes = probes[v] if isinstance(probes, dict) else probes` — a **manifested** voice absent from a dict-form probes block raised `KeyError: 'arendt'`, reproduced on the live corpus. So the cell is **a crash in engine code**, the class PENDING-126(c) closed **suite-side only**, and this is its second engine-side instance after `retrieve.py:134 _work_map`. The point did not dissolve; it moved. **Scope honoured anyway:** the cell is made *representable and non-crashing*, and what a report should DO with it stays unruled.
**§C — The control the ruling required, and what it bought.** The four assessed voices' `by_voice` is **byte-identical** to the pre-fix run at `ec6fa0b` — so the ordering argument held exactly: only the spread line moved and one key appeared, and **all 36 citations are invariant under the fix.** Landing 129 first cost nothing in fixture content.
**§D — Four directions, not two.** (1) June spec → camus attested in all three primitives, 7/6/6 probes asked. (2) Manifest-only spec → the key does **not** appear, and the report omits the block entirely (a warning that fires on the safe case is discarded with the dangerous one). (3) Fourth cell → attested, no crash. (4) Flat probe list → runs against every manifested voice, neither cell fires.
**§E — `pattern_finder.py` had no suite at all.** `tests/test_pattern_finder.py`, **22 checks**, fleet **7 → 8 suites, 263 checks**. ⚠ **Witnessed red BEHAVIOURALLY**, not by deleting the function: names left in place, behaviour reverted. Exit **1**, **six named failures**, camus by name and the `KeyError` resurfacing. My first probe deleted `voice_cross` instead and produced a **traceback, not a named failure** — an absent symbol is not the defect — and I read its exit code **through a pipe**, so the `0` reported was `tail`'s. Both corrected before the result was used; recorded because it is yesterday's *checks-are-the-weak-link* class inside the remedy for it.
**§F — ⚠ What this does not establish.** Nothing about whether any finding is **true**. The suite says so in its own output. The organ remains PASS-BUT-FALSELY; relevance is V3/V4's claim.
---
## PENDING-130 — V4's designated adversarial fixture is an empty file, and a Stage-1 completion criterion has no subject
**Date:** 2026-08-09
**Tag:** [PROPOSAL] — engine-side, D-1; asks the steward to *choose* a fixture, not to approve a fix
**Related:** `docs/stage-1-rebuild-plan-2026-07-05.md` §2.3 (V4) and §"Stage-1-rebuilt is done when" criterion 1 · `docs/tool-evolution-log.md` (the back-filled pass-1 entry) · `~/_Dev/studium-engine/CLAUDE.md` L61 · the KG drift-pattern *"cited a derived label instead of the substrate."*
**Found by:** checking the premise of the wrap's own literal question before acting on it.
**Summary.** Three documents instruct that the Station-I pass-1 **output** be preserved as V4's first adversarial fixture — *"the known-bad output is **V4's designated adversarial fixture** — do not delete or regenerate it."* **`corpus/pattern-finder-station-i-pass1.md` is 0 bytes.** It was committed empty at `38de1a9` (2026-06-26), is touched by **exactly one commit** in the repository's history, and has never been written. The **input spec** (`corpus/pattern-finder-station-i-pass1.json`, 3,879 B, 3 primitives) *is* preserved; the output is not.
**What depends on it.** The rebuild plan §2.3: *"Retro-gate the existing Station-I pattern-finder pass-1 output as the first live test — the known PASS-BUT-FALSELY run is the perfect adversarial fixture."* And criterion 1 of Stage-1-done: *"the retro-gated pattern-finder run has its false grounding caught."* **Both name an artifact that does not exist**, so criterion 1 is currently unsatisfiable — not failing, unsatisfiable.
**⚠ And the June run is unrecoverable, not merely missing.** It is not in git under any path. It also **cannot be reproduced by re-running**: since June the corpus has changed under the spec at least four times — `camus-la-chute` left the manifest, Musil is now the **EN** Wilkins/Pike (the spec's Musil probes are French), `weil-gravity-and-grace` was re-partitioned 2026-08-07, and `handke` was added. Any run today is a **different pass**, not a recovery.
**How the instruction survived seven weeks.** The sentence was carried forward through repeated doc-currency passes — it is in `CLAUDE.md`, the rebuild plan and the tool-evolution log — and **no pass ever opened the file**. This is the *cited-a-derived-label-instead-of-the-substrate* shape, and it is a fourth instance: a description of the artifact was read in place of the artifact, three times over, by an instruction whose entire content was *protect this artifact*.
**Options.**
- **(a) Designate the 2026-08-09 re-run as V4's adversarial fixture**, committed with its provenance stated in the file — a *2026-08-09 run of a June spec against a changed corpus*, explicitly **not** the June run — and correct the three documents' claims.
- **(b) Leave V4 without a fixture** and rewrite §2.3 and criterion 1 to name material that exists, deferring the fixture to whenever one is next produced.
- **(c) Record the loss and stop there** — remove the "do not regenerate" instruction, since it protects nothing.
**Recommendation: (a), with one condition the executor cannot discharge.** The re-run **has the property V4 needs**, demonstrably and by mechanical evidence, not by taste: 36 citations, **zero abstentions**, *"instantiated in 4 of 4 voices"* on every primitive, and **three passages grounding two different primitives each** (Eichmann L738 stands as evidence for both *threshold-without-decision* and *gray-zone-depletes*, via the same token `obedience`; Musil L31702 for both *attrition-erodes-attention* and *gray-zone*). Every citation is verbatim and correctly located — which is precisely why **V1 passes all 36** and why this fixture tests V3/V4 rather than V1.
⚠ **The condition, and it is the whole risk.** A fixture needs an **answer key** — *which* citations are the false ones. If the executor supplies both the known-bad run and its answer key, then the same hand writes the fixture and (later) the gate, which is the *"controls derived from the check, not from the property"* failure the discrimination gate exists to forbid. **The answer key must be marked by a differently-formed reader — the steward — before V4 is built.** The rendered report is written for exactly that reading. Until that marking exists, (a) is **half-done and must not be called a fixture.**
**Check that it worked.** The committed artifact's header states its own provenance and the fact that it is not the June run; the three documents no longer assert a preserved June output; and the steward's marked answer key exists as a separate, dated file. ⚠ **No mechanical control is available for the marking step** — its correctness is the steward's judgment, and saying so is the honest report of this item's limit.
**⚠ What this does not establish.** Nothing here recovers the June run, and nothing here establishes that the *June* pass and the *August* pass fail in the same way — only that both fail. It also does not touch PENDING-129: the August run's "4 of 4" is itself inflated by the silently dropped voice, so **the fixture and the defect are entangled**, and the order in which they are fixed changes the fixture's contents.
**Files affected:** `~/_Dev/studium-engine/corpus/pattern-finder-station-i-pass1.md` (currently 0 B); `docs/stage-1-rebuild-plan-2026-07-05.md` §2.3 + criterion 1; `docs/tool-evolution-log.md`; `~/_Dev/studium-engine/CLAUDE.md` L61.
**Awaiting:** Steward authorization — **and, under (a), the steward's marked answer key**, which no authorization can substitute for.
---
### AMENDMENT 1 — 2026-08-09, ruled (a) with four additions; ordering executed; figures restated
**§A — The ordering was the decision, and it was executed.** PENDING-129 landed first (`6f6bac5`), then the post-fix re-run was preserved (`8746dcf`). The ruling's mechanical argument held: because 129's own control requires the assessed voices to be byte-identical to the pre-fix run, **all 36 citations are invariant under the fix** — only the spread line moved. The pre-fix run at `ec6fa0b` is therefore **retained, not superseded wholesale**: it is 129's byte-identity control *and* the dated record of the defect. That reframes what `ec6fa0b` is for — committed for 130, load-bearing for 129.
**§B — ⚠ FIGURES RESTATED, because this item's evidence paragraph cited a now-superseded output.** The recommendation's grounds were measured on the **pre-fix** run. Re-measured on the post-fix run (`8746dcf`), the load-bearing numbers are **unchanged**: 36 citations · **zero abstentions** · three passages grounding two primitives each (Eichmann L738 for both *threshold-without-decision* and *gray-zone*, via `obedience`; Musil L31702 for both *attrition* and *gray-zone*; Levi L140 likewise). **What changed:** the fraction now reads *"4 of 4 voices searched"* and camus is attested as `not-in-corpus`, 19 probes asked. The false **denominator** is gone; the false **grounding** is not, which is the point of the fixture.
**§C — (1) The answer key cannot be delegated to the jurist, and that is now on the record.** The efficiency is foreclosed by the ratified doctrine's own text — jurist and executor *do not differ from each other in formation*, so their separation is of the weaker kind. Of the three parties, **only the steward is differently formed**. Naming it here so it is not proposed later as a convenience.
**§D — (2) Mark against the corpus, not against the report — 130's instrument run back over 130.** The report's claim that its citations are verbatim and correctly located **is the executor's claim about them**; marking the key by reading the rendered report reproduces the very shape this item records (a description read in place of the thing, three times over). **Answering which:** the report does **not** carry enough surrounding context to make the check possible from the file alone — it emits a 320-character snippet per citation (`_snip`) with `work` + `section_id` + line range. So the key must be marked **with the corpus open beside it**, opening the cited lines. The preserved header now says exactly that.
**§E — (3) Three moving parts, pinned.** The June run became unreproducible because spec date and corpus state were tracked and **the engine was not** — and 129 has just moved the engine, which would have done it again within hours. The post-fix header pins **spec sha · manifest sha + index `as_of` · engine commit `6f6bac5` + `pattern_finder.py` sha**, plus the emitted-bytes sha, with a stated round-trip: split on `END-PRESERVATION-HEADER` and the remainder is byte-identical to a fresh emit (**proven, not asserted**, both times).
**§F — (4) 'Retro-gated' is the word to strike.** Criterion 1 reads *"the **retro-gated** pattern-finder run has its false grounding caught."* Under (a) there is no retro-gated run — there is a **contemporaneously generated** one. Repairing only the artifact reference would preserve the false provenance inside the criterion that was unsatisfiable because of it. ⚠ **Not yet executed** — see §G.
**§G — THE STANDING CONDITION, AND WHY NO DOCUMENT WAS TOUCHED.** *No document may call the artifact V4's fixture until the marked key exists as a dated file.* Accordingly `docs/stage-1-rebuild-plan-2026-07-05.md` §2.3, its criterion 1, `docs/tool-evolution-log.md` and `CLAUDE.md` L61 are **deliberately unedited**. Updating them now would assert a fixture that is still half-done and **rebuild the seven-week gap under a fresh filename** — in the item that exists to establish nobody re-opens those files. The two artifacts are committed as **preservation**, and both headers say so in their first line.
**Files added:** `corpus/pattern-finder-station-i-rerun-2026-08-09.{md,json}` (`ec6fa0b`, pre-fix, 129's control) · `corpus/pattern-finder-station-i-rerun-2026-08-09-postfix.{md,json}` (`8746dcf`, the fixture candidate).
**Still awaiting:** the steward's **dated answer key, marked against the corpus**. Until it exists, (a) is half-done and the four documents stay as they are.
**§H — ⚠ CORRECTION, steward-caught 2026-08-09: THIS ITEM IS RULED, AND I TWICE WROTE THAT IT WAS NOT.** The steward's ruling reads *"PENDING-130 — (a) is right; the condition is the whole ruling"* and refers to *"the 130 authorization."* That is a **ruling with an unmet condition**, which is not the same fact as an **unruled item** — and conflating them is precisely the *disposition-clause-is-not-a-status* class this session has been working in. It appeared in two places: `8746dcf`'s commit message (*"PENDING-130 is unruled"*) and the post-fix artifact's preservation header (*"PENDING-130 proposes that it become one"*). **The header is corrected in place** (`fdc2a01`); the commit message is left standing, because a filed record records what was said when, and rewriting it would destroy the trail — this §H is the correction that joins it, per the REVIEWED-87 amendment lesson.
⚠ **Consequence worth stating, because it cuts against my own caution:** reading the artifact as *proposed-but-unruled* makes the delay look like an open question about whether it should be the fixture. It is not. **The decision is made; only the condition is outstanding.** Being over-cautious in the wrong direction is still a false statement of the record.
⚠ **A third, still-live distinction:** ruled-in-relay is not **placed**. Three states, three names: **ruled · placed · condition discharged.** None implies another.
**§I — PLACED 2026-08-09 as REVIEWED-114; conditions 1, 2, 4, 5 discharged.** `governance-drift-check.py` built-vs-ruled cleared (10 → 12 checked). **⚠ Reading the PLACED text changed what was done:** condition 4 reads *"§2.3, criterion 1 and `CLAUDE.md` L61 **may be corrected to name existing material**; they may not assert a fixture that is half-done."* The relay had been read as *leave all four untouched*, and §G recorded that reading. It was wrong, and it was preserving a live false claim (`CLAUDE.md` L61 asserted an empty file was the designated fixture). All four corrected `20f8958`, verified: no document asserts an existing artifact **is** a fixture — every surviving mention is a negation, a quotation of the struck words, or unrelated. **Third consecutive instance of the placed record answering a question the relay left open** — the standing finding, firing again.
**§J — Two residues in the placed entry, recorded so a later reader does not trip on them.** Raised once, and the steward has since amended the entry (the `If AUTHORIZED` tag line, which had read `REVIEWED-113`, now reads `REVIEWED-114`). Two remain and are **deliberately not re-raised**: (1) the Notes read *"**two** passages grounding two primitives each"*; the grounded JSON measures **three** — Eichmann L738, Musil L31702, Levi L140, each standing for two different primitives. The substrate figure is the one any later work should use. (2) The Decision line says *"five conditions"* over **seven** numbered items; 6 and 7 read as notes rather than conditions, so five is likely right and the numbering simply continues. Neither affects the disposition.
**Still open on this item: condition 3 — the steward's dated answer key, marked against the corpus.** Until it exists the item is **not archived**, no document names a fixture, and **V4 is not built.**
---