Add the §0 playbook and kubernetes-then-knative gate to the guide. Implement rmgr rapp skeleton/wrap/place, draft postgres consumers, and copy the fleet image workflow when missing.
215 lines
6.9 KiB
Markdown
215 lines
6.9 KiB
Markdown
---
|
|
id: RMGR-WP-0007
|
|
type: workplan
|
|
title: "Greenfield rapp wrap efficiency"
|
|
domain: infotech
|
|
repo: repo-manager
|
|
status: finished
|
|
owner: grok
|
|
topic_slug: infotech
|
|
created: "2026-08-18"
|
|
updated: "2026-08-18"
|
|
parent_project: prj-state-hub-retirement
|
|
related:
|
|
- RMGR-WP-0004
|
|
- RMGR-WP-0006
|
|
state_hub_workstream_id: "b24d47cd-25d6-4473-b057-6a6f8387ab30"
|
|
---
|
|
|
|
# Greenfield rapp wrap efficiency
|
|
|
|
## Goal
|
|
|
|
Make the Railiance managed-app wrap path usable **from scratch** for an
|
|
application that has no rapp yet, without rereading the estate or
|
|
hand-copying user-engine.
|
|
|
|
`RMGR-WP-0006` proved the contract and the absorb path
|
|
(`rapp-user-engine`). This workplan turns that into a short playbook plus
|
|
commands that emit the expensive files. It does **not** apply to a
|
|
cluster, invent rails or reefs, or store secret values.
|
|
|
|
Source of the work: session follow-up on
|
|
[`docs/RailianceAppDeploymentGuide.md`](../docs/RailianceAppDeploymentGuide.md)
|
|
after the user-engine rollout.
|
|
|
|
## Defaults this workplan locks
|
|
|
|
- Primary rail: `rail-kubernetes`.
|
|
- Package type: `manifest-managed-platform-service` unless the app
|
|
already has a Helm chart.
|
|
- Database: draft a `rapp-postgres` consumer. A dedicated Cluster is
|
|
opt-in only when placement policy already says so.
|
|
- Image: fleet `image.yaml` in the **app** repo; pin by digest in the
|
|
rapp. No workstation builds.
|
|
- `railiance/app.toml` is optional, not part of the first wrap.
|
|
- `bound_reefs` and public `exposure` stay unset until an explicit place
|
|
/ grant step.
|
|
- Files stay authoritative. The hub is only updated via
|
|
`fix-consistency`.
|
|
|
|
## Put a greenfield playbook at the front of the guide
|
|
|
|
```task
|
|
id: RMGR-WP-0007-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "dcf0b76c-05e8-44b4-b31a-33f0bc7273ce"
|
|
```
|
|
|
|
Update `docs/RailianceAppDeploymentGuide.md` so a new wrap does not
|
|
start in the user-engine absorb story.
|
|
|
|
- Add a one-page **§0 Greenfield playbook**: decide → `init` →
|
|
`skeleton` → app `image.yaml` → postgres consumer draft → `validate`
|
|
→ `place`.
|
|
- Keep axes, inventory, and the user-engine worked example as
|
|
reference, not the default procedure.
|
|
- Refresh inventory: `rapp-user-engine` is `verified`; mark P1/P4 as
|
|
implemented; drop “scaffolder not implemented.”
|
|
- State that `railiance/app.toml` is not required on the first wrap.
|
|
- Point the default database path at a `rapp-postgres` consumer, not a
|
|
dedicated Cluster.
|
|
|
|
Do not rewrite the family schemas here.
|
|
|
|
**Result (2026-08-18):** §0 playbook and §3.1 rail sequence added.
|
|
Inventory lists `rapp-user-engine` as verified. §12 names the live
|
|
commands.
|
|
|
|
## Generate a runtime skeleton from the app repo
|
|
|
|
```task
|
|
id: RMGR-WP-0007-T02
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "2c2c8306-b5b0-467a-a1a5-20c0f979e13d"
|
|
```
|
|
|
|
Add `rmgr rapp skeleton --path <rapp> --from-app <app>`.
|
|
|
|
Inspect the app checkout (Containerfile `EXPOSE` / `USER`, documented
|
|
health paths defaulting to `/healthz` and `/readyz`, image name
|
|
`forgejo.coulomb.social/coulomb/<app>`). Emit:
|
|
|
|
- `manifests/` Deployment, Service, ServiceAccount, default-deny plus
|
|
explicit NetworkPolicy
|
|
- Makefile targets `render`, `server-dry-run`, `deploy`, `status`,
|
|
`verify-live`, `rollback DIGEST=…`
|
|
- `tools/render.py` and `tools/verify_live.sh`
|
|
- a packaging test that forbids floating tags and secret values
|
|
|
|
Refuse Helm unless `--package-type helm-managed-platform-service` or a
|
|
chart already exists. Idempotent: do not overwrite reviewed manifests
|
|
without `--force`.
|
|
|
|
**Result (2026-08-18):** `rmgr rapp skeleton --from-app` inspects
|
|
Containerfile/deploy, absorbs `deploy/*.yaml` when present, otherwise
|
|
emits a hardened Deployment set.
|
|
|
|
## Install the fleet image-publish workflow on the app
|
|
|
|
```task
|
|
id: RMGR-WP-0007-T03
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "ec2d8fbb-2945-4144-b75e-beddf54a8b87"
|
|
```
|
|
|
|
As part of wrap/skeleton, copy the fleet
|
|
`.forgejo/workflows/image.yaml` into the **app** repo when missing.
|
|
Do not invent registry credentials. Do not build on the workstation.
|
|
Document that the first deploy waits on the CI digest.
|
|
|
|
**Result (2026-08-18):** `ensure_image_workflow` copies the fleet
|
|
workflow when missing and leaves an existing file alone.
|
|
|
|
## Draft the postgres consumer, do not apply it
|
|
|
|
```task
|
|
id: RMGR-WP-0007-T04
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "0fe3018a-b245-43b9-a0e2-e0ecb7f6d206"
|
|
```
|
|
|
|
Emit `rapp-postgres/consumers/<app>.yaml` as a **draft file** (or a
|
|
copy under the rapp `docs/` / `handoffs/` if the postgres repo is not a
|
|
sibling). Roles: owner / migration / runtime. Tenant-keying required.
|
|
Never write a dedicated CNPG Cluster unless `--dedicated-postgres` is
|
|
passed.
|
|
|
|
This task does not apply the consumer in `rapp-postgres` and does not
|
|
request a CCR.
|
|
|
|
**Result (2026-08-18):** drafts `handoffs/postgres-consumer.yaml` or
|
|
points at an existing `rapp-postgres/consumers/<app>.yaml`.
|
|
|
|
## Compose `rmgr rapp wrap`
|
|
|
|
```task
|
|
id: RMGR-WP-0007-T05
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "001e7b30-2a86-41f2-b731-415125e3b3e6"
|
|
```
|
|
|
|
Add `rmgr rapp wrap --app <app> --ownership-repo <app> --from-app
|
|
<path>` that runs init → skeleton → image workflow copy → consumer
|
|
draft → validate and **stops**. No `bound_reefs`, no cluster apply, no
|
|
exposure grant.
|
|
|
|
Refuse unknown rails, `rapp-` workload names, and overwrite of a live
|
|
declaration (same rules as `init`).
|
|
|
|
**Result (2026-08-18):** `rmgr rapp wrap` composes the steps and reports
|
|
`placed: false`, `applied: false`.
|
|
|
|
## Explicit place command
|
|
|
|
```task
|
|
id: RMGR-WP-0007-T06
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "076a64c5-cd83-4f7c-ba51-f3c61e5464e8"
|
|
```
|
|
|
|
Add `rmgr rapp place --path <rapp> --reef reef-railiance` that sets
|
|
`bound_reefs` only. Refuse unknown reefs. Do not set
|
|
`exposure.posture: public`.
|
|
|
|
**Result (2026-08-18):** `rmgr rapp place` sets `bound_reefs` and
|
|
refuses `reef-storage`.
|
|
|
|
## Pilot on tenant-engine, files only
|
|
|
|
```task
|
|
id: RMGR-WP-0007-T07
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "e3845311-b560-4fc2-ad76-5939145350a7"
|
|
```
|
|
|
|
Run the wrap path against `tenant-engine` / `rapp-tenant-engine`.
|
|
Prefer absorbing `tenant-engine/deploy/` when present over inventing a
|
|
second runtime.
|
|
|
|
Success: schema-valid `declared` or `draft` declaration, skeleton or
|
|
absorbed manifests, `rmgr rapp validate` passes, postgres consumer
|
|
**draft** exists, no cluster apply in this task.
|
|
|
|
`rapp-secrets-engine` is out of scope (likely not a long-running
|
|
workload). `rapp-vergabe-teilnahme` stays a `railiance-apps` residual.
|
|
|
|
**Result (2026-08-18):** wrap absorbed `tenant-engine/deploy/`, left the
|
|
live postgres consumer in place, skipped existing `image.yaml`,
|
|
validated `4 declaration(s) ok`. No cluster apply.
|
|
|
|
## Residuals
|
|
|
|
- Applying a drafted postgres consumer and CCR remains with
|
|
`rapp-postgres` / `railiance-platform`.
|
|
- First production deploy of a wrapped tenant-engine is a later
|
|
operator step, not this workplan.
|
|
- A `helm-managed-application` schema enum remains a `railiance-master`
|
|
change if the platform-service name still misleads after this path.
|