T08 fixes two defects in our own declaration. provider.R.available quoted a
30-day horizon audit-core does not solely control: at P1 the erasure horizon is
the instance maximum across co-residents, so a co-resident declaring longer
extends what a sender's records remain recoverable for, silently. Decision 4.5.4
names this for tiers; it applies to a provider quoting a number too, and the
provider block now says so. And user-engine, the only consumer, was notified
under Decision 6.1 -- what we declared, that E4 and R4 are unreachable here, and
that the retention number is a floor rather than a ceiling.
T03 writes docs/erasure-and-audit.md: the fact/payload split, why shreddability
is not retrofittable onto a chain committing to cleartext, and why the retained
hash is a confirmation oracle over low-entropy audit records. The framework half
was already resolved as Decision 4.5.3, so what remains is our own position. The
legal basis for retaining audit facts is routed to risk-nexus, open and visible.
T06 closes the review loop with net-kingdom: five findings adopted, declaration
validates clean, and the E line will go stale on an upgrade that Decision 6.1
deliberately does not require anyone to announce.
T07 enumerates the seven dependencies on the accept path and specifies five
recovery scenarios with integrity as a pass condition. It settled one thing: V2
is not reachable from P1 as built, since platform-pg runs instances 1 and
Decision 4.6.1 makes V the minimum across synchronous providers. V1 is the
ceiling here, not the next step. The exercise needs a live window.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The framework moved from draft-5 to draft-8 while this workplan ran. No finding
was reversed, but three things changed underneath it: R moved to 2 once
rapp-postgres declared the window, a sixth axis V (availability) appeared, and
the implemented-versus-evidenced distinction became a schema field.
T03 reduces: the confirmation-oracle finding landed as Decision 4.5.3 and
question 11 is marked framework-resolved, so no amendment remains -- only our
own position document. The legal question routes to risk-nexus rather than
the-custodian, per §19.11 and policy-nexus INTENT.
T06 reduces to confirmation: all five findings were adopted and the two stale
status lines it was going to flag are already fixed.
T07 is new. V1 needs critical dependencies enumerated, restart recovery
exercised and recovery time measured. The 2026-08-16 reboot walk observed ~40s
of unreadiness but is not an exercise and does not enumerate the dependency set.
T08 is new and covers two defects in our own declaration. provider.R.available
quotes a 30-day horizon we do not solely control -- at P1 the horizon is the
instance maximum across co-residents. And under Decision 6.1, user-engine was
never told what we declared, which makes the declaration drift rather than a
completed change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Written against draft-7, which landed after the task was drafted and moved the
target. Decision 5.4 fixes the location at tenancy.yaml in the repo root rather
than docs/, and fixes the schema: current, target, reviewed, gap,
placement_exceptions, service_class, per-path detail, provider block.
Declares I1 A2 E1 P1 R1. E is quoted at 1 although T04 put the E2 mechanism on
both paths, because §13.2 states a passing CI run is not E2 evidence -- the
artifact is adversarial, compares separate tenant contexts and carries a review
date. Our cross-tenant tests are mechanical, so under §13.1 the level is not
claimable until T05. The mechanism is recorded in paths.E and the reason in
gap.E. Claiming E2 off unit tests would be the overclaim §6 prohibits, and
refusing that reasoning is what found the read-path defect.
R stays at 1: R2 needs backupRetentionDays in rapp-postgres's consumer file,
requested in T02 and not ours to declare.
Two additions draft-7 forced. A credentials gap under Decision 9.2 -- our own
finding, adopted as a rule, and it binds us: ingest credentials are static
long-lived bearer tokens, declared as a stated gap rather than a silent
exclusion. And a provides block under Decision 5.5, declaring what a sender can
reach through this service: E2 now, E3 pending ADR-0003, E4 and R4 unreachable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
_read gated on may_read alone and never called permits_tenant, so any reader
credential could read every tenant through /v1/events, /v1/events/<id>,
/v1/dead-letters and /v1/secret-findings. Deployment bounded the exposure --
the only production sender holds may_read: false -- but the boundary was not in
the code, which is the difference between E2 and E1 on the tenancy posture
enforcement ladder.
Two rules, because the surfaces divide cleanly. Event reads are filtered to the
tenants the credential may act for. Surfaces with no tenant key to filter on --
stats, integrity, dead letters, secret findings -- require full tenant scope and
are refused rather than served instance-wide facts to a scoped reader.
A cross-tenant fetch returns 404 rather than 403. A distinguishable forbidden
would confirm that an event id exists and which tenant holds it, turning the
read surface into an existence oracle. Correlation lookup is filtered rather
than refused, since a correlation id legitimately spans tenants.
_readable_by fails closed: a record with no tenant is readable only at full
scope. Three existing tests read instance-wide surfaces with a scoped
credential, which this makes a 403; bound_app now carries an unrestricted
operator identity and those reads use it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three additions after review:
Retention position is now conditional on a date. Routing multi-year custody to
data.archive is mechanically right and practically unfunded, so the position
carries a 2026-12-31 review and names P2 as the fallback if no provision is
procured. Also folds in R1 -> R2, which needs only an explicit
backupRetentionDays: 30 and a published erasure horizon.
The erasure exemption names its legal dependency. Declining to build erasure
rests on audit evidence being exempt under legal obligation or legitimate
interest; that is a legal conclusion nobody in the estate is recorded as having
reached, and T03 routes it rather than absorbing it.
T04 now runs before T01 so the published vector reads E2 on both paths from its
first commit. T02 still runs first and corrects the E2 guess by message, since
that guess is live in canon and wrong today.
Framework finding 1 amended to declare per path, quote the minimum. E3 target
carries 2027-03-31.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assesses audit-core against NetKingdom Tenancy Posture v0.1 following the
rapp-postgres review request. The guessed vector I2 A3 E2 P1 R1 is too high on
three axes; the honest reading is I1 A2 E1 P1 R1.
The E correction is a real defect rather than a bookkeeping one: the read path
in ingestion._read gates on may_read alone and never calls permits_tenant, so a
reader credential can read any tenant. Bounded today by may_read: false on the
production sender and by default-deny networking, but not enforced in code.
Also records the retention position (ceiling stays 365, multi-year belongs to
data.archive not the WAL window) and the question-11 answer: crypto-shredding
does not reach R4 here, because the chain commits to a SHA-256 of the cleartext
record, which survives key destruction as a confirmation oracle.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Accept now extends a single-schema chain. Verify walks it; a rewritten
payload_hash is a break. Tamper evidence is that detector plus an
external chain-head attestation, not WORM.
Live receiver now reports custody_class=operational with a cited
30-day recoverable window (sha256:05fe1c06). Next workplan is
integrity verification so tamper_evidence can become honest.
Postgres now reports custody_class=operational with a cited 30-day
recoverable window. Join ITC-CAP operations.audit at D4, publish the
interface card, and overlay user-engine tenants [*] from Git so an
ExternalSecret refresh cannot shrink it.
Review of info-tech-canon 0.6.0, resource-control, fin-hub, and
railiance-master found production still claims archive custody after
the platform backup and ITC-CAP catalog made that claim false.
Logical dump of live audit_core restored locally in 4.1s; counts and
sample triples match the rapp-postgres drill. Retention is platform
backup, not an audit-core deletion window. Workplan finished.
SET ROLE during migrate so tables are not owned by a disposable lease.
Current image sha256:aec5575. T02/T03 recorded done after live rotation
and rollout undo. T05 remote run is partial (port-forward dropped).
Secret volume rotation swaps ..data. Sequential reads of username then
password can tear across two leases. Resolve the snapshot once.
Also document why ESO AppRole login cannot parent database/creds leases:
the token discard DROP ROLEs the role ESO just stored.