repo-manager/workplans/RMGR-WP-0007-greenfield-rapp-wrap-efficiency.md
codex c3f4ece7ea fix(workplans): adopt ADR-007 derived identifiers for unregistered records
These workplans exist only in the retired local hub. Their random pre-ADR-007
identifiers are refused by C-06 as stale references, so they cannot be
registered. Deriving from the canonical record id takes no identity from
anything: central does not hold them and the old ids die with the cache.

Records central already holds were deliberately left untouched.

Refs CUST-WP-0068-T06

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 20:21:52 +02:00

6.9 KiB

id type title domain repo status owner topic_slug created updated parent_project related state_hub_workstream_id
RMGR-WP-0007 workplan Greenfield rapp wrap efficiency infotech repo-manager finished grok infotech 2026-08-18 2026-08-18 prj-state-hub-retirement
RMGR-WP-0004
RMGR-WP-0006
f1987ed9-a148-55c2-8e76-fcbe2f81cc80

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 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

id: RMGR-WP-0007-T01
status: done
priority: high
state_hub_task_id: "149f1fda-1cb6-5be6-b0de-62435efe0dac"

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 → initskeleton → app image.yaml → postgres consumer draft → validateplace.
  • 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

id: RMGR-WP-0007-T02
status: done
priority: high
state_hub_task_id: "42531c77-2f01-5988-b769-ee649fdfeda6"

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

id: RMGR-WP-0007-T03
status: done
priority: high
state_hub_task_id: "8a345703-c6c1-56ba-807f-d2c57d66343f"

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

id: RMGR-WP-0007-T04
status: done
priority: medium
state_hub_task_id: "d92dffd6-bb84-5728-8442-058e567efd1a"

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

id: RMGR-WP-0007-T05
status: done
priority: high
state_hub_task_id: "65c7c442-fcc2-5048-81b5-9d440e3a4d44"

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

id: RMGR-WP-0007-T06
status: done
priority: medium
state_hub_task_id: "96a9af80-e24b-52ca-bd61-e3d5637134ce"

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

id: RMGR-WP-0007-T07
status: done
priority: high
state_hub_task_id: "2d2350a4-6a31-5b01-89eb-185bdd117703"

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.