2026-08-17 18:09:28 +02:00
|
|
|
|
---
|
|
|
|
|
|
id: RPF-WP-0018
|
|
|
|
|
|
type: workplan
|
|
|
|
|
|
title: "Align S3 with the estate policy surface (Tenancy Posture + policy-nexus)"
|
|
|
|
|
|
domain: financials
|
|
|
|
|
|
repo: railiance-platform
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: active
|
2026-08-17 18:09:28 +02:00
|
|
|
|
owner: codex
|
|
|
|
|
|
topic_slug: railiance
|
|
|
|
|
|
created: "2026-08-17"
|
|
|
|
|
|
updated: "2026-08-17"
|
|
|
|
|
|
related:
|
|
|
|
|
|
- POLICY-NEXUS-WP-0001
|
|
|
|
|
|
- TEN-WP-0009
|
|
|
|
|
|
- RAPP-POSTGRES-WP-0002
|
|
|
|
|
|
origin: routed
|
|
|
|
|
|
origin_ref: "net-kingdom/canon/standards/tenancy-posture_v0.1.md §19.2, §20"
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_workstream_id: "d40827cb-bb48-4cdd-9b41-8dfae116d705"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# RPF-WP-0018 — policy surface alignment
|
|
|
|
|
|
|
|
|
|
|
|
## Goal
|
|
|
|
|
|
|
|
|
|
|
|
Answer the two policy asks that landed on this repo, accept what fits,
|
|
|
|
|
|
push back on what does not, and leave behind artifacts that are checkable
|
|
|
|
|
|
rather than a promise to be good.
|
|
|
|
|
|
|
|
|
|
|
|
Done means: this repo has published a posture declaration, has accepted or
|
|
|
|
|
|
declined placement ownership in writing, has told its consumers their
|
|
|
|
|
|
quotas, and has answered `policy-nexus` on the one assignment in
|
|
|
|
|
|
`POLICY-NEXUS-WP-0001` that contradicts the OAS stack.
|
|
|
|
|
|
|
|
|
|
|
|
## Where the policy comes from
|
|
|
|
|
|
|
|
|
|
|
|
Two documents, from two owners, arriving in the same week.
|
|
|
|
|
|
|
|
|
|
|
|
1. **`net-kingdom/canon/standards/tenancy-posture_v0.1.md`** (draft-5,
|
|
|
|
|
|
proposed, reviewed by nobody). Routed by `rapp-postgres` on 2026-08-17
|
|
|
|
|
|
(message `d9da7d11`), foreshadowed by `tenant-engine` on 2026-08-16
|
|
|
|
|
|
(message `31aed179`). It asks this repo, **co-signed with
|
|
|
|
|
|
`adaptive-pricing`**, to own database placement policy — §8.2, §19.2 —
|
|
|
|
|
|
and to publish its own posture vector as the ratification test (§20.2).
|
|
|
|
|
|
2. **`policy-nexus/workplans/POLICY-NEXUS-WP-0001`** (proposed). It
|
|
|
|
|
|
assigns this repo the *substrate* for `policy.coulomb.social` — DNS,
|
|
|
|
|
|
TLS, ingress, hosting — and includes this repo in the ~68-ADR corpus it
|
|
|
|
|
|
intends to publish from `docs/adr/*.md`.
|
|
|
|
|
|
|
|
|
|
|
|
Both are drafts. Neither is ratified. Accepting them now is cheaper than
|
|
|
|
|
|
accepting them later, because both are still willing to change.
|
|
|
|
|
|
|
|
|
|
|
|
## What actually applies to us, and what does not
|
|
|
|
|
|
|
|
|
|
|
|
**Applies, and fits.** The placement ladder (P0–P4) describes our estate
|
|
|
|
|
|
accurately: `apps-pg` is a P1 shared cluster, `user-engine-pg` and
|
|
|
|
|
|
`target-revenue-pg` are P2. The §10.2 quota-disclosure obligation lands on
|
|
|
|
|
|
a document we already maintain, `docs/s3-consumer-interfaces.md`. The §9.1
|
|
|
|
|
|
ban on static long-lived database credentials is already how the credential
|
|
|
|
|
|
broker works. Nothing in the ladder requires us to move a single workload.
|
|
|
|
|
|
|
|
|
|
|
|
**Applies, but we cannot satisfy it yet.** §8.1 says placement triggers
|
|
|
|
|
|
MUST be *monitored*, not merely recorded. This repo has no monitoring
|
|
|
|
|
|
plane. `SCOPE.md` states we emit to `railiance-telemetry` "once the
|
|
|
|
|
|
evidence plane exists — seeded 2026-08-11, not yet implemented". Claiming
|
|
|
|
|
|
monitoring we do not have is the exact overclaim §6 prohibits, so T03
|
|
|
|
|
|
records each trigger with a named monitor or an explicit `unmonitored`
|
|
|
|
|
|
marker, and the marker is the honest answer until telemetry lands.
|
|
|
|
|
|
|
2026-08-17 21:55:11 +02:00
|
|
|
|
**Does not fit, and the policy should change.** Five findings, T07.
|
2026-08-17 18:09:28 +02:00
|
|
|
|
|
|
|
|
|
|
## Findings against the policy (recommendations, not yet routed)
|
|
|
|
|
|
|
|
|
|
|
|
**F1 — `POLICY-NEXUS-WP-0001` assigns S3 a concern S3 does not own.**
|
|
|
|
|
|
It states "`railiance-platform` owns the substrate — DNS, TLS, ingress,
|
|
|
|
|
|
hosting". Per `SCOPE.md`, DNS and OS-level concerns are S1
|
|
|
|
|
|
`railiance-infra`, and Kubernetes ingress is S2 `railiance-cluster`;
|
|
|
|
|
|
S3 owns shared *platform services*. Accepting the assignment as written
|
|
|
|
|
|
would re-import the boundary violation that `RAIL-PL-WP-0001` and ADR-003
|
|
|
|
|
|
exist to prevent.
|
|
|
|
|
|
|
|
|
|
|
|
*Recommend:* split T04 of that workplan. Ingress and TLS to S2, DNS to S1
|
|
|
|
|
|
or the reef boundary, and the genuinely S3 parts — an object-storage bucket
|
|
|
|
|
|
for the static output if it wants one, plus any credential lane — stay
|
|
|
|
|
|
here. This repo can co-sign the deployment without owning the substrate.
|
|
|
|
|
|
Adjacent and unresolved: `railiance-master` asked us on 2026-08-15
|
|
|
|
|
|
(`ba477968`) to confirm `bao.coulomb.social` does not publish on
|
|
|
|
|
|
reef-railiance. A second public name on the same rail should go through
|
|
|
|
|
|
whatever answers that question, not around it.
|
|
|
|
|
|
|
|
|
|
|
|
**F2 — this repo's decisions are structurally unpublishable.**
|
|
|
|
|
|
`policy-nexus` publishes canon and ADRs only, globbing `docs/adr/*.md`.
|
|
|
|
|
|
This repo has **no `docs/adr/` directory and no ADRs**. Its load-bearing
|
|
|
|
|
|
decisions live either in `docs/` as prose without frontmatter (24 files,
|
|
|
|
|
|
no status, revision, review date or owner — the fields T02/T05 of the
|
|
|
|
|
|
publication workplan require) or in the State Hub via `record_decision()`,
|
|
|
|
|
|
which is a read model and is not a publication source. The estate's
|
|
|
|
|
|
standing rule is that local files are the source of truth; for decisions,
|
|
|
|
|
|
this repo does not follow it.
|
|
|
|
|
|
|
|
|
|
|
|
*Recommend:* not a mass conversion. T05 here promotes the small set that
|
|
|
|
|
|
is genuinely decisional — the boundary rules, the credential-lane model,
|
|
|
|
|
|
the consumption-mode gate — into ADR form with the frontmatter
|
|
|
|
|
|
`policy-nexus` needs. The runbooks stay prose and stay unpublished, which
|
|
|
|
|
|
is what that workplan's scope rule already wants.
|
|
|
|
|
|
|
|
|
|
|
|
**F3 — §19.8 asks this repo for a number that lives in another repo.**
|
|
|
|
|
|
Cell sizing wants `platform-pg`'s declared maximum size. That spec —
|
|
|
|
|
|
`instances: 1`, `max_connections: 100`, `1Gi` — is `rapp-postgres`'s
|
|
|
|
|
|
cluster CR, not ours; `RAILIANCE-WP-0012` and `RAILIANCE-WP-0015`
|
|
|
|
|
|
deliberately moved the deployable surface to the rapp repos while this repo
|
|
|
|
|
|
kept custody and policy. The split is right and the question is misrouted
|
|
|
|
|
|
by one hop.
|
|
|
|
|
|
|
|
|
|
|
|
*Recommend:* accept §8.2 with the scope stated — **this repo owns the rule,
|
|
|
|
|
|
`rapp-postgres` owns the number**. We declare *that* a ceiling must be
|
|
|
|
|
|
published and what happens at it; they declare what it is. Same shape for
|
|
|
|
|
|
§19.9's retention floor and ceiling. `rapp-postgres`'s own analysis already
|
|
|
|
|
|
concedes the point: memory probably binds before connections do, at roughly
|
|
|
|
|
|
10MB per backend, and that is an observation only the package owner can
|
|
|
|
|
|
make.
|
|
|
|
|
|
|
|
|
|
|
|
**F4 — the posture vector is service-shaped; this repo is a layer.**
|
|
|
|
|
|
§5 asks a *service* to state one level per axis. `railiance-platform` is an
|
|
|
|
|
|
OAS layer that holds custody of several services with different postures.
|
|
|
|
|
|
One vector for the repo would be an average, which is exactly the
|
|
|
|
|
|
inaccuracy §6 prohibits. §20.2 invites this: "if a repo cannot express
|
|
|
|
|
|
itself in these five ladders, the ladders are wrong and this document
|
|
|
|
|
|
changes, not the repo."
|
|
|
|
|
|
|
|
|
|
|
|
*Recommend:* a layer repo publishes a **vector set** — one per service it
|
|
|
|
|
|
has custody of — plus a statement of which it owns versus operates. T01
|
|
|
|
|
|
does that and routes the finding back to `net-kingdom` as the framework's
|
|
|
|
|
|
first real correction from review rather than from research.
|
|
|
|
|
|
|
2026-08-17 21:55:11 +02:00
|
|
|
|
Refined while writing T01: the sharper form of F4 is that **the five
|
|
|
|
|
|
ladders describe a consumer of storage, not a provider of it.** Every S3
|
|
|
|
|
|
service scores at or near zero on I, A and E for the same structural
|
|
|
|
|
|
reason — a storage or credential platform has no tenant dimension of its
|
|
|
|
|
|
own. The `openbao` E line is the demonstration: `E: 0` is literally correct
|
|
|
|
|
|
and actively misleading, because the mechanism in place is
|
|
|
|
|
|
credential-scoped structural separation, the machinery E4 describes,
|
|
|
|
|
|
pointed at a consumer boundary rather than a tenant one. Proposed remedy is
|
|
|
|
|
|
a **provider declaration** beside the consumer vector, stating per axis the
|
|
|
|
|
|
maximum level the platform makes reachable and what the consumer must do to
|
|
|
|
|
|
reach it. Offered as an addition, not a renumbering.
|
|
|
|
|
|
|
|
|
|
|
|
**F5 — `policy-nexus` T02/T05 cannot be built against the corpus as it
|
|
|
|
|
|
stands.** Measured across the workstation on 2026-08-17: **69 ADRs in 19
|
|
|
|
|
|
repos** — closely matching that workplan's "roughly 68 across 18" — of
|
|
|
|
|
|
which **21 carry YAML frontmatter**, **41 carry any status field**, and
|
|
|
|
|
|
**2 carry any notion of a review date**. T02 specifies a front-matter-driven
|
|
|
|
|
|
renderer taking title, status, revision and review date from the source; T05
|
|
|
|
|
|
requires every page to show status, revision and last-reviewed, with a
|
|
|
|
|
|
staleness marker once a review interval is exceeded. Against this corpus
|
|
|
|
|
|
that renderer has nothing to read for 48 of 69 documents, and the currency
|
|
|
|
|
|
half of the repo's purpose has data for 2.
|
|
|
|
|
|
|
|
|
|
|
|
*Recommend:* T03 of that workplan should treat frontmatter as an **ingestion
|
|
|
|
|
|
precondition**, not a rendering input — a document without the required
|
|
|
|
|
|
fields is reported as non-conformant and left unpublished, rather than
|
|
|
|
|
|
rendered with blanks or with dates the site inferred. Inferring them is the
|
|
|
|
|
|
failure mode that workplan already names as its top risk: the publication
|
|
|
|
|
|
becomes a second source of truth. The corollary is that policy-nexus needs
|
|
|
|
|
|
a conformance report aimed at source repos before it needs a site, and this
|
|
|
|
|
|
repo's `docs/adr/README.md` is one repo's answer to it.
|
|
|
|
|
|
|
2026-08-17 18:09:28 +02:00
|
|
|
|
## Boundaries
|
|
|
|
|
|
|
|
|
|
|
|
- No workload moves placement level in this workplan. Declaring where
|
|
|
|
|
|
things are is separate from changing where they are.
|
|
|
|
|
|
- No monitoring is built here. T03 records the gap; closing it belongs
|
|
|
|
|
|
with `railiance-telemetry`.
|
|
|
|
|
|
- Co-signature with `adaptive-pricing` is *requested*, not assumed. If they
|
|
|
|
|
|
decline, T02 records single ownership and says so.
|
|
|
|
|
|
- This repo does not amend NetKingdom canon. Findings are routed; the
|
|
|
|
|
|
standard's owner decides.
|
|
|
|
|
|
|
|
|
|
|
|
## Tasks
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: RPF-WP-0018-T01
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: done
|
2026-08-17 18:09:28 +02:00
|
|
|
|
priority: high
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_task_id: "ff392a23-e72a-4442-843f-929f218404ae"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
```
|
|
|
|
|
|
**Publish the S3 posture vector set.** Write `docs/tenancy-posture.md`:
|
|
|
|
|
|
one vector per service under S3 custody (`openbao`, `apps-pg`, and the
|
|
|
|
|
|
`rapp-postgres`-operated clusters we hold policy for), each with `current`,
|
|
|
|
|
|
`target`, `reviewed`, and a `gap` note per axis below target. State plainly
|
|
|
|
|
|
which services this repo *owns* and which it only holds *policy* for.
|
|
|
|
|
|
Route F4 to `net-kingdom` with the vector set as the evidence.
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: RPF-WP-0018-T02
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: done
|
2026-08-17 18:09:28 +02:00
|
|
|
|
priority: high
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_task_id: "962fc494-bb9b-4f67-8e5b-2ed88a670945"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
```
|
|
|
|
|
|
**Accept placement ownership, scoped.** Write `docs/placement-policy.md`:
|
|
|
|
|
|
adopt the P0–P4 ladder by reference (do not restate it — the canon copy is
|
|
|
|
|
|
the source), record the default (P1 for platform services), and record a
|
|
|
|
|
|
named **placement owner per workload** for every consumer on an S3-custody
|
|
|
|
|
|
cluster. State the F3 split explicitly: rule here, number in
|
|
|
|
|
|
`rapp-postgres`. Request `adaptive-pricing` co-signature; record the answer
|
|
|
|
|
|
either way.
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: RPF-WP-0018-T03
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: done
|
2026-08-17 18:09:28 +02:00
|
|
|
|
priority: medium
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_task_id: "f6f30233-3f6e-44a0-a644-7268f9d88f3c"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
```
|
|
|
|
|
|
**Make triggers monitorable or honestly unmonitored.** For each of the five
|
|
|
|
|
|
§8 triggers, record in `docs/placement-policy.md` what signal would fire it,
|
|
|
|
|
|
who reads that signal, and at what cadence — or the literal marker
|
|
|
|
|
|
`unmonitored: pending railiance-telemetry`. Include the §8.3.3 obligation:
|
|
|
|
|
|
report which service classes are co-resident. Today that is
|
|
|
|
|
|
`latency-critical` (`tenant-engine`) beside `batch` (`audit-core`) on
|
|
|
|
|
|
`platform-pg`, which becomes a stated risk rather than an invisible one.
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: RPF-WP-0018-T04
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: done
|
2026-08-17 18:09:28 +02:00
|
|
|
|
priority: medium
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_task_id: "8a3ce90b-8af2-4dcd-9a35-77025d2123f2"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
```
|
|
|
|
|
|
**Disclose quotas to consumers (§10.2).** Extend
|
|
|
|
|
|
`docs/s3-consumer-interfaces.md` to `1.1.0` — additive under its own
|
|
|
|
|
|
compatibility rule — adding per-interface connection limits, statement and
|
|
|
|
|
|
idle-transaction timeouts, and backup retention to `apps-pg.v1` and
|
|
|
|
|
|
`rapp-postgres.v1`. Add the standing obligation that a change to any of
|
|
|
|
|
|
these is announced to bound consumers, not discovered by them.
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: RPF-WP-0018-T05
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: done
|
2026-08-17 18:09:28 +02:00
|
|
|
|
priority: medium
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_task_id: "a6da631d-fa4e-4c2b-acc3-d3cf53cfb57f"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
```
|
|
|
|
|
|
**Create the ADR surface (F2).** Create `docs/adr/` with an ADR template
|
|
|
|
|
|
carrying the frontmatter `policy-nexus` T02/T05 consume: title, status,
|
|
|
|
|
|
revision, owner, last-reviewed, review interval. Promote the decisions that
|
|
|
|
|
|
are already load-bearing and already written down elsewhere — the S3
|
|
|
|
|
|
boundary rule, the credential-lane model, the consumption-mode gate,
|
|
|
|
|
|
and the outcome of T02 — into ADRs. Runbooks stay prose. State in each ADR
|
|
|
|
|
|
which hub `record_decision()` id it supersedes, so the hub stops being the
|
|
|
|
|
|
only home for a decision.
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: RPF-WP-0018-T06
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: done
|
2026-08-17 18:09:28 +02:00
|
|
|
|
priority: low
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_task_id: "99f2a4d8-b20c-4c43-8c94-0bc469bfcc46"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
```
|
|
|
|
|
|
**Answer §19.9 — retention floor and ceiling.** Decide whether
|
|
|
|
|
|
`backupRetentionDays` gets a platform minimum (so a consumer asking for one
|
|
|
|
|
|
day gets a validation error rather than a quiet disappointment) and a
|
|
|
|
|
|
maximum (so nobody exhausts the volume). Record the rule here; the
|
|
|
|
|
|
enforcing validator is `rapp-postgres`'s. Carry `rapp-postgres` ADR-0002's
|
|
|
|
|
|
consequence forward: on a shared cluster a consumer's erasure horizon is the
|
|
|
|
|
|
maximum declared across co-residents, so a shorter horizon is a P2 trigger.
|
|
|
|
|
|
|
|
|
|
|
|
```task
|
|
|
|
|
|
id: RPF-WP-0018-T07
|
2026-08-17 21:55:11 +02:00
|
|
|
|
status: progress
|
2026-08-17 18:09:28 +02:00
|
|
|
|
priority: high
|
2026-08-17 21:55:11 +02:00
|
|
|
|
state_hub_task_id: "b021fda3-23bd-4843-8d1b-983b6ec582b5"
|
2026-08-17 18:09:28 +02:00
|
|
|
|
```
|
|
|
|
|
|
**Route the findings.** Reply to `rapp-postgres` and `tenant-engine` with
|
|
|
|
|
|
T01/T02 outcomes and F3/F4. Reply to `policy-nexus` with F1 (substrate
|
|
|
|
|
|
misassignment, with the S1/S2 split recommended) and F2 (ADR surface now
|
|
|
|
|
|
being built, plus the hub-decisions gap). Reply to `railiance-master` on
|
|
|
|
|
|
`ba477968`, since a second public name on reef-railiance depends on the
|
|
|
|
|
|
same answer. Mark the routed messages read.
|
|
|
|
|
|
|
|
|
|
|
|
## Sequencing
|
|
|
|
|
|
|
|
|
|
|
|
T01 and T02 are the ratification inputs and go first; T07 cannot be
|
|
|
|
|
|
answered without them. T03 hangs off T02's document. T04 and T05 are
|
|
|
|
|
|
independent and can run any time. T06 is last and cheap.
|
|
|
|
|
|
|
|
|
|
|
|
Deliberately not blocking on ratification: this repo publishes its
|
|
|
|
|
|
declaration whether or not the standard is ratified, because §6 makes
|
|
|
|
|
|
accuracy the conformance test and an accurate declaration is useful even if
|
|
|
|
|
|
the ladders are later renumbered.
|
|
|
|
|
|
|
|
|
|
|
|
## Risks
|
|
|
|
|
|
|
|
|
|
|
|
**Accepting ownership of a policy we cannot enforce.** §8.1 monitoring is
|
|
|
|
|
|
the specific case. Mitigation is T03's explicit `unmonitored` marker — an
|
|
|
|
|
|
owner who says what is not covered still owns it usefully; one who implies
|
|
|
|
|
|
coverage does not.
|
|
|
|
|
|
|
|
|
|
|
|
**Scope creep into S1/S2.** F1 is the live instance. Mitigation is that
|
|
|
|
|
|
this workplan routes the finding and does not build the ingress.
|
|
|
|
|
|
|
|
|
|
|
|
**A declaration that goes stale the day it is written.** Mitigation is the
|
|
|
|
|
|
`reviewed:` date on the vector set and the review interval in the ADR
|
|
|
|
|
|
template — the same currency mechanism `policy-nexus` T05 will read.
|