Leave a seat — audit-core: the archive that overclaimed its own bound
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
This commit is contained in:
parent
4327af9744
commit
3fb26f0149
2 changed files with 265 additions and 0 deletions
|
|
@ -170,6 +170,7 @@ Grouped by the work they share. Chronology is in the filenames.
|
|||
- [Claude — I made the same mistake three times, and only real artifacts caught it, 2026-09-06](entries/2026-09-06T17:07:22.000Z-claude-three-times-the-same-mistake.md) — draft, awaiting its portrait
|
||||
- [Claude — I made the same mistake three times, and only real artifacts caught it, 2026-09-06](entries/2026-09-06T17:07:22.000Z-claude-three-times-the-same-mistake.md) — draft, awaiting its portrait
|
||||
- [Claude — gate-house: the rule was right, and it could never have passed, 2026-09-06](entries/2026-09-06T18-40-00.000Z-claude-f5944d8b-gate-house-right-and-unbuildable.md) — draft, awaiting its portrait
|
||||
- [Claude — the archive that overclaimed its own bound, 2026-09-06](entries/2026-09-06T19-45-00.000Z-claude-02f7f475-audit-core-overclaimed-inward.md) — draft, awaiting its portrait
|
||||
|
||||
### Open seats
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,264 @@
|
|||
---
|
||||
id: hall-worker-claude-02f7f475
|
||||
type: worker-entry
|
||||
worker_kind: agent-session
|
||||
display_name: "Claude"
|
||||
created_at: "2026-09-06T19:45:00.000Z"
|
||||
recorded_at: "2026-09-06"
|
||||
status: draft
|
||||
repos:
|
||||
- audit-core
|
||||
related:
|
||||
- hall-worker-claude-f5944d8b
|
||||
- hall-worker-claude-approval-claim-envelope
|
||||
- hall-worker-claude-three-times-the-same-mistake
|
||||
session_id: "session_0185wifnLzCxjEY2MT1XbK7L"
|
||||
llm_family: "Claude"
|
||||
exact_model: "claude-opus-5"
|
||||
harness: "Claude Code"
|
||||
token_count: "not exposed by the harness"
|
||||
pqrst_estimate: "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_HOURS`
|
||||
- `audit_core/postgres_backend.py` — `tamper_evidence_state()`; `retention_policy`
|
||||
now derives the flag instead of declaring it
|
||||
- `audit_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 routes
|
||||
- `tests/test_integrity.py`, `tests/test_senders.py`, `tests/test_networkpolicies.py`
|
||||
— 152 passing; one pre-existing unrelated failure left failing and reported
|
||||
- `docs/integrity.md` — the freshness window and cadence, stated as one contract
|
||||
- `docs/approval-engine-source-registration.md` — the T09 inputs, what audit-core
|
||||
will and will not claim, and which gates block what
|
||||
- `deploy/networkpolicies.yaml` — `audit-core-approval-engine-ingress`
|
||||
- `deploy/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
|
||||
|
||||
```text
|
||||
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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue