[PROPOSAL] PENDING-124 (doctrine), and the census my own summary had outrun

124 files what the jurist asked be ruled once rather than conditioned twice more:
a check whose subject lies outside its own repo cannot be two-valued. Reached
independently in two subsystems on one day — 122 from portability, 123 from
acceptance design — which is this register's recurrence test. Recommendation is
(d): generalize R0 §3's already-ratified "unverified is not a failure state and
must not be collapsed into either neighbour" rather than mint a second home for
it, while noting R0 is D-1 and cannot govern the chamber or the global hook,
which may be the whole reason a ruling above D-1 is needed.

123 gains the rows its summary had claimed and its table never reached — the
item's own standard, turned on the item. Measuring them found something stronger
than the claim: with the hook file itself missing the commit produces ZERO
output, not an ambiguous silence. And it found me wrong in the other direction —
the core.hooksPath row does not show a disarm, because unsetting it locally falls
back to an armed global. That is a robustness property and is recorded as one.

123 also gains (e) in place of a flag, on the jurist's reasoning that a flag
nobody sets is a capability nobody has; the blast-radius census (one triggers
file today, ten repos under the global hooksPath); and the build order — 123
before 119(i) and 120(a), so a validator exists before the file it validates grows.

122 gains the three-state condition and the verification of its own contested
citation: REVIEWED-83 Amendment 1 is the classifier layer-error, and the figure
correction the jurist saw in e341242 is a secondary "routed not applied"
paragraph of that same amendment. Third subsystem stands on checked ground.

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 17:35:29 +02:00
co-authored by Claude Opus 5
parent b2df15c546
commit eeb9676bf4
+92
View File
@@ -1826,6 +1826,28 @@ So the pathspec was **not silence — it was a cost commitment inside the author
---
### AMENDMENT 1 — 2026-08-08, on the ruling's condition
*Appended, not substituted.*
**§A — REQUIRED THIRD RESULT STATE.** A live-corpus assertion makes one suite depend on `chamber-library` being present and reachable; every other suite builds under `tmp` and is portable. The item did not say what happens on a fresh clone with no chamber beside it, **and both obvious answers are wrong** — *red on absent* trains people to discount fleet red, which is the worst possible outcome for this thread specifically; *skip on absent* is the silent net, reintroduced inside the very assertion added to correct an overstatement.
Ruled: **three states — `bound` / `drifted` / `cannot-assess`** — and `cannot-assess` must be **distinguishable in the fleet summary and never folded into green.** A green fleet containing an unassessed binding case is the same overstatement one layer along.
**§B — The `REVIEWED-83 A1` leg of the analogy was challenged and is VERIFIED; it stands.** The jurist could corroborate the REVIEWED-84 leg (chamber `86311d6`, *"coverage never attests order"*) but not this one — the visible commit `e341242` reads as a two-column exposure patch. Checked against `~/REVIEWED.md`, which is authoritative: **REVIEWED-83 AMENDMENT 1 (2026-08-01) *is* the classifier layer-error.** Verbatim:
> **Why the control could not have caught it — and the shape is the one REVIEWED-84 already named.** The classifier's controls exercise its *decision rule*: given three signals, does it decide correctly? They cannot test whether three signals are *enough*. … REVIEWED-84 found that adding independence cannot fix an operator that discards position. This finds that adding controls cannot fix a triad that lacks a signal. **In both cases the control was correct and sat at the wrong layer.**
The `0 of 17` → `0 of 14` figure the jurist saw is a **secondary** paragraph of the same amendment, labelled there *"Consequential correction, routed not applied."* `e341242` shows the routed correction, not the finding. **"Third subsystem" therefore stands on checked ground**, and the amendment itself names the first two as one shape.
**§C — This does not prejudge PENDING-121, confirmed from both sides.** (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. ⚠ Also recorded: **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`; the real gap is finer and worse.
**§D — Doctrine candidate raised with this ruling, filed as PENDING-124.** The three-state requirement here and PENDING-123's independently-reached *"needs a third state, not a pass or a fail"* are the same finding in two subsystems on one day: **a check that reaches outside its own repo cannot be two-valued.** Ruled once rather than conditioned per item.
**Awaiting:** placement of the ruling.
---
## PENDING-123 — The pre-commit hook cannot distinguish "nothing to check" from "I am disarmed"
**Date:** 2026-08-08
@@ -1869,3 +1891,73 @@ Five disarming faults, five silences, indistinguishable from each other **and**
---
### AMENDMENT 1 — 2026-08-08, on the ruling's conditions
*Appended, not substituted.*
**§A — MY SUMMARY EXCEEDED MY TABLE, and the item's own standard catches it.** The summary claimed silence when the declaration is *"malformed, mis-typed, empty, or **absent**"* — but the table measured five faults and **had no `absent` row**, nor one for the hook itself missing or `core.hooksPath` unset. *A census whose summary exceeds its table is the shape this register spends its time catching.* Rows added rather than the claim narrowed, because measuring them turned up something stronger:
| case (each staging a real `corpus/` change) | hook ran? | check fired? | output lines |
|---|---|---|---|
| well-formed triggers present *(control)* | yes | **yes** | 5 |
| `.precommit-triggers` **absent** | yes | no | **2** |
| `hooksPath` set, **no pre-commit hook in it** | **no** | no | **0** |
| local `core.hooksPath` unset | yes | no | 2 |
**Two corrections to my own framing come out of this.**
1. ⚠ **The strongest row is the one I never claimed:** with the hook file itself missing, the commit produces **zero output**. Not an ambiguous silence — *no signal whatsoever*. Every "is the gate armed?" question below that line is unanswerable from the terminal.
2. ⚠ **The `core.hooksPath` unset row does NOT show a disarm, and I would have reported it as one.** Unsetting it *locally* falls back to the **global** setting, which is armed — so the hook still ran. That is a **robustness property**, not a fault, and it is recorded as such. My probe tested the wrong scope; overriding the global setting to test it properly would disarm the steward's live hook, and was not done.
**§B — (a)-behind-a-flag is REPLACED by (e): print the per-rule line exactly in the ambiguous case.** *A flag nobody sets is a capability nobody has.*
> **(e)** Print a per-rule line **only when a `.precommit-triggers` file exists and no rule matched.**
Three cases, all discriminated: a rule ran → existing output already says so, add nothing · nothing matched → one line, `2 rules declared, none matched staged paths (corpus/, corpus/sidecars/)` · no triggers file → print nothing, so **no noise in any other repo**. Zero cost in the normal case; the line appears in exactly the ambiguous one. It also **partly closes the fifth silence**: a typo'd `corpuss/` now shows as a declared rule that did not match on a commit that touched `corpus/` — catchable at the moment the reader is already looking. That is PENDING-98's mitigation shape, not a log.
**Revised recommendation: (b) + (e)**, with (a)'s full per-rule listing kept on `--verbose` for the never-yet-matched rule, which stays **honestly unknown**.
**§C — Blast radius of (b), censused 2026-08-08.** The hook is **global**, so turning a malformed declaration into a refused commit arms that refusal in every repo carrying a triggers file, present and future. Measured: **exactly one file exists today** — `~/_Dev/studium-engine/.precommit-triggers` — across **10** git repos under the global `hooksPath`. So today's blast radius is one repo; **the condition is about the future, and stands.** Required with (b): **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.*
**§D — SEQUENCING across the four open items: land 123 BEFORE 119(i) and 120(a).** Both of those add lines to `.precommit-triggers`; a validator that catches a malformed line should exist before the file grows. **Landing them in the other order means the first thing to test the new declarations is the declarations themselves.**
**§E — Related doctrine, filed as PENDING-124.** This item's *"needs a third state, not a pass or a fail"* and PENDING-122's `cannot-assess` are one finding reached twice in one day.
**Awaiting:** placement of the ruling. **Build order on placement: 123 → 119(i) → 120(a).**
---
## PENDING-124 — A check that reaches outside its own repo cannot be two-valued
**Date:** 2026-08-08
**Tag:** [PROPOSAL] — proposed as **doctrine**, not as a per-item condition
**Related:** PENDING-122 §A (`bound`/`drifted`/`cannot-assess`) · PENDING-123 §B and its acceptance test (the valid-but-never-matching rule *"needs a third state, not a pass or a fail"*) · PENDING-96 · REVIEWED-83 A1 + REVIEWED-84 (the control-at-the-wrong-layer pair) · the *silent net is uninformative* ladder entry.
**Raised by:** the jurist, ruling on 122/123 — *"a candidate for doctrine rather than for restating per item — I'd rather rule it once than condition it three more times."*
**Summary.** Proposed: **a check whose subject lies outside the repo it ships in must report three states, not two** — the property holds, the property fails, or **the property could not be assessed** — and the third must be distinguishable in whatever summary the check feeds, never folded into the passing state.
**Why it is doctrine and not two conditions.** It was reached **independently, in two subsystems, on one day**, by different routes. PENDING-122 arrived at it from portability: a fleet suite asserting live binding depends on `chamber-library` being present, and on a fresh clone *red-on-absent* trains people to discount fleet red while *skip-on-absent* is the silent net rebuilt inside the assertion added to remove one. PENDING-123 arrived at it from acceptance design: a declared rule that has never matched is not passing and not failing — it is **honestly unknown until something matches**. Same shape, no shared reasoning. A finding that arrives twice by different roads on the same day is the register's own recurrence test.
**The general form.** A two-valued check silently conflates *"I looked and the property holds"* with *"I could not look."* Inside one repo that conflation is usually harmless, because the subject is always present. **The moment a check reaches across a repo boundary, a network, a scheduler, or an optional dependency, absence becomes an ordinary condition rather than an error** — and a two-valued report must then assign it to pass or fail, both of which are lies of a different kind. This is the *silent net* entry's positive counterpart: that one says a net that never fires is uninformative; this says a net that **cannot tell you whether it was strung** must say so in its own output.
**Where it would already have applied, had it existed.** Not offered as proof — offered so the jurist can judge the scope by real instances rather than by the abstraction.
- The engine's `--check-only` reports two states today. Its `NOT_ESTABLISHED` block names what it did not establish **in prose**, which is the honest gesture without the machine-readable third value.
- `ingest_gate`'s own three-state source machinery (`validated` / `blocked` / `known-failed` / `failed`) already refuses two-valuedness for a *different* reason — declared-vs-new failure — which suggests the shape is native to this codebase and not an import.
- R0's region states are **already** three-valued (`verified` / `stale` / `unverified`) with an explicit clause that *"`unverified` is not a failure state and must not be collapsed into either neighbour."* ⚠ **That is the doctrine already ratified in one contract**, which is the strongest argument that it belongs above any single item — and also the reason to check whether this proposal is *new doctrine* or merely **the generalization of a clause that already exists**.
**Options.**
- **(a) Ratify as general doctrine** (home: the verification ladder as a named instrument, and/or `~/CLAUDE.md` epistemic discipline). Applies to every future check without re-argument.
- **(b) Ratify narrowly** — cross-repo checks only, leaving network/scheduler/optional-dependency cases to be argued when they arrive.
- **(c) Decline as doctrine; keep conditioning per item.** ⚠ The jurist's own objection: it would be the third and fourth conditioning in one day.
- **(d) Rule it a RESTATEMENT of R0 §3's `unverified` clause** and generalize *that*, rather than minting new doctrine beside it.
**Recommendation: (d), falling back to (a).** R0 §3 already argues the case in ratified-contract prose and does it well; minting a parallel doctrine would create the second home this register keeps ruling against. ⚠ But R0 is an **engine spec-note under D-1**, so it cannot govern the chamber or the global hook — which may be exactly why generalizing it needs a ruling above D-1 rather than a citation.
**Check that it worked — both directions required.** Any check landed under this doctrine must demonstrate a real `cannot-assess` (a genuinely absent subject) **and** a real assessment, and show the two are distinguishable **in the summary a human actually reads** — not merely in a return value. ⚠ A doctrine about honest reporting whose own compliance is unobservable would be self-refuting.
**⚠ What this does not establish.** It does not say what a consumer must *do* with `cannot-assess`; that is per-check. It does not make anyone read the third state — PENDING-98's gap, again, one layer out. And it is proposed on **two same-day instances**, which is the recurrence bar this register uses for a watch-item, **not** the evidence bar for a constitutional claim; if the jurist wants it held as provisional until a third independent instance arrives, that is a coherent disposition and I would not argue against it.
**Files affected:** `reference-verification-ladder.md` (a named instrument) and/or `~/CLAUDE.md` §Epistemic Discipline — ⚠ the latter is `[ESCALATE]`, steward's hand, per Constitutional Constraint 1.
**Awaiting:** Jurist design-gate, then steward authorization.
---