7.8 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|
| TREV-WP-0011 | workplan | Deploy Trust Service and Control Plane to the Railiance reef | infotech | target-revenue | active | claude | infotech | 2026-07-30 | 2026-07-30 | f40fa906-9fbc-4445-9ebc-62ec46ac17b5 |
Deploy Trust Service and Control Plane to the Railiance reef
Deploy the hosted Trust Service (service/app.py, WP-0006) and the
Control Plane interactive UI (service/control_plane_app.py, WP-0009-T04)
to Railiance infrastructure-as-code, on a rail hosted in reef-railiance's
grouped home substrate, fronted by the subdomain revenue.coulomb.social.
This is an infrastructure delivery workplan, not a governance one: it does
not authorize a real Phase to go live for any repo. That gate remains
workplans/TREV-WP-0008-governance-and-pilot-rollout.md T05, independent
of whether the software is reachable at a public URL. The Control Plane UI
itself already carries this disclaimer in its footer
(service/control_plane_templates/base.html) and will continue to once
deployed.
Reference deployment: railiance-vergabe-teilnahme /
railiance-apps/charts/vergabe-teilnahme is the closest existing precedent
— a Django app, its own Postgres, a Helm chart living in railiance-apps,
an Ingress with cert-manager.io/cluster-issuer: letsencrypt-prod, and
runtime secrets via an ExternalSecret reading an OpenBao
ClusterSecretStore. issue-core is a second precedent using a different
pattern — its own repo carries k8s/railiance and an ArgoCD Application
points repoURL directly at that repo rather than at railiance-apps. T01
below has to pick between these two patterns (or a third) rather than
assume one.
id: TREV-WP-0011-T01
status: todo
priority: high
human_accept_required: true
state_hub_task_id: "8dffe5e1-6f2b-4020-ac07-a108a8fc2edc"
Decide the deployment pattern (human gate). Concretely:
- Manifest home: does
target-revenuecarry its ownk8s/railiancepath (likeissue-core) with an ArgoCDApplicationpointing straight at this repo, or does the Helm chart/Ingress/manifests live inrailiance-apps/charts/target-revenuealongsidevergabe-teilnahme(this repo's TRSL licensing and its being a monetization-framework repo, not an application repo, may argue for keeping deploy manifests out-of-tree)? - Process topology:
service/app.py(Trust Service) andservice/control_plane_app.py(Control Plane UI) are two separate FastAPIappobjects today, sharing the same Postgres and the same Ed25519 signing key. Deploy as two Deployments/Services behind one Ingress with path-based routing, or mount one inside the other (app.mount("/control-plane", control_plane_app)) into a single process/image? The latter needs a small code change (WP-0009-T04's Optional-Next-Step note flagged this as undecided); the former needs no code change but two sets of secrets/probes. - Database: a dedicated CNPG (
CloudNativePG)Clusterfor this workload's Postgres (matching thecnpg-option-a-*manifests already inrailiance-apps), sized appropriately for a pilot-scale Trust Service instance — not the shared state-hub Postgres, per this project's own standing rule about never reusing that instance for hosted-service data. - Secrets: which values go through OpenBao +
ExternalSecret(TRF_SIGNING_KEY_HEX,TRF_CONTROL_PLANE_SECRET_KEY,TRF_DATABASE_URL/thetrf_approle password) versus which, if any, are fine as plain Helmvalues.yaml— following thereuse-surface-runtime-externalsecret.yamlpattern, oneClusterSecretStoreper workload namespace. - Subdomain and TLS: confirm
revenue.coulomb.socialDNS is (or will be) pointed at the Railiance ingress, and thatletsencrypt-prodissuing for acoulomb.socialsubdomain has no unresolved prerequisite (SAN limits, existing wildcard, etc.) — checkrailiance-infra/railiance-platformdocs rather than assuming parity withwhywhynot.de. - Founding credential bootstrap: how the first
binkyadmin credential is seeded into the deployed database — an idempotent migration-adjacent script, or a documented one-time manualkubectl exec/psqlstep, consistent with howrailiance-apps/railiance-platformalready handle comparable one-time bootstrap actions.
Record the decision here (Result) before any manifest is written — this gate exists because every later task in this workplan assumes a specific answer to each bullet above.
id: TREV-WP-0011-T02
status: todo
priority: high
state_hub_task_id: "d4b3dae4-eb2a-4bed-bc10-5ce90d972cec"
Containerize. Add a Dockerfile (and, if T01 decided on two
processes, two images or one image with two entrypoints/commands) building
the service extras (fastapi, uvicorn, jinja2, itsdangerous,
python-multipart, psycopg[binary], psycopg-pool) plus
static/whynot-design and control_plane_templates/ as part of the image
— nothing in T04's implementation currently assumes local filesystem paths
outside the package, but this should be verified for a container context
(non-root user, read-only root filesystem where the app's own static/
template files don't need write access). Push to
forgejo.coulomb.social/coulomb/target-revenue per the existing image
registry convention (vergabe-teilnahme's values.yaml image.repository
pattern).
id: TREV-WP-0011-T03
status: todo
priority: high
state_hub_task_id: "06567eb5-d924-4100-9cd5-19478121c3c7"
Provision the database and secrets per T01's decision: a CNPG
Cluster, the 0001–0006 migrations applied against it (as a Job, an
init step, or a documented manual run — decide which, consistent with
however railiance-apps's other CNPG-backed workloads handle first-boot
migration), the trf_app role and its grants (already defined in the
migration files themselves), an OpenBao ClusterSecretStore +
ExternalSecret surfacing TRF_SIGNING_KEY_HEX,
TRF_CONTROL_PLANE_SECRET_KEY, and the trf_app password/DSN into the
workload's namespace.
id: TREV-WP-0011-T04
status: todo
priority: high
state_hub_task_id: "e6ecf3e5-3a9d-4f00-92b1-a05817b19013"
Helm chart, Ingress, and ArgoCD wiring. Following T01's chosen home
(own-repo k8s/railiance vs. railiance-apps/charts/target-revenue):
Deployment(s)/Service(s)/Ingress for revenue.coulomb.social with
cert-manager.io/cluster-issuer: letsencrypt-prod and TLS, readiness/
liveness probes against a real health path (neither service/app.py nor
control_plane_app.py currently exposes one — add a trivial /healthz to
each rather than probing an authenticated or Postgres-dependent route),
and an ArgoCD Application (railiance-tenants project, matching
issue-core.application.yaml's shape) with automated sync.
id: TREV-WP-0011-T05
status: todo
priority: medium
state_hub_task_id: "37847415-19c4-43b5-8b0d-de7a4211bfdd"
Bootstrap and smoke-test the live deployment. Seed the founding
binky admin credential per T01's decision, confirm
https://revenue.coulomb.social/login is reachable and TLS-valid, sign in,
register a throwaway test Phase (id clearly marked as a smoke test, not a
real candidate), append a Development Credit entry, confirm the audit log
and metrics reflect it, then decide whether to leave that smoke-test Phase
in place (clearly labeled) or remove it — Phase Manifests are append-only
by design (no delete path), so if a smoke test is unacceptable to leave
behind, use a disposable local/staging instance for this step, not the
production deployment, and only do a read-only login check against the
real one. Update README.md's WP-0011 summary row and this workplan's
Result sections; add a short deployment note (URL, how to sign in, that no
Phase go-live is authorized by deployment alone) to docs/ or SCOPE.md
as appropriate.