These workplans exist only in the retired local hub. Their random pre-ADR-007 identifiers are refused by C-06 as stale references, so they cannot be registered. Deriving from the canonical record id takes no identity from anything: central does not hold them and the old ids die with the cache. Records central already holds were deliberately left untouched. Refs CUST-WP-0068-T06 Assistant: claude-code Assistant-Model: opus Assistant-Process: 2583210@bnt-lap001 Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
333 lines
16 KiB
Markdown
333 lines
16 KiB
Markdown
---
|
||
id: RPF-WP-0018
|
||
type: workplan
|
||
title: "Align S3 with the estate policy surface (Tenancy Posture + policy-nexus)"
|
||
domain: financials
|
||
repo: railiance-platform
|
||
status: finished
|
||
owner: codex
|
||
topic_slug: railiance
|
||
created: "2026-08-17"
|
||
updated: "2026-08-18"
|
||
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"
|
||
state_hub_workstream_id: "4fcb6026-2630-59a3-b5de-15f54efcf59d"
|
||
---
|
||
|
||
# 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.
|
||
|
||
**Does not fit, and the policy should change.** Five findings, T07.
|
||
|
||
## Findings against the policy (routed 2026-08-17, T07)
|
||
|
||
**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.
|
||
|
||
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.
|
||
|
||
## 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
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "88d1342b-5093-5fbc-aa84-1608d163b979"
|
||
```
|
||
**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
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "03f0a5bd-7876-5784-bf02-11cbcdf005bb"
|
||
```
|
||
**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
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "b602226f-8eb5-5609-995f-94f9074b0895"
|
||
```
|
||
**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
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "92ce14f6-afee-50f6-abd4-197c4724a589"
|
||
```
|
||
**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
|
||
status: done
|
||
priority: medium
|
||
state_hub_task_id: "58ef22f8-7f1b-5647-babd-eeb817b3ae31"
|
||
```
|
||
**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
|
||
status: done
|
||
priority: low
|
||
state_hub_task_id: "49c682a0-a9b7-59f0-ad65-79b4fb9bb79c"
|
||
```
|
||
**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
|
||
status: done
|
||
priority: high
|
||
state_hub_task_id: "ad7a159b-a395-50e0-a517-d605a1d70108"
|
||
```
|
||
**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.
|
||
|
||
## Closed 2026-08-18
|
||
|
||
All seven tasks done. What the workplan produced, and what it changed
|
||
elsewhere:
|
||
|
||
- `docs/tenancy-posture.md` + `tenancy.yaml` — the vector set, machine-readable
|
||
with the human reasoning kept beside it.
|
||
- `docs/placement-policy.md` — placement rule, owner per workload, triggers,
|
||
retention floor and ceiling.
|
||
- `docs/s3-consumer-interfaces.md` `1.1.0` — quota disclosure.
|
||
- `docs/adr/` — created from nothing; `ADR-0001`, `ADR-0002`, `ADR-0003`.
|
||
|
||
**Two findings were adopted upstream.** The provider-declaration proposal (F4,
|
||
narrowed) is in the framework and its canonical form is the `provider:` block
|
||
in `tenancy.yaml`. `adaptive-pricing` declined the standing co-signature and
|
||
supplied a stronger replacement — typed tier minima joined at tier definition —
|
||
which draft-8 adopted; `ADR-0002` records the outcome as single ownership plus
|
||
a mandatory typed constraint join, not as an absent signature.
|
||
|
||
**Three corrections were issued against our own output**, all in the same
|
||
direction — claiming levels we could not evidence. `openbao A: 2` retracted to
|
||
`A: 0`; the provider finding narrowed once §6's `flex-auth` precedent was read;
|
||
the §11 summary to `adaptive-pricing` corrected, since §11.2 keeps marketing
|
||
vocabulary free and only the *cannot-reach* claim is restricted, to E4. All
|
||
three are recorded in the documents rather than edited away.
|
||
|
||
**What this workplan deliberately did not do:** fix anything. It found that
|
||
`apps-pg` had no backup, no per-consumer controls and no isolation probes, and
|
||
published those as visible defects. `RPF-WP-0019` closes them.
|
||
|
||
**Left open, not owned here:** `bao.coulomb.social` still needs confirmation
|
||
against live reef state (`railiance-master` `ba477968`), and F1's substrate
|
||
split is with `policy-nexus` to act on.
|