tenant-engine/railiance/README.md
tegwick 6644ad8402
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 50s
Onboard tenant-engine to the staged-promotion contract
TEN-WP-0008. railiance/app.toml declares criticality=high, empty secrets,
isolated canary, and the live PostgreSQL digest as previous_stable.
Manifests render through kustomize (deploy/ and deploy/canary/). Stage 1
passed. Stage 2/3 Helm-only CLI gap requested as RAIL-BS-IN-0001 rather
than a dummy chart.

Assistant: grok
Assistant-Session: 01a04cea-e5e8-7081-a0fc-808ebbc35fa9
2026-08-29 14:51:27 +02:00

70 lines
2.7 KiB
Markdown

# Railiance staged promotion — tenant-engine
TEN-WP-0008 onboards this repo to `railiance.app.v1` without changing the
contract. Production is described, not redeployed.
## T02 decision: kustomize, not Helm, not a dummy chart
The schema accepts any stage `commands` and check `type`s including
`command` and `kubernetes`. This workload ships a multi-document
manifest, now rendered by `deploy/kustomization.yaml` (`kubectl apply -k
deploy/`). That is option 2 in TEN-WP-0008-T02: converting to kustomize is
cheap and matches the small-headless-service precedent
(`qonto-assistant`).
What the schema does **not** require, and what `bin/railiance
deploy|promote --apply` still requires, is a Helm chart plus
`values/stage3-production.yaml`. Plan mode of those commands fails closed
on "no Stage 2 helm check declared" / missing chart. That is a CLI gap,
not a missing field in `app.toml`. Per the workplan we do not paper over
it with a chart we would never apply. Requested of `railiance-bootstrap`
as `RAIL-BS-IN-0001`.
Stage commands in `app.toml` are therefore the kubectl invocations that
actually work against this shape. Stage 1 (`bin/railiance run`) validates
them by rendering both overlays locally.
## Canary
TEN-WP-0009 removed the ReadWriteOnce PVC and switched the Deployment to
`RollingUpdate`, so a second pod is storage-feasible. `canary_mode =
"isolated"` is a distinct Deployment/Service (`tenant-engine-canary`)
whose selector does not match the production Service. It does not take
`user-engine` traffic. Overlay: `deploy/canary/`.
## Recorded stable (T03)
`[stages.stage3].previous_stable` is the contract's copy of "what should
be running":
```
tenant-engine@sha256:a8e8086ffc5b772c1391b166f5e1884b90f7d327b152c205eceae129df555c24
```
That is the TEN-WP-0009 PostgreSQL runtime pin, the same digest
`deploy/base/tenant-engine.yaml` and `make verify-pin` use. Onboarding does
not ship a newer image.
## Rollback ladder
| Digest | Role |
| --- | --- |
| `a8e8086ffc…` | current stable (PostgreSQL) |
| `023ac49f5c…` | previous PostgreSQL image (leased-login ownership defect) |
| `7dc9d7bf1f…` | last SQLite/PVC image — **not** a rollback target after any PostgreSQL write |
Older TEN-WP-0007 pins (`44ca65f3…` / `08be0b1d…` / `2249e8c6…`) remain
the lifecycle/guardrail feature ladder: rolling past a pre-lifecycle
digest removes routes `user-engine` depends on.
## Secrets
`secrets.references = []` is deliberate. Postgres URL and flex-auth
caller token are projected by those platforms from OpenBao. This repo
does not catalogue them.
## Criticality
`high`. Argument is in `[app].description`. Not `critical`: not
internet-facing, holds no application secret, fail-closed on outage.
Not `medium`: flex-auth and key-cape are live consumers.