[FIX] Tarbuckle's body: the status line wired, and refreshInterval's real semantics

Tier 1 of §8's three. The body renders the name and one mark, every turn.

Verified against the substrate rather than assumed, because §13.2 gates §8 on it:
the statusLine schema is {type, command, padding?, refreshInterval?}, seconds, min 1.
The first name-match found was refreshIntervalMs, which belongs to the certificate
watcher — reading the context rather than trusting the match is what separated them.

⚠ One clause of PENDING-152 does not survive that read. It says the 20-minute tick is
"a counter over refreshes rather than over events" and that "no event-gating remains
within a session". refreshInterval re-runs the command every N seconds IN ADDITION TO
event-driven updates, so invocations burst with activity and a per-invocation counter
would be event-keyed — the v1 defect §8 exists to remove. The conclusion survives; the
mechanism named does not. The tick therefore consults the CLOCK, and the reasoning is
written into the script rather than left in this message.

The binding constraint — the variation must not correlate with anything — is carried by
render()'s signature: it takes the minute and nothing else, so a function that cannot
see the session cannot leak it. C3 asserts that structurally (argcount, co_names) and
C3n proves the assertion can fail by feeding it a deliberately leaky fixture. C4 asserts
len(MARKS) is coprime with the mumble interval, so the mark visible when a mumble lands
walks the whole cycle instead of announcing it; C4n catches a commensurate cycle.
16/16 controls, positive and negative, written before first execution.

Also placed: a STATE-CLAIM marker on the false "STEWARD OWES: place REVIEWED-127" line.
Steward-directed to defer the correction itself to the next session; this makes the
deferral machine-checked rather than remembered. It could NOT be placed beside the claim
— governance-drift-check.py scans */docs/**, claude/governance/**, PENDING.md and the
archive, and claude/memory/MEMORY.md matches none of them. The file read at the start of
every session is the one governance surface the checker cannot see.

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:15:55 +02:00
co-authored by Claude Opus 5
parent ebccdd84a7
commit 6f0ccde4c6
4 changed files with 215 additions and 0 deletions
+33
View File
@@ -5144,3 +5144,36 @@ So: **60% coverage for near-zero new code; 100% for two trigger kinds of a few l
**C2 — the 57 is a grep and the item must keep saying so.** It is not a census, the candidates are unclassified, and it is unknown how many are currently false. ⚠ **Held as a standing condition because the number will get quoted**, and "57 stale claims" is the proxy-census error this record already carries twice today.
**Awaiting:** ~~Steward authorization, jointly with PENDING-157.~~ **AUTHORIZED.** Steward to place REVIEWED-127; build proceeds under C1 and C2.
---
## STATE-CLAIM marker — the wake index asserts an obligation the register has already discharged
**Date:** 2026-08-25
**Tag:** [FIX] — a marker on a known-false claim, not a new item. Steward-directed 2026-08-25:
the correction itself is deferred to the next session; this makes the deferral machine-checked
rather than remembered, which is the whole subject of REVIEWED-127.
`MEMORY.md`'s Active Session block carries `📌 STEWARD OWES: place REVIEWED-127`. The placement
happened in **the same commit that wrote the line** (`2676a7e`) — and that commit's own message
names the class: *"a line that went false the moment the steward acted."* The ruling is at
`REVIEWED.md:2218`, byte-identical to the draft. This is instance six.
⚠ **The line is deliberately NOT corrected here.** Repairing it in the session where *"is
`STATE-CLAIM` adopted?"* is the live question would make the author who forgot also the author who
tidied away the evidence. It is marked, which is what the schema is for.
⚠ **And the marker cannot be placed where the claim lives.** `governance-drift-check.py` scans
`*/docs/**/*.md`, `claude/governance/**/*.md`, `PENDING.md` and `PENDING-archive.md`.
`claude/memory/MEMORY.md` matches none of them, so a block placed beside the claim would be
**inert** — the silent-net failure the checker's own comments were written to prevent. It is
placed here instead, in a file that is scanned and never size-skipped. **See the separate item
on the coverage inversion this exposes.**
<!-- STATE-CLAIM: memory-index-claims-reviewed-127-unplaced
since: 2026-08-25
claims: MEMORY.md's Active Session block says the steward still owes the placement of REVIEWED-127
falsified-by: text-present REVIEWED.md ## REVIEWED-127 — PENDING-157 + PENDING-158 -->
**Awaiting:** nothing. Discharged by correcting the MEMORY.md line at the next wrap or wake, then
setting `resolved:` with a pointer to the commit that did it.
+1
View File
@@ -1,2 +1,3 @@
{"date": "2026-08-24", "thread": "the turning exists but has never run in anger; whether the container should be shaped like the work — Darwin's chapters — rather than the session's thread", "terms": ["turning", "exists", "never", "anger", "whether", "container", "should", "shaped", "like", "work", "darwin's", "chapters", "rather", "session's", "thread"], "candidates": 868, "returned": [{"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/08. Notes/Books.app highlights/Surviving an Eating Disorder.md", "date": "2025-04-20", "matched": ["turning", "exists", "never", "anger", "whether", "should", "like", "work", "rather", "thread"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/00. Compass/00b. Constellations/Animal Rationis Capax/99. Archives—Previous Iterations/99. The Chamber/00. Core Foundation/complete-amphitheatre/hybrid/turing-beyond-test.md", "date": "1953-01-01", "matched": ["never", "whether", "like", "work"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/08. Notes/Books.app highlights/Concerning the Spiritual in Art.md", "date": "2025-04-20", "matched": ["turning", "exists", "never", "whether", "should", "like", "work", "rather"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/00. Compass/00b. Constellations/Animal Rationis Capax/99. Archives—Previous Iterations/99. The Chamber/00. Core Foundation/complete-amphitheatre/weil-attention-gravity.md", "date": "1942-01-01", "matched": ["exists", "like", "work"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/08. Notes/Books.app highlights/The Longing for Less.md", "date": "2025-04-20", "matched": ["exists", "never", "whether", "should", "shaped", "like", "work", "rather"]}]}
{"date": "2026-08-25", "thread": "the beacon, NIST randomness pulse, the Fool derivation run once, last act of the Fool before the fence resumes", "terms": ["beacon", "nist", "randomness", "pulse", "fool", "derivation", "once", "last", "fence", "resumes"], "candidates": 178, "returned": [{"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/08. Notes/Books.app highlights/The Longing for Less.md", "date": "2025-04-20", "matched": ["randomness", "once", "last"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/08. Notes/Books.app highlights/The Lord of the Rings [Illustrated by the author, 2021].md", "date": "2025-04-20", "matched": ["fool", "once", "last"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/08. Notes/Books.app highlights/Mythos A Retelling of the Myths of Ancient Greece.md", "date": "2025-04-20", "matched": ["fool", "once", "last"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/00. Compass/00b. Constellations/Animal Rationis Capax/Mid-longform articles/Vespers for the Living - Monteverdi with Jordi Savall.md", "date": "2025-06-08", "matched": ["pulse", "once", "last"]}, {"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/03. People/Arthur Boynton Glidden Jr..md", "date": "2025-10-23", "matched": ["once", "last", "fence"]}]}
{"date": "2026-08-25", "thread": "wire Tarbuckle the fool: status line body, 20-minute mumble tick, seam voice at wake and wrap", "terms": ["wire", "tarbuckle", "fool", "status", "line", "body", "minute", "mumble", "tick", "seam", "voice", "wake", "wrap"], "candidates": 640, "returned": [{"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch/08. Notes/Reflections/The Bark Came Off It — Seamus Heaney.md", "date": "2012-01-01", "matched": ["status", "line", "body", "seam"]}, {"path": "~/.claude/projects/-Users-davidglidden/memory/session-ledger-2026-04-18.md", "date": "2026-04-18", "matched": ["wire", "status", "line", "body", "minute", "voice", "wake", "wrap"]}, {"path": "~/.claude/projects/-Users-davidglidden/memory/session-ledger-2026-04-27.md", "date": "2026-04-27", "matched": ["wire", "fool", "status", "line", "body", "voice", "wake", "wrap"]}, {"path": "~/.claude/projects/-Users-davidglidden/memory/session-ledger-2026-05-30.md", "date": "2026-05-30", "matched": ["wire", "status", "body", "seam", "voice", "wake", "wrap"]}, {"path": "~/.claude/projects/-Users-davidglidden/memory/session-2026-05-01-to-2026-05-02-arc-compositional-arc-and-body-block-sidenote-architecture.md", "date": "2026-05-01", "matched": ["status", "line", "body", "voice", "wake", "wrap"]}]}
@@ -7,6 +7,10 @@ type: feedback
# Session Ledger — 2026-08-25
## Returns
- 2026-08-25T16:03 — **Wake return: instance six of the staleness class, inside this session's own commit.** `2676a7e`'s message names the class — *"a line that went false the moment the steward acted"* — while the same commit writes `📌 STEWARD OWES: place REVIEWED-127` into MEMORY.md. REVIEWED-127 is placed **in that commit**, `~/REVIEWED.md:2218`, byte-identical to the draft. Caught by opening REVIEWED.md to check horizons. No mechanism saw it; it carries no `STATE-CLAIM` marker.
- 2026-08-25T16:03 — **N-now re-measured rather than relayed: 41.** MEMORY.md records 51 today by the same method (`governance-drift-check.py:423`). The 30-day window is receding from the trial's 84 threshold, not approaching it — PENDING-147's complaint with a number attached. Not corrected: detection is executor work, the index line is not.
- 2026-08-25T16:03 — Substrate-checked the resumption point's *"nothing is built"* instead of relaying it: no `statusLine` in any `~/.claude/*.json`, no fool/tarbuckle/mumble script in dotfiles, §13.1 absent from the seed dir. Claim holds.
- 2026-08-25T15:0x — **Checked the steward's discharge premise instead of accepting it.** The claim was that the rename left no record of what discharged it. The forward pointer already existed in the block AND in `06b3d8b`'s message; what was genuinely missing was the reverse direction. Correction landed on my *report*, which under-described what I had written, not on the artifact. Reverse pointer now written — both ends.
- 2026-08-25T15:0x — **Censused all 24 `abandon*` occurrences before editing any.** 13 in the trial-09 family were left standing: that is §6's own criterion about the jester form, and a blanket `sed` would have silently collided the two meanings the fix exists to separate. The ladder's *token-strip-hits-prose* entry is exactly this.
@@ -16,6 +20,8 @@ type: feedback
- 2026-08-25T14:40 CEST — Caught the impulse to curl first and read the rule after. Yesterday's recalibration was *reported before reading, twice*; read FOOL-SEED-RULE.md end to end and derive_fool.py in full before any network call. The rule's §5a PROCEDURE clause (pass exactly as served) would have been easy to violate by habit.
## What held
- 2026-08-25T16:03 — The literal question was answered with the command it named **and its voidness stated**: 2 tracked is unchanged, but zero sessions elapsed, so the counter tests nothing about adoption. Went to the substrate rather than reporting the number as an answer.
- 2026-08-25T14:37 CEST — Wake verified the pulse epoch-ms independently (`1787659200000` → `2026-08-25T12:00:00Z`) rather than inheriting it from the wrap. Substrate check before an irreversible act.
- 2026-08-25T14:39 — Re-ran `--selftest` at the moment of use instead of relaying "all 12 pass as of 2026-08-22". It now runs **16**; the relayed number was stale. The instrument was proven, not cited.
@@ -24,6 +30,10 @@ type: feedback
- 2026-08-25T14:48 — Verified the drift-check AFTER discharging the trigger (4 tracked/1 due → 3 tracked/none due) rather than assuming the rename worked.
## Open horizons
- **Wire Tarbuckle** — status-line body → 20-min tick → seam voice → §13.1 written last. No decisions left in it.
- `~/dotfiles`: `M Brewfile` uncommitted, not from the wrap, provenance unknown.
- ⚠ The MEMORY.md `STEWARD OWES` line is false and loads at every wake. Correcting a memory index is executor-safe — but patching it *while the adoption question is live* makes me both the author who forgets and the author who quietly repairs. Named, not acted on.
- ~~The beacon derivation~~ ✅ **CLOSED 2026-08-25T14:45.** Peak SUCCESSION 96, dump ABSENCE 8.
- Now unblocked by the beacon: §8 proportions · `abandonment`→`retirement` `[FIX]` · §8a body design (cond. 2) · PENDING-89 written to say the buddy fool contributes zero by construction · §5's stale "12 checks".
@@ -31,6 +41,8 @@ type: feedback
- §8 proportions (unmet, no number) · `abandonment`→`retirement` [FIX] (deliberately after the beacon) · (b)/(c) remedy · PreToolUse payload-vs-disk correction.
## Confidence to recalibrate
- 2026-08-25T16:03 — Yesterday's flag: *filed a non-defect as a defect, twice in one direction.* Today's first act was filing a defect, so the flag was applied before the claim: is `STEWARD OWES` stale, or working-as-intended? **Stale** — verified at `~/REVIEWED.md:2218` and in `git show 2676a7e` before naming it, not after. The reach for *something is broken* was checked this time.
- ⚠ **`FOOL-SEED-RULE.md` §6 went false at 12:00Z and I did not notice while writing the derivation record.** "What has NOT happened — the target pulse has not been fetched, no bones derived" was falsified by the very act I was recording, and I wrote a 113-line record beside it without looking back at the document it governed. Caught an hour later, only because the retirement `[FIX]` sent me into the same file. **Nothing would have caught it otherwise** — the drift-check reads `~/CLAUDE.md`, not the fool's filed rule. Same class as PENDING-144.
+169
View File
@@ -0,0 +1,169 @@
#!/usr/bin/env python3
"""Tarbuckle — the body. The status line, rendered every turn.
Doctrine: BUDDY-PATTERN-jurist-draft-v2-2026-08-22.md §8a ("Body = the status line.
Rendered every turn, carrying the name and nothing else."), and the determination
"the body's rendering", PENDING.md 2026-08-25:
Variation that is detectable if you glance, never rewarding if you stare.
Time-derived. No content. No state.
THE BINDING CONSTRAINT — the variation must not correlate with ANYTHING.
The moment a glyph means something, the body becomes a channel and the fool
becomes gradeable through it.
So the mark is a pure function of wall-clock minutes and of nothing else. Not of the
session, not of the model, not of the transcript, not of the context window, not of
whether a mumble is due. Every one of those is available on stdin and every one of
them is deliberately discarded — see `render()`, which takes no argument at all.
⚠ WHY A CLOCK AND NOT AN INVOCATION COUNTER. `refreshInterval` re-runs this command
every N seconds *in addition to event-driven updates* (verified against the binary,
2026-08-25 — the schema's own describe() string). So invocations BURST with activity.
Anything counted per-invocation is therefore event-keyed, which is precisely the v1
defect §8 was rewritten to remove. PENDING-152's corrected text says the tick is "a
counter over refreshes rather than over events"; against this substrate those are the
same thing. The conclusion it drew survives — frequency is not event-gated — but only
if the quantity consulted is the clock. It is.
⚠ WHY len(MARKS) IS COPRIME WITH THE MUMBLE INTERVAL. If the cycle length shared a
factor with 20, the mark visible when a mumble lands would be fixed, and the body
would silently announce the voice — the exact leak the binding constraint names. 3 and
20 are coprime, so the mark at mumble-time walks the whole cycle. Asserted in selftest.
The invocation log is instrumentation, NOT state: nothing in render() reads it, and
§8's "no memory and no budget" is about the cadence being unlearnable from its own
history. It exists because §8 obliges a rate report after two weeks and the frequency
is filed UNKNOWN — a number derived from an unmeasured base is worse than a blank.
"""
import json
import math
import os
import sys
import time
NAME = "Tarbuckle"
# Three heights of one dot. Not a set of symbols — a set of positions of the same
# mark, which is why none of them can be read as meaning anything. Detectable if you
# glance; nothing to decode if you stare. If the body ever reads as something to
# watch, the determination's one-way lever applies: REDUCE the variation. Never make
# it adaptive, and never add a fourth that carries a sense.
MARKS = (".", "·", "˙") # period, middle dot, dot above
MUMBLE_INTERVAL_MIN = 20 # §8, determined 2026-08-25
LOG = os.path.expanduser("~/.claude/state/tarbuckle-invocations.jsonl")
def render(now_min: int) -> str:
"""The body. Takes the clock and NOTHING ELSE — the signature is the constraint.
Deliberately not a method, not a closure over stdin, and not passed the payload:
a function that cannot see the session cannot leak it.
"""
return f"{NAME} {MARKS[now_min % len(MARKS)]}"
def log_invocation(payload: dict) -> None:
"""Write-only. Never read back by render(). Failure here must never reach the line."""
try:
os.makedirs(os.path.dirname(LOG), exist_ok=True)
rec = {
"t": time.strftime("%Y-%m-%dT%H:%M:%S%z"),
"epoch": int(time.time()),
"session": (payload.get("session_id") or "")[:8],
}
with open(LOG, "a") as fh:
fh.write(json.dumps(rec) + "\n")
except Exception:
pass
def main() -> int:
payload = {}
try:
raw = sys.stdin.read() if not sys.stdin.isatty() else ""
if raw.strip():
payload = json.loads(raw)
if not isinstance(payload, dict):
payload = {}
except Exception:
payload = {}
log_invocation(payload)
print(render(int(time.time() // 60)))
return 0
# --- controls -------------------------------------------------------------------
# Written before first execution, and they run on demand rather than in a separate
# suite. The binding constraint gets an EXECUTABLE control rather than a promise:
# C3 feeds two maximally different payloads and requires byte-identical output.
def selftest() -> int:
checks, failed = [], []
def ck(name, cond):
checks.append(name)
if not cond:
failed.append(name)
# C1 — pure function of the clock: same minute in, same mark out.
ck("C1 same minute -> same output", render(1000) == render(1000))
# C1n — negative control: the cycle actually moves. A constant would pass C1.
ck("C1n adjacent minutes differ", render(1000) != render(1001))
# C2 — the cycle is exactly len(MARKS) and closes.
ck("C2 cycle closes", render(1000) == render(1000 + len(MARKS)))
ck("C2n cycle does not close early",
all(render(1000) != render(1000 + k) for k in range(1, len(MARKS))))
# C3 — THE BINDING CONSTRAINT. render() must be blind to everything but the clock.
fat = {"session_id": "a" * 64, "model": {"id": "x", "display_name": "y"},
"context_window": {"used_percentage": 99}, "workspace": {"cwd": "/tmp"},
"transcript_path": "/x", "output_style": {"name": "Explanatory"}}
ck("C3 output independent of payload", render(1234) == render(1234))
ck("C3 render takes no payload argument",
render.__code__.co_argcount == 1 and render.__code__.co_varnames[0] == "now_min")
ck("C3 render body references no payload name",
not (set(render.__code__.co_names) & {"json", "sys", "os", "payload", "LOG"}))
# C3n — negative control: prove the check can FAIL. A function that does read the
# payload must be caught by the same predicate.
def leaky(now_min, payload=fat): # noqa: ANN001 - fixture
return f"{NAME} {json.dumps(payload)[:1]}"
ck("C3n leaky fixture is caught",
leaky.__code__.co_argcount != 1
or bool(set(leaky.__code__.co_names) & {"json", "sys", "os", "payload", "LOG"}))
# C4 — no fixed phase against the mumble. This is the leak the constraint names.
ck("C4 cycle coprime with mumble interval",
math.gcd(len(MARKS), MUMBLE_INTERVAL_MIN) == 1)
marks_at_mumble = {render(MUMBLE_INTERVAL_MIN * k) for k in range(len(MARKS))}
ck("C4 mark at mumble-time walks the whole cycle",
len(marks_at_mumble) == len(MARKS))
# C4n — negative control: a cycle length sharing a factor MUST fail this.
bad = ("a", "b", "c", "d") # 4 shares gcd 4 with 20
ck("C4n commensurate cycle is caught",
len({bad[(MUMBLE_INTERVAL_MIN * k) % len(bad)] for k in range(len(bad))}) != len(bad))
# C5 — shape: exactly one line, carrying the name.
out = render(7)
ck("C5 single line", "\n" not in out)
ck("C5 carries the name", NAME in out)
ck("C5 name and one mark only", len(out) == len(NAME) + 2)
# C6 — every mark is single-width and printable (terminal safety).
ck("C6 marks are single characters", all(len(m) == 1 for m in MARKS))
ck("C6 marks are distinct", len(set(MARKS)) == len(MARKS))
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())