Files
the-custodian/docs/hub-core-extraction-boundary.md

12 KiB

Hub-Core Extraction Boundary

Last reviewed: 2026-06-07

Purpose

This note starts CUST-WP-0025-T05 by translating the original hub-core idea into a current implementation boundary. The State Hub implementation no longer lives under the-custodian/state-hub; the authoritative source checkout is /home/worsch/state-hub, and the planned package target is /home/worsch/hub-core.

The extraction must preserve a clean FOS split:

  • hub-core owns reusable hub primitives.
  • state-hub becomes the first dev-hub implementation and keeps development coordination concepts such as topics, workstreams, tasks, decisions, dependencies, SBOM, token accounting, and kaizen agents.
  • Future hubs such as ops-hub and fin-hub depend on hub-core without pulling in dev-hub coordination tables.

First Package Slice

Create /home/worsch/hub-core as a uv-managed Python package with this initial layout:

hub_core/
  __init__.py
  database.py
  models/
    __init__.py
    base.py
    domain.py
    managed_repo.py
    agent_message.py
    capability_catalog.py
    capability_request.py
    progress_event.py
    tpsc.py
  schemas/
    __init__.py
    domain.py
    managed_repo.py
    agent_message.py
    capability.py
    progress_event.py
    tpsc.py
  routers/
    __init__.py
    domains.py
    repos.py
    messages.py
    tpsc.py
    policy.py

This slice avoids the models that currently carry dev-hub foreign keys. It is large enough to prove packaging, import style, SQLAlchemy metadata ownership, router dependency injection, and State Hub compatibility before the more entangled surfaces move.

Current implementation status:

  • 2026-06-06: /home/worsch/hub-core was created and committed with base, domain, managed repo, agent message, capability catalog, and TPSC models plus matching schemas.
  • 2026-06-06: router factory functions were added for domains, repos, messages, TPSC, and policy lookup. These factories accept host-supplied dependencies instead of importing State Hub globals.
  • 2026-06-06: shared utilities and migration scaffold were added: slug normalization, pagination, repo path resolution, trailing-slash path normalization, Alembic templates, and an initial core-schema migration.
  • 2026-06-06: progress event and capability request adapter seams were added. Hub-core uses generic JSON context fields where State Hub currently has dev-specific workstream/task/topic/decision foreign keys.
  • 2026-06-07: progress and capability REST router factories were added. T05 now has the package-side models, schemas, routers, migration scaffold, and shared utilities needed before T06/T08.
  • 2026-06-07: HubCoreMCPServer was added as the first T06 slice. It wraps the generic REST endpoints with FastMCP tools and keeps the MCP layer stateless.
  • 2026-06-07: T06/T07 completed in hub-core with orientation and DoI MCP tools, canonical FOS §10 risk/alert event types, /progress/risks and /progress/alerts REST views, and matching MCP read tools.
  • 2026-06-07: T08 started in State Hub. hub-core is now an editable dependency, and State Hub re-exports message and DoI response schemas from hub_core.schemas with full pytest coverage passing.
  • 2026-06-07: T08 schema imports expanded. Hub-core's TPSC schema/report contract now matches State Hub, and State Hub re-exports api.schemas.tpsc from hub_core.schemas.tpsc.
  • 2026-06-07: T08 domain schema imports started. State Hub now imports base domain schemas from hub_core.schemas.domain while keeping dev-hub-specific domain detail and summary schemas local.
  • 2026-06-07: T08 router imports started. State Hub now mounts the hub-core messages router factory with State Hub's own AgentMessage model injected, proving the router seam can avoid cross-metadata SQLAlchemy model imports.
  • 2026-06-07: T08 policy router import completed. State Hub now mounts the hub-core policy router factory with local path validation plus read/write callbacks, proving non-DB routers can move behind callback seams.
  • 2026-06-07: T08 TPSC router import completed. State Hub now mounts the hub-core TPSC router factory with State Hub's own repo and TPSC models injected, extending the host-model seam to a multi-model router.
  • 2026-06-07: T08 progress router import completed. State Hub now mounts the hub-core progress router factory with State Hub's own progress model and schemas injected, preserving topic/workstream/task filters while gaining the shared risk and alert progress views.
  • 2026-06-07: T08 domains router import completed. State Hub now mounts the hub-core domains router factory with State Hub's own domain/repo models and schemas injected, plus callbacks for dev-hub detail counts and archive validation.
  • 2026-06-07: T08 additional schema imports completed. State Hub now imports generic capability catalog/status/dispute schemas and the repo path-register schema from hub-core, and State Hub repo create/read schemas extend the hub-core contracts while adding dev-hub fields.
  • 2026-06-07: T08 capability catalog router import completed. State Hub now mounts the hub-core capability catalog router factory with State Hub's own domain, repo, and catalog models injected, while keeping capability request workflow routes local.
  • 2026-06-07: T08 capability request read router import completed. State Hub now mounts the hub-core request list/detail router factory with State Hub's own domain and request models injected, while keeping request creation, status transitions, acceptance, patching, dispute, and reroute workflow routes local.
  • 2026-06-07: CUST-WP-0048 T04 repos router boundary resolved. State Hub now mounts the hub-core repo registry factory for collection, lookup, detail, update, and host-path routes with State Hub's own models and schemas injected, while keeping onboarding, DoI, scope-health, dispatch, archive, and consistency-sync routes local.

Extract Now

These State Hub files are suitable for the first extraction after import-path rewriting and small router seams:

Source in /home/worsch/state-hub Target role
api/models/base.py Declarative base, timestamps, UUID helper.
api/models/domain.py Core domain identity; remove relationships to dev-hub-only models from core.
api/models/managed_repo.py Core repo registry; make topic_id, SBOM, and sync timestamps extension fields or keep them in dev-hub until a second pass.
api/models/agent_message.py Generic agent inbox and thread model.
api/models/tpsc.py Third-party service catalog/snapshot primitives.
api/schemas/domain.py Core domain schemas; split dev-hub counts from generic read models.
api/schemas/managed_repo.py Core repo schemas; keep dispatch/scope-health schemas in dev-hub.
api/schemas/agent_message.py Generic message schemas.
api/schemas/tpsc.py Generic TPSC schemas.
api/routers/messages.py Mostly self-contained generic router.
api/routers/progress.py Generic progress-event router once dev-hub foreign keys move behind subject_refs or extension mapping.
api/routers/capability_requests.py Generic capability catalog/request router once dev-hub flow side effects and task unblocking stay in dev-hub.
api/routers/tpsc.py Generic catalog and GDPR report router.
api/routers/policy.py Generic policy document router if policy roots become configurable.

The first committed router seam is factory-based rather than global:

from hub_core.routers import create_domains_router

app.include_router(create_domains_router(get_session))

That shape lets each hub keep its own database session configuration and mount only the generic routers it wants.

Shared Utilities

The initial utility set is intentionally small and dependency-light:

Module Purpose
hub_core.utils.slugs Convert user-facing names into stable lowercase slugs.
hub_core.utils.pagination Shared limit/offset bounds and SQLAlchemy pagination.
hub_core.utils.paths Resolve repo paths from host_paths before falling back to local_path.
hub_core.utils.routing Normalize a path or URL path component while preserving query strings and fragments.

Migration Scaffold

/home/worsch/hub-core now carries Alembic template files under hub_core/migrations/ plus versions/0001_core_schema.py. The first migration covers only the currently extracted core tables:

  • domains
  • managed_repos
  • agent_messages
  • capability_catalog
  • capability_requests
  • progress_events
  • tpsc_catalog
  • tpsc_snapshots
  • tpsc_entries

Needs An Adapter Seam

These are still part of the target architecture, but the current State Hub implementation is coupled to dev-hub concepts:

Surface Coupling to resolve
Domain and domains.py detail views Detail counts now use a dev-hub callback behind the hub-core router factory. Domain relationships still need a later model split if State Hub stops carrying topics/goals on the core table.
ManagedRepo State Hub create/read schemas now extend hub-core contracts, with topic_id, SBOM fields, and state-sync timestamps kept as dev-hub extensions. Generic repo registry collection, lookup, detail, update, and host-path routes now mount from the hub-core factory; State Hub keeps onboarding, DoI, scope-health, dispatch, archive, and consistency-sync behavior locally.
CapabilityRequest Catalog schemas, catalog CRUD routes, and read-only request list/detail routes now import from hub-core. Adapter seam is implemented with generic request_context and fulfillment_context; State Hub still needs a later refactor to map workstream/task references into those fields or a dev-hub extension table before request workflow routes can move.
ProgressEvent Adapter seam implemented with generic subject_refs; State Hub still needs a later refactor to map topic/workstream/task/decision foreign keys into that field or a dev-hub extension table.
MCP tools in mcp_server/server.py Generic tools are still mixed into the State Hub server module. T08 should begin replacing those registrations with HubCoreMCPServer inheritance or composition while dev-hub keeps its own tools.

The first two adapter seams are now implemented in hub-core:

  • ProgressEvent.subject_refs: generic JSON references for hub-local subjects.
  • CapabilityRequest.request_context and fulfillment_context: generic JSON context for hub-local workstreams, tasks, incidents, services, budgets, or other future hub entities.

Keep In Dev-Hub

The following State Hub areas should not move into hub-core during T05:

  • Topics, workstreams, tasks, decisions, dependencies, and flow state.
  • Extension points, technical debt, interface changes, SBOM, token events, and contribution accounting.
  • Dashboard-specific loaders and Observable views.
  • Workplan-file parsing and consistency reconciliation.
  • Kaizen agents, scope health, dispatch views, and recently-on-scope reports.

Verification Plan

The first hub-core commit should pass these checks before State Hub is refactored to import it:

  1. python3 -m compileall hub_core
  2. A minimal import test that imports every model, schema, and router module.
  3. SQLAlchemy metadata inspection proving the initial core tables are registered.
  4. A FastAPI smoke app that mounts the extracted routers with an injected get_session dependency.
  5. cd /home/worsch/state-hub && make test remains green before and after the editable hub-core dependency is introduced.

Next Step

Continue CUST-WP-0048 by resolving the capability request write workflow and then the generic MCP registration split. Do not rename State Hub to dev-hub until T05-T08 prove the shared package boundary.