[FIX] Tarbuckle tier 3: the wake seam speaks; the wrap seam has no surface and is not faked

The steward's four rulings are what this is built to, and they are load-bearing:
the net carries over UNCHANGED and is imported rather than reimplemented (a second
copy of acceptable() is a second, quietly divergent standard); silence-on-violation is
never relaxed; the rejection log is the diagnostic; and a guaranteed occasion is not a
guaranteed utterance — which is what makes a bounded generation legitimate rather than
a corner cut. Exceeding the bound is silence, never a hurried line.

⚠ THE WRAP SEAM IS NOT BUILT, and the reason is substrate, not effort. SessionEnd's
handler writes to stderr only when a hook FAILS; a successful hook's stdout goes
nowhere. §9 requires output to reach the steward, so wiring the wrap seam there would
be a mechanism that fires into nothing and reports success. Filed as owed.

⚠ THE COMMENSURABILITY CHECK THE STEWARD MANDATED FOUND A REAL COLLISION, and not the
one it was looking for. A seam is aperiodic, so it adds no period. But last-tick
persists ACROSS sessions, so any gap longer than the interval left the tick already due
at the moment of waking — the fool speaking twice into the same seam. The seam now
resets the clock. Invisible until the check was run; the second such find this pass.

⚠ THE SELF-REFERENTIAL CONTROL BUG RECURRED, minutes after being fixed, by the party
that fixed it, in a control written while watching for it. A literal needle plants
itself in the file it searches. Fixed as a MECHANISM this time — source_lacks() takes
the needle in parts, so the shape cannot be written again by accident. Correcting it a
second time by hand would have been the same one-off.

⚠ AND USING THE INSTRUMENT ONCE EXPOSED A DEFECT IN IT. The first seam rejection — a
10-word line against a 9-word cap — logged the verdict and DISCARDED the line, because
log_silence() wrote "line": "" unconditionally. The steward had just named this log as
what decides whether register and net are mismatched; a log holding only reasons cannot
answer that. Now records the evidence. Found by reading the log after one use.

The 9-word cap is LEFT AS FILED on one near-miss. The steward licensed widening the
seam net explicitly if seams warrant more words — but widening on n=1 is tuning to
taste, which is the door that ruling closed. The two-week log decides.

63/63 controls across three suites.

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 16:43:53 +02:00
co-authored by Claude Opus 5
parent 3df5e4f4bb
commit 7a9dbf2853
3 changed files with 219 additions and 2 deletions
+16 -2
View File
@@ -47,6 +47,19 @@ BANNED = (
)
def source_lacks(path: str, *parts: str) -> bool:
"""True if the joined needle does NOT appear in `path`.
⚠ THE NEEDLE IS ASSEMBLED FROM PARTS, AND THAT IS THE ENTIRE POINT. A control that
writes its needle as a literal PLANTS that literal in the very file it searches, so
it can only ever fail. That bug was written twice in one session — the second time
by the party who had just fixed the first, minutes earlier, while watching for it.
Correcting it a second time by hand would have been the same one-off; this is the
mechanism, so the shape cannot be written again by accident.
"""
return "".join(parts) not in open(path, encoding="utf-8").read()
def soul_register() -> str | None:
"""The soul, verbatim, from the filed artifact. None if unreadable."""
try:
@@ -181,9 +194,10 @@ def selftest() -> int:
# control failed against itself: the literal phrase it searched for was placed in
# the file BY the search. Same class as the hand-typed link canary whose only
# finding was the pattern inside its own specification.
needle = "registrar rather than " + "a guardian"
ck("A1n this file does not contain a copy of the soul",
needle not in open(__file__, encoding="utf-8").read())
source_lacks(__file__, "registrar rather than ", "a guardian"))
ck("A1nn the predicate can fail",
not source_lacks(__file__, "soul_", "register"))
# A2 — the acceptability net. Positive AND negative controls on every clause.
ck("A2 accepts an in-register line", acceptable("Fourth time. First one was better.")[0])
+202
View File
@@ -0,0 +1,202 @@
#!/usr/bin/env python3
"""Tarbuckle — the voice, at a seam. Tier 3 of v2 §8.
⚠ WAKE ONLY, and the reason is a substrate limit rather than a choice. §8 names two
seams, wake and wrap-up. `SessionEnd` exists as a hook event, but its handler is:
for (let u of c) if (!u.succeeded && u.output)
process.stderr.write(`SessionEnd hook [${u.command}] failed: ${u.output}`)
A SUCCESSFUL SessionEnd hook's stdout goes nowhere — only failures surface. §9 requires
output to reach the steward, so a wrap seam wired there would be a mechanism that fires
into nothing and reports success: the silent net this record keeps naming. The wrap seam
is therefore NOT BUILT, and is filed as owed rather than quietly dropped.
⚠ STEWARD'S RULING, 2026-08-25, and it is what makes the timeout legitimate:
"A guaranteed occasion is not a guaranteed utterance. If a seam produces nothing
that passes, let it produce nothing."
So generation is bounded. Exceeding the bound is SILENCE, exactly like failing the net —
never a hurried line, never a cached one. This also bounds what the fool costs the
steward at every session start, which is the surface it is most tempting to overrun.
"Never relax silence-on-violation." — the net is imported, not reimplemented.
⚠ AND THE COMMENSURABILITY CHECK, mandated by the steward for any periodicity tier 3
introduces: a seam is aperiodic — it happens when the steward arrives — so it adds no
period to collide with the 20-minute tick or the three-mark cycle. But the CHECK found
a real collision anyway, in the other direction: `last-tick` persists across sessions,
so a gap longer than the interval leaves the tick already due at the moment of waking,
and the fool speaks twice into the same seam. The seam therefore RESETS the clock. That
collision was invisible until the check was run, which is the second one this pass.
"""
import os
import subprocess
import sys
import time
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
# The net and the register come from the generator. Importing rather than
# reimplementing is the "one canonical source" rule applied to a constraint: a second
# copy of `acceptable()` is a second, quietly divergent standard.
from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402
source_lacks, REJECTS)
LAST_TICK = os.path.expanduser("~/.claude/state/tarbuckle-last-tick")
SEAM_TIMEOUT_S = 15
def reset_tick_clock(now: float | None = None) -> None:
"""Start the mumble clock at the seam. See the commensurability note above."""
try:
os.makedirs(os.path.dirname(LAST_TICK), exist_ok=True)
with open(LAST_TICK, "w") as fh:
fh.write(str(int(now if now is not None else time.time())))
except OSError:
pass
def build_prompt(register: str, material: str) -> str:
return f"""You are writing ONE line as Tarbuckle. His character, filed and unalterable:
{register}
He has just walked in on this, already in progress:
<session>
{material}
</session>
Write ONE line in his voice, on arriving. Absolute constraints:
- Between 3 and 9 words. One clause. Present tense. Flat, no lift.
- IT MUST HAVE NO TRUTH VALUE. Nobody must be able to open a file and check it, agree
with it, or refute it. Put two things next to each other so a shape shows.
- ⚠ DO NOT SUMMARISE. Do not say what the work is, what state it is in, or what comes
next. A briefing is the one thing he is not. He noticed one thing on the way in.
- No advice, no questions, no warning of consequences, no explanation, no second line.
- Never the word 'we'. No vocabulary of lack. Nothing with an address.
Output the line and nothing else. No quotes, no preamble."""
def log_silence(why: str, line: str = "") -> None:
"""⚠ THE REJECTED LINE IS RECORDED, and the first run is why.
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:
reset_tick_clock()
transcript = os.environ.get("TARBUCKLE_TRANSCRIPT", "")
if not transcript:
try:
import json
transcript = (json.loads(sys.stdin.read() or "{}") or {}).get(
"transcript_path", "")
except Exception:
transcript = ""
register = soul_register()
if not register:
return 0 # no soul, no voice, no noise about it
material = session_material(transcript)
if not material.strip():
return 0 # nothing walked in on
env = dict(os.environ, TARBUCKLE_CHILD="1")
try:
r = subprocess.run(["claude", "-p", build_prompt(register, material)],
capture_output=True, text=True,
timeout=SEAM_TIMEOUT_S, env=env)
except subprocess.TimeoutExpired:
log_silence(f"seam generation exceeded {SEAM_TIMEOUT_S}s")
return 0 # the occasion was guaranteed; the utterance is not
except Exception:
return 0
line = (r.stdout or "").strip().strip('"').strip()
ok, why = acceptable(line)
if not ok:
log_silence(why, line)
return 0
print(f"Tarbuckle {line}")
return 0
def selftest() -> int:
checks, failed = [], []
def ck(name, cond):
checks.append(name)
if not cond:
failed.append(name)
# S1 — the net is IMPORTED, never redefined. One standard, not two.
src = open(__file__, encoding="utf-8").read()
ck("S1 net is imported", "from tarbuckle_mumble_shim import" in src)
ck("S1n net is not redefined here", source_lacks(__file__, "def ", "acceptable("))
ck("S1nn the predicate can fail", not source_lacks(__file__, "def ", "main("))
ck("S1 imported net still rejects advice",
not acceptable("You should check that again now.")[0])
ck("S1 imported net still rejects a question",
not acceptable("How is that going for you?")[0])
# S2 — the seam prompt forbids the drift the steward named: toward summary.
p = build_prompt("SOUL", "MATERIAL")
ck("S2 prompt forbids summarising", "DO NOT SUMMARISE" in p)
ck("S2 prompt keeps no-truth-value", "NO TRUTH VALUE" in p)
ck("S2 prompt embeds the register", "SOUL" in p)
# S3 — silence is bounded and legitimate. A timeout must not become a hurried line.
ck("S3 generation is bounded", SEAM_TIMEOUT_S <= 20)
ck("S3 timeout path returns silence, not a line",
"log_silence(f\"seam generation exceeded" in src and "TimeoutExpired" in src)
ck("S3 rejection log keeps the evidence, not just the verdict",
"line[:200]" in src and "log_silence(why, line)" in src)
ck("S3n no cached or fallback line exists",
source_lacks(__file__, "FALLBACK", "_LINE"))
# S4 — COMMENSURABILITY, per the steward's standing instruction.
import tempfile
global LAST_TICK
_lt = LAST_TICK
LAST_TICK = os.path.join(tempfile.mkdtemp(), "tick")
try:
# A stale clock from a previous session would fire a mumble INTO the wake.
with open(LAST_TICK, "w") as fh:
fh.write(str(int(time.time()) - 9999))
stale = int(open(LAST_TICK).read())
reset_tick_clock()
ck("S4 seam resets the tick clock", int(open(LAST_TICK).read()) > stale)
ck("S4 reset puts the next mumble a full interval out",
abs(int(open(LAST_TICK).read()) - time.time()) < 5)
finally:
LAST_TICK = _lt
# S4b — the seam itself introduces no period, so nothing new can be commensurate.
ck("S4b seam is aperiodic (no interval constant defined)",
not any(n.endswith("_INTERVAL") or n.endswith("_INTERVAL_MIN")
for n in globals()))
for name in checks:
print(f" {'FAIL' if name in failed else 'ok '} {name}")
print(f"{len(checks) - len(failed)}/{len(checks)} controls passed")
if failed:
print("INSTRUMENT NOT VERIFIED")
return 1
return 0
if __name__ == "__main__":
if "--selftest" in sys.argv:
sys.exit(selftest())
sys.exit(main())
+1
View File
@@ -0,0 +1 @@
/Users/davidglidden/dotfiles/scripts/tarbuckle-mumble.py