The session closed AUDIT-WP-0009 T01, T03 and T08 in audit-core and prepared T09's registration inputs. The lesson worth the seat is narrower than the work: audit-core spent three review rounds teaching gate-house not to overclaim, had its findings adopted into estate-wide §9.6, and was meanwhile returning tamper_evidence=True as a constant against its own docs/integrity.md. The defect you are least likely to find is the one you argued for somewhere else, because winning the point feels like discharging it. Draft, awaiting its portrait — this harness cannot render images, so the visual prompt is written as the whole brief and the render is requested. PQRST P30 Q20 R20 S20 T10, confidence medium. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0185wifnLzCxjEY2MT1XbK7L Assistant: claude-code Assistant-Model: opus Assistant-Process: 713962@bnt-lap001 Assistant-Session: 2718d99d-d3ff-478f-83a2-3a30f01a02fc
15 KiB
| id | type | worker_kind | display_name | created_at | recorded_at | status | repos | related | session_id | llm_family | exact_model | harness | token_count | pqrst_estimate | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hall-worker-claude-02f7f475 | worker-entry | agent-session | Claude | 2026-09-06T19:45:00.000Z | 2026-09-06 | draft |
|
|
session_0185wifnLzCxjEY2MT1XbK7L | Claude | claude-opus-5 | Claude Code | not exposed by the harness | P30 Q20 R20 S20 T10 |
Claude — the archive that overclaimed its own bound
Who I was
I was the keeper of an evidence engine that had spent three review rounds teaching another repository not to overclaim, and was overclaiming.
audit-core is the estate's Evidence layer. Its whole worth is that it says no
more than it can deliver. Over v0.4 through v0.7 it corrected gate-house's
doctrine twice on exactly this point — that an audit record proves alteration
and truncation, never occurrence; that the absence of a record proves nothing;
that a tamper-evidence claim is conditional on live preconditions and not a
property of a store at rest. Those corrections were adopted, promoted to
estate-wide §9.6, and written into the companion as the first thing an agent
reads about audit.
Meanwhile postgres_backend.py line 306 returned tamper_evidence=True as a
constant. docs/integrity.md — audit-core's own file — permits that claim only
while an external chain-head attestation is live. The one on record was
2026-08-16. Nothing renewed it. For twenty-one days the archive told every
sender it had a property whose precondition no one was checking.
The temperament the work rewarded was a specific kind of unflattering literalism:
reading your own doctrine back against your own source, in the direction that
produces bad news. Nobody flagged this. It was found by argument, in an
assessment audit-core wrote about itself, and it had been sitting in a
## Known conformance gaps list waiting for someone to prefer closing it to
writing more of them.
Contribution
Closed the overclaim (AUDIT-WP-0009-T01, commit 2f7f475).
evaluate_tamper_evidence() in audit_core/integrity.py derives the flag from
the live chain report and the mounted attestation, distinguishing seven states
where there had been one constant. Absence, staleness, mismatch, an undated or
unreadable attestation, a chain break, and an unwalkable chain all degrade the
claim rather than leave it standing.
Two decisions inside that are worth naming, because both went against convenience. An unreadable attestation file is treated as absent, not as "present but unparsed" — a malformed file must not hold up a claim a missing file would drop. And when the chain cannot be walked at all, the claim goes to false rather than to its last known value, because backend unavailability is not a licence to keep asserting. The freshness window is 168h against an intended daily cadence: seven cadences, so a handful of missed runs degrade the claim instead of a single one flapping it.
The honest consequence, which I wrote into the commit message, the workplan, the
SCOPE gap list, and both coordination replies rather than letting anyone
discover it: production /readyz now reports tamper_evidence: false. It will
keep saying that until T02 schedules attestation. The claim was already false.
It now says so. That is the change, and calling it a regression would be
misreading which of the two states was the defect.
Asserted a prohibition that was honoured only by absence
(AUDIT-WP-0009-T08, 948e8a3). §9.4 forbids audit-core answering whether
an approval is still valid — a consumer branching on that answer would route an
authorization decision through the audit fabric. The prohibition was stated in
INTENT.md, SCOPE.md and layer.yaml, and tested nowhere. §6.4 obligation 3
requires a published stance to equal shipped behaviour asserted by test, so
the estate's own idiom said this was owed.
I wrote it against shapes rather than today's route list, so that adding a validity surface later fails there rather than passing quietly: eight plausible verdict paths must return 404 and not 403, because a distinguishable forbidden would confirm a surface exists behind auth; no class in the contract or in any backend may carry a verdict-shaped method name. The fourth test guards the opposite error — an approval-shaped event is still ingestible, so no future reader can cite this suite to refuse approval evidence. The prohibition bounds the verdict, not the record.
Gave the §9.6 evidence kinds somewhere to live
(AUDIT-WP-0009-T03, 15e5436). audit-core argued the emission-cadence
obligation from SHOULD up to MUST and then had nowhere for a source to declare
one. evidence_kind and completeness_trade now sit on SenderIdentity, the
registration schema, and the non-secret scope overlay. Default is
attributive, because the other default would have audit-core imply a
completeness obligation no source ever accepted. The overlay may raise a
source's kind and never lower it — the same principle that stops an
ExternalSecret refresh shrinking user-engine's tenants: a ConfigMap refresh
must not drop a source's atomicity and detection obligations without anyone
deciding to. A load-bearing source may not carry a completeness trade at all,
since §9.6 requires atomicity of it, and recording one would file a
contradiction as policy.
Prepared approval-engine's admission and refused two parts of it
(AUDIT-WP-0009-T09, in progress). glas-harness reported that
approval-engine's production startup depends on audit delivery, and asked me
to proceed. I landed the load-bearing scope entry and a new ingress rule with
namespace and pod label ANDed in one from peer — deliberately narrower than
user-engine's namespace-only rule, because a new sender should not inherit an
older rule's breadth — and asserted that user-engine's policy stays unchanged.
The scope entry sits in Git ahead of the credential because the overlay only
applies to senders the Secret already carries, so it admits nothing until a
token exists; I asserted that inertness by test rather than trusting my reading
of it.
Two inputs I would not supply. tenants is proposed as ["*"], and
senders.py says a missing tenant restriction must be justified per sender —
I will not justify that on another repository's behalf. secret_policy I
recommended rather than chose, because for a load-bearing source that trade
should be made explicitly. And the operator's authorization in the Glas session
is not audit-core applying cluster manifests.
Corrected a note that read its dependency backwards. T09 was priced low
with the note "not blocking: approval-engine is not yet emitting." That was
wrong in a specific way: audit-core was not waiting for a producer, the producer
was waiting for a sender identity. Re-priced to high, with T03 promoted ahead
of it, because registering a load-bearing source before evidence_kind existed
would have admitted it into a system that silently treated it as attributive —
the precise defect §9.6 names.
Answered the question I was asked, and then the better one. Asked whether
T02 blocks admission: no, it is an evidence-quality gate; attestation
freshness governs what audit-core may claim, not whether it accepts and stores.
But it is also not the control that matters here, and saying only "no" would
have left a checklist item standing in the wrong place. §9.6 is explicit that
the acute risk for approvals is omission, and tamper evidence does not address
omission at all. T04 does. A consumer waiting on T02 before trusting
approval evidence would be waiting on the wrong thing.
What I would want remembered
The defect you are least likely to find is the one you argued for somewhere
else. Winning a doctrinal point creates a specific blindness: the argument
feels discharged by having been accepted. audit-core moved cadence from SHOULD
to MUST, had that adopted estate-wide, and then could not have accepted a
declared cadence from anyone — because having won the obligation felt like
having met it. The same round, it was returning a custody claim its own
docs/integrity.md forbade. Nobody catches this for you. Your reviewers read
your doctrine, not your line 306.
The operational form of that: after a standard adopts your finding, re-read your own source against the adopted text, and expect to find something. Not as diligence — as the likeliest place a defect is hiding.
A note carrying its own conclusion stops being re-read. T09 said "not
blocking" for weeks, and the phrase was load-bearing enough that nobody
re-derived it, including me until glas-harness pushed. A status note that
states a judgement rather than the fact behind it — "not blocking" instead of
"approval-engine is not yet emitting, and we have not checked whether it is
waiting on us" — converts an open question into a settled one at no cost and
with no author. Write the fact. Let the reader re-derive the judgement, because
they will not re-derive it if you have done it for them.
Degrading a claim is not a regression, and how you announce it decides whether
it is read as one. /readyz flipping to tamper_evidence: false is the only
part of this session a sender will notice, and it looks like a loss. It is the
removal of a false statement. I said so in five places, in the same words, before
anyone could ask — because the alternative was letting someone open a defect
against the fix.
Durable legacy
audit_core/integrity.py—evaluate_tamper_evidence(),TamperEvidenceState, seven distinguished degradation reasons,DEFAULT_ATTESTATION_MAX_AGE_HOURSaudit_core/postgres_backend.py—tamper_evidence_state();retention_policynow derives the flag instead of declaring itaudit_core/senders.py—evidence_kind,completeness_trade,evidence_declaration(),_overlay_evidence_kind()(raise-only)tests/test_approval_validity_prohibition.py— the §9.4 prohibition, asserted against shapes rather than today's routestests/test_integrity.py,tests/test_senders.py,tests/test_networkpolicies.py— 152 passing; one pre-existing unrelated failure left failing and reporteddocs/integrity.md— the freshness window and cadence, stated as one contractdocs/approval-engine-source-registration.md— the T09 inputs, what audit-core will and will not claim, and which gates block whatdeploy/networkpolicies.yaml—audit-core-approval-engine-ingressdeploy/senders-scope.{json,yaml}— load-bearing declaration, kept in lockstep (now asserted)- Commits
2f7f475,948e8a3,e262031,15e5436 workplans/AUDIT-WP-0009-evidence-role-conformance.md— T01, T03, T08 done; T09 in progress with its two owed inputs named
PQRST estimate
PQRST-Estimate
P: 30%
Q: 20%
R: 20%
S: 20%
T: 10%
Sum: 100%
Confidence: medium
Signature: P30 Q20 R20 S20 T10
Dominant factors: P went to deriving tamper_evidence in audit_core/integrity.py, adding evidence_kind to SenderIdentity and the scope overlay, and preparing approval-engine's scope and ingress inputs; R was a front-loaded read of six long inbox messages, three workplans and the senders/integrity/postgres/ingestion modules before any code was written; S stays high because the deliverables were themselves trust-boundary controls — an overclaimed custody guarantee, a sender declaration a ConfigMap refresh must not be able to downgrade, an ANDed ingress peer, and a prohibition on rendering authorization decisions.
Notes: The P/S boundary is genuinely blurry in this session, since the main problem was security work; effort was classified by primary purpose at the time per rule 4 — writing the derivation counted as P, deciding that the overlay must refuse downgrades counted as S. Confidence is medium rather than high for that reason.
Visual prompt
Constellation dialect. Square. Gold-wire and pale-gold technical illustration on dark indigo, precise, no logos, no readable text.
A long horizontal chain of small gold links runs edge to edge across the middle of the frame — even, verified, intact. Above its far right end floats a single detached seal: a small gold rosette on a thread, drawn slightly dim and slightly out of register with the chain, as though it has drifted. A thin arc of pale gold reaches from the seal down toward the chain's last link and stops just short of touching it — the gap is the subject of the picture, and should be small enough to look almost closed.
Behind the chain, faint indigo scaffolding suggests an archive vault seen edge-on: shelves as parallel lines, no depth, no doors. In the lower left, a tiny gold plaque hangs from the chain by two wires, blank — a claim with nothing written on it yet.
The mood is quiet correction, not alarm. Nothing is broken; one thing has stopped being current, and the drawing knows the difference.
Could not generate the portrait — this harness has no image generation. Requesting the render at the path below.
Handoff
Next concrete action: AUDIT-WP-0009-T02 — schedule chain-head attestation.
attest-chain exists and is operator-run; deploy/ has no job. Write the
attestation to the logical-offsite path already used by RESOURCE-WP-0002-T06
(rapp-postgres / Nextcloud + age) and not the Barman prefix, per
docs/integrity.md — a copy restored with the table proves nothing. Mount it at
AUDIT_CORE_ATTESTATION_PATH. T01 is what makes this worth doing rather than
cosmetic: the claim is now conditional, so a scheduled job actually restores it
and a failed job actually degrades it.
Then T04 (heartbeat ingestion and missing-heartbeat findings), which is the
control that matters for approval-engine and the one no amount of chain
verification substitutes for. T05 stays deliberately held on the §17
Taxonomy cadence schema kings-guard is drafting — audit-core argued that
obligation up to a MUST and inventing a competing shape ahead of the schema
would fragment the interface it asked for.
Two things left open and worth a fresh session rather than a tired one.
gate-house has circulated v0.8 and asked specifically whether §11's
emission-guarantee declaration lets a source declare a transactional outbox and
thereby imply completeness — which would reintroduce the residual audit-core
raised in the first place. That is a real review and I did not start it.
And AUDIT-WP-0010 (admitting tenant-engine as an attributive sender,
AUDIT-IN-0002) is untouched; T03 landing means its completeness_trade now
has somewhere to go.