core-hub/docs/specs/runtime-absorption-plan.md
tegwick 4a2d4fa981
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / pytest-smoke (push) Failing after 3s
docs: align absorption plan with hub-core
2026-08-21 10:59:39 +02:00

11 KiB
Raw Blame History

Core Hub to hub-core absorption plan

Status: accepted for CORE-WP-0010-T02 / HUB-WP-0004-T06 Reviewed: 2026-08-21
Strategy: route-group migration with Core Hub retained as rollback; no client dual-write and no big-bang cutover

This Core Hub record is aligned with the canonical joint plan at hub-core/docs/core-hub-absorption-plan.md and State Hub decision 12514947-6cc0-42a0-98ca-9aacc9d875b0. It turns the inventory in runtime-absorption-inventory.md into ordered, testable migration slices. Hub-core owns the surviving runtime selected by its ADR-0001. Core Hub remains the public /api/v2 authority until each route group passes its own data, contract, consumer, and rollback gates.

Decisions

  1. One target runtime. Hub-core ships the importable wheel and primary OCI image. Core Hub is a temporary source and rollback runtime, not a permanent host for hub-core.
  2. Internal candidate first. A hub-core candidate deployment receives no public traffic until it has a published source revision, immutable image digest, durable PostgreSQL backend, migrations, compatible authentication, and green readiness.
  3. Route groups, not percentages. Traffic moves by coherent API group. Random percentage canaries would send related bootstrap calls to different authorities and are not permitted.
  4. One writer per route group. Read-only requests may be mirrored for comparison. Production clients never dual-write. Write cutover uses a short drain, final delta replay, route switch, and one active writer.
  5. Isolated metadata during dual-run. Core Hub keeps the core_hub schema; hub-core uses its own migration lineage and schema. Cross-importing either service's SQLAlchemy metadata is prohibited.
  6. Stable identity and safe key migration. Durable IDs are preserved. API-key prefixes, hashes, scopes, and status may move; raw bearer tokens or one-time full keys must never enter migration bundles or evidence.
  7. Archive last. Core Hub stays deployable until the final stabilization gate, reverse-delta requirement, and residual ownership record are closed.

Runtime and database shape

The candidate uses a distinct hub-core-owned schema, provisionally hub_runtime, beside retained legacy schema core_hub in the existing platform PostgreSQL allocation. This does not consume another application database slot. The target adds its own audit ledger and migration lineage; Core Hub models and migrations are not imported. Deployment remains owned by rapp-core-hub during dual-run, with final package naming/ownership recorded before this repository is archived.

Entry gates

Absorption implementation does not begin until all of these are evidenced:

  • the completed HUB-WP-0004-T01T05 work is committed and pushed;
  • a hub-core wheel and OCI image identify the same revision and version;
  • rapp-core-hub can deploy a second, cluster-internal candidate without changing hub.coulomb.social;
  • hub-core has a production PostgreSQL PortStore/compatibility store, audit ledger, and migrations, and fails readiness when durable storage or its authorization dependency is unavailable;
  • the existing operator token and copied API-key hashes authenticate through the candidate without exposing credential values;
  • Core Hub export, hub-core import, row-count, canonical-digest, and delta replay commands are repeatable and record non-secret migration metadata;
  • the hub-core conformance profile and Core Hub compatibility tests pass against the candidate.

The current in-memory hub-core backend is a conformance implementation, not an absorption target. Its deliberate production-readiness failure is a useful gate and must not be bypassed.

Ordered slices

Slice Surface Move condition Consumer gate
S0 — candidate foundation image, API/MCP processes, migrations, durable store/audit, auth adapter, group controls, health/readiness All entry gates above; all seven source tables representable; no public route hub-core conformance plus Core Hub contract suite
S1 — system/discovery health/readiness; widget/event/annotation/policy catalogs; compatibility OpenAPI/docs and aliases Response status, headers, and canonical JSON match; dependency-aware readiness public probes, ops-hub public gate, activity-core resolver
S2 — registry/manifests hubs, capability manifests/activation, hub registry IDs and legacy serialization preserved; counts/digests match; activation audited ops-hub can resolve/update its manifest; reverse delta proven
S3 — consumers/credentials API consumers, key issuance, /token Hashes/prefixes only; auth deny cases and custody separation pass; rate/quota residual explicit existing ops-hub and activity-core credentials; reverse key-hash delta proven
S4 — widgets/interaction widgets; interaction-event append/list mapped to port.events.interaction Historical IDs/timestamps retained; event families remain separate; projection/reverse replay pass ops-hub and activity-core correlated append/readback
S5 — deferred/console empty annotation, requirement, decision, deployment and outcome collections; /console Exact empty/error behavior; residual disposition per collection; console has no source-schema reads operator CLI, protected console, visual smoke
S6 — whole-host authority all /api/v2, API/MCP entrypoints and remaining traffic Final backup/delta has zero unexplained drift; operator approves; seven consecutive stable days before retirement hub-core conformance and Core Hub, ops-hub, activity-core gates together

Related calls within a slice move as one traffic group. In particular, public traffic must not mix old and new authorities inside registry, credential, or widget/interaction workflows whose identifiers cross resource boundaries.

Compatibility adapters

Hub-core's named ports are not themselves the legacy /api/v2 contract. The target needs an explicit compatibility composition layer:

  • hub and manifest resources map to port.registry while preserving legacy IDs, body fields, activation behavior, pagination envelope, and hub-registry projection;
  • interaction events map to port.events.interaction with a stable correlation ID, original event ID, widget reference, view context, event type, metadata, and occurrence/recording timestamps;
  • widgets and API consumers/keys remain compatibility resources until a named replacement port is accepted; they must not be forced into registry records;
  • health/readiness retain the response shape expected by deployed Core Hub smoke tooling until consumers adopt the hub-core-native shape;
  • /api/v2/openapi.json, YAML/docs discovery, and required unprefixed aliases remain versioned compatibility artifacts through final cutover.

Data movement and comparison

For each durable slice:

  1. Export source records in dependency order with a schema version, source revision, high-water mark, and bundle SHA-256.
  2. Validate without writing; reject unknown fields, missing parents, raw secret shapes, duplicate identities, or a lower target schema version.
  3. Upsert into the target by stable ID. Re-running the same bundle must be idempotent and recorded as such.
  4. Compare table/resource counts, sorted identity sets, and canonical row digests. Timestamp formatting and JSON key order are normalized before hashing; semantic field differences are not ignored.
  5. Mirror only safe GET requests and compare status plus canonical response. Exercise writes with isolated migration fixtures, never by duplicating a production client request.
  6. At route cutover, drain writes for that group, capture the final high-water delta, import/compare it, switch the route group, and enable target writes.

Migration evidence may contain IDs, counts, hashes, versions, timestamps, and pass/fail results. It must not contain raw API keys, bearer tokens, database credentials, Authorization headers, or copied Kubernetes Secrets.

Traffic controls and rollback

rapp-core-hub owns one logical switch per slice with the states legacy, shadow, and candidate, plus independently observable legacy/candidate write-group sets. The concrete carrier may use the joint plan's HUB_CORE_V2_GROUPS, HUB_CORE_V2_WRITE_GROUPS, and CORE_HUB_V2_WRITE_GROUPS or equivalent Helm values. Configuration must reject overlapping writer sets, and every rendered release must reveal the selected state as non-secret evidence.

Rollback remains possible while a slice is target-owned:

  1. stop new target writes for the affected route group;
  2. export and verify the target-only delta by stable ID;
  3. replay that delta to Core Hub when the old source must become writable;
  4. compare counts/digests and run the consumer gate;
  5. switch the whole route group back to source.

If reverse replay is not implemented for a write slice, rollback is limited to the period before target writes are enabled. That limitation blocks public cutover and must be visible in the evidence report.

Required evidence per slice

  • hub-core source revision, package version, and OCI digest;
  • Core Hub source revision and deployed Helm revision;
  • source/target schema versions and migration bundle hash;
  • before/after counts, identity-set comparison, and canonical digest result;
  • compatibility/OpenAPI diff result;
  • auth positive and negative checks without credential disclosure;
  • named consumer smoke reports and correlation IDs;
  • selected route state, switch time, observer, and rollback result or reason it was not invoked.

Any schema mismatch, unexplained count/digest drift, secret-shaped evidence, auth broadening, consumer failure, or non-green readiness stops the slice and keeps public authority on Core Hub.

Ownership

Owner Responsibility
hub-core compatibility modules, durable store/migrations, import/delta/reverse-delta, conformance
core-hub source export, legacy fixtures/OpenAPI, canonical response comparison, rollback service
rapp-core-hub candidate deployment, immutable image pin, route switches, rollout/rollback evidence
railiance-platform / rapp-postgres PostgreSQL, credential delivery, backup/restore readiness
ops-hub bootstrap and registry consumer gate
activity-core interaction resolver, append, and readback gate
operator approval for every production writer change, S6 public authority, and later repository archive

Next executable work

After hub-core publishes its completed T01T06 revision, start S0. The first implementation commit should add the durable PostgreSQL boundary and legacy auth/health compatibility in hub-core, plus a candidate deployment mode in rapp-core-hub. It must not change public DNS or ingress.