249 lines
12 KiB
Markdown
249 lines
12 KiB
Markdown
# 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:
|
||
|
||
```text
|
||
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.
|
||
- 2026-06-22: HUB-WP-0002 completed. Added
|
||
`create_capability_request_write_router` with host callbacks for routing,
|
||
model construction, flow transitions, notifications, task-unblock, patch,
|
||
dispute, and reroute side effects. State Hub mounts write routes from the
|
||
factory while keeping dev-hub columns (`requesting_workplan_id`,
|
||
`blocking_task_id`, `fulfilling_workplan_id`) on its extended model.
|
||
- 2026-06-22: `HubCoreMCPServer.attach_to()` registers generic MCP tools on a
|
||
host server with `exclude` for dev-hub overrides. State Hub now composes
|
||
hub-core messaging, capability read lifecycle, TPSC list/DoI, and FOS §10
|
||
tools while keeping enriched orientation, repo registration, capability
|
||
request creation, TPSC ingest, and service registration tools 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:
|
||
|
||
```python
|
||
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` | Write routes now mount from `create_capability_request_write_router` with host callbacks. State Hub keeps workplan/task columns on its model; generic hubs use `request_context` / `fulfillment_context` JSON. Optional future step: map State Hub columns into JSON and drop duplicate fields. |
|
||
| `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 register via `HubCoreMCPServer.attach_to(mcp, exclude=...)`. Remaining local tools: dev-hub orientation (`get_state_summary`, `get_domain_summary`), extended repo/capability/TPSC contracts, and all workstream/task/decision tooling. |
|
||
|
||
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
|
||
|
||
Close **CUST-WP-0048** T05–T07: run full State Hub regression, mark the child
|
||
workplan finished, and return to **CUST-WP-0025** dev-hub rename (T09+). Do not
|
||
rename State Hub to dev-hub until CUST-WP-0048 closes.
|