This repository has been archived on 2026-07-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core-hub/docs/specs/testing-release-and-migration.md

3.4 KiB

Testing, Release, and Migration Spec

Test Layers

  • unit tests for models, validators, and services
  • API tests for route behavior and auth semantics
  • contract tests from fixtures
  • migration tests for Alembic revisions and imports
  • consumer smokes for ops-hub and activity-core
  • optional Playwright visual checks once UI exists

Release Gates

A Core Hub release cannot replace Inter-Hub until:

  • public /api/v2 compatibility smokes pass;
  • protected route auth behavior is proven without exposing secrets;
  • ops-hub bootstrap smoke passes;
  • activity-core sink smoke passes or is explicitly deferred to State Hub fallback;
  • data import row counts and relationship checks pass;
  • rollback path is documented;
  • production operator approves cutover.

Migration Gates

  • Extract Inter-Hub schema and route inventory.
  • Build fixture set from representative production-safe records.
  • Import data into Core Hub staging.
  • Compare row counts and key relationships.
  • Run dual-read or shadow smokes.
  • Switch traffic only after smoke evidence is recorded.

Migration Bundle v1

Core Hub staging imports use core-hub.migration.v1 JSON bundles. The bundle is the handoff contract from the Haskell Inter-Hub export path into the Python/FastAPI replacement:

  • schemaVersion: core-hub.migration.v1
  • source: normally inter-hub-haskell
  • exportedAt: export timestamp for operator traceability
  • records.hubs
  • records.hubCapabilityManifests
  • records.apiConsumers
  • records.apiKeys
  • records.widgets
  • records.interactionEvents

API key records may contain keyPrefix, keyHash, scopes, status, and lifecycle metadata. They must not contain full key material, raw tokens, or secrets. Existing runtime keys are not recoverable from Inter-Hub unless an approved custody path provides them; migration preserves only non-secret evidence.

The reference schema is contracts/schemas/migration-bundle.schema.json, with a minimal fixture at contracts/fixtures/migration/interhub-minimal.bundle.json.

Import Procedure

Validate a bundle without database access:

PYTHONPATH=src uv run --extra dev python scripts/core_hub_migrate.py validate \
  contracts/fixtures/migration/interhub-minimal.bundle.json

Dry-run against the configured target database:

CORE_HUB_DATABASE_URL=postgresql+asyncpg://... \
PYTHONPATH=src uv run --extra dev python scripts/core_hub_migrate.py import \
  /secure/operator/path/interhub-export.bundle.json --dry-run

Import after the dry-run report is reviewed:

CORE_HUB_DATABASE_URL=postgresql+asyncpg://... \
PYTHONPATH=src uv run --extra dev python scripts/core_hub_migrate.py import \
  /secure/operator/path/interhub-export.bundle.json

Each successful import writes a migration_runs row containing the source, schema version, bundle SHA-256, row counts, warnings, and relationship checks.

Rollback Procedure

For staging, reset the target database and replay the same bundle after fixing the export or mapper. For production cutover, take a database snapshot before import, keep Inter-Hub read-only during verification, and roll traffic back to Inter-Hub if row counts, relationship checks, or consumer smokes fail. Do not delete or rotate legacy key custody records during the rollback window.

Haskell Retirement Gate

Do not retire production Inter-Hub or the haskelseed/Haskell build lane until Core Hub serves the required compatibility surface and production traffic has moved.