Refine AUDIT-WP-0008 open tasks against draft-8.
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>
This commit is contained in:
parent
0511801f67
commit
4d5d989344
5 changed files with 150 additions and 60 deletions
2
SCOPE.md
2
SCOPE.md
|
|
@ -38,7 +38,7 @@ audit-core exists to provide the capability described in INTENT.md.
|
|||
(`docs/evidence/chain-head-20260816.json`).
|
||||
- ITC-CAP case: `data/capability/audit-core-operational.json` at D4.
|
||||
`data.archive` is an unmet requirement.
|
||||
- Tenancy posture: `tenancy.yaml` (NetKingdom Tenancy Posture v0.1 draft-7,
|
||||
- Tenancy posture: `tenancy.yaml` (NetKingdom Tenancy Posture v0.1 draft-8,
|
||||
Decision 5.4). Declared `I1 A2 E1 P1 R1`, target `E3` and `R2`. E is quoted
|
||||
at 1 although the E2 mechanism is in place on both paths — the §13 E2
|
||||
artifact is adversarial and does not exist yet (AUDIT-WP-0008-T05).
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
| task | AUDIT-WP-0007-T03 | done | — | workplans/AUDIT-WP-0007-integrity-verification.md |
|
||||
| task | AUDIT-WP-0007-T04 | done | — | workplans/AUDIT-WP-0007-integrity-verification.md |
|
||||
| task | AUDIT-WP-0007-T05 | done | — | workplans/AUDIT-WP-0007-integrity-verification.md |
|
||||
| task | AUDIT-WP-0008-T01 | todo | — | workplans/AUDIT-WP-0008-tenancy-posture-alignment.md |
|
||||
| task | AUDIT-WP-0008-T01 | done | — | workplans/AUDIT-WP-0008-tenancy-posture-alignment.md |
|
||||
| task | AUDIT-WP-0008-T02 | done | — | workplans/AUDIT-WP-0008-tenancy-posture-alignment.md |
|
||||
| task | AUDIT-WP-0008-T03 | todo | — | workplans/AUDIT-WP-0008-tenancy-posture-alignment.md |
|
||||
| task | AUDIT-WP-0008-T04 | done | — | workplans/AUDIT-WP-0008-tenancy-posture-alignment.md |
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ consumer_needs:
|
|||
feedback: []
|
||||
tenancy_posture:
|
||||
declared_at: tenancy.yaml
|
||||
framework: net-kingdom/canon/standards/tenancy-posture_v0.1.md (draft-7)
|
||||
framework: net-kingdom/canon/standards/tenancy-posture_v0.1.md (draft-8)
|
||||
current: I1 A2 E1 P1 R1
|
||||
target: I1 A2 E3 P1 R2
|
||||
provides_reachable:
|
||||
|
|
|
|||
93
tenancy.yaml
93
tenancy.yaml
|
|
@ -1,22 +1,29 @@
|
|||
# audit-core tenancy posture
|
||||
#
|
||||
# Declared per NetKingdom Tenancy Posture v0.1 (draft-7),
|
||||
# Declared per NetKingdom Tenancy Posture v0.1 (draft-8),
|
||||
# net-kingdom/canon/standards/tenancy-posture_v0.1.md.
|
||||
# Location and schema per Decision 5.4; per-path detail per Decision 5.2;
|
||||
# provider block per Decision 5.5.
|
||||
#
|
||||
# Conformance is accuracy, not altitude (§6). Nothing here is claimed above
|
||||
# what this repo can evidence today, and two rungs are deliberately declared
|
||||
# lower than the mechanism in place — see `gap.E` and `gap.R`.
|
||||
# what this repo can evidence today. E is deliberately declared lower than the
|
||||
# mechanism in place because the adversarial artifact is still absent.
|
||||
|
||||
schema_version: "0.1"
|
||||
framework: netkingdom-tenancy-posture
|
||||
service: audit-core
|
||||
role: tenant-audit-service
|
||||
|
||||
tenancy:
|
||||
reviewed: "2026-08-17"
|
||||
review_due: "2027-02-17"
|
||||
service_class: batch # §8.3.2. Co-resident with latency-critical
|
||||
# tenant-engine on platform-pg; the mixture is
|
||||
# reported by the platform, not hidden.
|
||||
|
||||
current: { I: 1, A: 2, E: 1, P: 1, R: 1 }
|
||||
target: { I: 1, A: 2, E: 3, P: 1, R: 2 }
|
||||
current: { I: 1, A: 2, E: 1, P: 1, R: 2, V: 0 }
|
||||
implemented: { E: 2 }
|
||||
target: { I: 1, A: 2, E: 3, P: 1, R: 2, V: 1 }
|
||||
|
||||
# §5.2 — declare per path, quote the minimum. The quoted E above is the
|
||||
# minimum across paths. As of AUDIT-WP-0008-T04 both paths carry the same
|
||||
|
|
@ -70,14 +77,6 @@ tenancy:
|
|||
functional indexes built on non-leakproof functions. E4 is unreachable at
|
||||
P1 by the §3.2 coupling and is not a target.
|
||||
|
||||
R: >-
|
||||
R1 today: the platform default 30-day window applies and audit-core has
|
||||
declared nothing above it. R2 is requested and in flight — audit-core has
|
||||
asked rapp-postgres to add `backupRetentionDays: 30` to
|
||||
consumers/audit-core.yaml, making the window declared rather than
|
||||
inherited. That file is rapp-postgres's, so R2 is not audit-core's to
|
||||
declare unilaterally. The erasure horizon is published on /readyz as
|
||||
recoverable_days.
|
||||
R_ceiling: >-
|
||||
R4 is unreachable under the current design and is not a target. Per
|
||||
Decision 4.5.3 — which this repo found — the hash chain commits to a
|
||||
|
|
@ -104,30 +103,46 @@ tenancy:
|
|||
data.archive provision is procured by then, audit-core reopens placement
|
||||
under the §4.5 retention trigger, with P2 as the fallback — a worse answer
|
||||
than archive, named now so it is not improvised later.
|
||||
V: >-
|
||||
No exercise establishes restart recovery for the complete audit path.
|
||||
V1 is the target; replica count or Kubernetes restart policy is not
|
||||
treated as evidence.
|
||||
|
||||
# §5.5 — audit-core provisions operations.audit to senders, so it declares
|
||||
# what it makes reachable for a consumer's audit trail, not only where it
|
||||
# sits. A sender's tenant separation inside the trail is audit-core's to
|
||||
# enforce; the sender cannot reach a level this service does not offer.
|
||||
provides:
|
||||
capability: operations.audit
|
||||
profile: administrative
|
||||
reachable:
|
||||
E2: >-
|
||||
Reachable now. A sender credential is bound to the tenants it may write
|
||||
for and, if it may read, to the tenants it may read back.
|
||||
E3: >-
|
||||
Not reachable yet. Requires rapp-postgres's ADR-0003 GUC contract
|
||||
applied to the audit_core schema. Targeted 2027-03-31.
|
||||
E4: >-
|
||||
Unreachable. One database, one runtime credential, no per-tenant
|
||||
credential and no per-tenant substrate. A sender needing a structural
|
||||
guarantee that another tenant cannot reach its audit records cannot get
|
||||
it here, and should be told so rather than sold E2 in E4's language
|
||||
(§11.4).
|
||||
R2: >-
|
||||
Reachable once the declared window lands; the horizon is already
|
||||
published on /readyz.
|
||||
R4: >-
|
||||
Unreachable by design, per R_ceiling above. A consumer with a verified
|
||||
erasure obligation over its audit trail cannot discharge it here.
|
||||
provider:
|
||||
capability: operations.audit
|
||||
profile: administrative
|
||||
axes:
|
||||
E:
|
||||
available: 2
|
||||
maximum: 3
|
||||
conditions:
|
||||
- "E3 requires rapp-postgres ADR-0003 applied to audit_core and its EXPLAIN probe."
|
||||
- "E4 is unreachable at P1 with one runtime credential."
|
||||
evidence:
|
||||
- "audit_core/ingestion.py"
|
||||
- "tests/test_ingestion.py"
|
||||
R:
|
||||
available: 2
|
||||
maximum: 2
|
||||
conditions:
|
||||
- "R4 is unreachable while the integrity chain commits to cleartext hashes."
|
||||
evidence:
|
||||
- "rapp-postgres/consumers/audit-core.yaml"
|
||||
- "audit_core/interface.py"
|
||||
V:
|
||||
available: 0
|
||||
maximum: 1
|
||||
conditions:
|
||||
- "Exercise restart recovery across audit-core, platform-pg and OpenBao."
|
||||
|
||||
evidence:
|
||||
A2:
|
||||
- "audit_core/ingestion.py"
|
||||
- "tests/test_ingestion.py"
|
||||
E1:
|
||||
- "audit_core/postgres_backend.py"
|
||||
- "tests/test_backend_conformance.py"
|
||||
P1: "rapp-postgres/docs/evidence/isolation-2026-08-10.md"
|
||||
R2:
|
||||
- "rapp-postgres/consumers/audit-core.yaml"
|
||||
- "tests/test_interface.py"
|
||||
|
|
|
|||
|
|
@ -22,8 +22,18 @@ Answer the `rapp-postgres` review request against NetKingdom Tenancy Posture
|
|||
v0.1, declare an accurate posture vector, and close the one gap the assessment
|
||||
exposed in running code.
|
||||
|
||||
Canonical framework: `net-kingdom/canon/standards/tenancy-posture_v0.1.md`
|
||||
(rendered copy in `policy-nexus/build/tenancy-posture.html`).
|
||||
Canonical framework: `net-kingdom/canon/standards/tenancy-posture_v0.1.md`,
|
||||
published by `policy-nexus` at `policy.coulomb.social`.
|
||||
|
||||
> **Framework moved twice under this workplan.** The assessment below was made
|
||||
> against **draft-5**; the framework is now at **draft-8**. The assessment still
|
||||
> holds — no finding was reversed — but three things changed underneath it:
|
||||
> `R` moved 1 → 2 once `rapp-postgres` declared the window, a sixth axis **V
|
||||
> (availability)** appeared that we had no position on, and the
|
||||
> implemented-versus-evidenced distinction we used informally for `E` became a
|
||||
> schema field. `tenancy.yaml` tracks draft-8 and validates clean against
|
||||
> `net-kingdom/tools/tenancy-posture/validate.py`. T07 and T08 exist because of
|
||||
> draft-8, not because of the original review.
|
||||
|
||||
## Assessment — what the ladders say about us
|
||||
|
||||
|
|
@ -331,20 +341,24 @@ status: todo
|
|||
priority: high
|
||||
state_hub_task_id: "0003954e-5033-457f-b9aa-97efdefe9beb"
|
||||
```
|
||||
Answer question 11 in `docs/erasure-and-audit.md`: the fact/payload split, the
|
||||
encrypt-then-hash constraint, the confirmation-oracle finding, and the R2-not-R4
|
||||
target. Record as an audit-core position; send the §4.5 condition to NetKingdom
|
||||
as a framework amendment.
|
||||
Answer question 11 in `docs/erasure-and-audit.md`.
|
||||
|
||||
**Name the legal dependency explicitly and route it.** The document must state
|
||||
that declining to build erasure rests on audit evidence being exempt under legal
|
||||
obligation or legitimate interest, that this is a legal conclusion, and that no
|
||||
one in the estate is recorded as having reached it. Route that question to
|
||||
`the-custodian` for an owner rather than closing it here — audit-core is not
|
||||
competent to answer it and should not appear to have. The position is publishable
|
||||
with the dependency open; it is not publishable with the dependency hidden.
|
||||
**Reduced by draft-8.** The framework half is already resolved upstream: the
|
||||
confirmation-oracle finding landed as **Decision 4.5.3**, and §19.11 is now
|
||||
marked *framework resolved*, recording that audit-core targets R2 and is
|
||||
explicitly not a fleet R4 target. There is no amendment left to send. What
|
||||
remains is audit-core's own position document — the fact/payload split, the
|
||||
encrypt-then-hash constraint, why the retained cleartext hash defeats key
|
||||
destruction, and the R2 ceiling — so the reasoning lives in this repo rather
|
||||
than only in someone else's canon.
|
||||
|
||||
**Route the legal question to `risk-nexus`, not `the-custodian`.** §19.11 ends
|
||||
"the legal basis for retaining audit facts remains a risk/legal question outside
|
||||
this framework", and `policy-nexus` INTENT records that judging what an external
|
||||
rule demands of the estate moved to `risk-nexus` on 2026-08-17. That is the
|
||||
owner. The position is publishable with the dependency open; it is not
|
||||
publishable with the dependency hidden.
|
||||
|
||||
```task
|
||||
id: AUDIT-WP-0008-T04
|
||||
status: done
|
||||
priority: high
|
||||
|
|
@ -375,9 +389,65 @@ status: todo
|
|||
priority: medium
|
||||
state_hub_task_id: "ed58ca37-755b-4284-b1ac-2a02baaceb21"
|
||||
```
|
||||
Send the five framework review findings to `net-kingdom` (owner of the canon
|
||||
path) and `policy-nexus` (owner of the rendered copy), as a §20.2 review
|
||||
response rather than as objections.
|
||||
Close the review loop with `net-kingdom`.
|
||||
|
||||
**Mostly overtaken.** All five findings were adopted across draft-7 and draft-8,
|
||||
and the two stale status lines this task was going to flag are already fixed.
|
||||
Nothing is outstanding as a *finding*.
|
||||
|
||||
What remains is confirmation rather than argument: acknowledge the adoptions,
|
||||
confirm the §5 worked example `I1 A2 E1 P1 R2 V0` is accurate as written, and
|
||||
state that `tenancy.yaml` validates clean against
|
||||
`tools/tenancy-posture/validate.py`. Flag one thing forward — the E line becomes
|
||||
wrong the day T05 lands, and under Decision 6.1 an *upgrade* has no notification
|
||||
duty, so the correction is ours to send unprompted or it will simply sit stale.
|
||||
|
||||
```task
|
||||
id: AUDIT-WP-0008-T07
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
Reach **V1** on the availability axis, new in draft-8.
|
||||
|
||||
We declared `V0` because nothing exercises restart recovery for the complete
|
||||
audit path. §13's V1 row asks for three things and they are all mechanical:
|
||||
critical dependencies enumerated, restart/recreate recovery exercised, and the
|
||||
interruption plus measured recovery time recorded. Decision 4.6.1 makes V
|
||||
end-to-end, so the enumeration must include `platform-pg` and the credential
|
||||
path — a receiver that restarts in 5s over a database that takes 90s is not V1
|
||||
at 5s.
|
||||
|
||||
The 2026-08-16 reboot walk in the operator runbook is close but is not this: it
|
||||
observed ~40s of unreadiness after a node reboot, without enumerating the
|
||||
dependency set or recording a measured recovery time as an exercise. Decision
|
||||
4.6.1 is explicit that a replica count or a status page is not evidence.
|
||||
|
||||
Write the exercise procedure and the dependency enumeration here; the exercise
|
||||
itself runs against railiance01 and needs a live window.
|
||||
|
||||
```task
|
||||
id: AUDIT-WP-0008-T08
|
||||
status: todo
|
||||
priority: high
|
||||
```
|
||||
Disclose the shared-substrate retention coupling in our **provider** block, and
|
||||
notify `user-engine` under Decision 6.1.
|
||||
|
||||
Two defects in our own declaration, both found by reading draft-8 back against
|
||||
`tenancy.yaml`:
|
||||
|
||||
- **`provider.R.available: 2` is misleading as written.** It tells a sender it
|
||||
gets a 30-day horizon. At P1 the horizon is the *instance maximum* across
|
||||
co-residents (§4.5), so a co-resident declaring longer silently extends what
|
||||
we hand our senders. Decision 4.5.4 makes exactly this the reason a bare `R2`
|
||||
minimum is insufficient. We are not a tier, but we are a provider quoting a
|
||||
number we do not solely control, and the provider block must say so.
|
||||
- **Our consumers were never told.** Decision 6.1: updating `tenancy.yaml`
|
||||
without notifying dependants is declaration drift, not a completed change.
|
||||
`user-engine` is the only sender and has not been told that `E4` and `R4` are
|
||||
unreachable here, nor that current `E` is 1. This is not a downgrade — it is a
|
||||
first accurate declaration replacing someone else's generous guess — but the
|
||||
notification duty is the same and the guess was public.
|
||||
|
||||
## Done when
|
||||
|
||||
|
|
@ -390,4 +460,9 @@ response rather than as objections.
|
|||
- The §5 worked example for `audit-core` is corrected upstream.
|
||||
- Two dates are recorded and monitored per §8.1 rather than merely written:
|
||||
`data.archive` review 2026-12-31, E3 target 2027-03-31.
|
||||
- The erasure legal question has an owner outside audit-core.
|
||||
- The erasure legal question has an owner outside audit-core (`risk-nexus`).
|
||||
- `tenancy.yaml` validates clean against the normative validator, and keeps
|
||||
doing so as the framework revises.
|
||||
- V1 is evidenced by an exercise, not asserted from a restart policy (T07).
|
||||
- The provider block discloses what it does not solely control, and every
|
||||
consumer of `operations.audit` has been told what it declares (T08).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue