diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index a842928..039404a 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -14,6 +14,7 @@ | workplan | RMGR-WP-0004 | active | — | workplans/RMGR-WP-0004-repository-standards-conformance.md | | workplan | RMGR-WP-0005 | active | — | workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md | | workplan | RMGR-WP-0006 | finished | — | workplans/RMGR-WP-0006-railiance-app-wrapper-setup.md | +| workplan | RMGR-WP-0007 | proposed | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | | task | RMGR-WP-0001-T01 | done | — | workplans/RMGR-WP-0001-foundation.md | | task | RMGR-WP-0001-T02 | done | — | workplans/RMGR-WP-0001-foundation.md | | task | RMGR-WP-0001-T03 | done | — | workplans/RMGR-WP-0001-foundation.md | @@ -53,3 +54,10 @@ | task | RMGR-WP-0006-T03 | done | — | workplans/RMGR-WP-0006-railiance-app-wrapper-setup.md | | task | RMGR-WP-0006-T04 | done | — | workplans/RMGR-WP-0006-railiance-app-wrapper-setup.md | | task | RMGR-WP-0006-T05 | done | — | workplans/RMGR-WP-0006-railiance-app-wrapper-setup.md | +| task | RMGR-WP-0007-T01 | todo | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | +| task | RMGR-WP-0007-T02 | todo | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | +| task | RMGR-WP-0007-T03 | todo | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | +| task | RMGR-WP-0007-T04 | todo | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | +| task | RMGR-WP-0007-T05 | todo | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | +| task | RMGR-WP-0007-T06 | todo | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | +| task | RMGR-WP-0007-T07 | todo | — | workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md | diff --git a/workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md b/workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md new file mode 100644 index 0000000..d472c1e --- /dev/null +++ b/workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md @@ -0,0 +1,191 @@ +--- +id: RMGR-WP-0007 +type: workplan +title: "Greenfield rapp wrap efficiency" +domain: infotech +repo: repo-manager +status: proposed +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: todo +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. + +## Generate a runtime skeleton from the app repo + +```task +id: RMGR-WP-0007-T02 +status: todo +priority: high +state_hub_task_id: "2c2c8306-b5b0-467a-a1a5-20c0f979e13d" +``` + +Add `rmgr rapp skeleton --path --from-app `. + +Inspect the app checkout (Containerfile `EXPOSE` / `USER`, documented +health paths defaulting to `/healthz` and `/readyz`, image name +`forgejo.coulomb.social/coulomb/`). 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`. + +## Install the fleet image-publish workflow on the app + +```task +id: RMGR-WP-0007-T03 +status: todo +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. + +## Draft the postgres consumer, do not apply it + +```task +id: RMGR-WP-0007-T04 +status: todo +priority: medium +state_hub_task_id: "0fe3018a-b245-43b9-a0e2-e0ecb7f6d206" +``` + +Emit `rapp-postgres/consumers/.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. + +## Compose `rmgr rapp wrap` + +```task +id: RMGR-WP-0007-T05 +status: todo +priority: high +state_hub_task_id: "001e7b30-2a86-41f2-b731-415125e3b3e6" +``` + +Add `rmgr rapp wrap --app --ownership-repo --from-app +` 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`). + +## Explicit place command + +```task +id: RMGR-WP-0007-T06 +status: todo +priority: medium +state_hub_task_id: "076a64c5-cd83-4f7c-ba51-f3c61e5464e8" +``` + +Add `rmgr rapp place --path --reef reef-railiance` that sets +`bound_reefs` only. Refuse unknown reefs. Do not set +`exposure.posture: public`. + +## Pilot on tenant-engine, files only + +```task +id: RMGR-WP-0007-T07 +status: todo +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. + +## 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.