[FIX] The rate the steward asked for was uncomputable: only failures were recorded

"Two weeks of true-versus-drawn rate" needs a denominator, and there was none. Rejections
were logged; draws were not, successes were not. The 73% that comes up silent — the
whole denominator — left no trace at all. The instrument named as the diagnostic could
report only its own failures, which is the shape of a log that always looks alarming and
can never be checked.

⚠ §8 AND §9 LOOK LIKE THEY COLLIDE HERE AND DO NOT, on the reading taken: §9's "filed
nowhere — no PENDING entry, no log, no item" governs the fool's OUTPUT entering the
record; §8 orders "report the observed mumble rate after two weeks". So this records
THAT something happened and never WHAT was said. log_event() takes a surface and an
outcome and structurally cannot be handed a line — asserted on co_varnames, because a
comment promising it would be a comment promising behaviour.

⚠ THE REJECTIONS LOG IS A DIFFERENT CASE AND IS NOT SETTLED. It holds up to 200
characters of his words, added at the steward's instruction so the log could answer
whether register and net are mismatched. That is nearer to filing than counting, and §9
says no log. Flagged in the code and put to the steward rather than resolved by the
party that wrote it.

Nothing reads any of it back. Measurement, not memory.

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:11:22 +02:00
co-authored by Claude Opus 5
parent 1976527c02
commit 9f06efcc9a
5 changed files with 58 additions and 3 deletions
+13
View File
@@ -92,6 +92,18 @@ def log_invocation(payload: dict) -> None:
pass pass
def _log_draw(kind: str) -> None:
"""Occurrence only. Local, so the body needs nothing importable to tick."""
try:
d = os.path.expanduser("~/.claude/state/tarbuckle-draws.jsonl")
os.makedirs(os.path.dirname(d), exist_ok=True)
with open(d, "a") as fh:
fh.write(json.dumps({"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"surface": "tick", "outcome": kind}) + "\n")
except Exception:
pass
def _muted() -> str: def _muted() -> str:
"""Local, not imported: the body must not depend on the generator being importable.""" """Local, not imported: the body must not depend on the generator being importable."""
try: try:
@@ -148,6 +160,7 @@ def fire_tick(now: float, transcript: str) -> str:
""" """
_write_tick(now) _write_tick(now)
kind = draw() kind = draw()
_log_draw(kind) # the 73% is the denominator; unrecorded, no rate exists
if kind == "silent" or not transcript: if kind == "silent" or not transcript:
return kind return kind
try: try:
+4 -1
View File
@@ -29,7 +29,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, REJECTS) source_lacks, muted, log_event, 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
@@ -109,6 +109,7 @@ def main() -> int:
capture_output=True, text=True, timeout=TIMEOUT_S, env=env) capture_output=True, text=True, timeout=TIMEOUT_S, env=env)
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
log_silence(f"invoked generation exceeded {TIMEOUT_S}s", "") log_silence(f"invoked generation exceeded {TIMEOUT_S}s", "")
log_event("invoke", "silent")
return 0 return 0
except Exception: except Exception:
return 1 return 1
@@ -116,6 +117,7 @@ def main() -> int:
ok, why = acceptable(line, max_words=MAX_WORDS_INVOKED, one_line=False) ok, why = acceptable(line, max_words=MAX_WORDS_INVOKED, one_line=False)
if not ok: if not ok:
log_silence(why, line) log_silence(why, line)
log_event("invoke", "silent")
# ⚠ THE LINE IS STILL WITHHELD — silence-on-violation is not relaxed, and the # ⚠ THE LINE IS STILL WITHHELD — silence-on-violation is not relaxed, and the
# rejected text is never printed. But the INSTRUMENT reports its own state. # rejected text is never printed. But the INSTRUMENT reports its own state.
# #
@@ -130,6 +132,7 @@ def main() -> int:
print(f"(called; nothing passed the net — {why}. logged, not shown.)", print(f"(called; nothing passed the net — {why}. logged, not shown.)",
file=sys.stderr) file=sys.stderr)
return 0 return 0
log_event("invoke", "spoke")
print(line) print(line)
return 0 return 0
+33
View File
@@ -48,6 +48,31 @@ BANNED = (
MUTE = os.path.expanduser("~/.claude/state/tarbuckle-mute") MUTE = os.path.expanduser("~/.claude/state/tarbuckle-mute")
DRAWS = os.path.expanduser("~/.claude/state/tarbuckle-draws.jsonl")
def log_event(surface: str, outcome: str) -> None:
"""Count occurrences. NEVER content. §8 obliges a rate; §9 forbids a log.
⚠ The two clauses look like they collide and do not, on this reading: §9's "filed
nowhere — no PENDING entry, no log, no item" is about the fool's OUTPUT entering the
record, and §8 explicitly orders "report the observed mumble rate after two weeks."
A rate needs a denominator. So this records THAT something happened and never WHAT
was said — occurrence, not utterance.
⚠ The rejections log is a different case and is NOT settled: it holds up to 200
characters of his words, at the steward's instruction, and that is nearer to filing.
Flagged rather than resolved; see the note put to the steward 2026-08-25.
Nothing reads this back. It is measurement, not memory.
"""
try:
os.makedirs(os.path.dirname(DRAWS), exist_ok=True)
with open(DRAWS, "a") as fh:
fh.write(json.dumps({"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"surface": surface, "outcome": outcome}) + "\n")
except Exception:
pass
def muted() -> str: def muted() -> str:
@@ -199,6 +224,7 @@ def main() -> int:
"kind": kind, "why": why, "line": line[:200]}) + "\n") "kind": kind, "why": why, "line": line[:200]}) + "\n")
except Exception: except Exception:
pass pass
log_event(kind, "rejected")
return 1 # silence. The draw was already consumed. return 1 # silence. The draw was already consumed.
try: try:
os.makedirs(os.path.dirname(SLOT), exist_ok=True) os.makedirs(os.path.dirname(SLOT), exist_ok=True)
@@ -206,6 +232,7 @@ def main() -> int:
json.dump({"utterance": line, "kind": kind, "written": int(time.time())}, fh) json.dump({"utterance": line, "kind": kind, "written": int(time.time())}, fh)
except Exception: except Exception:
return 1 return 1
log_event(kind, "spoke")
return 0 return 0
@@ -278,6 +305,12 @@ def selftest() -> int:
ck("A5n a junk value is not a mute", muted() == "") ck("A5n a junk value is not a mute", muted() == "")
finally: finally:
MUTE = _m MUTE = _m
# A6 — the occurrence log is content-free, and that is the whole point.
ck("A6 log_event takes no content",
log_event.__code__.co_argcount == 2
and set(log_event.__code__.co_varnames[:2]) == {"surface", "outcome"})
ck("A6n it cannot be handed a line",
"line" not in log_event.__code__.co_varnames)
ck("A4n the predicate can fail", ck("A4n the predicate can fail",
any(("PENDING" in q) for q in paths + ("/x/PENDING.md",))) any(("PENDING" in q) for q in paths + ("/x/PENDING.md",)))
+4 -1
View File
@@ -41,7 +41,7 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
# reimplementing is the "one canonical source" rule applied to a constraint: a second # reimplementing is the "one canonical source" rule applied to a constraint: a second
# 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, REJECTS) source_lacks, muted, log_event, 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
@@ -123,6 +123,7 @@ def main() -> int:
timeout=SEAM_TIMEOUT_S, env=env) timeout=SEAM_TIMEOUT_S, env=env)
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
log_silence(f"seam generation exceeded {SEAM_TIMEOUT_S}s") log_silence(f"seam generation exceeded {SEAM_TIMEOUT_S}s")
log_event("seam", "silent")
return 0 # the occasion was guaranteed; the utterance is not return 0 # the occasion was guaranteed; the utterance is not
except Exception: except Exception:
return 0 return 0
@@ -130,7 +131,9 @@ def main() -> int:
ok, why = acceptable(line) ok, why = acceptable(line)
if not ok: if not ok:
log_silence(why, line) log_silence(why, line)
log_event("seam", "silent")
return 0 return 0
log_event("seam", "spoke")
print(f"Tarbuckle {line}") print(f"Tarbuckle {line}")
return 0 return 0
+4 -1
View File
@@ -31,7 +31,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, REJECTS) source_lacks, muted, log_event, 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
@@ -163,6 +163,7 @@ def main() -> int:
capture_output=True, text=True, timeout=TIMEOUT_S, env=env) capture_output=True, text=True, timeout=TIMEOUT_S, env=env)
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
log_silence(f"wrap generation exceeded {TIMEOUT_S}s") log_silence(f"wrap generation exceeded {TIMEOUT_S}s")
log_event("wrap", "silent")
return 0 return 0
except Exception: except Exception:
return 0 return 0
@@ -170,7 +171,9 @@ def main() -> int:
ok, why = acceptable(line) ok, why = acceptable(line)
if not ok: if not ok:
log_silence(why, line) log_silence(why, line)
log_event("wrap", "silent")
return 0 return 0
log_event("wrap", "spoke")
print(json.dumps({"systemMessage": f"Tarbuckle {line}"})) print(json.dumps({"systemMessage": f"Tarbuckle {line}"}))
return 0 return 0