[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:
co-authored by
Claude Opus 5
parent
448ce373ca
commit
2472ed8e88
+56
@@ -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).
|
||||
|
||||
---
|
||||
|
||||
+125
@@ -1169,3 +1169,128 @@ data in the ratified spec, thin consumer in dotfiles — the pattern REVIEWED-10
|
||||
the engine's own manifest and sidecars and needs no cross-repo enumeration. Each stage carries
|
||||
a both-directions control — drift reported when a binding is stale, clean reported on a
|
||||
genuinely clean corpus.
|
||||
|
||||
## REVIEWED-102 — PENDING-119 — REVIEWED-101 condition 6 placed (e)'s consumer in dotfiles, on reasoning the same ruling says (e) does not engage
|
||||
**Date:** 2026-08-08
|
||||
**Decision:** AUTHORIZED — option (i), with condition 6 of REVIEWED-101 explicitly narrowed on the record, and one condition on (i).
|
||||
|
||||
**Notes:** The ambiguity is mine. Condition 6 was drafted flat, under a heading that read "Placement", and left its scope to be inferred from a
|
||||
sentence four lines below it. That is a jurist defect, not an executor misreading. The item is right that the two texts admit both readings, and
|
||||
right that the narrow reading is the one the reasoning supports: condition 6's argument is ownership of a cross-repo invariant, and (e) does not
|
||||
enumerate one. It follows the engine's own declared pointers into the chamber; the surface list that (a) needs is precisely what (e) does not need.
|
||||
That was already the stated basis for severing (e) from the spec amendment, and the same severance carries the placement.
|
||||
|
||||
1. NARROWING, recorded as a ruling and not as a charitable reading: condition 6 of REVIEWED-101 governs consumers that must ENUMERATE the
|
||||
cross-repo binding surface — (a) and (c). It does not govern (e). Left unrecorded, the next reader relitigates this.
|
||||
|
||||
2. The recorded reason for rejecting (ii) is that it inverts the condition it honours. A ~/dotfiles/scripts/check-source-binding.sh whose body is
|
||||
one exec of engine/ingest_gate.py --check-only puts an engine path and an engine flag into the global layer. That is the coupling REVIEWED-100
|
||||
rejected, reintroduced in the name of a condition written to prevent coupling. A rule that produces the outcome it exists to forbid is being read
|
||||
at the wrong grain.
|
||||
|
||||
3. Kept in view, because the reflex runs the other way: the placement question only became live because the executor delegated to ingest_gate
|
||||
instead of writing a fresh sha-comparing script. Had it duplicated the logic, condition 6 would have been straightforwardly correct. The better
|
||||
implementation is what made the condition misfit — a rule's misfit is not automatically an implementation error.
|
||||
|
||||
4. The fleet-census finding is SPLIT OUT as PENDING-122. "No fleet suite validates live binding" is not evidence for a placement dispute; it is a
|
||||
standing correction to what fleet-green certifies, owed to anyone reading a green fleet. Filed inside PENDING-119 it dies if PENDING-119 is
|
||||
deferred. Same objection made at REVIEWED-101 condition 5; consistency requires making it again. It belongs with PENDING-96 as one family — a green
|
||||
that attests less than its surface suggests.
|
||||
|
||||
5. CONDITION on (i): 0.218 s over 14 sources is honest about being burst-sized, and the check is unconditional on every commit, scaling with
|
||||
sources × file size. State the threshold now with its action — when it exceeds ~1 s, (e) re-scopes or hands off to (a)'s scheduled job. A
|
||||
per-commit cost that grows unremarked converts a tripwire into a --no-verify habit, which is this thread's own failure class arriving by the back
|
||||
door.
|
||||
|
||||
**If AUTHORIZED:** Proceed with (i) — one line in the engine's .precommit-triggers. Record the condition-5 threshold beside it. Tag commits with
|
||||
REVIEWED-102.
|
||||
|
||||
## REVIEWED-103 — PENDING-120 — The fleet trigger covers corpus/ but not the engine code the fleet exists to test
|
||||
**Date:** 2026-08-08
|
||||
**Decision:** AUTHORIZED — option (a), with the scope framing corrected and the acceptance fixture decomposed.
|
||||
|
||||
**Notes:** The demonstration is the strongest part: eecc8bb touched the gate and the gate's own test floor, and the hook printed nothing. First
|
||||
real non-probe commit since the trigger landed, and it ran nothing. That is a measured failure, not a reasoned risk — the same standard
|
||||
REVIEWED-100 credited PENDING-116 for.
|
||||
|
||||
1. CORRECTION to the scope-honesty note. The item says REVIEWED-100 "did not rule the pathspec". As to the ruling, that is accurate — REVIEWED-100
|
||||
authorizes the mechanism and the both-halves acceptance and says nothing about paths. But PENDING-116's own Costs section does: "the trigger paths
|
||||
must be scoped tightly (corpus/, corpus/sidecars/) so ordinary docs commits do not pay it." So the pathspec was not silence — it was a cost
|
||||
commitment in the authorized item. This does not change the outcome; it changes the bar. The widening must be SHOWN to preserve the discrimination
|
||||
that commitment bought, which is exactly why (b) is correctly rejected and (a) is not. Record it as revising a stated cost-control with its
|
||||
justification intact, not as filling a gap. In-scope repair is the more comfortable framing and the less accurate one.
|
||||
|
||||
2. The acceptance test DECOMPOSES; one fixture cannot meet "neither may be a synthetic probe if a real one is available". (i) Fires on a real
|
||||
engine change — replay eecc8bb against the widened pathspec; genuinely real, genuinely available, and it is the commit that demonstrated the gap —
|
||||
but eecc8bb was green, so it proves firing only. (ii) Refuses on red — requires an induced red unless history holds a real red engine/ commit; if
|
||||
one exists use it, and if not, say the fixture is synthetic rather than letting "real fixture" cover both halves. (iii) Docs-only still runs
|
||||
nothing — unchanged, and the half that proves discrimination.
|
||||
|
||||
3. The adjacent gap was checked and the answer is NO; filed as PENDING-123. The hook does not distinguish "no trigger path matched" from "the
|
||||
declaration is malformed or its command is missing". Five disarming faults were tested against a positive control, each staging a real corpus/
|
||||
change the hook must catch: pathspec typo, no separator, empty command, comments-only, empty file. All five silent, all exit 0. A typo disarms the
|
||||
gate permanently and invisibly. This is also why eecc8bb running nothing went unremarked — its output is byte-identical to a fully disarmed hook's.
|
||||
|
||||
4. INTERACTION with PENDING-119. If both land, .precommit-triggers carries two lines with overlapping paths and engine commits pay ~2 s (fleet) +
|
||||
0.218 s (binding). Declare the order in the file so a red is attributable to one check without reading both.
|
||||
|
||||
**If AUTHORIZED:** Proceed with (a) — corpus/ engine/ tests/ scripts/run-fleet.sh. Land the three-part acceptance separately, labelling the
|
||||
induced-red fixture synthetic if no real red engine/ commit exists. Tag commits with REVIEWED-103.
|
||||
|
||||
## REVIEWED-104 — PENDING-122 — What a green fleet certifies, and what it does not: no suite validates live binding
|
||||
**Date:** 2026-08-08
|
||||
**Decision:** AUTHORIZED — option (a), with a required third result state.
|
||||
|
||||
**Notes:** A live-corpus assertion makes one suite depend on chamber-library being present and reachable. Every other suite builds under tmp and is
|
||||
portable; this one will not be. The item does not say what happens on a fresh clone with no chamber beside it, and both obvious answers are wrong.
|
||||
Red on absent is a suite going red for reasons unrelated to the code under test, which trains people to discount fleet red — the worst possible
|
||||
outcome for this particular thread. Skip on absent is the silent net, in the very assertion added to correct an overstatement.
|
||||
|
||||
1. CONDITION: three states — bound / drifted / cannot-assess — and cannot-assess must be distinguishable in the fleet summary, never folded into
|
||||
green. A green fleet that includes an unassessed binding case is the same overstatement one layer along.
|
||||
|
||||
2. The REVIEWED-83 A1 leg of the analogy was challenged as uncorroborated and has been verified against ~/REVIEWED.md, which is authoritative.
|
||||
REVIEWED-83 Amendment 1 (2026-08-01) IS the classifier layer-error: "The classifier's controls exercise its decision rule … They cannot test
|
||||
whether three signals are enough … In both cases the control was correct and sat at the wrong layer." The 0 of 17 → 0 of 14 figure visible in
|
||||
e341242 is a secondary paragraph of that same amendment, labelled "Consequential correction, routed not applied." Third subsystem stands on checked
|
||||
ground, and the amendment itself names the first two as one shape.
|
||||
|
||||
3. Does not prejudge PENDING-121, confirmed from both sides. Option (a) closes the distance between "the gate works" and "the corpus is bound" at
|
||||
whole-file granularity only; anchor correctness is 121's gate and the two land independently. Recorded with it: REVIEWED-101 §C's "fourth surface —
|
||||
the reading index carries no hash" was wrong, and 121 corrects it — the runbook binds the index outward by source_sha256, and the real gap is
|
||||
finer and worse.
|
||||
|
||||
4. The three-state requirement is raised to doctrine as PENDING-124 rather than conditioned again per item.
|
||||
|
||||
**If AUTHORIZED:** Proceed with (a), three-valued. Tag commits with REVIEWED-104. Land after REVIEWED-105 if both are authorized.
|
||||
|
||||
## REVIEWED-105 — PENDING-123 — The pre-commit hook cannot distinguish "nothing to check" from "I am disarmed"
|
||||
**Date:** 2026-08-08
|
||||
**Decision:** AUTHORIZED — (b) now, plus (e) in place of a flag; (a)'s full listing retained on --verbose.
|
||||
|
||||
**Notes:** The strongest item of this set. Positive control first, six rows, mechanism read from the hook's own source down to the two lines that
|
||||
swallow the difference — `[ -n "$cmd" ] || continue` and the `2>/dev/null` that erases "git could not resolve this pathspec". And it answers
|
||||
PENDING-120 §C: "Running pre-commit checks…" with nothing after it is what a fully disarmed hook prints, which is why eecc8bb went unremarked.
|
||||
|
||||
1. Instead of (a) behind a flag — a flag nobody sets is a capability nobody has — option (e): print the per-rule line ONLY when a
|
||||
.precommit-triggers file exists and no rule matched. A rule ran, existing output already says so; nothing matched, one line naming the declared
|
||||
rules and the staged paths; no triggers file, print nothing, so no noise in any other repo. Zero cost in the normal case, and the line appears in
|
||||
exactly the ambiguous case. It also partly closes the fifth silence: a typo'd corpuss/ shows as a declared rule that did not match on a commit that
|
||||
touched corpus/, catchable at the moment the reader is already looking — PENDING-98's mitigation shape, not a log. Keep (a)'s full per-rule
|
||||
listing on --verbose for the never-yet-matched rule, which stays honestly unknown.
|
||||
|
||||
2. The item's own standard, turned on the item: the summary claimed silence when the declaration is "malformed, mis-typed, empty, or absent", and
|
||||
the table had no absent row, nor one for the hook itself missing or core.hooksPath unset. Rows added. Measuring them found something stronger than
|
||||
the claim — with the hook file missing, the commit produces ZERO output, not an ambiguous silence — and found the executor wrong in the other
|
||||
direction: unsetting core.hooksPath locally falls back to an armed global, so that row is a robustness property, not a fault, and is recorded as
|
||||
one.
|
||||
|
||||
3. Blast radius of (b). The hook is global, so a refusal on malformed declarations arms in every repo carrying a triggers file, present and future.
|
||||
Censused 2026-08-08: exactly one exists today (studium-engine), across ten repos under the global hooksPath. Today's radius is one repo; the
|
||||
condition is about the future and stands. Required: the refusal message names file, line number and fault, and states --no-verify. A gate that
|
||||
blocks without saying why is replaced by habit within a week.
|
||||
|
||||
4. SEQUENCING across the four open items: land 123 before 119(i) and 120(a). Both add lines to .precommit-triggers; a validator that catches a
|
||||
malformed line should exist before the file grows. In the other order, the first thing to test the new declarations is the declarations themselves.
|
||||
|
||||
**If AUTHORIZED:** Proceed with (b) + (e). Build order: REVIEWED-105 → REVIEWED-102 (i) → REVIEWED-103 (a). Tag commits with REVIEWED-105.
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
node_type: memory
|
||||
type: feedback
|
||||
originSessionId: 7d08dad4-626a-484c-870b-8f1a9674db7a
|
||||
modified: 2026-08-08T13:30:54.198Z
|
||||
modified: 2026-08-08T14:45:17.679Z
|
||||
---
|
||||
|
||||
# Session Ledger — 2026-08-08
|
||||
@@ -180,6 +180,37 @@ the omission is itself the finding above.*
|
||||
work; it is that I reach for a check whose vocabulary I have not verified against the thing
|
||||
it must match** — the substrate-vs-description class, pointed at my own instruments.
|
||||
|
||||
### ⎯ SESSION 3 authorization moves ⎯
|
||||
|
||||
- **REVIEWED-101 (e) — engine half BUILT** (`eecc8bb`), wiring deliberately **NOT** placed.
|
||||
Built as a **delegation** to `ingest_gate.py`, which already enforced §1.1 on both
|
||||
named surfaces. Suite 24 → **41**; fleet **221/221, 7/7 exit 0**.
|
||||
- **PENDING-119** filed `[PROPOSAL]` — condition 6 vs the ruling's own "(e) needs no
|
||||
cross-repo enumeration". **Steward directed: file, do not wire.**
|
||||
- **PENDING-120** filed `[HARDENING]` — the trigger's pathspec misses `engine/`+`tests/`.
|
||||
**Steward directed: file separately.**
|
||||
- **PENDING-117 AMENDMENT 2** appended — pointer only, nothing above altered.
|
||||
- Commits: engine `eecc8bb`, `f1bb227`; dotfiles `02c6875`. **Neither repo pushed** —
|
||||
engine `ahead 2`, dotfiles `ahead 1`; the push belongs to the wrap.
|
||||
|
||||
- **T~15:5x — the day's error class has a mechanical root, found at last.** `ls` is
|
||||
**aliased** in this profile (eza-like; it rejects a bare path as an `--icons` value).
|
||||
Instance (7) above was never a missing file — the alias ate the argument and returned
|
||||
exit 2. Switched to `command ls`. Worth keeping: **an exit code from an aliased command
|
||||
is evidence about the alias, not about the world.** Two of the day's seven check-errors
|
||||
reduce to this one shell fact.
|
||||
- **T~16:0x — an eighth, caught and not narrated:** read `${PIPESTATUS[0]}` after an
|
||||
intervening `echo` had already clobbered it, printing `exit=` empty. Re-ran clean.
|
||||
Same family: **a check whose vocabulary I had not verified against its own mechanics.**
|
||||
|
||||
- **What held, this session.** Every claim that entered a commit message or a governance
|
||||
filing was substrate-checked first: the fixture-only census by enumerating all six
|
||||
invocations rather than grepping; the delegation argument by reading L128–131/L150–153;
|
||||
the write hazard by reasoning about index-vs-worktree and then *not* asserting it
|
||||
untested; byte-identity of the refactored write by an empty `git diff`; the red
|
||||
direction on the **real** manifest with a `cmp`-verified restoration. **The errors
|
||||
stayed in throwaway checks; nothing false reached a durable surface.**
|
||||
|
||||
## Sub-agent dialogues
|
||||
|
||||
## Bypasses
|
||||
|
||||
Reference in New Issue
Block a user