[FIX] The jurist's three conditions on the rejection log, made structural; §9 fix corrected

CONDITION 1, and it is the one that had to stop being an intention: log_rejection()
refuses an empty `why`, and acceptable() returns an empty `why` EXACTLY when the line
passed. So there is no call site from which an accepted line could be written — logging
one would require inventing a violation it does not have. The same guarantee render()
takes from its signature, applied to the clause the jurist named as the condition under
which this log is not a §9 breach. Both polarities asserted.

CONDITION 2: deletion tracked as its own DEFERRED-DECISION on 2026-09-08, so retaining
it requires an act rather than an omission. A corpus of suppressed speech would let
someone reconstruct a register — the hazard PENDING-153's freeze exists to prevent.

CONDITION 3: not read for content before then. ⚠ Not clean already, and the item says so:
the executor displayed one rejected line to the steward earlier today, before the
condition existed. Disclosed rather than left to be discovered.

⚠ THE §9 [FIX] WAS OVER-APPLIED AND THE EXECUTOR APPLIED IT AS GIVEN. The clause is a
disjunction with one live branch; only the jurist half is unreachable. The first edit
struck the whole thing and rewrote the clause. A [FIX] tag licenses implementing
directly; it does not license implementing UNREAD, and the disjunction was visible in a
three-word span. Corrected, both versions left visible.

PENDING-159 AMENDMENT 2 files the jurist's answer to the item's own caveat and the
narrowing it produces: the marker may be NOTED, NEVER COUNTED — an aggregate becomes a
measurement, and a measurement invites accuracy. And PENDING-89 now carries the sentence
saying what it can and cannot expect: individual instances, unaggregated, in unknown
proportion, non-neutral — therefore NO correlation statistic. If its falsifier needs a
rate, it needs another instrument or an honest admission that it has none.

125 controls across five scripts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J6hZXNYSxEfZseBGTni4sf
This commit is contained in:
David F Glidden
2026-08-25 17:19:18 +02:00
co-authored by Claude Opus 5
parent 593c983999
commit b95ee736bd
7 changed files with 184 additions and 50 deletions
+66
View File
@@ -942,6 +942,22 @@ already-filed, already-authorized reads to be performed.** Starving for want of
different condition from starving for want of an instrument, and it is the cheaper one to end. different condition from starving for want of an instrument, and it is the cheaper one to end.
### AMENDMENT — 2026-08-25 — what this item can and cannot expect to receive from the fourth position
*Jurist-directed, from PENDING-159. Filed here because this item is the consumer, and a consumer that does not know what arrives will infer from silence.*
**This item asks whether the parties' misses correlate. A differently-positioned party is the only instrument that could produce evidence either way — and the terms on which any such evidence arrives are now fixed, and are narrow.**
- **It arrives only if the steward chooses to note it.** The provenance marker is optional and always will be. Its absence means nothing: not that no outside observation occurred, only that none was marked. ⚠ **This item may never read an empty period as a negative result.**
- **It arrives one at a time, never as a rate.** The datum is *this observation had an outside origin*. ⚠ **It may not be aggregated.** *"Four of eleven this month came from outside"* turns a fact about the steward's relaying into a measurement, and a measurement invites the question of whether it is accurate — which is the gradeability §2 forbids arriving through the side door.
- **It never carries content or attribution.** §9: the claim is the steward's, in his words. The marker says an origin was outside the trio; it does not say what was said or who said it.
- ⚠ **It is not neutral.** A marked observation arrives in front of the jurist differently and is likely to be weighed more heavily. **Anything this item concludes through the marker is concluded through that effect**, and must say so.
**Consequence for this item's design, stated so it is not discovered later:** the fourth position **cannot supply a correlation statistic.** It can supply individual instances, unaggregated, in unknown proportion to the instances that occurred. ⚠ **If this item's falsifier requires a rate, that falsifier cannot be satisfied this way and the item must find another instrument or say plainly that it has none.**
**And the reason the terms are narrow is not caution — it is that the alternatives collapse the position.** Counting makes it a measurement; implementing the marker makes it a channel; giving the jurist eyes makes it adjudication. Each is PENDING-159's option 3 arriving by a different road.
## PENDING-90 — First L2 transfer: checker position in the calibration loop ## PENDING-90 — First L2 transfer: checker position in the calibration loop
**Date:** 2026-08-02 **Date:** 2026-08-02
**Tag:** [ESCALATE] **Tag:** [ESCALATE]
@@ -5309,3 +5325,53 @@ The item flagged §11's shared-formation hazard. **The jurist says that is the w
⚠ **Nothing is built for this and nothing should be.** A marker with an implementation is a channel, and a channel is option 3 arriving by the back door. The executor notes this explicitly because its own reflex on reading (e) was to reach for a script. ⚠ **Nothing is built for this and nothing should be.** A marker with an implementation is a channel, and a channel is option 3 arriving by the back door. The executor notes this explicitly because its own reflex on reading (e) was to reach for a script.
**Awaiting:** steward. Option 3 requires no further consideration. **Awaiting:** steward. Option 3 requires no further consideration.
### AMENDMENT 2 — 2026-08-25 — the jurist answers the item's own caveat, and narrows (e) accordingly
*Two corrections from the jurist, both of their own prior positions, received via the steward.*
#### (a) The `[FIX]` on §9 was over-applied, and the executor applied it as given
The jurist had said the clause should read that the *executor* yields *"since it's the only party that can"* — and the executor struck the whole disjunction and rewrote it. **Both were wrong in the same direction.**
> *"The clause reads 'the executor or jurist yields the floor' — a disjunction, and the executor half is implementable and correct. So it isn't dead text; it's a clause with one live branch and one unreachable one. The fix is to strike the jurist from the disjunction, not to rewrite the clause."*
⚠ **The executor's own failure here is worth naming: it received a `[FIX]` from the jurist and executed it without checking the clause against it.** A `[FIX]` tag licenses implementing directly; it does not license implementing *unread*. The clause was three words long and the disjunction visible in it. **Corrected in the doctrine, with both versions left visible.**
#### (b) The item's caveat on option 2 is ANSWERED, and the answer has a limit that becomes a rule
The item filed option 2 with: ⚠ *"untested against §2; a bare count may itself be gradeable."* The jurist takes it rather than passing it:
> *"A bare count is gradeable only if something can be checked against it — and nothing can. There is no register of Tarbuckle's utterances to audit a count against, because §9 files nothing. The marker records that the steward attributed an origin, and that attribution has no external referent. It's a fact about his relaying, not a claim about the world."*
⚠ **And the limit, which narrows (e) and is filed as the narrowing:**
> *"If the marker were ever AGGREGATED — 'four of eleven observations this month came from outside' — the aggregate starts to look like a measurement, and a measurement invites the question of whether it's accurate. So: **the marker may be noted, never counted.** If PENDING-89 wants a datum, the datum is *this observation had an outside origin*, one at a time, never a rate."*
**(e) is amended to read: option 2, optional, NEVER COUNTED, nothing built.**
#### (c) ⚠ The standing line, restated because it is the one most likely to erode
> *"If anything gets built for this, the ruling has been reversed by construction."*
A marker with an implementation is a channel; a channel is option 3 by the back door. **No script, no field, no counter, no `status` line.** The executor records that its own first reflex was to build one, and that the reflex will recur.
**Awaiting:** steward. PENDING-89 to carry the sentence in AMENDMENT 3 below.
<!-- DEFERRED-DECISION: tarbuckle-rejection-log-deleted
since: 2026-08-25
trigger: date 2026-09-08
owner: executor
discriminator: The rejection log at ~/.claude/state/tarbuckle-rejects.jsonl is
TEMPORARY and dies with the fortnight's report. Jurist ruling 2026-08-25: "a
permanent store of rejected lines is a corpus, and a corpus of his suppressed
speech is exactly what would let someone reconstruct a register" — the hazard
PENDING-153's freeze exists to prevent for the soul. Read it ONCE, on this date,
for the rate and the pattern of violations; then DELETE it. Reading it for
content before then is reading Tarbuckle by the back door and would shape the net
toward lines the reader happens to like. ⚠ Not clean already: the executor
displayed one rejected line to the steward on 2026-08-25, before this condition
existed. Disclosed rather than left for the reader to discover.
⚠ Same date as mumble-rate-two-week-report, deliberately: one reading, one
deletion, one occasion.
-->
@@ -368,15 +368,18 @@ unreliable. Plan for that rather than discovering it.
- **ONE LINE** for the ordinary case. Paragraph-length governance prose is the - **ONE LINE** for the ordinary case. Paragraph-length governance prose is the
genre the trio already metabolizes; the constraint is what keeps the fool genre the trio already metabolizes; the constraint is what keeps the fool
uningestible. uningestible.
- **Named invocation:** the steward calls it by name, the ~~executor or jurist~~ - **Named invocation:** the steward calls it by name, the executor ~~or jurist~~
**executor** yields the floor, the fool answers at length. yields the floor, the fool answers at length.
<!-- [FIX] 2026-08-25, jurist-specified on their own draft: "or jurist" is dead <!-- [FIX] 2026-08-25, jurist-specified on their own draft, then CORRECTED by the
text. The jurist has no substrate access (PENDING-82 open), so in a jurist jurist the same day — recorded because the correction is instructive. The first
conversation the floor can be yielded and there is nobody to yield it to. The version struck the whole disjunction and rewrote the clause as "the executor
executor is the only party that can. Struck rather than deleted so the next yields", on the ground that it was dead text. It is not dead text: it is a
reader sees a clause was retired and why, not a sentence that was always this DISJUNCTION WITH ONE LIVE BRANCH AND ONE UNREACHABLE ONE. The executor half is
shape. Raised by the steward asking how the fool speaks to the jurist; the implementable and correct; only the jurist half names a path the substrate
substantive half of that question is PENDING-159. --> cannot provide (no substrate access — PENDING-82 open). So the jurist is struck
FROM the disjunction and the clause otherwise stands. Smaller than first said,
and the executor had over-applied a fix it was handed. Struck rather than
deleted so the next reader sees what was retired. Substance: PENDING-159. -->
- `mute` / `off` available at all times. Mute rate may be counted; muting is - `mute` / `off` available at all times. Mute rate may be counted; muting is
never a fault. never a fault.
@@ -154,6 +154,45 @@ surface and nothing else:
elaborates, and elaboration is how a gesture becomes a claim. The prompt spends most of elaborates, and elaboration is how a gesture becomes a claim. The prompt spends most of
its constraint budget there, and a violation is still silence. its constraint budget there, and a violation is still silence.
## 7b · The two logs, and why only one of them is a §9 problem
| file | holds | status |
|---|---|---|
| `tarbuckle-draws.jsonl` | occurrence only — surface + outcome | **permanent.** Counting is not filing; §8 obliges a rate and a rate needs a denominator |
| `tarbuckle-rejects.jsonl` | violation reason **+ up to 200 chars of a suppressed line** | ⚠ **temporary, dies 2026-09-08** |
**Jurist ruling, 2026-08-25.** The rejection log is *"a log of my instruction, not of
Tarbuckle… the rejected lines were never uttered: he was silent, and the log holds what
silence cost."* Nothing in it entered the room, so nothing can be cited from it. **Three
binding conditions:**
1. ⚠ **Rejections only — made STRUCTURAL, not intentional.** `log_rejection()` refuses an
empty `why`, and `acceptable()` returns an empty `why` **exactly when the line
passed**. So no call site exists from which an accepted line could be written: to log
one you would have to invent a violation it does not have. Same guarantee `render()`
takes from its signature. Asserted with both polarities.
2. ⚠ **Temporary.** Deleted 2026-09-08 with the report — *"a corpus of his suppressed
speech is exactly what would let someone reconstruct a register."* Tracked as
`DEFERRED-DECISION: tarbuckle-rejection-log-deleted` so it cannot be quietly retained.
3. ⚠ **Not read for content before then.** Reading as it accumulates is reading Tarbuckle
by the back door and would shape the net toward liked lines. **Not clean already:** the
executor displayed one rejected line to the steward on 2026-08-25, before the condition
existed. Disclosed, not buried.
## 7c · The word caps, and the criterion that decides them
Ordinary surfaces 3–9 words; invoked 180. **Both left as filed.** The steward licensed
widening on evidence, and single near-misses are not evidence.
⚠ **The criterion is the SHAPE of the rejections, not their count** (jurist, 2026-08-25):
> *"Scattered rejections mean the net is doing its job; clustered ones at the ceiling
> mean the ceiling is wrong."*
**And the asymmetry that raises the stakes at one surface only:** the invoked surface is
the only place he speaks at length, so a rejection there is *a summons answered with
silence*. Read on 2026-09-08, once, with the deletion.
## 8 · Owed ## 8 · Owed
⚠ **This list omitted named invocation in its first version, on the day it was written.** ⚠ **This list omitted named invocation in its first version, on the day it was written.**
+4 -9
View File
@@ -30,7 +30,7 @@ import time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402 from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402
source_lacks, muted, log_event, # noqa: E402 source_lacks, muted, log_event, # noqa: E402
echoes_soul, REJECTS) echoes_soul, log_rejection, REJECTS)
MAX_WORDS_INVOKED = 180 # §9's "at length", made a number MAX_WORDS_INVOKED = 180 # §9's "at length", made a number
TIMEOUT_S = 90 # the steward is deliberately waiting; he may take longer TIMEOUT_S = 90 # the steward is deliberately waiting; he may take longer
@@ -87,14 +87,9 @@ Absolute constraints, none of which the floor suspends:
Speak.""" Speak."""
def log_silence(why: str, line: str) -> None: def log_silence(why: str, line: str = "") -> None:
try: """Routed through the canonical writer, which cannot record an accepted line."""
import json log_rejection(why, line, "invoke")
with open(REJECTS, "a") as fh:
fh.write(json.dumps({"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"kind": "invoked", "why": why, "line": line[:400]}) + "\n")
except Exception:
pass
def main() -> int: def main() -> int:
+57 -8
View File
@@ -90,6 +90,44 @@ def muted() -> str:
return "" return ""
def log_rejection(why: str, line: str, surface: str = "") -> None:
"""The rejection log. ⚠ STRUCTURALLY UNABLE TO RECORD AN ACCEPTED LINE.
Jurist ruling, 2026-08-25, on whether this log breaches §9's "filed nowhere":
"The rejection log is a log of my instruction, not of Tarbuckle... The rejected
lines were never uttered: he was silent, and the log holds what silence cost.
Nothing there entered the room... the fool cannot be cited from it because
there is nothing to cite — only material the net suppressed.
THE CONDITION: the log holds rejections only. If it ever holds an accepted
line, that is filing, straightforwardly, and §9 is breached."
Made structural rather than intentional, as the ruling asked. `why` is acceptable()'s
violation reason, and it is EMPTY EXACTLY WHEN THE LINE PASSED. Refusing an empty
`why` means no call site exists from which an accepted line could be written: to log
one you would have to invent a violation it does not have. Same guarantee render()
takes from its signature — a function that cannot be handed the thing it must not
see.
⚠ TEMPORARY. Deleted on 2026-09-08 with the fortnight's report, per the same ruling:
"a permanent store of rejected lines is a corpus, and a corpus of his suppressed
speech is exactly what would let someone reconstruct a register." Tracked as a
DEFERRED-DECISION so it cannot be quietly retained.
⚠ NOT READ FOR CONTENT BEFORE THEN. Reading it as it accumulates is reading Tarbuckle
by the back door and would shape the net toward lines the reader happens to like.
"""
if not why:
return # an accepted line has no reason; there is no path
try:
with open(REJECTS, "a") as fh:
fh.write(json.dumps({"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"kind": surface, "why": why,
"line": line[:200]}) + "\n")
except Exception:
pass
def _grams(text: str, n: int) -> set: def _grams(text: str, n: int) -> set:
w = re.findall(r"[a-z']+", text.lower()) w = re.findall(r"[a-z']+", text.lower())
return {" ".join(w[i:i + n]) for i in range(len(w) - n + 1)} return {" ".join(w[i:i + n]) for i in range(len(w) - n + 1)}
@@ -260,12 +298,7 @@ def main() -> int:
if echo: if echo:
ok, why = False, f"recited the soul: {echo!r}" ok, why = False, f"recited the soul: {echo!r}"
if not ok: if not ok:
try: log_rejection(why, line, kind)
with open(REJECTS, "a") as fh:
fh.write(json.dumps({"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"kind": kind, "why": why, "line": line[:200]}) + "\n")
except Exception:
pass
log_event(kind, "rejected") log_event(kind, "rejected")
return 1 # silence. The draw was already consumed. return 1 # silence. The draw was already consumed.
try: try:
@@ -279,6 +312,8 @@ def main() -> int:
def selftest() -> int: def selftest() -> int:
global MUTE, REJECTS
import tempfile
checks, failed = [], [] checks, failed = [], []
def ck(name, cond): def ck(name, cond):
@@ -333,8 +368,6 @@ def selftest() -> int:
ck("A4 material paths are session/soul only", ck("A4 material paths are session/soul only",
not any(("PENDING" in q or "REVIEWED" in q) for q in paths)) not any(("PENDING" in q or "REVIEWED" in q) for q in paths))
# A5 — the mute switch, and that every surface must be able to see it. # A5 — the mute switch, and that every surface must be able to see it.
import tempfile
global MUTE
_m = MUTE _m = MUTE
MUTE = os.path.join(tempfile.mkdtemp(), "mute") MUTE = os.path.join(tempfile.mkdtemp(), "mute")
try: try:
@@ -361,6 +394,22 @@ def selftest() -> int:
not echoes_soul("Second surface you've found for the same voice.", _soul)) not echoes_soul("Second surface you've found for the same voice.", _soul))
ck("A7n passes an ordinary short observation", ck("A7n passes an ordinary short observation",
not echoes_soul("Third one that's held together with a name.", _soul)) not echoes_soul("Third one that's held together with a name.", _soul))
# A8 — THE JURIST'S CONDITION, structural. An accepted line has no `why`, so there
# is no call from which it could be written.
_r = REJECTS
REJECTS = os.path.join(tempfile.mkdtemp(), "rej.jsonl")
try:
log_rejection("", "an accepted line, offered to the log", "test")
ck("A8 an accepted line CANNOT be logged", not os.path.exists(REJECTS))
log_rejection("12 words", "a rejected line", "test")
ck("A8n a rejected line IS logged", os.path.exists(REJECTS))
ck("A8n the predicate can fail",
"a rejected line" in open(REJECTS).read())
log_rejection("", "a second accepted line", "test")
ck("A8 accepted lines never appear",
"second accepted" not in open(REJECTS).read())
finally:
REJECTS = _r
ck("A6n it cannot be handed a line", ck("A6n it cannot be handed a line",
"line" not in log_event.__code__.co_varnames) "line" not in log_event.__code__.co_varnames)
ck("A4n the predicate can fail", ck("A4n the predicate can fail",
+3 -17
View File
@@ -42,7 +42,7 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
# copy of `acceptable()` is a second, quietly divergent standard. # copy of `acceptable()` is a second, quietly divergent standard.
from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402 from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402
source_lacks, muted, log_event, # noqa: E402 source_lacks, muted, log_event, # noqa: E402
echoes_soul, REJECTS) echoes_soul, log_rejection, REJECTS)
LAST_TICK = os.path.expanduser("~/.claude/state/tarbuckle-last-tick") LAST_TICK = os.path.expanduser("~/.claude/state/tarbuckle-last-tick")
SEAM_TIMEOUT_S = 15 SEAM_TIMEOUT_S = 15
@@ -84,22 +84,8 @@ Output the line and nothing else. No quotes, no preamble."""
def log_silence(why: str, line: str = "") -> None: def log_silence(why: str, line: str = "") -> None:
"""⚠ THE REJECTED LINE IS RECORDED, and the first run is why. """Routed through the canonical writer, which cannot record an accepted line."""
log_rejection(why, line, "seam")
This logged `"line": ""` unconditionally, so the very first seam rejection — a
10-word line against a 9-word cap — recorded the verdict and threw away the
evidence. The steward had named this log as the instrument for deciding whether
the register and the net are mismatched; a log holding only reasons cannot answer
that. Found by reading the log after one use, which is the whole argument for
reviewing an instrument after every run rather than after failures.
"""
try:
import json
with open(REJECTS, "a") as fh:
fh.write(json.dumps({"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"kind": "seam", "why": why, "line": line[:200]}) + "\n")
except Exception:
pass
def main() -> int: def main() -> int:
+3 -7
View File
@@ -32,7 +32,7 @@ import time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402 from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402
source_lacks, muted, log_event, # noqa: E402 source_lacks, muted, log_event, # noqa: E402
echoes_soul, REJECTS) echoes_soul, log_rejection, REJECTS)
FIRED = os.path.expanduser("~/.claude/state/tarbuckle-wrap-fired") FIRED = os.path.expanduser("~/.claude/state/tarbuckle-wrap-fired")
TIMEOUT_S = 15 TIMEOUT_S = 15
@@ -132,12 +132,8 @@ Output the line and nothing else. No quotes, no preamble."""
def log_silence(why: str, line: str = "") -> None: def log_silence(why: str, line: str = "") -> None:
try: """Routed through the canonical writer, which cannot record an accepted line."""
with open(REJECTS, "a") as fh: log_rejection(why, line, "wrap")
fh.write(json.dumps({"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"kind": "wrap", "why": why, "line": line[:200]}) + "\n")
except Exception:
pass
def main() -> int: def main() -> int: