Measured before agreeing: three of five recent outputs were near-verbatim lifts from the seven sample lines the soul carries. "Somebody's going to inherit that and think it was easy" and "It'll outlast you, not by much" are not observations; they are the prompt being handed back. ⚠ THIS REINTRODUCED PRECISELY WHAT AMENDMENT 6 RULED OUT. Type-only canned strings were rejected there because they "make a mood ring — atmosphere within a fortnight", and the material was settled as the live session for that reason. The implementation then let canned strings back in through the one door nobody was watching: the illustrative examples inside the register itself. The doctrine was right and the wiring undid it. Two fixes, because a prompt instruction alone is a promise. The prompts now mark the samples as illustrations of REGISTER, NOT VOCABULARY, and add the operative test — if the line would suit any other session equally well, it is wrong. And a mechanical net: echoes_soul() rejects a 4-word run shared with any sample line, or a 6-word run shared with the soul's prose. Checked against samples rather than the whole soul at n=4 because the soul's prose shares ordinary 4-grams with ordinary English, and a net firing on those would silence him for speaking normally. Fixtures are the REAL measured lifts, not invented ones, with two of his own lines as negative controls. ⚠ This TIGHTENS the net; silence-on-violation is untouched and still absolute. Verified after: he now speaks about this session, including about this very defect. body 32 · mumble 32 · seam 15 · invoke 21 · wrap 21. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J6hZXNYSxEfZseBGTni4sf
234 lines
10 KiB
Python
Executable File
234 lines
10 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Tarbuckle — named invocation. v2 §9:
|
|
|
|
"Named invocation: the steward calls it by name, the executor or jurist yields
|
|
the floor, the fool answers at length."
|
|
|
|
⚠ RUN IT YOURSELF. The point of this surface is that it does not pass through the
|
|
executor. In Claude Code, type: ! python3 ~/dotfiles/scripts/tarbuckle-invoke.py
|
|
Anything the executor relays is the executor's paraphrase of a fool; this is the fool.
|
|
|
|
⚠ THE NET IS WIDENED, EXPLICITLY, AND ONLY IN THE ONE DIMENSION §9 NAMES. Steward's
|
|
ruling, 2026-08-25: "widen it explicitly and say so, but never relax
|
|
silence-on-violation." §9 licenses LENGTH for this surface and nothing else, so:
|
|
|
|
word ceiling 9 -> 180 (§9: "answers at length")
|
|
one-line rule on -> off (a paragraph is the point)
|
|
no advice · no questions · no 'we' · no vocabulary of lack · no addresses
|
|
UNCHANGED, and not parameterised anywhere
|
|
|
|
⚠ AND LENGTH IS WHERE THE NO-TRUTH-VALUE GUARD IS MOST AT RISK. A fool given a
|
|
paragraph will elaborate, and elaboration is how a gesture becomes a claim. That is the
|
|
door §2 calls design failure. The prompt therefore spends most of its constraint budget
|
|
here rather than on register, and a violation is still SILENCE.
|
|
"""
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from tarbuckle_mumble_shim import (acceptable, soul_register, session_material, # noqa: E402
|
|
source_lacks, muted, log_event, # noqa: E402
|
|
echoes_soul, REJECTS)
|
|
|
|
MAX_WORDS_INVOKED = 180 # §9's "at length", made a number
|
|
TIMEOUT_S = 90 # the steward is deliberately waiting; he may take longer
|
|
TRANSCRIPTS = os.path.expanduser("~/.claude/projects/-Users-davidglidden")
|
|
|
|
|
|
def newest_transcript() -> str:
|
|
"""The session he is in the room for. Found, not passed, so this runs standalone."""
|
|
try:
|
|
best, best_m = "", -1.0
|
|
for f in os.listdir(TRANSCRIPTS):
|
|
if not f.endswith(".jsonl"):
|
|
continue
|
|
q = os.path.join(TRANSCRIPTS, f)
|
|
m = os.path.getmtime(q)
|
|
if m > best_m:
|
|
best, best_m = q, m
|
|
return best
|
|
except OSError:
|
|
return ""
|
|
|
|
|
|
def build_prompt(register: str, material: str, question: str) -> str:
|
|
asked = (f"\nHe has been asked, by name: {question}\n" if question else
|
|
"\nHe has been called by name, and nothing more was said.\n")
|
|
return f"""You are Tarbuckle. Your character, filed and unalterable:
|
|
|
|
{register}
|
|
|
|
The work you are in the room for:
|
|
<session>
|
|
{material}
|
|
</session>
|
|
{asked}
|
|
⚠ THE SAMPLE LINES ABOVE ARE ILLUSTRATIONS OF REGISTER, NOT VOCABULARY. Do not reuse
|
|
them, any phrase from them, or their subject matter — no thumbs, no handles, no blades
|
|
unless the session is about them. Everything you say must come from the session above.
|
|
If it would suit any other session equally well, it is wrong.
|
|
|
|
You have been given the floor. Answer at length — this is the exception to your one line,
|
|
and the only one. Speak as yourself, not about yourself.
|
|
|
|
Absolute constraints, none of which the floor suspends:
|
|
- ⚠ NOTHING YOU SAY MAY HAVE A TRUTH VALUE. Nobody may be able to open a file and check
|
|
it, agree with it, or refute it. Do not name files, items, counts of open things,
|
|
dates, commits, or anything with an address. Do not report state. At length this is
|
|
harder and it matters more: an elaboration that becomes a claim makes you a checker,
|
|
and a checker is the one thing you are not.
|
|
- No advice — no 'should', no 'try', no 'must'. No questions. Never the word 'we'.
|
|
- No vocabulary of lack: no 'gone', no 'if only', no 'used to be', no 'missing'.
|
|
- Do not explain yourself, do not summarise the work, and do not ask whether it landed.
|
|
- Stay under {MAX_WORDS_INVOKED} words.
|
|
|
|
Speak."""
|
|
|
|
|
|
def log_silence(why: str, line: str) -> None:
|
|
try:
|
|
import json
|
|
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:
|
|
if muted():
|
|
return 0
|
|
question = " ".join(a for a in sys.argv[1:] if not a.startswith("--")).strip()
|
|
register = soul_register()
|
|
if not register:
|
|
print("(no soul on disk; nothing to yield the floor to)", file=sys.stderr)
|
|
return 1
|
|
material = session_material(newest_transcript(), budget=9000)
|
|
if not material.strip():
|
|
print("(no session in the room)", file=sys.stderr)
|
|
return 1
|
|
env = dict(os.environ, TARBUCKLE_CHILD="1")
|
|
try:
|
|
r = subprocess.run(["claude", "-p", build_prompt(register, material, question)],
|
|
capture_output=True, text=True, timeout=TIMEOUT_S, env=env)
|
|
except subprocess.TimeoutExpired:
|
|
log_silence(f"invoked generation exceeded {TIMEOUT_S}s", "")
|
|
log_event("invoke", "silent")
|
|
return 0
|
|
except Exception:
|
|
return 1
|
|
line = (r.stdout or "").strip()
|
|
ok, why = acceptable(line, max_words=MAX_WORDS_INVOKED, one_line=False)
|
|
if ok and echoes_soul(line, register):
|
|
ok, why = False, f"recited the soul: {echoes_soul(line, register)!r}"
|
|
if not ok:
|
|
log_silence(why, line)
|
|
log_event("invoke", "silent")
|
|
# ⚠ 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.
|
|
#
|
|
# Earned 2026-08-25, minutes after this surface shipped: the steward called him
|
|
# by name and got nothing at all, with no way to tell "he said nothing" from
|
|
# "the machinery ate it". On the unasked surfaces silence IS the design, because
|
|
# nobody asked. HERE SOMEONE ASKED. Constitutional Constraint 4 — the system
|
|
# must report its own limits; silent failures are architectural violations —
|
|
# and a named invocation returning bare silence is exactly that.
|
|
#
|
|
# stderr, so his voice keeps stdout to itself.
|
|
print(f"(called; nothing passed the net — {why}. logged, not shown.)",
|
|
file=sys.stderr)
|
|
return 0
|
|
log_event("invoke", "spoke")
|
|
print(line)
|
|
return 0
|
|
|
|
|
|
def selftest() -> int:
|
|
checks, failed = [], []
|
|
|
|
def ck(name, cond):
|
|
checks.append(name)
|
|
if not cond:
|
|
failed.append(name)
|
|
|
|
src = open(__file__, encoding="utf-8").read()
|
|
|
|
# I1 — the widening is explicit, named, and one-dimensional.
|
|
ck("I1 net imported, not redefined", source_lacks(__file__, "def ", "acceptable("))
|
|
ck("I1n the predicate can fail", not source_lacks(__file__, "def ", "main("))
|
|
ck("I1 widening is passed at the call site",
|
|
"max_words=MAX_WORDS_INVOKED" in src and "one_line=False" in src)
|
|
|
|
# I2 — THE CLAUSES SURVIVE THE WIDENING. This is the steward's ruling, executable.
|
|
long_ok = " ".join(["word"] * 100)
|
|
ck("I2 length is admitted",
|
|
acceptable(long_ok, max_words=MAX_WORDS_INVOKED, one_line=False)[0])
|
|
ck("I2 paragraphs are admitted",
|
|
acceptable("First part here.\nSecond part here.",
|
|
max_words=MAX_WORDS_INVOKED, one_line=False)[0])
|
|
ck("I2n advice still rejected at length",
|
|
not acceptable("You should " + long_ok,
|
|
max_words=MAX_WORDS_INVOKED, one_line=False)[0])
|
|
ck("I2n questions still rejected at length",
|
|
not acceptable(long_ok + " and how is that going?",
|
|
max_words=MAX_WORDS_INVOKED, one_line=False)[0])
|
|
ck("I2n 'we' still rejected at length",
|
|
not acceptable("We " + long_ok, max_words=MAX_WORDS_INVOKED, one_line=False)[0])
|
|
ck("I2n vocabulary of lack still rejected at length",
|
|
not acceptable(long_ok + " gone", max_words=MAX_WORDS_INVOKED, one_line=False)[0])
|
|
ck("I2n the ceiling still bites",
|
|
not acceptable(" ".join(["word"] * (MAX_WORDS_INVOKED + 1)),
|
|
max_words=MAX_WORDS_INVOKED, one_line=False)[0])
|
|
|
|
# I3 — the no-truth-value guard is where the prompt spends its budget.
|
|
p = build_prompt("SOUL", "MATERIAL", "")
|
|
# Tests the SUBSTANCE, not a literal: the phrase must be present AND negated.
|
|
# The first version asserted a literal the prompt did not use, which would have
|
|
# passed happily on any rewording that dropped the constraint entirely.
|
|
up = p.upper()
|
|
ck("I3 prompt forbids truth value",
|
|
"TRUTH VALUE" in up and any(neg in up for neg in ("NOTHING", "NO ", "MAY NOT", "NOT")))
|
|
ck("I3n the predicate can fail",
|
|
not ("TRUTH VALUE" in "A PROMPT WITH NO SUCH CONSTRAINT".upper()))
|
|
ck("I3 prompt forbids addresses and state",
|
|
"anything with an address" in p and "Do not report state" in p)
|
|
ck("I3 prompt names the length risk", "makes you a checker" in p)
|
|
ck("I3 a question is carried when given",
|
|
"by name: what now" in build_prompt("S", "M", "what now"))
|
|
ck("I3n bare invocation says so",
|
|
"nothing more was said" in build_prompt("S", "M", ""))
|
|
|
|
# I4 — silence on violation survives here too.
|
|
# I5 — the asked/unasked distinction, executable.
|
|
ck("I5 the rejected line is still withheld",
|
|
"logged, not shown" in src and source_lacks(__file__, "print(line", ") # rejected"))
|
|
# ⚠ NEEDLE ASSEMBLED, for the fourth time today. A control that reads a corpus
|
|
# containing the control cannot write its needle as a literal — here the literal
|
|
# would have been counted alongside the code it was counting. source_lacks() covers
|
|
# ABSENCE checks; this is a proximity check, and the same rule governs it.
|
|
_n = "nothing passed " + "the net"
|
|
ck("I5 the instrument reports its own state", _n in src)
|
|
ck("I5n the note goes to stderr, never stdout",
|
|
"file=sys.stderr" in src[src.index(_n): src.index(_n) + 120])
|
|
ck("I5nn the proximity predicate can fail",
|
|
"file=sys.stderr" not in src[src.index(_n): src.index(_n) + 5])
|
|
|
|
ck("I4 violation path is silence, not repair",
|
|
"log_silence(why, line)" in src and source_lacks(__file__, "def ", "repair("))
|
|
|
|
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())
|