adaptive-pricing/workplans/ADAPTIVE-WP-0009-tenancy-posture-alignment.md
codex f759735aab
Some checks failed
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Has been cancelled
ADAPTIVE-WP-0009: record draft-6 review outcome
Draft-6 (net-kingdom 2744ce7) applies tenant-engine's review only; findings
1-5 all still stand. Adds two findings from draft-6 itself: off-ladder
notation (P-, R0/R1) with no declaration form, and no obligation to notify
dependent tiers when a delivering service downgrades its posture. Reframes
T06 to reuse draft-6's level-plus-named-exception grammar.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 21:52:15 +02:00

284 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: ADAPTIVE-WP-0009
type: workplan
title: "Tenancy Posture alignment — tier assurance claims"
domain: financials
repo: adaptive-pricing
status: proposed
owner: codex
topic_slug: helix-forge
created: "2026-08-17"
updated: "2026-08-17"
state_hub_workstream_id: "ac4f4540-75a1-4dbf-9cb7-57e5be97499f"
---
# Tenancy Posture alignment — tier assurance claims
Align `adaptive-pricing` with **NetKingdom Tenancy Posture v0.1**
(`net-kingdom/canon/standards/tenancy-posture_v0.1.md`, proposed / draft-5),
raised by `rapp-postgres` on 2026-08-17.
The framework names this repo in three places: publish a posture vector
(§20.2), map plan tiers to minimum levels jointly with `tenant-engine` (§19 Q5),
and co-sign placement policy ownership with `railiance-platform` (§8.2 / Q2).
## Position
**Nothing is blocked today.** All three models in
`projects/coulomb-pricing/data/pricing-models.json`
(`flat-899-eur-monthly`, `membership-plus-credits`, `membership-plus-overage`)
are silent on isolation, availability and retention. §11 constrains only tiers
that make such a claim, so the estate has no live over-claim to correct.
This workplan is therefore **preparatory guard-rail work**: build the ability to
express and validate an assurance claim *before* a tier is written that needs
one. It is deliberately additive — no existing catalog entry, schema consumer or
test changes meaning.
**The gap is structural, not editorial.** `PricingModel` today carries
`commitments` (untyped `kind`/`value`) and `eligibility` (free strings). Neither
can express "this tier requires `E3 P2 R2`", and `validate_pricing_model` has no
rule that would catch a tier claiming isolation it cannot evidence. §11.3
requires the mapping be "recorded once when the tier is defined" — this repo owns
tier definition, so this repo owns the recording surface.
## Draft-6 update (2026-08-17)
The framework moved to **draft-6** (`net-kingdom` commit `2744ce7`) after this
workplan was written. It applies `tenant-engine`'s review only; **none of the
five findings below are addressed yet**, which is expected — T05 has not replied.
Three things in draft-6 change how we should proceed:
**The ratification test is proven, not theoretical.** tenant-engine assessed
itself, could not express itself in three places, and the document changed —
§4.1, §4.4, §5.2 and a new E registry exception. T06 now has live precedent to
cite rather than an invitation in §20.2.
**Draft-6 establishes exactly the shape findings 1 and 3 need.** The new
**registry exception** (declare an E level plus a named list of tables excluded
because they are registries, not tenant data) and **Decision 5.2** (a level
reports the weakest surface, not the best) both work by *level plus a named,
reviewable exception*. That is the pattern to reuse when proposing an
availability floor and a retention P floor — an amendment consistent with the
document's own new grammar is far cheaper to land than a novel one.
**The delivering service got weaker, and that is a sellability fact.**
`tenant-engine` self-corrected from a guessed `I2 A3 E2 P1 R1` down to
`I1 A2 E2 P— R0/R1` — acting identity arrives in the request body, three read
routes are unauthorized including the one `flex-auth` calls for `aal2`-class
decisions, and it is still on SQLite. Consequence for this repo: **no tier
resting on tenant-engine can make an isolation claim of any kind today.**
Nothing is blocked, because no tier makes one — but this is the concrete reason
T02/T03 should land before a tier author assumes otherwise.
## Findings against the framework
Raised for amendment, not as blockers. Detail belongs in T06.
Findings 15 were raised against draft-5 and all still stand in draft-6.
Findings 67 are new, from draft-6 itself.
1. **Availability has no ladder.** §11.3 and Q5 both require an availability
claim to map to "a minimum level the delivering service actually holds", but
the five axes are I, A, E, P, R — none is availability. §17 concedes it: "an
availability floor belongs in §11's minimum-level vocabulary alongside
isolation." The requirement exists; the vocabulary does not. The availability
half of Q5 is **not answerable as written**.
2. **§11.4 prohibits without sanctioning an alternative.** An "another tenant
cannot reach your data" claim requires E4, and E4 requires P3 (§3.2) — a
dedicated cluster per tenant. Correct, but it makes the strongest claim the
most expensive one, which is exactly the commercial pressure that produces
the over-claim §11 guards against. A prohibition with no compliant wording
beside it gets routed around.
3. **A retention claim needs a P floor, not just an R level.** Under §4.5 a
consumer's erasure horizon is the maximum across co-residents, so a tier's
retention promise can be broken by onboarding an unrelated customer, with no
change to the tier or its holder. §18 routes this to the consumer review
checklist; it also needs to bind the tier side, as the E4/P3 coupling does.
4. **Authority direction between tier and service is unstated.** Q5 puts the
mapping in the tier definition; §5 puts `placement_exceptions` in the
service's posture vector — and its own example says "see adaptive-pricing tier
definition". Two records, no stated primacy, silent drift in both directions.
5. **§8.3.1 constrains pricing design directly.** Co-residents are equal and no
resource governor exists, so a performance-differentiated tier is unsellable
below P2. This is a pricing-model validation rule, not only an ops fact.
6. **Off-ladder notation appears in a worked example.** Draft-6 records
`tenant-engine` as `P—` (still on SQLite, below P0's meaning) and `R0/R1` (a
dual value). Neither is on any ladder. This is the same wall T01 hit from the
other side: the ladders have no way to say *not on this axis at all*, so the
first two repos to try both invented notation. Strengthens T01's proposed
`not-applicable` declaration form — it is now a demonstrated gap with two
independent instances, not a special plea from a design-time repo.
7. **`P—` is a sellability fact with no home.** A tier's minimum is only as good
as the delivering service's actual level, and draft-6 shows that level can be
revised *downward* by a self-report at any time. Nothing in §11 obliges a
service to notify the tiers that depend on it when its posture drops. A tier
recorded as conformant at definition time can silently become an over-claim
through no act of its own — the same coupling as finding 3, one layer up.
Propose: a posture downgrade (§6 permits them, declared) must notify the
owners of any tier whose recorded minimum it breaches.
## Publish The Repo Posture Vector
```task
id: ADAPTIVE-WP-0009-T01
status: todo
priority: high
state_hub_task_id: "870c32dc-89dd-415f-b45f-f9484dd5119b"
```
Publish `adaptive-pricing`'s posture vector per §5 / §20.2, declared in-repo
(Decision 5.1).
The honest answer is that the five ladders do not fit: this repo is a
design-time analysis and definition surface with **no runtime multi-tenant
datastore**. §3.3 scopes the P and R ladders to "a service's primary datastore";
adaptive-pricing has none. It does hold customer-attributable commercial data
(member ledgers, payment records, LTV scenarios) as repo JSON under the
Coulomb proving ground — which is a data-handling fact worth stating, and not a
tenancy posture.
Declare `not-applicable` per axis with reasoning rather than forcing a row of
zeros. §20.2 invites exactly this: "if a repo cannot express itself in these five
ladders, the ladders are wrong and this document changes, not the repo." Report
the finding as the framework asked to have it reported, and propose a
`no-runtime-datastore` declaration form so other design-time repos are not
pushed into a misleading `P0 R0`.
## Extend The Canonical Schema With Assurance Claims
```task
id: ADAPTIVE-WP-0009-T02
status: todo
priority: high
state_hub_task_id: "4420edb0-c9ea-4d2c-850e-2435cbd57f34"
```
Add an **optional** `assurance_claims` block to the canonical pricing schema
(`adaptive_pricing_core/pricing_models.py`, `docs/PricingModelSchema.md`).
Shape: claim kind (`isolation` | `availability` | `retention` | `performance`),
customer-facing wording, the minimum levels it requires
(`{I,A,E,P,R}` — plus availability once §11.3's vocabulary exists), the
delivering service, and an evidence reference.
Constraints:
- Optional and defaulted. Absent block = silent tier = unaffected, per §11.
- Typed, not free-text — the point is that a validator can read it.
- Records the *internal* minimum only. §11.2 leaves marketing language free;
the customer-facing wording field exists so the two can be checked against
each other, not so the ladder leaks into a price page.
- Do not extend `commitments` for this. A commitment is something the customer
owes; an assurance claim is something we owe them.
## Add Boundary-Engine Validation For Claims
```task
id: ADAPTIVE-WP-0009-T03
status: todo
priority: high
state_hub_task_id: "96c3340d-2429-4901-800c-2c7144ab14f4"
```
Extend `adaptive_pricing_core/boundary_engine.py` with explainable rules, in
keeping with the existing explainable-validation design:
- A claim present ⇒ minimum levels recorded and a delivering service named.
- "Cannot reach" isolation wording ⇒ `E4`, and `E4``P3` (§3.2, §11.4).
- Retention claim ⇒ an R level **and** a P floor sufficient for the promised
erasure horizon (finding 3). On shared substrate the horizon is not ours to
promise.
- "Deleted data is gone" ⇒ `R4`, or a disclosed erasure horizon (§11.4). Where
R4 is key-destroyed, the wording must not imply regulatory endorsement (§4.5).
- Performance-differentiated tier ⇒ `P2` or above (§8.3.1, finding 5).
Each failure must explain which axis and which framework section it answers to.
A validator that says "non-conformant" without naming the axis reproduces the
conflation §3 exists to end.
## Gate Claims At Tier Definition
```task
id: ADAPTIVE-WP-0009-T04
status: todo
priority: medium
state_hub_task_id: "9821bc6b-d8ec-41e2-b4ea-ebf1f2dc91a6"
```
Wire the claim check into `adaptive_pricing_core/governance.py` as an approval
requirement, so §11.3's "recorded once when the tier is defined" is a gate rather
than a convention. A tier acquiring or changing an assurance claim requires
human approval with the evidence reference attached — consistent with SCOPE's
rule that customer-visible pricing changes are never autonomous.
Explicitly **not** per-campaign review. §11.3 says the review happens at tier
definition; a gate that fires more often than that will be worked around.
## Answer Q5 And Q2
```task
id: ADAPTIVE-WP-0009-T05
status: wait
priority: high
state_hub_task_id: "3aa82ae3-4a79-4a18-a74e-668e94652ecd"
```
Blocked on T02/T03 for Q5, and on Bernd's decision for Q2.
**Q5 — tier → minimum level mapping,** jointly with `tenant-engine`. Answerable
for isolation and retention once T02/T03 land. **Not answerable for
availability** until finding 1 is resolved; say so rather than inventing a level.
`tenant-engine` owns which plan a tenant holds; this repo owns the terms — state
that split when replying so the seam is recorded.
**Q2 — placement co-signature.** Recommend **accepting, scoped**: co-signer means
a veto on placement policy changes that would invalidate an existing tier's
recorded minimum — not a seat in per-workload placement operations. §8.2's
reasoning holds and the stated alternative is real (placement decided purely on
operational grounds then constrains what can be sold), but unscoped co-signature
on an ops decision puts a commercial repo in a ticket queue. Bernd's call.
Reply on the State Hub to message `6d5293ca-4f69-46a6-a78e-b469e626b83d`.
## Contribute Framework Amendments Back
```task
id: ADAPTIVE-WP-0009-T06
status: todo
priority: medium
state_hub_task_id: "489cffb7-9ec3-4335-a93c-0b276a843f8d"
```
Submit the §"Findings" items to `net-kingdom` while v0.1 is still `proposed`.
**Frame them in draft-6's own grammar.** The registry exception and Decision 5.2
both work by *declared level plus a named, reviewable exception*, and draft-6
adopted tenant-engine's corrections wholesale because the ratification test said
it must. Amendments shaped like the ones already accepted will land; novel
structure will not. Cite `2744ce7` as precedent.
Proposed amendments:
- **An availability axis.** Prefer adding one over striking availability from
§11.3/Q5, because §17's "no P1 tenant has HA" is a hard sellability fact that
needs somewhere to live. Sketch: `V0` no position, `V1` restart recovery on a
single instance (what `platform-pg` is today), `V2` replicated failover,
`V3` multi-zone with declared RTO/RPO. Note the letter collision — `A` is
Authorization — which is itself a small argument the framework should settle
rather than inherit.
- **A sanctioned fallback phrasing in §11**, naming what P2/E3 honestly
delivers (noisy-neighbour behaviour, capacity predictability, an independent
restore path) so a tier author has a compliant thing to say and not only a
prohibition. This is the amendment most likely to prevent a real over-claim.
- **A Decision in §4.5** binding a retention claim to a P floor, as §3.2 binds
E4 to P3.
- **A primacy statement** for finding 4: the tier definition is authoritative
for the minimum; a service's `placement_exceptions` is derived and must
reconcile against it.
- **An off-ladder declaration form** covering both `no-runtime-datastore` (T01)
and draft-6's ad-hoc `P—` (finding 6). One notation, two instances already.
- **A downgrade-notification obligation** in §11 (finding 7): a declared posture
drop must reach the owners of any tier whose recorded minimum it breaches.
Route via `policy-nexus` if it owns canon publication; otherwise direct to
`rapp-postgres` as the raising agent and `net-kingdom` as canon owner.