RPF-WP-0018 T01-T06: publish S3 posture, placement policy, quotas, ADR surface
T01 docs/tenancy-posture.md - vector set per service rather than one repo vector, with the provider-versus-consumer finding routed to net-kingdom. T02/T03/T06 docs/placement-policy.md - accepts placement ownership scoped to rule-here/number-there, records a placement owner per workload, reports the latency-critical + batch co-residency on platform-pg, marks the connection-ceiling trigger unmonitored pending railiance-telemetry, and answers the retention floor/ceiling question. T04 s3-consumer-interfaces 1.1.0 - quota disclosure per SS10.2. Surfaces that apps-pg has no backup, no resource limits and no tuned parameters. T05 docs/adr/ created with a mandatory-frontmatter convention and the first three ADRs. This repo previously held none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b83194741d
commit
e7e4e33bb8
9 changed files with 809 additions and 12 deletions
67
docs/adr/ADR-0001-s3-platform-service-boundary.md
Normal file
67
docs/adr/ADR-0001-s3-platform-service-boundary.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
title: "ADR-0001 — S3 owns platform services, not the substrate beneath them"
|
||||
status: accepted
|
||||
revision: "1.0"
|
||||
owner: railiance-platform
|
||||
date: "2026-08-17"
|
||||
last_reviewed: "2026-08-17"
|
||||
review_interval: 12m
|
||||
---
|
||||
|
||||
# ADR-0001 — S3 owns platform services, not the substrate beneath them
|
||||
|
||||
## Context
|
||||
|
||||
`railiance-platform` is S3 on the OAS Stack: the shared services several
|
||||
applications depend on — PostgreSQL, secrets, cache, object storage. The layers
|
||||
around it are S1 `railiance-infra` (OS and host concerns), S2
|
||||
`railiance-cluster` (Kubernetes runtime, ingress), S4 `railiance-enablement`
|
||||
(tooling and CI), S5 `railiance-apps` (workloads).
|
||||
|
||||
This boundary has been stated in `SCOPE.md` and in ADR-003 of `railiance-infra`
|
||||
since the five-repo split, and it has been tested twice. `RAIL-PL-WP-0001`
|
||||
existed to extract platform services *out* of S2 subcharts. On 2026-08-17
|
||||
`POLICY-NEXUS-WP-0001` assigned this repo "the substrate — DNS, TLS, ingress,
|
||||
hosting" for `policy.coulomb.social`, which would move the boundary back the
|
||||
other way.
|
||||
|
||||
The pressure is predictable and will recur: S3 is the layer that looks like it
|
||||
owns infrastructure, because it owns things that feel infrastructural. Recording
|
||||
the rule as an ADR rather than as a line in `SCOPE.md` gives future requests
|
||||
something to be answered against.
|
||||
|
||||
## Decision
|
||||
|
||||
**S3 owns shared platform *services* and the interfaces consumers bind to. It
|
||||
does not own DNS, TLS, Kubernetes ingress, host configuration, or CI.** A
|
||||
request that would place any of those here is redirected to S1, S2 or S4 rather
|
||||
than absorbed, even when this repo is the closest available owner and even when
|
||||
absorbing it would be faster.
|
||||
|
||||
Where S3 has a genuine part in such a request — an object-storage bucket, a
|
||||
credential lane, a database — it supplies that part and co-signs the rest. It
|
||||
does not become the owner of the whole by being the first repo asked.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `POLICY-NEXUS-WP-0001` T04 needs splitting: ingress and TLS to S2, DNS to S1
|
||||
or the reef boundary, storage and credentials here. Routed as `RPF-WP-0018`
|
||||
finding F1.
|
||||
- A request this repo declines does not thereby become nobody's. Declining
|
||||
carries an obligation to name the owner, which is why F1 names two.
|
||||
- The rule cuts against this repo's convenience in the common case. That is
|
||||
what makes it a rule rather than a preference.
|
||||
- `rapp-openbao` and `rapp-postgres` are the same principle applied inward:
|
||||
the deployable package left, custody and policy stayed. See
|
||||
`docs/rapp-openbao-boundary.md` and `docs/rapp-postgres-boundary.md`.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Accept the substrate assignment as written.** Fastest, and the requester had
|
||||
already resolved it with the operator. Rejected: it re-imports the coupling
|
||||
`RAIL-PL-WP-0001` spent a workplan removing, and a boundary that yields to
|
||||
whoever asks most recently is not a boundary.
|
||||
|
||||
**Own ingress for S3-adjacent services only.** A narrower version, and it fails
|
||||
on the first argument about what counts as adjacent. The line has to be drawn
|
||||
where it can be checked.
|
||||
81
docs/adr/ADR-0002-placement-policy-ownership.md
Normal file
81
docs/adr/ADR-0002-placement-policy-ownership.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
---
|
||||
title: "ADR-0002 — S3 owns the placement rule; the package repo owns the number"
|
||||
status: proposed
|
||||
revision: "1.0"
|
||||
owner: railiance-platform
|
||||
date: "2026-08-17"
|
||||
last_reviewed: "2026-08-17"
|
||||
review_interval: 6m
|
||||
---
|
||||
|
||||
# ADR-0002 — S3 owns the placement rule; the package repo owns the number
|
||||
|
||||
## Context
|
||||
|
||||
`net-kingdom/canon/standards/tenancy-posture_v0.1.md` §8.2 proposes that
|
||||
database placement policy — dedicated versus shared, and when that changes —
|
||||
be owned by `railiance-platform`, co-signed by `adaptive-pricing`.
|
||||
`tenant-engine` raised the same gap independently on 2026-08-16: both patterns
|
||||
are live on railiance01, neither is written down, and each new service copies
|
||||
whichever neighbour it looked at.
|
||||
|
||||
The complication is that this repo no longer holds the specs. `RAILIANCE-WP-0012`
|
||||
and `RAILIANCE-WP-0015` moved the deployable surface to the `rapp-*` repos.
|
||||
`platform-pg`'s `instances`, `max_connections`, memory limit and retention are
|
||||
`rapp-postgres`'s cluster CR. Tenancy Posture §19.8 nonetheless asks *this repo*
|
||||
for `platform-pg`'s declared maximum size — a question one hop from where its
|
||||
answer lives.
|
||||
|
||||
Accepting ownership without stating this would produce either an answer we
|
||||
cannot substantiate or a quiet non-answer.
|
||||
|
||||
## Decision
|
||||
|
||||
**Accept placement ownership, split along rule and number.**
|
||||
|
||||
*This repo owns the rule:* the default placement level, what overrides it, who
|
||||
is accountable for each workload's placement, that a shared cluster must publish
|
||||
a ceiling and an overflow target before its third consumer, that retention has a
|
||||
floor and a ceiling, and that a consumer's erasure horizon on shared substrate
|
||||
is disclosed rather than inherited silently.
|
||||
|
||||
*The package repo owns the number:* what the ceiling actually is, which resource
|
||||
binds first, what the retention values are, and the validator that enforces them
|
||||
where the CR lives.
|
||||
|
||||
**Placement ownership per workload sits with the consuming repo; this repo
|
||||
co-signs.** The consumer knows its latency requirement, erasure horizon and
|
||||
compliance position; S3 knows the substrate. A placement change needs both.
|
||||
Putting the decision solely here would recreate the problem §8.2 exists to
|
||||
avoid — an operations-shaped repo holding a commercial decision alone.
|
||||
|
||||
`adaptive-pricing` co-signature is requested, not assumed.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `docs/placement-policy.md` is the operative document; this ADR is the
|
||||
decision behind it.
|
||||
- §19.8 is answered by obligation rather than by number: Rule P-4.1 requires
|
||||
`platform-pg` and `apps-pg` to declare a ceiling before their third consumer.
|
||||
Both are at two consumers.
|
||||
- This repo owes `apps-pg`'s ceiling under its own rule. A policy whose author
|
||||
is exempt is not a policy.
|
||||
- §8.1 requires triggers to be *monitored*. This repo has no monitoring plane,
|
||||
so the connection-and-memory-ceiling trigger is recorded `unmonitored`
|
||||
pending `railiance-telemetry`. Declaring a ceiling is a partial substitute —
|
||||
a written threshold is checkable by a human at provisioning, which beats a
|
||||
limit discovered by an OOM kill.
|
||||
- If `adaptive-pricing` declines, this ADR is revised to record single
|
||||
ownership explicitly rather than leaving an unsigned co-signature line.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Decline ownership; route it to `rapp-postgres`.** They hold the specs and the
|
||||
operational knowledge. Rejected: placement is a cross-cluster question and
|
||||
`rapp-postgres` owns one package. A policy owned by one substrate's operator
|
||||
cannot govern movement between substrates.
|
||||
|
||||
**Accept whole, including the numbers.** Rejected: it would either re-import
|
||||
the deployable surface this repo deliberately gave up, or produce numbers
|
||||
restated here that drift from the CR — a second source of truth for exactly the
|
||||
values a consumer must be able to trust.
|
||||
67
docs/adr/ADR-0003-decisions-live-in-the-repo.md
Normal file
67
docs/adr/ADR-0003-decisions-live-in-the-repo.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
title: "ADR-0003 — Decisions that bind others live in docs/adr, not only in the State Hub"
|
||||
status: accepted
|
||||
revision: "1.0"
|
||||
owner: railiance-platform
|
||||
date: "2026-08-17"
|
||||
last_reviewed: "2026-08-17"
|
||||
review_interval: 12m
|
||||
---
|
||||
|
||||
# ADR-0003 — Decisions that bind others live in `docs/adr`, not only in the State Hub
|
||||
|
||||
## Context
|
||||
|
||||
This repo recorded decisions with the State Hub's `record_decision()` and wrote
|
||||
governing content as prose in `docs/` — 24 files on 2026-08-17, none carrying a
|
||||
status, owner, revision or review date. It held no ADRs at all.
|
||||
|
||||
Two things made that a defect rather than a style.
|
||||
|
||||
**The hub is a read model.** The estate's standing rule is that local files are
|
||||
the source of truth and the hub reflects them. A decision that exists only as a
|
||||
hub record inverts that for the one class of content where it matters most.
|
||||
|
||||
**`policy-nexus` publishes canon and ADRs only**, globbing `docs/adr/*.md` from
|
||||
each repo. A repo with no ADRs is invisible to the estate's publication surface
|
||||
no matter how much governing content it holds. This repo owns S3 boundary
|
||||
rules, the credential-lane model and the consumption-mode gate — all binding on
|
||||
other repos, all unpublishable.
|
||||
|
||||
The gap was structural, not an oversight: nothing in the session protocol ever
|
||||
told anyone to write an ADR here.
|
||||
|
||||
## Decision
|
||||
|
||||
**A decision that binds anyone outside this repo is recorded as an ADR in
|
||||
`docs/adr/`, with the frontmatter in `docs/adr/README.md`, before or alongside
|
||||
any hub record.** The hub record points at the ADR; it does not replace it.
|
||||
|
||||
Runbooks and procedures stay as prose in `docs/` and stay unpublished. The test
|
||||
is not importance — several runbooks are critical — but whether the document
|
||||
*decides* something for someone else.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `docs/adr/` exists, with a convention, a template and this repo's first three
|
||||
ADRs.
|
||||
- Existing prose is not converted wholesale. Content is promoted when it is
|
||||
next touched, or when a consumer needs to cite it.
|
||||
- `last_reviewed` and `review_interval` are mandatory here, which is stricter
|
||||
than the estate norm — of 69 ADRs across 19 repos on 2026-08-17, 21 had YAML
|
||||
frontmatter and 2 had any notion of a review date. `POLICY-NEXUS-WP-0001` T05
|
||||
cannot compute staleness without those fields and must not invent them, since
|
||||
inventing them would make the publication a second source of truth, which is
|
||||
that workplan's own top risk. Routed as `RPF-WP-0018` finding F5.
|
||||
- Session protocol guidance should follow, so the next agent writes an ADR
|
||||
without being told. Not done in this ADR.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Keep decisions in the hub and have `policy-nexus` read it.** Rejected on
|
||||
both sides: it would make a read model authoritative, and it would give the
|
||||
publication surface a source that no repo can diff or review.
|
||||
|
||||
**Add frontmatter to all 24 existing `docs/` files.** Rejected. Most are
|
||||
runbooks that should not be published, and stamping them with a status would
|
||||
assert a decision that was never made.
|
||||
69
docs/adr/README.md
Normal file
69
docs/adr/README.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
---
|
||||
title: "ADR convention for railiance-platform"
|
||||
status: accepted
|
||||
revision: "1.0"
|
||||
owner: railiance-platform
|
||||
date: "2026-08-17"
|
||||
last_reviewed: "2026-08-17"
|
||||
review_interval: 12m
|
||||
---
|
||||
|
||||
# ADRs in this repo
|
||||
|
||||
Work record: `RPF-WP-0018` T05.
|
||||
|
||||
Until 2026-08-17 this repo held **no ADRs**. Its decisions lived either as
|
||||
prose in `docs/` without status or ownership, or in the State Hub via
|
||||
`record_decision()`. Both are wrong homes, for the same reason: the hub is a
|
||||
read model and prose is not addressable as a decision. `policy-nexus`
|
||||
publishes canon and ADRs only, so a repo with no ADRs publishes nothing —
|
||||
regardless of how much governing content it holds. See `ADR-0003`.
|
||||
|
||||
## What gets an ADR here
|
||||
|
||||
A decision gets an ADR when it **binds someone other than the person who made
|
||||
it** — another repo, a future maintainer, or a consumer of an S3 interface.
|
||||
|
||||
| Content | Home | Published |
|
||||
| --- | --- | --- |
|
||||
| A decision binding others | `docs/adr/` | yes |
|
||||
| A procedure someone follows | `docs/*.md` runbook | no |
|
||||
| Live interface values | `docs/s3-consumer-interfaces.md` | no |
|
||||
| Work sequencing | `workplans/` | no |
|
||||
|
||||
Runbooks stay prose deliberately. A site that publishes everything publishes
|
||||
nothing in particular, and `POLICY-NEXUS-WP-0001` T03 already draws that line.
|
||||
|
||||
## Frontmatter is mandatory
|
||||
|
||||
Every ADR carries the YAML block below. The fields are not decoration: they
|
||||
are exactly what `POLICY-NEXUS-WP-0001` T02 and T05 consume to render a page
|
||||
and to mark it stale.
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "ADR-NNNN — short imperative statement of the decision"
|
||||
status: proposed | accepted | superseded | withdrawn
|
||||
revision: "1.0"
|
||||
owner: railiance-platform
|
||||
date: "YYYY-MM-DD" # when decided
|
||||
last_reviewed: "YYYY-MM-DD"
|
||||
review_interval: 6m | 12m # after which the page shows as stale
|
||||
supersedes: ADR-NNNN # optional
|
||||
superseded_by: ADR-NNNN # optional
|
||||
---
|
||||
```
|
||||
|
||||
`last_reviewed` and `review_interval` are the two fields the rest of the estate
|
||||
mostly lacks — of 69 ADRs across 19 repos on 2026-08-17, 2 carried any notion
|
||||
of a review date. A publication surface cannot compute staleness without them
|
||||
and must not invent them, so they are required here.
|
||||
|
||||
Numbering is `ADR-NNNN`, four digits, never reused. A superseded ADR keeps its
|
||||
number and its file; it gains `superseded_by` and its status changes. Nothing
|
||||
is deleted — the published URL must keep resolving.
|
||||
|
||||
## Sections
|
||||
|
||||
Context · Decision · Consequences · Alternatives considered. Keep the decision
|
||||
statement to one paragraph a reader can quote.
|
||||
Loading…
Add table
Add a link
Reference in a new issue