T02-T04 were completed 2026-08-18; the draft-8 outcome section still said they were outstanding. Replies sent to railiance-platform (section 11 correction accepted; tier-P-floor trigger accepted as ours, narrowing our earlier blanket monitoring caveat) and tenant-engine (grouping unaffected, Q5 ownership agreed, plan-derived ceiling interface welcomed as new scope). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
395 lines
20 KiB
Markdown
395 lines
20 KiB
Markdown
---
|
||
id: ADAPTIVE-WP-0009
|
||
type: workplan
|
||
title: "Tenancy Posture alignment — tier assurance claims"
|
||
domain: financials
|
||
repo: adaptive-pricing
|
||
status: finished
|
||
owner: codex
|
||
topic_slug: helix-forge
|
||
created: "2026-08-17"
|
||
updated: "2026-08-18"
|
||
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-8),
|
||
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 own the typed tier constraints that `railiance-platform` reconciles during
|
||
placement (§8.2). The earlier standing co-signature proposal was declined and
|
||
is no longer the policy.
|
||
|
||
## 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-7 update (2026-08-17)
|
||
|
||
Draft-7 (`net-kingdom` commit `357109b`) applies three more reviews —
|
||
`audit-core`, `railiance-platform`, `flex-auth` — for eleven changes.
|
||
|
||
**Finding 6 is resolved. Withdraw it.** Decision 5.3 makes `n/a` an admissible,
|
||
conformant level, declared with a stated reason: "`P0` presupposes a database and
|
||
`R0` presupposes retained data". This is exactly what T01 needed and it arrived
|
||
from another repo's review. `tenancy.yaml` is also now the adopted convention for
|
||
the declaration (from `flex-auth`), carrying `current`, `target`, `reviewed`,
|
||
`gap`, `placement_exceptions`, `service_class`, per-path detail and — for a
|
||
provider — the §5.5 provider declaration. **T01 no longer proposes a format; it
|
||
fills in the one that exists.**
|
||
|
||
**Findings 1, 2, 3, 4, 5 and 7 all still stand, and there is a reason.** §11 is
|
||
byte-identical across drafts 5, 6 and 7. Four repos have now reviewed and none
|
||
touched it, because §11 is the commercial section and this repo owns it. Nobody
|
||
else was going to find these. That raises the priority of T06 rather than
|
||
lowering it.
|
||
|
||
**Every guessed posture has been too generous, on every repo that self-reported.**
|
||
`flex-auth` is `I1 A0 E2 P n/a R n/a` — `/v1/check` authenticates no caller, so
|
||
any workload with network reach can assert any subject and receive an
|
||
authoritative allow. `apps-pg` is `I0 A0 E0 P n/a R0`, where `R0` means no
|
||
backup configured at all. Combined with `tenant-engine` on SQLite, the
|
||
commercial read is blunt: **no tier can support an isolation, availability or
|
||
retention claim against the estate as it stands today.** Nothing is blocked
|
||
because nothing claims — but nothing is sellable either, and that is the fact a
|
||
tier author needs before drafting, not after.
|
||
|
||
**Providers declare separately now (§5.5).** A provider states what it *makes
|
||
reachable*; `apps-pg` provides `P1` while its own `P` is `n/a`. A tier's
|
||
guarantee therefore depends on two declarations, not one — the provider's
|
||
reachability and the consuming service's own level. T02's constraint artifact
|
||
must reference both or it will validate against half the picture.
|
||
|
||
## Draft-8 outcome (2026-08-17)
|
||
|
||
All six surviving findings were adopted, with one useful refinement to finding
|
||
4: no record is a copied derivative. The tier definition is authoritative for
|
||
its typed minimum and wording; the service declaration is authoritative for
|
||
current posture; the provider declaration is authoritative for available
|
||
infrastructure. Approval joins them and fails closed on stale or missing input.
|
||
|
||
The framework now has V0–V4 availability, sanctioned honest language for
|
||
E3/P2/R2/V1, an R-plus-P rule for retention promises, P2 or an enforceable
|
||
governor for performance-differentiated tiers, and downgrade propagation to
|
||
dependent tier owners. §8.2 records the declined co-signature and its typed
|
||
constraint replacement.
|
||
|
||
T01 is complete in root `tenancy.yaml`. It declares the local observatory at
|
||
I0/A0/E0 and P/R `n/a`, rather than using `n/a` to hide its unauthenticated
|
||
single-user HTTP surface. T06 is complete because the amendments are in
|
||
draft-8. T02–T04 were completed on 2026-08-18: the typed `assurance_claims`
|
||
block, the hard boundary constraint and the tier-definition approval gate are
|
||
all in place, with the suite green. No current model carries an assurance
|
||
claim, so the absence is a declared capability gap rather than a live
|
||
over-claim.
|
||
|
||
## 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 1–5 were raised against draft-5 and all still stand in draft-6.
|
||
Findings 6–7 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.~~ RESOLVED in draft-7**
|
||
by Decision 5.3 (`n/a` is a level, and it is conformant). Kept for the record.
|
||
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: done
|
||
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 datastore 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.
|
||
|
||
Completed in `tenancy.yaml`. P and R are `n/a` because there is no runtime
|
||
datastore. I/A/E/V are zero with reasons because the local observatory HTTP
|
||
surface exists and has no authentication, authorization, tenant enforcement or
|
||
availability position. A repo-level row of `n/a` would have concealed that
|
||
surface.
|
||
|
||
## Extend The Canonical Schema With Assurance Claims
|
||
|
||
```task
|
||
id: ADAPTIVE-WP-0009-T02
|
||
status: done
|
||
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,V}`), 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.
|
||
|
||
Completed 2026-08-18. `PricingModel.assurance_claims` is optional and defaults
|
||
to an empty tuple, preserving every existing silent tier. The validator checks
|
||
claim identity, kind, customer wording, typed in-range axis minima, delivering
|
||
service, evidence, erasure horizon and mechanism. The canonical shape and its
|
||
definition-time semantics are documented in `docs/PricingModelSchema.md`.
|
||
|
||
## Add Boundary-Engine Validation For Claims
|
||
|
||
```task
|
||
id: ADAPTIVE-WP-0009-T03
|
||
status: done
|
||
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.
|
||
|
||
Completed 2026-08-18. The hard `assurance-claims` boundary constraint is silent
|
||
for tiers without claims and produces axis- and section-specific failures for
|
||
the E4/P3 coupling, shared-substrate erasure horizons, R4 wording,
|
||
key-destruction language, performance governors and availability failure scope.
|
||
Focused and full-suite regression coverage is green.
|
||
|
||
## Gate Claims At Tier Definition
|
||
|
||
```task
|
||
id: ADAPTIVE-WP-0009-T04
|
||
status: done
|
||
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.
|
||
|
||
Completed 2026-08-18. `assess_tier_definition_assurance()` compares the new
|
||
tier definition with its previously approved definition and emits blocking
|
||
approval requirements only for added, changed or removed claims. Each gate
|
||
carries the claim's evidence reference. An unchanged definition proceeds, and
|
||
the API explicitly warns publication/campaign callers not to turn it into a
|
||
recurring gate.
|
||
|
||
## Answer Q5 And Q2
|
||
|
||
```task
|
||
id: ADAPTIVE-WP-0009-T05
|
||
status: done
|
||
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, retention and availability once T02/T03 land. V now supplies the
|
||
availability vocabulary; the typed mapping still waits on implementation.
|
||
`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. Decided 2026-08-17 by Bernd: decline the
|
||
signature, bind via artifact instead.**
|
||
|
||
adaptive-pricing publishes tier minimums as typed constraints (T02/T03) and asks
|
||
railiance-platform to validate placement against them. Ownership stays single;
|
||
the check runs every time rather than when someone remembers to route it. §8.2's
|
||
concern is right — placement decided purely on operational grounds does constrain
|
||
what can be sold — but a signature is the wrong instrument for a constraint that
|
||
is machine-checkable, and tier minimums are machine-checkable by construction.
|
||
|
||
**No interim veto.** A scoped veto was considered and dropped: its only purpose
|
||
would be protecting existing claim-bearing tiers, and there are none. Not being
|
||
live is what makes the direct move safe.
|
||
|
||
**Named revisit trigger** — if a tier carrying an isolation, availability or
|
||
retention claim is drafted before the constraint artifact lands, reopen this
|
||
decision rather than assume it. Declining must not be open-ended.
|
||
|
||
Accept the P ladder, the triggers and §8.1's monitoring obligation
|
||
unconditionally. Caveat to raise: §8.1 says triggers MUST be monitored and never
|
||
says by whom; if that defaults to adaptive-pricing it is a standing obligation on
|
||
a repo with no on-call. Propose it is railiance-platform's.
|
||
|
||
Reply on the State Hub to message `6d5293ca-4f69-46a6-a78e-b469e626b83d`.
|
||
|
||
Completed 2026-08-18. Q5 is implemented as the typed `assurance_claims`
|
||
artifact: adaptive-pricing owns the authoritative tier wording and minima;
|
||
tenant-engine owns assignment of a tenant to the tier id and does not copy the
|
||
terms; railiance-platform joins current service/provider declarations during
|
||
placement reconciliation. The current three Coulomb tiers remain explicitly
|
||
silent and therefore define no minima. Q2 remains declined: placement has one
|
||
owner and a machine-enforced artifact boundary, not a nominal co-signature.
|
||
railiance-platform owns trigger monitoring because adaptive-pricing has no
|
||
runtime/on-call surface. The implementation answer was sent on State Hub after
|
||
the full suite passed (54 tests).
|
||
|
||
## Contribute Framework Amendments Back
|
||
|
||
```task
|
||
id: ADAPTIVE-WP-0009-T06
|
||
status: done
|
||
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.
|
||
|
||
Completed in NetKingdom draft-8. All surviving findings were incorporated;
|
||
finding 6 remains withdrawn as resolved by draft-7.
|