The custodians initial cross repo task and workplan tracking hub
Find a file
tegwick 821b5d6c89 fix(STATE-WP-0064): parse consistency sweep stdout with skip prefixes
Extract the JSON payload from mixed script output and document Railiance01
kubectl sync steps. Mark T02 done after cluster bridge and resolver canaries.
2026-06-21 20:56:35 +02:00
.claude/rules Add shared credential-routing template and propagation tooling 2026-06-18 22:48:43 +02:00
api fix(STATE-WP-0064): parse consistency sweep stdout with skip prefixes 2026-06-21 20:56:35 +02:00
dashboard STATE-WP-0062 T5: docs, first-party↔repo test, mark workplan finished 2026-06-19 21:16:37 +02:00
docs fix(STATE-WP-0064): parse consistency sweep stdout with skip prefixes 2026-06-21 20:56:35 +02:00
flows feat(tasks): adopt canonical task statuses 2026-05-26 01:32:50 +02:00
history docs(history): cross-link BRIDGE-WP-0005 restart cleanup workplan 2026-06-21 20:12:17 +02:00
infra feat(STATE-WP-0064): add consistency sweep remote-all API endpoint 2026-06-21 20:19:22 +02:00
mcp_server feat: add State Hub bulk status skill 2026-06-07 20:11:07 +02:00
migrations STATE-WP-0062 T1: two-dimension service_catalog model + migration 2026-06-19 20:46:07 +02:00
policies STATE-WP-0062 T4: Service DoM uses "Level" not "Tier" 2026-06-19 21:03:35 +02:00
prompts feat(sbom): CUST-WP-0013 — expand SBOM infra to terraform, ansible, and tool manifests 2026-03-12 04:40:26 +01:00
registry Add capability registry scaffold and seed entries from reuse-surface 2026-06-16 01:34:23 +02:00
scripts Add shared credential-routing template and propagation tooling 2026-06-18 22:48:43 +02:00
skills/state-hub feat: add State Hub bulk status skill 2026-06-07 20:11:07 +02:00
task_flow_engine Harden flow advancement exit assertions 2026-05-23 16:41:21 +02:00
templates/recently-on-scope Implement RecentlyOnScope domain digest 2026-05-22 13:45:53 +02:00
tests fix(STATE-WP-0064): parse consistency sweep stdout with skip prefixes 2026-06-21 20:56:35 +02:00
workplans fix(STATE-WP-0064): parse consistency sweep stdout with skip prefixes 2026-06-21 20:56:35 +02:00
.custodian-brief.md chore(consistency): sync task status from DB [auto] 2026-06-21 20:24:29 +02:00
.dockerignore Locked in cytoscape.js as visualization for dep graph 2026-05-03 01:43:50 +02:00
.env.example feat(CUST-WP-0014): repo sync automation & Gitea inventory 2026-03-16 01:41:16 +01:00
.gitignore Fix Claude instruction imports 2026-06-18 00:29:04 +02:00
AGENTS.md Add shared credential-routing template and propagation tooling 2026-06-18 22:48:43 +02:00
alembic.ini Add state-hub v0.1 — local-first state service for the Custodian 2026-02-24 17:47:49 +01:00
CLAUDE.md Add shared credential-routing template and propagation tooling 2026-06-18 22:48:43 +02:00
custodian_cli.py cli command statehub register with install 2026-06-05 13:09:25 +02:00
Dockerfile Locked in cytoscape.js as visualization for dep graph 2026-05-03 01:43:50 +02:00
INTENT.md docs: clarify state hub intent 2026-05-17 21:37:02 +02:00
LICENSE Initial commit 2026-05-17 16:15:50 +00:00
Makefile fix: stabilize consistency make wrappers 2026-06-07 19:49:17 +02:00
pyproject.toml feat: import core schemas from hub-core 2026-06-07 01:20:57 +02:00
README.md feat: add workplan aliases and legacy meter 2026-06-04 08:25:31 +02:00
SCOPE.md Normalize workplan IDs and activate parents on task start 2026-05-23 16:31:28 +02:00
statehub_register.py cli command statehub register with install 2026-06-05 13:09:25 +02:00
uv.lock feat: import core schemas from hub-core 2026-06-07 01:20:57 +02:00

State Hub

State Hub is the live coordination service for the Custodian ecosystem: PostgreSQL persistence, FastAPI API, FastMCP server, Observable dashboard, consistency tooling, and repo/workplan synchronization.

This repository is the standalone home for the service. It was extracted from the former embedded implementation at:

/home/worsch/the-custodian/state-hub

Extraction State

The extraction workplan CUST-WP-0043 - State Hub Repo Extraction is complete.

Current state:

  • The implementation has been imported here with subtree history.
  • CUST-WP-0042 has been re-homed into this repository.
  • The old embedded tree in the-custodian remains only as a pointer.
  • This repository is authoritative for State Hub code, docs, tests, dashboard, migrations, scripts, policies, and State Hub-local workplans.

Workplans

New State Hub-local workplans should use the prefix:

STATE-WP-0001

Legacy Custodian-hosted State Hub plans, such as CUST-WP-0042, may retain their existing IDs when that preserves State Hub workstream/task continuity. Do not create duplicate workstreams manually; write the workplan file first, then run consistency sync.


Stack

Layer Technology Port
Database PostgreSQL 16-alpine (Docker) 127.0.0.1:5432
API FastAPI + SQLAlchemy 2.0 async + asyncpg 127.0.0.1:8000
MCP server FastMCP SSE 127.0.0.1:8001
Dashboard Observable Framework 127.0.0.1:3000
CLI custodian (Python, uv entry point)

All services bind to 127.0.0.1 only — nothing exposed to the network.


Setup

Prerequisites

  • Docker Engine
  • Python 3.12+ with uv (pip install uv)
  • Node.js 18+ (dashboard only)

First-time

cd /home/worsch/state-hub

cp .env.example .env          # edit POSTGRES_PASSWORD
make install                  # uv sync
make db                       # docker compose up postgres
make migrate                  # alembic upgrade head
make seed                     # insert 6 canonical topics
make api                      # db + migrate + uvicorn :8000 (restarts if running)

Dashboard

make dashboard    # installs dashboard deps if needed, then Observable dev server on :3000
make dashboard-check  # installs deps if needed, then runs Observable build

Start Everything

To start all the infrastructure on separate consoles do:

make db           # docker compose up postgres
make mcp-http     # start state-hub mcp service
make dashboard    # Observable dev server on :3000
make bridges      # Set up ssh bridges for cross machines access

CLI

make install-cli              # symlink .venv/bin/custodian → ~/.local/bin
custodian status              # API health + summary totals
custodian register-project    # register cwd as a Custodian project

Makefile Targets

Target What it does
make install uv sync — install Python deps + entry points
make install-cli Symlink custodian to ~/.local/bin
make db Start postgres container
make db-tools Start postgres + pgadmin (http://127.0.0.1:5050)
make migrate alembic upgrade head
make seed Insert 6 canonical topics
make api db + wait + migrate + uvicorn (restarts if running)
make dashboard-install Install dashboard npm deps from dashboard/package-lock.json
make dashboard-check Build the Observable dashboard as a smoke/regression check
make dashboard Install deps if needed, then start Observable dev server (restarts if running)
make check curl /state/health
make test Python test suite plus make dashboard-check
make register-project DOMAIN=x PROJECT_PATH=y Register a project
make clean docker compose down -v (destroys DB volume)

Database Schema

Five tables in dependency order:

topics
└── workstreams
    └── tasks (self-FK: parent_task_id)
        └── progress_events
decisions (FK: topic_id, workstream_id — at least one required)
    └── progress_events

Enums

Enum Values
topic_status active · paused · archived
workstream_status proposed · ready · active · blocked · backlog · finished · archived
task_status wait · todo · progress · done · cancel
task_priority low · medium · high · critical
decision_type made · pending
decision_status open · resolved · escalated · superseded
domain custodian · railiance · markitect · coulomb_social · personhood · foerster_capabilities

Governance constraints encoded in schema

  • No hard DELETE endpoints — only soft: archived, cancel, superseded
  • progress_events has no updated_at and no DELETE endpoint (append-only per constitution §5)
  • decisions with financial/legal keywords + pending type → auto-set escalation_note (§4)

API

Interactive docs at http://127.0.0.1:8000/docs once the API is running.

Key endpoint: /state/summary

Returns a full snapshot in one call — used by both the MCP server and dashboard:

{
  "generated_at": "...",
  "totals": {
    "topics":      { "active": 6, "paused": 0, "archived": 0, "total": 6 },
    "workstreams": { "ready": 1, "active": 1, "blocked": 0, "finished": 1, "total": 3 },
    "tasks":       { "wait": 0, "todo": 9, "progress": 0, "done": 11, "cancel": 0, "total": 20 },
    "decisions":   { "open": 1, "resolved": 0, "escalated": 0, "total": 1 }
  },
  "topics": [...],             // topics with nested workstream stubs
  "blocking_decisions": [...], // pending decisions only
  "waiting_tasks": [...],
  "recent_progress": [...],    // last 20 events
  "open_workstreams": [...]
}

Router summary

Prefix Operations
/topics CRUD (soft-delete: archived)
/workplans Preferred CRUD surface for repo-backed workplans (soft-delete: archived)
/workstreams Legacy compatibility CRUD surface; usage is recorded by legacy-meter
/tasks CRUD (soft-delete: cancel); PATCH updates status
/decisions CRUD (soft-delete: superseded); auto-escalation
/progress GET list + POST append — no DELETE
/legacy-meter Register, meter, and review legacy interface usage
/state/summary Full snapshot
/state/health DB connectivity check

See docs/workplan-terminology-transition.md for the workstream-to-workplan compatibility policy and retirement criteria.


MCP Server

Runs as a persistent SSE service on :8001, independent of the Claude Code session. Restart it anytime without restarting Claude Code.

make mcp-http   # start (or restart) the MCP SSE server on :8001

Registered at user scope in ~/.claude.json:

{ "type": "sse", "url": "http://127.0.0.1:8001/sse" }

To re-register from scratch:

claude mcp remove state-hub -s user 2>/dev/null || true
claude mcp add-json -s user state-hub '{"type":"sse","url":"http://127.0.0.1:8001/sse"}'

See mcp_server/TOOLS.md for the full tool reference card (30 lines, faster than reading server.py).

Tools at a glance

Query (read-only): get_state_summary · get_topic · list_blocked_tasks · list_pending_decisions · get_recent_progress

Mutate (each auto-emits a progress event): create_task · update_task_status · record_decision · resolve_decision · add_progress_event · update_workstream_status

Resources: state://summary · state://topics · state://workstreams/{topic_slug} · state://decisions/blocking · state://tasks/blocked


custodian CLI

Installed into .venv/bin/custodian by uv sync; symlinked to ~/.local/bin by make install-cli.

custodian register-project [--domain DOMAIN] [--path PATH]
  • --path defaults to current working directory
  • --domain is auto-detected from project_charter_v*.md frontmatter if omitted
custodian status

Prints API health, totals, and any blocking decisions.

What register-project does

  1. Verifies the API is reachable (fails fast with make api hint)
  2. Looks up the topic ID for the domain via /topics/?status=active
  3. Checks that state-hub is in ~/.claude.json
  4. Writes $PROJECT_PATH/CLAUDE.md from scripts/project_claude_md.template
  5. Posts a milestone progress event recording the registration

Project Registration Scripts

Script Purpose
scripts/register_project.sh Shell version of custodian register-project
scripts/patch_mcp_cwd.py Legacy: patched cwd for the old stdio registration (no longer needed)
scripts/project_claude_md.template CLAUDE.md template with {PROJECT_NAME}, {DOMAIN}, {TOPIC_ID}
scripts/seed.py Insert the 6 canonical topics into a fresh database
scripts/pull_image.py WSL2 workaround: pull Docker images via Python urllib with Range-request chunking

Dashboard

Four pages at http://127.0.0.1:3000 (dev) or built with npm run build:

Page Content
Overview Status cards, task-by-status chart, recent activity feed, decisions due within 7 days
Workstreams Filterable table by domain/status/owner; selected workstream task list; progress timeline
Decisions Pending tab (with escalation highlights) and Made tab; resolution velocity chart
Progress Append-only event feed with author badges; 30-day event volume chart

Data loaders (src/data/*.json.py) are Python scripts that call the local API. They run at dev-server start and on npm run build. Clear the cache if data appears stale:

rm -rf dashboard/src/.observablehq/cache/

Known Issues / WSL2 Notes

  • TLS bad record MAC on large downloads: WSL2 corrupts packets on big TCP transfers. Use scripts/pull_image.py instead of docker pull for future image pulls.
  • MCP server is now SSE, not stdio: Re-registration is claude mcp add-json -s user state-hub '{"type":"sse","url":"http://127.0.0.1:8001/sse"}'. The patch_mcp_cwd.py script and .mcp.json config are legacy artifacts from the old stdio setup.
  • AsyncSession concurrency: SQLAlchemy 2.0 async sessions don't support concurrent operations. All queries in /state/summary run sequentially on a single session.