The register had nine waits in four days, one four hops deep: F-0003's embargo waited on F-0009, which waited on railiance-platform, which waited on live OpenBao verification, which waited on a credential nobody has. No single link was wrong, which is why it needed a rule. docs/method/dependencies.md: the register never waits to decide, it decides and revises. Every wait carries who, what, since, what it would change, what happens if nobody answers, and the date that default applies. Depth one — a record never waits on a record that is itself waiting. Defaults are dates and are pessimistic: silence costs the grade the evidence supports rather than buying a softer one, and owners are told the default in advance because a default nobody was warned about is an ambush. Applied: F-0009's embargo now lifts on railiance-platform reporting coverage, with live verification as a refinement rather than a condition, cutting the F-0003 chain from four hops to two. All eight open waits are typed with defaults. make check reports them with age, owner and default date, flags defaults come due, and catches depth-two violations. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
324 lines
16 KiB
Markdown
324 lines
16 KiB
Markdown
---
|
||
id: RISK-F-0008
|
||
type: finding
|
||
title: "The legal basis for retaining audit facts against an erasure request has been assumed, never established"
|
||
status: open
|
||
reported_by: audit-core
|
||
reported_via: audit-core
|
||
routed_by: audit-core
|
||
date_reported: "2026-08-18"
|
||
date_filed: "2026-08-19"
|
||
system: audit-core
|
||
environment: production
|
||
fix_owner: risk-nexus
|
||
fix_tracking: unset
|
||
related: [RISK-F-0005]
|
||
supersedes: RISK-N-0002
|
||
# Graded by risk-nexus 2026-08-19 — docs/rulings/2026-08-19-third-grading.md
|
||
severity: medium
|
||
severity_at_production: high
|
||
impact: I3
|
||
likelihood: L2
|
||
fidelity_modifier: false
|
||
production_rescore: true
|
||
disclosure: public
|
||
publication: pending-handover
|
||
escalation: required
|
||
escalation_trigger: 2
|
||
escalation_status: partially-answered
|
||
escalation_answered: "2026-08-20"
|
||
escalation_answered_by: the-custodian
|
||
escalation_act: rule
|
||
decision: "identity in audit records: opaque subject ids preferred, agent identifiers where possible, operator credentials only where necessary, policy decisions tracked to the responsible party; zone-level privacy guarantees may raise the floor"
|
||
outstanding: "a defensible retention period per category (waits on audit-core's co-residency horizon), and the trigger list for buying an external answer"
|
||
determination: RISK-REG-0001
|
||
last_checked: "2026-08-20T10:02:41Z"
|
||
next_check: "2026-08-20T10:02:41Z"
|
||
cadence: instant
|
||
clean_streak: 0
|
||
waiting_on:
|
||
- who: audit-core
|
||
what: "does a keyed commitment restore erasability without breaking chain verification; what is the platform-pg co-residency horizon"
|
||
since: "2026-08-20"
|
||
would_change: "a working keyed commitment narrows RISK-REG-0001 to retained-by-obligation categories only"
|
||
default: "encrypt-then-hash recorded as the only known route, and the retention period recorded as unstateable"
|
||
default_at: "2026-11-17"
|
||
- who: the-custodian
|
||
what: "rule the trigger list for buying an external determination"
|
||
since: "2026-08-19"
|
||
would_change: "fixes when the estate stops running on an assumption"
|
||
default: "the assumption is recorded in the register as an assumption"
|
||
default_at: "2026-11-17"
|
||
graded_by: risk-nexus
|
||
ruling: RISK-RULING-2026-08-19-C
|
||
---
|
||
|
||
# RISK-F-0008 — the exemption nobody has established
|
||
|
||
## What is true
|
||
|
||
`audit-core` holds audit evidence across tenants, targets `R2` on the Tenancy
|
||
Posture retention ladder, and has declared `R4` — verified erasure —
|
||
unreachable by design. The technical reasoning is sound and documented
|
||
(`audit-core/docs/erasure-and-audit.md`, framework Decision 4.5.3):
|
||
crypto-shredding would destroy the evidence the service exists to hold, and
|
||
their integrity chain commits to a SHA-256 of the cleartext record, which
|
||
survives key destruction as a confirmation oracle against low-entropy audit
|
||
rows. Destroying a key does not erase content a surviving commitment can still
|
||
be tested against.
|
||
|
||
The consequence is that if an Article 17 request arrives naming a data subject
|
||
in the audit trail, `audit-core` has no mechanism. The answer would rest on
|
||
audit evidence being exempt — legal obligation, or legitimate interest in fraud
|
||
and security investigation.
|
||
|
||
**Those grounds are ordinary. Nobody in this estate has actually reached them.**
|
||
`audit-core` routed the question here on 2026-08-18 rather than absorbing it,
|
||
saying plainly that they are not competent to answer it and that they have been
|
||
assuming it. §19.11 of the framework says the same in its own words: the legal
|
||
basis for retaining audit facts remains a risk/legal question outside the
|
||
framework.
|
||
|
||
## Why this repo owns it
|
||
|
||
This is the first finding where `fix_owner` is `risk-nexus`.
|
||
|
||
`INTENT.md` moved regulatory intake here from `policy-nexus` on 2026-08-17,
|
||
precisely because deciding what a rule demands of us is a judgement about risk
|
||
rather than an act of publishing. `audit-core` routed it by both available
|
||
routes and asked for an owner rather than an opinion. Refusing it would be this
|
||
repo declining its own remit.
|
||
|
||
What this repo owns is the **record**: what the source says, when, and what
|
||
therefore is or is not established. It does not own legal advice — `INTENT.md`
|
||
is explicit — and it does not own the redesign. If the basis does not hold,
|
||
`audit-core` owns encrypt-then-hash at accept time, and that is not
|
||
retrofittable onto events already accepted.
|
||
|
||
## The three questions, as asked
|
||
|
||
1. On what basis does the estate retain personal data inside audit records
|
||
against an erasure request, and does that basis hold for the categories
|
||
`audit-core` stores?
|
||
2. Does it hold across the full 30-day recoverable window and beyond, given
|
||
that at `P1` the real erasure horizon is the maximum across every
|
||
co-resident on `platform-pg`, not the value `audit-core` declares?
|
||
3. If it does not hold, `R4` is urgent rather than theoretical, and the answer
|
||
is a substantial redesign with a long lead time.
|
||
|
||
## Register ruling — 2026-08-19
|
||
|
||
`medium` today (`I3` × `L2`), `high` at production, `public`, **escalated on
|
||
trigger 2**.
|
||
|
||
`I3`: an unmet retention obligation in the audit store crosses from a technical
|
||
question to an obligation with an outside counterparty, and the remediation is
|
||
a non-retrofittable redesign rather than a patch. `L2`: no request has arrived
|
||
and the estate holds no real data subject's records yet, but the trigger is
|
||
somebody else's to pull and needs no foothold here.
|
||
|
||
`production_rescore: true`. The likelihood of an Article 17 request is a
|
||
function of having real users; that is exactly what production means.
|
||
|
||
**Escalation, trigger 2** — "creates or reveals an obligation with an outside
|
||
counterparty". It reveals one. The estate cannot decide unilaterally that this
|
||
obligation is small, and the operator is the only party who can commission an
|
||
answer that is more than an assumption. The ask is narrow: authorise someone to
|
||
establish the basis, or record that the estate knowingly runs on the assumption
|
||
and for how long.
|
||
|
||
**Disclosure `public`.** Nothing here shortens a path to a defect: it is a
|
||
question about a legal basis, published as a question. `audit-core`'s technical
|
||
reasoning is already written down and worth reading.
|
||
|
||
## How it got here
|
||
|
||
Ruled a note on 2026-08-19 (`RISK-N-0002`) on the reasoning that no obligation
|
||
exists yet. That ruling was made without reading `audit-core`'s message, which
|
||
had been in this repo's inbox since 2026-08-18 and asks specifically for an
|
||
owner. The note was wrong on the second floor test: recording this *does*
|
||
change a decision, because the redesign it might force cannot be retrofitted
|
||
and therefore has to be decided early or not at all.
|
||
|
||
`RISK-N-0002` is superseded by this record.
|
||
|
||
## Reviews
|
||
|
||
- **2026-08-19** — promoted from note, graded, escalated. Open at review:
|
||
has the basis been established or the assumption recorded; has anything
|
||
changed about what categories `audit-core` stores.
|
||
|
||
## Suggested disposition — 2026-08-20, proposed by risk-nexus
|
||
|
||
Offered because this repo owns the finding and the operator asked for a
|
||
direction. It is not legal advice, and this repo cannot make it into one: what
|
||
follows is a *route to an answer* and a hedge against the answer being no.
|
||
|
||
### The reframe: the expensive thing is not the legal question
|
||
|
||
`audit-core` asks whether the exemption holds. That question is cheap to
|
||
answer badly and expensive to answer properly, and the temptation is to
|
||
schedule the proper version and wait.
|
||
|
||
But the cost of a "no" is not fixed — it grows daily. The remedy they name,
|
||
encrypt-then-hash at accept time, cannot be retrofitted onto events already
|
||
accepted. **Every day the estate accepts events under the current scheme, the
|
||
un-erasable set grows by one day.** So the decision that actually needs taking
|
||
now is not "is it exempt" but "do we keep manufacturing records we could never
|
||
erase while we find out".
|
||
|
||
That splits the finding into two decisions with very different prices.
|
||
|
||
### 1. Establish the basis internally, now, for the cost of an afternoon
|
||
|
||
Not a legal opinion — a **written determination** that says which ground is
|
||
being relied on, for which category of data, and for how long. Today the
|
||
estate has no such document; that is the whole finding.
|
||
|
||
The shape it should take, per category of personal data in the audit trail:
|
||
|
||
| Category | Likely ground | The part that is actually arguable |
|
||
| --- | --- | --- |
|
||
| Operator and agent identifiers | Art 6(1)(f) legitimate interest in security, with Recital 49 squarely on point | little — this is the ordinary case |
|
||
| Counterparty or end-user identifiers in event payloads | Art 17(3)(e), defence of legal claims; Art 6(1)(f) | **duration**, not existence |
|
||
| Commercial records that happen to pass through audit | Art 17(3)(b) plus German §257 HGB / §147 AO retention | scope — retention duties cover books and invoices, not application logs generally |
|
||
|
||
Where such determinations usually fail is **not** the ground. It is the
|
||
retention period: a blanket "we keep audit forever under legitimate interest"
|
||
is much weaker than "we keep these fields for N months because X". That lands
|
||
precisely on `audit-core`'s question 2 — the real horizon being the maximum
|
||
across every co-resident on `platform-pg` rather than the declared value.
|
||
|
||
Recording the determination converts an assumption into a position that can be
|
||
argued with. That is what this register exists to produce, and it does not
|
||
require a lawyer to write down.
|
||
|
||
### 2. Stop the un-erasable set from growing — a cheaper hedge than the redesign
|
||
|
||
`audit-core`'s stated obstacle is precise and correct: their chain commits to
|
||
`SHA-256(cleartext)`, audit records are low-entropy, so the retained hash
|
||
survives key destruction as a confirmation oracle. Guess, hash, compare.
|
||
|
||
The oracle exists because the commitment is over cleartext with no secret in
|
||
it. A **keyed commitment** removes it: replace the digest with an HMAC (or a
|
||
hash over record plus a high-entropy per-subject salt) where the key or salt
|
||
lives outside the audit store and is destroyable per subject.
|
||
|
||
What that buys, and why it is cheaper than the redesign they costed:
|
||
|
||
- Destroying the per-subject key makes the commitment untestable — no guess
|
||
can be confirmed. That is crypto-shredding restored, which their analysis
|
||
correctly found unavailable under a plain hash.
|
||
- The integrity chain still verifies. It chains over commitment values, and
|
||
those persist after key destruction; what is lost is the ability to
|
||
re-derive a commitment from cleartext, which is exactly what erasure means.
|
||
- It is a change at accept time only. No re-processing of stored events, no
|
||
new storage layer, no change to the read path.
|
||
|
||
This is a suggestion to `audit-core`, not an instruction, and they own whether
|
||
it is sound — they know their chain and this repo does not. The claim worth
|
||
testing with them is narrow: **does a keyed commitment restore erasability
|
||
without breaking chain verification?** If yes, the expensive redesign becomes a
|
||
contingency rather than a plan, and the daily accrual stops.
|
||
|
||
### 3. Buy the real answer only when something triggers it
|
||
|
||
An external determination costs money and needs a real question. Propose three
|
||
triggers, any of which fires it:
|
||
|
||
- the estate first holds a real person's data;
|
||
- a counterparty contract requires a stated erasure position;
|
||
- an actual Art 17 request arrives.
|
||
|
||
Until one fires, the internal determination plus the hedge is a proportionate
|
||
posture, and `severity_at_production: high` plus `production_rescore: true`
|
||
already guarantee this is re-read before production completes.
|
||
|
||
### What this repo would record if the operator agrees
|
||
|
||
`status: accepted` with the determination attached, `escalation` answered as
|
||
`rule`, and the review kept at 90 days. The finding stays open and visible
|
||
until the determination exists — an accepted risk with no written basis is the
|
||
same assumption it started as, wearing a different word.
|
||
|
||
### Also worth saying, because it is the cheapest fix of all
|
||
|
||
Every field of personal data that never enters the audit trail is a field with
|
||
no erasure question. Where an opaque subject identifier would carry the same
|
||
evidentiary weight as a name or an address, the identifier is strictly better,
|
||
and that is a `audit-core` design choice available today at no legal cost.
|
||
|
||
## Operator decision — 2026-08-20: minimise the identity, keep the accountability
|
||
|
||
The custodian ruled on what goes into an audit record, which is the half of
|
||
this finding that shrinks the question rather than answering it:
|
||
|
||
1. **Opaque subject identifiers are preferred.** Where an opaque id carries the
|
||
same evidentiary weight as a name or an address, it is the id that goes in.
|
||
2. **Agent identifiers where possible.** Agents act; attribute to the acting
|
||
agent identity rather than to a person behind it.
|
||
3. **Operator credentials only where necessary.** Not as a convenience, not as
|
||
a default — where the record genuinely requires the operator.
|
||
4. **Policy decisions are tracked to the responsible party.** Accountability is
|
||
preserved by linking a decision to who is answerable for it, not by
|
||
retaining personal data in the record itself.
|
||
5. **Zone guarantees may raise the floor.** If a zone establishes additional
|
||
privacy, pseudonymity or anonymity guarantees, those apply — the current
|
||
level is not a permanent ceiling. That work is `zone-engine`'s
|
||
(`ZONE-WP-0001`), and this finding should be re-read when a zone lands one.
|
||
|
||
**Why this is more than a preference.** Personal data that never enters the
|
||
audit trail has no erasure question, no exemption to establish, and nothing to
|
||
argue about with a regulator. Points 1-3 shrink the population the legal basis
|
||
has to cover; point 4 is what stops that shrinking from costing accountability,
|
||
which is the usual objection to minimising an audit log.
|
||
|
||
It also changes the shape of the accrual problem. The un-erasable set still
|
||
grows daily, but each day's records now carry less that would need erasing —
|
||
so the cost of a "no" answer falls with every event accepted under the new
|
||
rule rather than rising.
|
||
|
||
**What is still outstanding**, and stays escalated:
|
||
|
||
- The **written determination** of the retention basis — which ground, for
|
||
which category, for how long. `risk-nexus` owns writing it; it needs no
|
||
further authorisation and is scheduled into the next workplan.
|
||
- The **trigger list** for buying an external answer (first real person's data,
|
||
first counterparty contract requiring a stated position, first Art 17
|
||
request). Proposed, not yet ruled on.
|
||
|
||
The escalation is therefore `partially-answered`, not closed. `make check` will
|
||
keep listing it.
|
||
|
||
**Routed to `audit-core` on 2026-08-20**, together with the keyed-commitment
|
||
question — which remains theirs to judge, because they know their chain.
|
||
|
||
## The determination exists — 2026-08-20
|
||
|
||
`docs/regulatory/RISK-REG-0001` (`audit-retention-basis.md`). The estate now
|
||
has a written position rather than an assumption, which was this finding's
|
||
substance.
|
||
|
||
What it says, in short: Art 6(1)(f) with Art 32 for operator and agent audit
|
||
records; Art 17(3)(e) for records evidencing a counterparty transaction;
|
||
Art 17(3)(b) only where a commercial or tax retention duty independently
|
||
applies, and not extended to application logs generally.
|
||
|
||
**The weak part is duration, not existence**, and the record says so rather
|
||
than sounding confident. A position of the form "we keep audit forever because
|
||
it is audit" is the one that fails; a period per category is what holds. The
|
||
estate does not have one yet, and the reason is `audit-core`'s own question 2 —
|
||
at `P1` the real horizon is the maximum across every co-resident on
|
||
`platform-pg`, not the declared value. **That infrastructure fact is the most
|
||
likely point of failure in the whole position.**
|
||
|
||
The operator's minimisation ruling improves this materially: it shrinks the
|
||
category whose retention is hardest to justify, leaving mostly the row where
|
||
the ground is strong. A weak argument avoided by holding less data beats a
|
||
strong one relied upon.
|
||
|
||
The finding stays open. What remains is a retention period per category, which
|
||
waits on the co-residency horizon, and the trigger list for buying an external
|
||
determination. The record is reviewed every 90 days with this finding, or
|
||
immediately on any trigger.
|
||
- **2026-08-20** — not clean: The determination now exists: RISK-REG-0001 states the grounds per category and names duration as the weak point. Cadence instant → instant; checked again immediately.
|