--- id: REUSE-WP-0011 type: workplan title: "Federation hub service on railiance01 and hub CLI" domain: helix_forge repo: reuse-surface status: proposed owner: codex topic_slug: helix-forge created: "2026-06-15" updated: "2026-06-15" --- # Federation hub service on railiance01 and hub CLI Close the next federation gap: a **hosted registry hub** on production cluster node `railiance01` (`92.205.130.254`) 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 | **Proposed public URL (confirm in T05):** `https://reuse-hub.whywhynot.de` ## 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_HUB_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` | Capability request or companion task | | Ingress / TLS / DNS | `railiance-apps` + DNS owner | T05 — human confirmation for hostname | | 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 hub endpoint (env REUSE_SURFACE_HUB_URL or --hub-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: todo priority: high ``` 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: todo priority: high ``` 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: todo priority: high ``` Extend `reuse-surface` CLI with `hub` subcommands: - `register`, `update`, `show`, `list`, `status` - `--hub-url` flag and `REUSE_SURFACE_HUB_URL` env support - `REUSE_SURFACE_HUB_TOKEN` for authenticated writes - Document in `tools/README.md` and `AGENTS.md` ## Containerize And Publish Deployment Artifacts ```task id: REUSE-WP-0011-T04 status: todo priority: medium ``` Provide: - `Dockerfile` for the hub service - Example k8s manifests or Helm values template under `deploy/` or `docs/deploy/` - Image naming convention: `gitea.coulomb.social/coulomb/reuse-surface-hub:` - CI job or documented build/push steps (coordinate with `railiance-forge` registry guidance) ## Deploy Hub To railiance01 ```task id: REUSE-WP-0011-T05 status: wait priority: medium ``` Deploy the hub as a governed release on `railiance01`: - Confirm hostname (default `reuse-hub.whywhynot.de`) and DNS A record - Traefik ingress + cert-manager TLS - PVC for SQLite data - Inject hub write token via SOPS/sealed secret - Verify `GET /health` and `GET /v1/federated` from workstation and from cluster **Blocked on:** DNS decision, operator secret provisioning, and `railiance-apps` Helm release slot (may need companion workplan task there). ## Document Operations And Dogfood Registrations ```task id: REUSE-WP-0011-T06 status: todo priority: medium ``` Update `docs/RegistryFederation.md` with hub-centric workflow. Register `reuse-surface` index URL via CLI. Document how agents discover `GET /v1/federated` without local `sources.yaml` maintenance. Update `SCOPE.md` and `docs/IntentScopeGapAnalysis.md` when hub is live. ## Add Tests And CI Coverage ```task id: REUSE-WP-0011-T07 status: todo priority: medium ``` 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.