From f46f46172077a844c936146ed7c654152384f42c Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 6 Jun 2026 19:33:53 +0200 Subject: [PATCH] docs: start CUST-WP-0025 hub-core extraction --- docs/hub-core-extraction-boundary.md | 120 ++++++++++++++++++++ workplans/CUST-WP-0025-fos-hub-bootstrap.md | 51 ++++++--- 2 files changed, 157 insertions(+), 14 deletions(-) create mode 100644 docs/hub-core-extraction-boundary.md diff --git a/docs/hub-core-extraction-boundary.md b/docs/hub-core-extraction-boundary.md new file mode 100644 index 0000000..ac39c22 --- /dev/null +++ b/docs/hub-core-extraction-boundary.md @@ -0,0 +1,120 @@ +# Hub-Core Extraction Boundary + +Last reviewed: 2026-06-06 + +## 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 + tpsc.py + schemas/ + __init__.py + domain.py + managed_repo.py + agent_message.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. + +## 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/tpsc.py` | Generic catalog and GDPR report router. | +| `api/routers/policy.py` | Generic policy document router if policy roots become configurable. | + +## 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 | Counts topics, workstreams, extension points, and technical debt. Hub-core should expose a domain summary hook that dev-hub can implement. | +| `ManagedRepo` | Contains `topic_id`, SBOM fields, and state-sync timestamps. Keep minimal repo identity in core, then add dev-hub extensions. | +| `CapabilityRequest` | Points at workstreams and tasks. Hub-core needs generic context fields or optional extension references before extraction. | +| `ProgressEvent` | Points at topics, workstreams, tasks, and decisions. Hub-core should define event identity, type, summary, detail, author, and timestamps, with hub-specific subject references added by each hub. | +| MCP tools in `mcp_server/server.py` | Generic tools are mixed into a single dev-hub server module. T06 should create a base registration class that receives API client/config dependencies and lets dev-hub add its own tools. | + +## 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 + +Create the `/home/worsch/hub-core` package with only the first package slice, +commit that seed independently, then return to `/home/worsch/state-hub` for the +first import-based refactor. Do not rename State Hub to dev-hub until T05-T08 +prove the shared package boundary. diff --git a/workplans/CUST-WP-0025-fos-hub-bootstrap.md b/workplans/CUST-WP-0025-fos-hub-bootstrap.md index b8f67dd..edefb90 100644 --- a/workplans/CUST-WP-0025-fos-hub-bootstrap.md +++ b/workplans/CUST-WP-0025-fos-hub-bootstrap.md @@ -8,7 +8,7 @@ status: active owner: custodian topic_slug: custodian created: "2026-03-20" -updated: "2026-03-20" +updated: "2026-06-06" state_hub_workstream_id: "293a74fe-a85a-4ad6-8933-23d52a72fe8b" --- @@ -119,9 +119,16 @@ Document the OIDC contract as `canon/standards/iam-profile_v0.1.md`: ## Phase 2 — Hub Extraction & Dev Hub Rename **Goal**: Extract generic hub-core package; rename state-hub to dev-hub. -**Repo**: the-custodian (extraction), hub-core (new repo) +**Repo**: the-custodian (governance and workplan), `/home/worsch/state-hub` +(authoritative source), `/home/worsch/hub-core` (new target repo) **Runs in parallel with Phase 1.** +**Current repo reality (2026-06-06):** `CUST-WP-0043` completed the State Hub +repo extraction, so this repository now keeps only the `state-hub/README.md` +pointer. Phase 2 implementation work must read and refactor the standalone +`/home/worsch/state-hub` checkout, while this workplan keeps the coordination +record in `the-custodian`. + ### Extraction Boundary **Generic hub-core (~17 MCP tools, ~6 models, ~6 routers):** @@ -136,19 +143,27 @@ Document the OIDC contract as `canon/standards/iam-profile_v0.1.md`: ```task id: CUST-WP-0025-T05 -status: todo +status: in_progress priority: high state_hub_task_id: "04bf480c-8847-4a89-a4f2-e7c5fc51088d" ``` -Create `hub-core` as a standalone repo with `pyproject.toml` (uv-managed). -Extract from state-hub: +Create `/home/worsch/hub-core` as a standalone repo with `pyproject.toml` +(uv-managed). Extract from `/home/worsch/state-hub`: - Generic SQLAlchemy models (Domain, AgentMessage, CapabilityCatalog, CapabilityRequest, ManagedRepo, TPSC*, ProgressEvent) - Generic Pydantic schemas - Generic FastAPI routers (domains, repos, messages, capability_requests, tpsc, policy) - Alembic migration templates for core schema - Shared utilities (slug resolution, pagination, trailing-slash normalization) +Implementation start (2026-06-06): reviewed the standalone State Hub source and +captured the first extraction boundary in +`docs/hub-core-extraction-boundary.md`. Several candidate "generic" models still +reference dev-hub tables (`topics`, `workstreams`, `tasks`, `decisions`), so the +initial package slice should start with base DB primitives, domains, repos, +messages, TPSC catalog/snapshots, and adapter seams for progress and capability +requests rather than a blind file copy. + ### T06 — Hub-core FastMCP base server ```task @@ -193,7 +208,7 @@ priority: high state_hub_task_id: "daf1d8ac-b55a-4692-b359-2671ddf6fc8a" ``` -Refactor the state-hub codebase: +Refactor the standalone `/home/worsch/state-hub` codebase: - Replace generic models/routers/schemas with imports from hub-core - Keep dev-specific code (topics, workstreams, tasks, decisions, etc.) in state-hub - Ensure all existing tests pass with the new import structure @@ -209,13 +224,13 @@ state_hub_task_id: "2148a804-7d6a-4e26-b1a8-08da24929c88" ``` Rename across all integration points: -- `state-hub/mcp_server/server.py`: name="state-hub" → "dev-hub" +- `/home/worsch/state-hub/mcp_server/server.py`: name="state-hub" → "dev-hub" - `~/.claude/CLAUDE.md`: 3 locations (registration commands, references) -- `state-hub/scripts/register_project.sh`: validation checks -- `state-hub/scripts/patch_mcp_cwd.py`: config checks -- `state-hub/custodian_cli.py`: config checks -- `state-hub/scripts/project_rules/session-protocol.template`: template text -- `state-hub/api/main.py`: service metadata response +- `/home/worsch/state-hub/scripts/register_project.sh`: validation checks +- `/home/worsch/state-hub/scripts/patch_mcp_cwd.py`: config checks +- `/home/worsch/state-hub/custodian_cli.py`: config checks +- `/home/worsch/state-hub/scripts/project_rules/session-protocol.template`: template text +- `/home/worsch/state-hub/api/main.py`: service metadata response ### T10 — MCP config migration script @@ -226,7 +241,7 @@ priority: medium state_hub_task_id: "5953f129-089d-4d90-bbe5-f86da4eac1bf" ``` -Create `state-hub/scripts/migrate_mcp_config.py` that: +Create `/home/worsch/state-hub/scripts/migrate_mcp_config.py` that: - Reads `~/.claude.json` - Renames `mcpServers["state-hub"]` to `mcpServers["dev-hub"]` - Preserves all other settings @@ -258,7 +273,7 @@ state_hub_task_id: "e55ae544-3cea-485e-80d5-a9696ef97b96" ``` Gate: all of the following must pass before Phase 2 is considered complete: -- `cd state-hub && make test` — full test suite +- `cd /home/worsch/state-hub && make test` — full test suite - `make fix-consistency REPO=the-custodian` — workplan ↔ DB sync - `make check-consistency-all` — all registered repos - Manual smoke test: start dev-hub MCP server, run get_domain_summary from a domain repo @@ -269,6 +284,14 @@ Gate: all of the following must pass before Phase 2 is considered complete: **Depends on**: Phase 2 (hub_core available), Phase 1 (identity for service auth). **Repo**: ops-hub (new standalone repo, registered under custodian domain) +**Inventory-first implementation slice (2026-06-05):** `CUST-WP-0047` +carves out the minimum useful part of T14/T16/T18 before the full standalone +`ops-hub` scaffold exists: a repo-owned service inventory contract, an initial +service/location/evidence seed, and the handoff path for Inter-Hub widgets and +activity-core probes. The T13-T19 tasks below remain the long-term ops-hub +implementation; the inventory slice produces input artifacts that the eventual +ops-hub repo can ingest rather than replace. + ### T13 — Create ops-hub repo from hub-core scaffold ```task