Tenancy Posture §8.3: service class, and why there is no QoS axis
Question 12 asked whether to add a quality-of-service dimension. No - because we could not enforce it. Community PostgreSQL has no resource governor, so a declared priority would be an unenforced claim in a declaration, which is what retiring tenantIsolation was about. An axis implies graduation and enforcement and this has neither. Co-residents are equal, and a consumer whose latency cannot survive an unprioritised neighbour escalates to P2. Service class is still declared, as a category not a level: it informs placement, acts as a trigger, and gives "acceptable degradation" in the noisy-neighbour artifact something to be acceptable relative to - what batch tolerates is an outage for latency-critical. Class mixture must be visible, because an unenforceable risk nobody can see is worse than one that is stated. rapp-postgres now reports it and the live instance already flags latency-critical beside batch. Gateway-level prioritisation in a connection proxy is recorded as the known escalation short of P2 - real, and infrastructure we do not run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
101e659725
commit
e25545d9d0
1 changed files with 50 additions and 8 deletions
|
|
@ -457,6 +457,51 @@ in a YAML comment nobody re-reads is documentation, not control.
|
|||
selection is a commercial decision as much as a technical one; an
|
||||
operations-shaped repo should not hold it alone.
|
||||
|
||||
### 8.3 Service class — a placement input, never a priority
|
||||
|
||||
A latency-critical consumer and a batch consumer can share an instance today
|
||||
with nothing distinguishing them. `tenant-engine` sits on `flex-auth`'s
|
||||
synchronous authorization path and chose a 5s statement timeout for that
|
||||
reason; `audit-core`, co-resident, is not latency-critical. Nothing prioritises
|
||||
between them.
|
||||
|
||||
**The framework does not add a QoS axis, because the platform cannot enforce
|
||||
one.** Community PostgreSQL has no resource governor: no per-role CPU or I/O
|
||||
priority, no resource queues, no workload classes. Those exist in EDB's
|
||||
enterprise variant, in Greenplum, and in SQL Server — not in what we run. A
|
||||
declared priority level would therefore be an unenforced claim sitting in a
|
||||
declaration, which is precisely what retiring `tenantIsolation` was about. An
|
||||
axis implies graduation and enforcement; this has neither.
|
||||
|
||||
**Decision 8.3.1 — co-residents are equal.** On shared substrate no consumer's
|
||||
query yields to another's. A consumer whose latency requirement cannot survive
|
||||
an unprioritised neighbour must escalate to `P2`. That is the honest mechanism
|
||||
and it is the only one we have.
|
||||
|
||||
**Decision 8.3.2 — service class is declared anyway**, as a category rather
|
||||
than a level: `latency-critical`, `interactive`, or `batch`. It buys three
|
||||
things, none of which is priority:
|
||||
|
||||
- **A placement input.** Mixing `latency-critical` with `batch` on one instance
|
||||
is a recognised mismatch. It may still be the right call — it is right today
|
||||
— but it should be a decision, not an accident of who was provisioned when.
|
||||
- **A trigger.** A `latency-critical` consumer acquiring a `batch` co-resident
|
||||
is a recorded placement trigger under §8, on the same footing as noisy
|
||||
neighbour.
|
||||
- **An acceptance criterion for evidence.** The noisy-neighbour artifact in §13
|
||||
asks whether measured degradation is *acceptable*; without a declared class
|
||||
that word has no referent. Degradation tolerable for `batch` may be an
|
||||
outage for `latency-critical`.
|
||||
|
||||
**Decision 8.3.3 — class mixture must be visible.** The platform reports which
|
||||
classes are co-resident. An unenforceable risk that nobody can see is strictly
|
||||
worse than one that is stated.
|
||||
|
||||
The known escalation short of P2 is gateway-level prioritisation — ordering
|
||||
submissions in a connection proxy by the requesting tenant's current
|
||||
consumption. It is real, it is where the industry puts this when it must, and
|
||||
it is new infrastructure we do not run. Recorded as the option, not adopted.
|
||||
|
||||
## 9. Credentials as a tenancy control
|
||||
|
||||
Short-lived leased credentials re-read at connection checkout, with
|
||||
|
|
@ -558,7 +603,7 @@ E2 evidence.**
|
|||
| **E3** | `FORCE ROW LEVEL SECURITY` on every tenant table; no `BYPASSRLS` on leased roles; probe that a session without the GUC reads nothing; probe that a wrong GUC reads nothing; `EXPLAIN` comparison | Mechanical |
|
||||
| **E4** | Per-tenant credential demonstrated unable to connect to another tenant's substrate | Mechanical |
|
||||
| **P1–P4** | Provisioning declaration plus the platform's isolation probes | Mechanical |
|
||||
| **P1–P2 (noisy neighbour)** | A recorded baseline of per-consumer resource usage; a run in which one consumer saturates its declared allowance; evidence that the governance controls **bind** (the greedy consumer is held at its limits) and that the degradation co-residents experience is **measured, recorded and judged acceptable**; the aggregate headroom at time of measurement | **Adversarial**, load-generated, with a review date |
|
||||
| **P1–P2 (noisy neighbour)** | A recorded baseline of per-consumer resource usage; a run in which one consumer saturates its declared allowance; evidence that the governance controls **bind** (the greedy consumer is held at its limits) and that the degradation co-residents experience is **measured, recorded and judged acceptable against each one's declared service class** (§8.3); the aggregate headroom at time of measurement | **Adversarial**, load-generated, with a review date |
|
||||
| **R2** | Declared retention rendered; erasure horizon published and reported in the operator surface | Mechanical |
|
||||
| **R3** | Sweep evidence records: timestamp, dataset, identifiers removed, authorising policy reference | Mechanical |
|
||||
| **R4** | Erasure demonstrated across live data, backups and derived copies within the horizon | **Adversarial** |
|
||||
|
|
@ -778,13 +823,10 @@ minimum-level vocabulary alongside isolation.
|
|||
*personal payload*, encrypted per subject and shreddable. Raised because a
|
||||
naive "R4 everywhere" target would instruct the audit service to destroy
|
||||
its own evidence. The answer is `audit-core`'s, not this framework's.
|
||||
12. **Quality of service** — *owner needed.* The framework has no vocabulary
|
||||
for saying one consumer's latency matters more than another's.
|
||||
`tenant-engine` sits on `flex-auth`'s synchronous authorization path and
|
||||
chose a 5s statement timeout for that reason; it shares an instance with
|
||||
`audit-core`, which is not latency-critical. Nothing prioritises between
|
||||
them. Either add a QoS dimension or state that all co-residents are equal
|
||||
and latency-critical consumers must escalate to P2.
|
||||
12. **Quality of service** — **resolved 2026-08-17.** Co-residents are equal;
|
||||
a declared *service class* informs placement but never grants priority.
|
||||
See §8.3. The question asked whether to add a QoS dimension; the answer is
|
||||
no, and the reason is that we could not enforce one.
|
||||
|
||||
**Routed elsewhere, deliberately.** The tenant identifier
|
||||
`tenant:<grouping>:<name>` embeds headcount bands (`small`, `medium`, `large`)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue