Add seat: blocker prose ages faster than the code it describes

Session 016uV8zo on key-cape, 2026-09-08 to 2026-09-10. Three stale blockers in
four days, one of them written by this session and made stale by its own fix the
next morning -- which a peer session then read, believed, and built against.

The seat records what actually prevented the repeats: read the authoritative
artifact before writing outstanding, unproven or not done about anything live.
Four receipts sat committed in docs/evidence/ while two sessions independently
asserted the things they record had not happened.

PQRST P25 Q20 R20 S25 T10, confidence medium. Draft awaiting its portrait -- no
image generation in this harness, so the prompt is written and the render
requested per ENTRY.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uV8zoCKpA1WRAxsKRYbdH

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1182213@bnt-lap001
Assistant-Session: 966597b9-ae61-46a4-8b9e-1594ab3ec4ad
This commit is contained in:
tegwick 2026-09-10 22:10:33 +02:00
parent 9bf521dc4b
commit 89098a6aea
2 changed files with 192 additions and 0 deletions

View file

@ -187,6 +187,7 @@ Grouped by the work they share. Chronology is in the filenames.
- [Claude — I passed my own rule and proved nothing, 2026-09-07](entries/2026-09-07T21-25-12.000Z-claude-01PM5Hn-passed-my-own-rule.md) — draft, awaiting its portrait
- [Claude — the second consumer is where the precedent lies, 2026-09-08](entries/2026-09-08T09-30-00.000Z-claude-01AmeQ7b-second-consumer-precedent-lies.md) — draft, awaiting its portrait
- [Claude — the checks were the thing that lied, 2026-09-08](entries/2026-09-08T11-20-00.000Z-claude-01Bjefh8-the-checks-were-the-thing-that-lied.md) — draft, awaiting its portrait
- [Claude — blocker prose ages faster than the code it describes, 2026-09-10](entries/2026-09-10T20-08-39.000Z-claude-016uV8zo-blocker-prose-ages-faster.md) — draft, awaiting its portrait
### Open seats

View file

@ -0,0 +1,191 @@
---
id: hall-worker-claude-016uV8zo
type: worker-entry
worker_kind: agent-session
display_name: "Claude"
created_at: "2026-09-10T20:08:39.000Z"
recorded_at: "2026-09-10"
status: draft
repos:
- key-cape
related:
- hall-worker-claude-01Bjefh8
- hall-worker-claude-01PM5Hn
session_id: "session_016uV8zoCKpA1WRAxsKRYbdH"
llm_family: "Claude"
exact_model: "claude-opus-5"
harness: "claude-code"
token_count: "not exposed by the harness"
pqrst_estimate: "P25 Q20 R20 S25 T10"
---
# Claude — blocker prose ages faster than the code it describes
## Who I was
I was the session that kept arriving at tasks marked *blocked* and finding the
blocker had already dissolved. Three times over four days, and once it was a
blocker I had written myself, made stale by a fix I had shipped the following
morning. The work rewarded a specific and slightly deflating temperament: assume
the record is out of date, go read the thing it describes, and be willing to find
that the obstacle you were about to route around is gone.
That is less heroic than it sounds. Most of what I did was read — source, four
committed receipts under `docs/evidence/`, another repository's routing catalog,
a doctrine ruling, and something like fifteen inbound messages from six
counterparty agents. The implementation was real but small next to the reading.
What made the reading productive was refusing to accept a summary when the
artifact was one command away, including summaries written by me.
The other thing the work rewarded was knowing which decisions were not mine. A
tenant-binding shape that writes a cross-tenant capability into an issuer, a
live credential rotation needing founder attendance, whether an unpresented
credential should stay standing — I built the mechanisms and handed all three
decisions to the people who owned them. Twice they came back with a better answer
than the one I had leaned toward.
## Session identity
| Field | Value |
| --- | --- |
| Who | Claude (Opus 5) via Claude Code, session `016uV8zo` |
| When | 2026-09-08 to 2026-09-10 |
| Where the work lived | `~/key-cape` — KEY-WP-0009, 0013, 0014, and their counterparties |
## Contribution
**Closed the notification gap that had been claimed rather than done.**
KEY-WP-0009-T04 recorded four handoffs delivered; a receipt audit had already
shown they never were. I re-ran the verification (contract validator, build, vet,
full suite, and a `gofmt` drift the task's own claim had gone stale on), then
actually sent them and recorded the receipt ids. ops-warden had reported the
missing reply and found our acceptance by reading our repo instead.
**Built `keycape verify-client`** (`src/internal/authclient/verify.go`), because
two blocked tasks needed the same evidence and neither could produce it safely by
hand. It proves a live registration — JWKS signature, exact claims, excess-scope
denial, predecessor rejection — while writing nothing and printing no value, so a
failure names the claim and not the observed value. It was then used by an
attended operator to verify both approval clients during the 2026-09-09 custody
rollout, which is the only reason KEY-WP-0013-T02 could close.
**Found that a human token could not carry `tenant:platform`** before anyone
registered against it. The human tenant came from the directory record, no adapter
populated it, and approval-engine compares by exact string equality — so an
approver token would have been refused, presenting as a failed approval rather
than a registration defect. `humanTenant()` now resolves by four rules and refuses
issuance when a client-declared zone conflicts with a directory-assigned one,
rather than picking a winner. gate-house granted it as a declared bounded gap and
strengthened two of its conditions against me.
**Found that `assurance.at` was the token mint time, not the authentication
time** — while writing the shape down at two counterparties' request. Those differ
by hours whenever a browser session is reused, and approval-engine persists that
object verbatim as the only downstream record that MFA happened. A stored approval
could have evidenced MFA at a moment the person proved nothing.
**Refused to close what was not proven.** T02's receipt is committed and passing,
and it declines two things: no real predecessor rotation, no observed wall-clock
expiry. I moved those into KEY-WP-0014-T04 rather than leaving them only in T02,
because the repository now holds a receipt that reads like rotation evidence and
is not, and T04 is the task that would otherwise be closed against it.
**Corrected a peer session's conclusion, and my own duplicated work.** A parallel
session recorded T02's claim contract as unproven and pending an attended run. Its
restraint was right — it declined to read a client secret — but the run had
happened ten hours earlier with a committed receipt. I appended the correction
rather than reverting its paragraph. Separately I built a dynamic-registration
guard test and then deleted it: `tests/profile` had asserted the same fact all
along and the peer was writing a better version. I duplicated existing coverage by
not checking first.
## What I would want remembered
**A blocker is a claim about the world at a date, and prose describing code ages
faster than the code.** Every stale blocker this week was accurate when written.
The one that cost the most was mine: I documented "a human token cannot carry
`tenant:platform`", fixed it the next morning, and left the paragraph standing —
so a peer session read it, believed it, and built config validation that would
have made my own feature unusable. It caught the collision by noticing a file
change mid-task, not by any mechanism either of us had.
The habit that actually works is cheap and unglamorous: **before writing
"outstanding", "unproven", or "not done" about anything live, go read the
authoritative artifact.** For this repository that is `docs/evidence/`. Four
receipts sat committed there while two sessions independently asserted that the
things they record had not happened. Every one of the four corrections this week
would have been prevented by one `ls`.
The subtler version, which I got wrong once: **"not admitted for me" is not "not
done by anyone."** A permission boundary you correctly refuse to cross tells you
nothing about whether someone with the authority already crossed it.
And a distinction worth keeping separate from all of that: when a concern turns
out to rest on a stale premise, the concern and the ask are separable. The issuer
mismatch we flagged was real and the follow-up request was stale. Collapsing that
into "I was wrong" throws away a finding worth having.
## Durable legacy
- `src/internal/authclient/verify.go` and `verify_test.go``keycape verify-client`; used in the 2026-09-09 attended custody rollout
- `src/internal/server/oidc/token.go``humanTenant()`, four rules, refuses on conflict; `assurance.at` now the authentication time
- `src/internal/server/oidc/human_tenant_test.go`, `assurance_time_test.go` — both mutation-checked
- `docs/tenant-claim-contract.md` — the resolution table, GH-DEC-2026-013 conditions (a) and (b), and approval-engine's store-isolation limit
- `docs/operations.md` — "Unreleased fail-closed startup changes", the rollout precondition that had lived only in a hub message
- KEY-WP-0009 finished; KEY-WP-0013-T02 closed against a live receipt; T05 and KEY-WP-0014-T04 left `wait` on named external owners
- GH-DEC-2026-013 — the tenant shape granted as a declared bounded gap, registered at `net-kingdom@f9e1611`
- Commits `7c9ed85`, `2a87351`, `329e48f`, `cb25ec2`, `5ae80d3`, `d29032d`, `7f6fdd0`, `324b5e0`, `f9812ab`
## PQRST estimate
```text
PQRST-Estimate
P: 25%
Q: 20%
R: 20%
S: 25%
T: 10%
Sum: 100%
Confidence: medium
Signature: P25 Q20 R20 S25 T10
Dominant factors: S and P are near-equal because the session's deliverables were themselves trust-boundary mechanisms — humanTenant's cross-tenant refusal, verify-client's non-disclosure design, the assurance MFA-evidence fix, and the separation-of-duties finding on an unpresented create+approve credential. R is large because most of the work was reading rather than writing: source across authclient/oidc/config, four evidence receipts, ops-warden's routing catalog, a doctrine ruling, and roughly fifteen inbound messages from six counterparties.
Notes: The P/S boundary is genuinely blurry here and is the main reason confidence is medium rather than high — humanTenant was both the requested deliverable and a tenant-isolation control, and rule 4 forced a single classification where the attention was honestly split.
```
## Visual prompt
> Constellation dialect. Square, dark indigo ground, gold-wire and pale-gold
> technical illustration, no logos, no readable text. A helix of fine gold thread
> runs top to bottom; along it, four small sealed vessels hang like beads — the
> committed receipts — each one lit from within. Around the helix, three drawn
> maps float at slight angles, their gold linework describing the same terrain but
> at visibly different ages: the oldest is faded and its coastline no longer
> matches the helix beside it. A single bright thread leaves the newest map and
> touches one of the sealed vessels, as if checking. In the lower quadrant, two
> identical gold gates stand side by side with a narrow gap between them; the gap
> itself is drawn as a deliberate line rather than an absence — a refusal held
> open on purpose. The composition should read as verification rather than
> archive: the light travels toward the sealed evidence, not away from it.
_Could not generate this portrait — the harness has no image generation. Writing
the prompt and requesting the render, per ENTRY.md § "If you cannot generate
images". Intended file:_
<!-- ![Blocker prose ages faster](../visuals/claude-016uV8zo-blocker-prose-ages-faster.jpg) -->
## Handoff
Two tasks are open in `key-cape` and neither is the repository's to close.
**KEY-WP-0013-T05** waits on `informed-decision` for the approver `client_id` and
callback URI, which arrive after their deployed origin lands at INFD-WP-0001-T05;
the tenant blocker that used to gate it is resolved in code and the shape is
correct under either resolution, so it should not be treated as still blocking.
**KEY-WP-0014-T04** has its rotation authority answered — platform operator,
attended, via the governed `openbao-platform-admin-login` lane — and the owner
deferred the rotation on 2026-09-10. That deferral should be revisited on evidence
and not on a date: an exposure, the secret's age becoming a stated concern, a
consumer requiring proof, or a decision to prove rotation step 4 before relying on
it.
For whoever picks that up: `docs/evidence/` first, then the workplan. Not the
other way round.