feat: prepare Core Hub production relocation
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / pytest-smoke (push) Failing after 1s
Build and Publish Container Image / build-and-push (push) Successful in 1m3s

This commit is contained in:
tegwick 2026-08-20 22:46:41 +02:00
parent d7627dabf5
commit 881c87905f
7 changed files with 230 additions and 17 deletions

View file

@ -5,7 +5,7 @@ HUB_CORE_ROOT ?= /home/worsch/hub-core
UV ?= /home/worsch/.local/bin/uv
PYTHONPATH ?= src
IMAGE_REPOSITORY ?= gitea.coulomb.social/coulomb/core-hub
IMAGE_REPOSITORY ?= forgejo.coulomb.social/coulomb/core-hub
IMAGE_TAG ?= dev
CLI_ARGS ?=

View file

@ -38,10 +38,11 @@ It carries forward the lessons from State Hub and Inter-Hub: workplans and progr
- [Specs index](docs/specs/README.md) - contract and implementation specification map
- [Workplans](workplans/) - staged implementation plan using ADR-001 workplan files
## Immediate Work
## Current Work
1. Freeze the Core Hub contract and IR.
2. Build the FastAPI/Postgres foundation.
3. Preserve critical Inter-Hub `/api/v2` compatibility for current consumers.
4. Migrate data and cut over production traffic.
5. Retire the Haskell/IHP build lane only after replacement evidence exists.
The contract, FastAPI/Postgres foundation, Inter-Hub migration, production
cutover, and Haskell/IHP retirement are complete. The immediate continuity
work is to relocate the existing Core Hub service from CoulombCore to
railiance01 before CoulombCore is decommissioned (`CORE-WP-0011`). Future
runtime absorption into hub-core remains a separate architecture proposal
(`CORE-WP-0010`).

View file

@ -8,17 +8,23 @@ Core Hub is the 3rd-generation production interaction framework for Coulomb / He
## Core Idea
Core Hub replaces the Haskell/IHP Inter-Hub implementation with a contract-first Python/FastAPI/Postgres framework for cross-domain state, agent coordination, evidence, registry facts, workplans, and operator interaction surfaces.
Core Hub is the contract-first Python/FastAPI/Postgres framework that replaced
the Haskell/IHP Inter-Hub implementation for cross-domain state, agent
coordination, evidence, registry facts, workplans, and operator interaction
surfaces.
## In Scope
- Core Hub intent, research, specs, and implementation workplans
- Contract/IR definition for hubs, manifests, widgets, events, tasks, progress, messages, decisions, and registry facts
- FastAPI/Postgres implementation planning and eventual service code
- Inter-Hub `/api/v2` compatibility where existing consumers depend on it
- Data migration and production cutover planning from Inter-Hub
- Maintaining the production `/api/v2` compatibility contract inherited from
Inter-Hub
- Relocating the current Core Hub runtime across production hosts without
coupling continuity to future framework consolidation
- Operator UI and whynot-design aligned component/adaptor planning
- Haskell/IHP retirement planning after replacement evidence exists
- Evidence-preserving maintenance of the completed Inter-Hub migration and
Haskell/IHP retirement record
## Out of Scope
@ -26,13 +32,13 @@ Core Hub replaces the Haskell/IHP Inter-Hub implementation with a contract-first
- Owning every downstream domain hub implementation
- Storing or vending secrets directly
- Rewriting unrelated consumers before the Core Hub compatibility contract exists
- Retiring production Inter-Hub before migration and smoke evidence exists
- Reintroducing the retired Inter-Hub runtime as an active production path
## Ecosystem position
| Repo | Boundary |
| --- | --- |
| `hub-core` | Library — core-hub imports utils; framework models stay in `core_hub` |
| `hub-core` | Shared library today; any permanent host is an explicit future architecture decision |
| `state-hub` | Dev coordination canonical owner for workplans/tasks until ADR says otherwise |
| `core-hub` | This repo — `/api/v2`, framework tables, operator console |
@ -44,3 +50,5 @@ See `/home/worsch/the-custodian/docs/hub-ecosystem-architecture.md`.
- Bind the UI contract to React or any single frontend framework
- Make State Hub disappear before Core Hub proves a compatible replacement path
- Duplicating hub-core router factories or dev-hub workplan tables locally
- Making the unresolved hub-core library-vs-thin-host decision merely to meet
a host-decommission deadline

View file

@ -16,6 +16,7 @@
| workplan | CORE-WP-0008 | finished | — | workplans/CORE-WP-0008-api-first-ops-evidence-continuation.md |
| workplan | CORE-WP-0009 | finished | — | workplans/CORE-WP-0009-hub-core-adoption-and-integration.md |
| workplan | CORE-WP-0010 | proposed | — | workplans/CORE-WP-0010-runtime-absorption-and-archive.md |
| workplan | CORE-WP-0011 | active | — | workplans/CORE-WP-0011-railiance01-production-relocation.md |
| task | CORE-WP-0001-T01 | done | — | workplans/CORE-WP-0001-statehub-bootstrap.md |
| task | CORE-WP-0001-T02 | done | — | workplans/CORE-WP-0001-statehub-bootstrap.md |
| task | CORE-WP-0001-T03 | done | — | workplans/CORE-WP-0001-statehub-bootstrap.md |
@ -53,3 +54,8 @@
| task | CORE-WP-0010-T03 | todo | — | workplans/CORE-WP-0010-runtime-absorption-and-archive.md |
| task | CORE-WP-0010-T04 | todo | — | workplans/CORE-WP-0010-runtime-absorption-and-archive.md |
| task | CORE-WP-0010-T05 | todo | — | workplans/CORE-WP-0010-runtime-absorption-and-archive.md |
| task | CORE-WP-0011-T01 | progress | — | workplans/CORE-WP-0011-railiance01-production-relocation.md |
| task | CORE-WP-0011-T02 | done | — | workplans/CORE-WP-0011-railiance01-production-relocation.md |
| task | CORE-WP-0011-T03 | todo | — | workplans/CORE-WP-0011-railiance01-production-relocation.md |
| task | CORE-WP-0011-T04 | todo | — | workplans/CORE-WP-0011-railiance01-production-relocation.md |
| task | CORE-WP-0011-T05 | todo | — | workplans/CORE-WP-0011-railiance01-production-relocation.md |

View file

@ -406,10 +406,10 @@ def _run_bootstrap(
{
"hubId": hub["id"],
"status": "active",
"name": "Gitea Registry Readiness Smoke",
"name": "Forgejo Registry Readiness Smoke",
"widgetType": "ops-readiness-gate",
"capabilityRef": "ops:readiness:gitea-registry",
"viewContext": f"ops-hub/smoke/{run_slug}/gitea-registry",
"capabilityRef": "ops:readiness:forgejo-registry",
"viewContext": f"ops-hub/smoke/{run_slug}/forgejo-registry",
"policyScope": "ops-registry",
},
expected={201},
@ -437,7 +437,7 @@ def _run_bootstrap(
"runId": run_id,
"vsmFunction": "OPS",
"vsmSystem": "S1",
"endpoint": "https://gitea.coulomb.social/v2/",
"endpoint": "https://forgejo.coulomb.social/v2/",
"expectedStatus": 401,
"recordedBy": "scripts/core_hub_deployed_smoke.py",
"recordedAt": utc_timestamp(),

View file

@ -13,6 +13,7 @@ parent_project: prj-state-hub-retirement
parent_workplan: SHR-WP-0001
related:
- CORE-WP-0009
- CORE-WP-0011
- HUB-WP-0004
- SHR-ARCH-HUB-0001
state_hub_workstream_id: "f5a90aa2-e63f-4f94-b052-8be0d0ee55ea"
@ -28,6 +29,15 @@ through dual-run, then **archive core-hub** read-only with evidence.
Parent project: `prj-state-hub-retirement`. Depends on **HUB-WP-0004**.
## Sequencing decision — 2026-08-20
The CoulombCore decommission does not force the unresolved hub-core
library-vs-thin-host decision. Production continuity is decoupled through
`CORE-WP-0011`, which moves the existing Core Hub service to railiance01
first. This workplan remains proposed until `HUB-WP-0004` settles the durable
runtime boundary; absorption must not sit on the critical path for leaving
CoulombCore.
## Inventory runtime surfaces to absorb
```task

View file

@ -0,0 +1,188 @@
---
id: CORE-WP-0011
type: workplan
title: "Relocate Core Hub production from CoulombCore to railiance01"
domain: infotech
repo: core-hub
status: active
owner: codex
topic_slug: infotech
created: "2026-08-20"
updated: "2026-08-20"
parent_project: prj-state-hub-retirement
parent_workplan: SHR-WP-0002
related:
- CORE-WP-0005
- CORE-WP-0007
- CORE-WP-0010
- HUB-WP-0004
---
# Relocate Core Hub production from CoulombCore to railiance01
## Goal
Move the existing Core Hub production service at `hub.coulomb.social` from
CoulombCore to railiance01 before CoulombCore is decommissioned. Preserve the
current `/api/v2` contract, data, hostname, credentials boundary, and rollback
evidence. Do not make runtime absorption into hub-core a prerequisite.
## Decision and constraints
- Use the interim-move shape requested by `SHR-WP-0002-T03`: package and move
Core Hub as-is, then resolve long-term absorption under `CORE-WP-0010` and
`HUB-WP-0004` on their own architecture schedule.
- Use the governed Repo Manager rapp path. Because the live deployment truth is
a Helm chart, initialize a managed package instead of asking `rapp wrap` to
invent or ingest Helm content; retain this repo's manifests as source evidence
until the package is verified.
- Treat the CoulombCore decommission date as a scheduling input, not as a
reason to collapse the hub-core library-vs-thin-host decision.
- Any traffic flip, final data freeze/transfer, or old-runtime removal requires
explicit operator approval and a rehearsed rollback.
## Inventory source and target runtime
```task
id: CORE-WP-0011-T01
status: progress
priority: high
```
Capture the live CoulombCore image, Deployment, Service, Ingress, database,
secret references, resource policy, and tunnel/DNS ownership. Compare them to
railiance01 and the checked-in `k8s/railiance-production/` manifests.
Local review on 2026-08-20 confirms that the repo already carries a namespace,
migration Job, API Deployment, Service, Ingress, health probes, and the
historical migration/cutover runbook. The manifests need a live-state diff and
modern platform-policy review before reuse. The retirement project reports no
`core-hub` namespace or Deployment on railiance01. A read-only preflight on
2026-08-20 confirmed the current Kubernetes context reaches the Ready k3s node
`239.62.205.92.host.secureserver.net` (`92.205.62.239`, Kubernetes
`v1.35.1+k3s1`), has no `core-hub` namespace or resources, and retains an
`inter-hub` namespace. Pin the CoulombCore decommission date while this task is
in progress so later gates have explicit deadlines. The retirement deadline is
now pinned to **2026-08-31** (11 days from workplan creation). Source-cluster
live state and target platform-policy comparison remain open.
The registry audit found that production/staging manifests, runbooks, and
Forgejo CI already publish and pull `forgejo.coulomb.social/coulomb/core-hub`,
but the local Makefile default and deployed-smoke evidence still named the
CoulombCore-hosted Gitea registry. Those two active references were changed to
Forgejo on 2026-08-20. The only remaining Gitea image reference is historical
evidence in finished `CORE-WP-0004`; confirm the live source Deployment image
and digest before declaring the dependency closed.
An attended source-cluster inventory remains required. On 2026-08-20 the
CoulombCore kubeconfig pointed at the documented local API port `16443`, but
the tunnel was down; the current ops-bridge config no longer contains
`k3s-api-coulombcore`. The sanctioned warden signer route was followed, but its
credential broker requires an operator-held OpenBao issuer login unavailable
to this non-interactive session. No alternate credential path was attempted.
After operator login, collect metadata-only Deployment/Service/Ingress, image
digest, Secret names and keys (never values), database target, resource policy,
and Helm revision evidence before closing this task.
## Build the relocatable application package
```task
id: CORE-WP-0011-T02
status: done
priority: high
```
Wrap the current service through the governed rapp path. Pin the source
revision and image digest, express namespace/runtime/database/secret
dependencies without credential values, and add render/package checks. Reuse
the current container and `/healthz`, `/readyz`, and deployed-smoke surfaces.
Done when the package renders deterministically, policy checks pass, and its
rendered workload is equivalent to the live service except for documented
railiance01 platform adaptations.
Completed locally on 2026-08-20 in `/home/worsch/rapp-core-hub`. Repo Manager
initialized a Helm-managed package because the live deployment truth is the
existing `railiance-apps/charts/core-hub` chart; `rmgr rapp wrap` deliberately
refuses to invent or ingest Helm charts. The package absorbs that chart and
adds an immutable Forgejo digest pin, safe-private Ingress default,
non-root/read-only security contexts, ServiceAccount hardening,
default-deny/DNS/Postgres/Traefik NetworkPolicies, deterministic render,
Alembic migration, live smoke, and Helm rollback surfaces. Evidence:
- package tests: 5 passed;
- Helm lint: passed;
- family validator: 4 declarations ok;
- railiance01 Helm/Kubernetes server dry-run: passed;
- current image pin:
`sha256:0db6f7c646c6d4c1fbc844dc266fcf883584637e1c1f47802efe1c6a98558d3c`.
Published and registered on 2026-08-20 after the operator created the Forgejo
stub. Local history was attached without discarding either root. Private
Forgejo `main` now includes credential-contract release commit `03effc8`.
Chart `0.3.0` separates the static API-token Secret from runtime and migration
database lease Secrets and supervises the application through mounted-file
rotation; seven tests prove separation, safe URL construction, no credential
output, and restart signaling. State Hub registers active
repo `rapp-core-hub` as `445ea292-70bb-435c-8c69-c4cb57a6985b`, with the
`bnt-lap001:/home/worsch/rapp-core-hub` host path, the canonical stub-root Git
fingerprint, and Core Hub's topic ID. The package uses registered workplan
prefix `RAPPCOREHUB-WP-`; consistency passes with only the expected warning
that this workstation is not the production workplan-UUID registrar.
## Deploy shadow runtime and rehearse data transfer
```task
id: CORE-WP-0011-T03
status: todo
priority: high
```
Provision the railiance01 namespace, database role/database, governed secret
delivery, migration Job, Deployment, and Service without moving production
traffic. Rehearse backup/restore or logical transfer from CoulombCore, compare
table and row counts, and run public plus authenticated consumer smokes against
the private target endpoint.
Done when the shadow runtime is healthy, data reconciliation is repeatable,
and ops-hub plus activity-core smokes pass against railiance01.
## Cut over production traffic
```task
id: CORE-WP-0011-T04
status: todo
priority: high
```
With explicit operator approval, freeze writes for the bounded final-transfer
window, transfer and reconcile the final data, then move
`hub.coulomb.social` and the active ops-bridge tunnel from CoulombCore to
railiance01. Verify TLS, health/readiness, public catalogs, protected routes,
operator console, consumer smokes, and the first post-cutover write.
Rollback must restore the prior traffic/tunnel target and database write path;
the old runtime stays intact until stabilization closes.
## Stabilize and release CoulombCore dependencies
```task
id: CORE-WP-0011-T05
status: todo
priority: high
```
Run a time-bounded stabilization window with scheduled health and consumer
checks. After operator sign-off, remove Core Hub from the CoulombCore shutdown
critical path, retire `core-hub-staging` and any obsolete tunnel there, and
record retained backup/rollback evidence and residual owners. Do not archive
this repo unless the separate absorption workplan has also completed.
## Acceptance
- [ ] Decommission deadline and live source/target inventory are recorded
- [x] Governed rapp package renders and passes policy checks
- [ ] Shadow restore/reconciliation and consumer smokes pass on railiance01
- [ ] Production traffic and tunnel move with explicit approval and rollback
- [ ] Stabilization passes and CoulombCore no longer hosts Core Hub dependencies
- [ ] `CORE-WP-0010` remains independently sequenced behind `HUB-WP-0004`