--- id: REUSE-WP-0011 type: workplan title: "Federation hub service on railiance01 and hub CLI" domain: helix_forge repo: reuse-surface status: archived owner: codex topic_slug: helix-forge created: "2026-06-15" updated: "2026-06-15" state_hub_workstream_id: "c4171a8c-604e-4214-b189-2094477aa6ea" --- # Federation hub service on railiance01 and hub CLI Close the next federation gap: a **hosted registry hub** on production cluster node **Railiance01** (`92.205.62.239`; CoulombCore `92.205.130.254` is bootstrap only) that records which repositories publish capability indexes, plus a **CLI client** for registering and updating those records without hand-editing `registry/federation/sources.yaml` on every machine. This extends WP-0010 (HTTP fetch) and WP-0005 (federation compose) from pull-only client workflows to a central coordination surface agents and repos can target. ## Problem Today each consumer must: 1. Know sibling repo raw index URLs or local checkout paths. 2. Maintain `registry/federation/sources.yaml` locally. 3. Run `reuse-surface federation compose` to materialize `federated.yaml`. There is no shared source of truth for **which repos are registered** in the helix_forge federation, and no stable HTTP endpoint on Railiance infrastructure for discovery without cloning every repo. ## Target outcome | Surface | Deliverable | |---|---| | Hosted service | HTTP API on `railiance01` storing repo registrations and serving a composed federated index | | CLI client | `reuse-surface hub register`, `update`, `list`, `status` against the hub API | | Operations | Container image, deployment manifests, TLS ingress, documented runbook | | Dogfood | `reuse-surface` and at least one sibling repo registered via the hub | **Public URL:** `https://reuse.coulomb.social` (DNS A → `92.205.62.239`) ## Design decisions (draft) - **Hub role:** Federation **coordinator**, not capability host. Stores repo metadata and index URLs; does not ingest or edit individual capability entry Markdown files. - **Registration model:** Mirror federation source fields (`repo`, `url` or `index`, `domain`, `enabled`, `required`, `cache_ttl_seconds`, `description`). Hub is authoritative for cross-repo membership; local `sources.yaml` may optionally sync from hub or point at hub-composed output only. - **Compose strategy:** Hub periodically or on-demand fetches enabled remote `url` sources (reuse WP-0010 fetch/cache logic) and merges into `GET /v1/federated` output. Local-only `index` paths are **not** valid hub registrations unless expressed as published raw URLs. - **Auth (MVP):** Token-based write access via `REUSE_SURFACE_TOKEN` / `Authorization: Bearer`; read endpoints public for agent discovery. - **Persistence (MVP):** SQLite on a PVC inside the hub container. Postgres via cnpg is a follow-up if multi-replica or backup requirements emerge. - **Availability target:** Promote `capability.registry.register` toward **A4** (service API) for hub register/update flows once deployed and tested. ## Placement and cross-repo coordination | Concern | Owner repo | Coordination | |---|---|---| | Hub service code, API schema, CLI | `reuse-surface` | This workplan | | Container image build and push | `reuse-surface` + `railiance-forge` | OCI registry on `gitea.coulomb.social` | | Helm release on `railiance01` | `railiance-apps` | **RAILIANCE-WP-0007** (companion workplan) | | Ingress / TLS / DNS | `railiance-apps` + DNS owner | DNS live → `92.205.62.239` | | Traefik / cert-manager primitives | `railiance-cluster` / `railiance-platform` | Reuse existing stack | | Secrets (hub token, TLS) | Operator | SOPS / sealed secrets; never commit plaintext | Reference deployment pattern: `railiance-apps/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md` (Traefik ingress, cert-manager `letsencrypt-prod`, Helm values SOPS). ## API sketch (T01 refines) ```text GET /health GET /v1/repos # list registrations POST /v1/repos # register repo (auth required) GET /v1/repos/{repo} # get one registration PATCH /v1/repos/{repo} # update registration (auth required) DELETE /v1/repos/{repo} # deregister (auth required, optional MVP) GET /v1/federated # composed federated index (YAML or JSON) POST /v1/federated/compose # trigger refresh (auth required, optional MVP) ``` Registration body aligns with `schemas/federation.schema.yaml` `$defs/source`, plus hub metadata (`registered_at`, `updated_at`, `registered_by`). ## CLI sketch (T03 refines) ```bash # Configure service URL (env REUSE_SURFACE_URL or --base-url) reuse-surface hub status reuse-surface hub list reuse-surface hub register --repo state-hub \ --url https://gitea.coulomb.social/coulomb/state-hub/raw/main/registry/indexes/capabilities.yaml \ --domain helix_forge reuse-surface hub update --repo state-hub --enabled true reuse-surface hub show --repo state-hub ``` Local federation manifest sync (optional stretch): `reuse-surface hub sync` writes `registry/federation/sources.yaml` from hub state for offline compose. ## Safety contract - Do not commit hub tokens, TLS private keys, or decrypted Helm values. - Do not store capability entry bodies on the hub — URLs and metadata only. - Fail closed on schema validation errors when composing federated output. - Require human approval before irreversible DNS or production cutover steps. --- ## Define Hub API And Registration Schema ```task id: REUSE-WP-0011-T01 status: done priority: high state_hub_task_id: "4ed50506-eef6-4bfc-9e00-65d2aefa9338" ``` Author `specs/FederationHubAPI.md` and `schemas/hub-registration.schema.yaml` defining repo registration records, API request/response shapes, auth model, and error codes. Reuse federation source fields where possible. Record decision in hub workplan design section or `docs/decisions/` if scope warrants. ## Implement Hub Service ```task id: REUSE-WP-0011-T02 status: done priority: high state_hub_task_id: "b12401ab-82f8-433f-a662-06ab71715f25" ``` Add a deployable hub service under `reuse_surface/` (e.g. `hub/` package or `hub_service/` entrypoint): - FastAPI application exposing T01 endpoints - SQLite persistence for registrations - Integrate WP-0010 remote fetch/cache for `url` sources when composing federated output - `GET /v1/federated` returns merged index with `source_repo` attribution - Health check suitable for k8s probes ## Implement Hub CLI Client ```task id: REUSE-WP-0011-T03 status: done priority: high state_hub_task_id: "38fec6ce-23c0-4157-8350-7d112b9e8264" ``` Extend `reuse-surface` CLI with `hub` subcommands: - `register`, `update`, `show`, `list`, `status` - `--base-url` flag and `REUSE_SURFACE_URL` env support - `REUSE_SURFACE_TOKEN` for authenticated writes - `reuse-surface serve` to run the API locally or in container - Document in `tools/README.md` and `AGENTS.md` ## Containerize And Publish Deployment Artifacts ```task id: REUSE-WP-0011-T04 status: done priority: medium state_hub_task_id: "24eec9ad-21fc-4f0b-8671-72d955b15e68" ``` Provide: - `Dockerfile` for the hub service - Example k8s manifests or Helm values template under `docs/deploy/` - Image: `gitea.coulomb.social/coulomb/reuse-surface:` - CI job or documented build/push steps (coordinate with `railiance-forge` registry guidance) ## Deploy Hub To railiance01 ```task id: REUSE-WP-0011-T05 status: done priority: medium state_hub_task_id: "7f26a70f-7b7d-413d-8162-931c6dffef6a" ``` Deployed on `railiance01` (Helm revision 3, image `cb7a6e4`): - Pod `reuse-surface` Running; `GET /health` OK via ingress resolve - `reuse-surface` registered; `GET /v1/federated` returns 12 capabilities - TLS cert still pending: DNS must route to cluster ingress `92.205.130.254` (same pattern as `hub.coulomb.social`; current A record propagates elsewhere) ## Document Operations And Dogfood Registrations ```task id: REUSE-WP-0011-T06 status: done priority: medium state_hub_task_id: "f7913b00-f6d1-4950-bb57-db49a453e6f4" ``` Updated `docs/RegistryFederation.md` and `SCOPE.md` with hub workflow. Dogfood: `reuse-surface` registered at hub (`/v1/repos`, `/v1/federated`). Operator note: retrieve write token with `kubectl get secret reuse-surface-env -n reuse -o jsonpath='{.data.REUSE_SURFACE_TOKEN}' | base64 -d`. Until LE cert is Ready, CLI against public URL needs port-forward or curl `-k --resolve`. ## Add Tests And CI Coverage ```task id: REUSE-WP-0011-T07 status: done priority: medium state_hub_task_id: "40871958-f665-4726-9ff6-f8a840d685bd" ``` Add pytest coverage for hub API handlers and CLI client (use TestClient and mock HTTP). Extend CI to run hub tests. Hub deployment smoke test documented as a manual or post-deploy check in T05.