generated from coulomb/repo-seed
chore: update standalone state hub wiring
This commit is contained in:
2
Makefile
2
Makefile
@@ -257,7 +257,7 @@ fix-consistency-all:
|
||||
|
||||
## Cancel open tasks belonging to completed/archived workstreams.
|
||||
## Safe to run at any time; also suitable for a daily cron job.
|
||||
## Cron example: 0 3 * * * cd ~/the-custodian/state-hub && make cleanup-stale
|
||||
## Cron example: 0 3 * * * cd ~/state-hub && make cleanup-stale
|
||||
cleanup-stale:
|
||||
uv run python scripts/cleanup_stale_tasks.py
|
||||
|
||||
|
||||
15
README.md
15
README.md
@@ -4,8 +4,8 @@ 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 replaces the former
|
||||
embedded implementation at:
|
||||
This repository is the standalone home for the service. It was extracted from
|
||||
the former embedded implementation at:
|
||||
|
||||
```text
|
||||
/home/worsch/the-custodian/state-hub
|
||||
@@ -15,13 +15,12 @@ embedded implementation at:
|
||||
|
||||
The repo is being prepared by `CUST-WP-0043 - State Hub Repo Extraction`.
|
||||
|
||||
During extraction:
|
||||
During the extraction window:
|
||||
|
||||
- The live implementation still exists in `the-custodian/state-hub/`.
|
||||
- This repo owns the standalone baseline and will become authoritative after
|
||||
the implementation move and verification gate.
|
||||
- State Hub implementation work should land here once registration and
|
||||
workplan re-homing are complete.
|
||||
- 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` should remain only as a pointer once
|
||||
the verification gate passes.
|
||||
|
||||
## Workplans
|
||||
|
||||
|
||||
7
SCOPE.md
7
SCOPE.md
@@ -29,15 +29,14 @@ telemetry.
|
||||
## Current Extraction Note
|
||||
|
||||
This repo is being established as the standalone State Hub home under
|
||||
`CUST-WP-0043`. Until the extraction verification gate passes, the prior live
|
||||
implementation remains at:
|
||||
`CUST-WP-0043`. The implementation has been imported here from:
|
||||
|
||||
```text
|
||||
/home/worsch/the-custodian/state-hub
|
||||
```
|
||||
|
||||
After verification, this repository becomes the authoritative implementation
|
||||
tree and the embedded copy should be removed or replaced with a pointer.
|
||||
After verification, this repository is authoritative and the embedded copy in
|
||||
`the-custodian` should be removed or replaced with a pointer.
|
||||
|
||||
## Workplan Convention
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
PUBLISHER = "the-custodian/state-hub"
|
||||
PUBLISHER = "state-hub"
|
||||
|
||||
|
||||
class EventEnvelope(BaseModel):
|
||||
|
||||
@@ -38,7 +38,7 @@ Two services are exposed through the tunnel:
|
||||
### Start the services
|
||||
|
||||
```bash
|
||||
cd ~/the-custodian/state-hub
|
||||
cd ~/state-hub
|
||||
|
||||
make api # FastAPI on :8000
|
||||
make mcp-http # MCP SSE server on :8001 (separate terminal)
|
||||
|
||||
@@ -317,7 +317,7 @@ CSS variables, so they adapt correctly to both light (`air`) and dark
|
||||
## Running the dashboard
|
||||
|
||||
```bash
|
||||
cd ~/the-custodian/state-hub/dashboard
|
||||
cd ~/state-hub/dashboard
|
||||
|
||||
npm run dev # Preview server on :3000 with hot reload
|
||||
npm run build # Static build into dist/
|
||||
|
||||
@@ -38,7 +38,7 @@ If the API goes offline while you are viewing a page:
|
||||
To restart the API:
|
||||
|
||||
```bash
|
||||
cd ~/the-custodian/state-hub
|
||||
cd ~/state-hub
|
||||
make api # db + migrate + uvicorn (restarts if already running)
|
||||
```
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ The CLI is installed via `make install-cli` from the state-hub directory.
|
||||
Ensure `~/.local/bin` is on your `PATH`.
|
||||
|
||||
**`ERROR: Cannot reach API`**
|
||||
The state hub API must be running: `cd ~/the-custodian/state-hub && make api`
|
||||
The state hub API must be running: `cd ~/state-hub && make api`
|
||||
|
||||
**`CLAUDE.custodian.md` already exists**
|
||||
Re-running `custodian register-project` overwrites it with a fresh
|
||||
|
||||
@@ -71,7 +71,7 @@ custodian register-project --domain <slug>
|
||||
|
||||
```bash
|
||||
# Auto-detects lockfile at repo root
|
||||
cd ~/the-custodian/state-hub
|
||||
cd ~/state-hub
|
||||
make ingest-sbom REPO=<slug> REPO_PATH=/absolute/path
|
||||
|
||||
# Multi-ecosystem repo — scan all lockfiles recursively
|
||||
|
||||
@@ -205,7 +205,7 @@ The hub's schema is organised in concentric layers:
|
||||
## Running the hub
|
||||
|
||||
```bash
|
||||
cd ~/the-custodian/state-hub
|
||||
cd ~/state-hub
|
||||
|
||||
make db # Start PostgreSQL (Docker)
|
||||
make migrate # Alembic upgrade head
|
||||
|
||||
@@ -107,7 +107,7 @@ const _liveEl = html`<div class="live-indicator">
|
||||
<span style="color:${_ok ? 'var(--theme-foreground-focus)' : 'red'}">●</span>
|
||||
${_ok
|
||||
? `Live · updated ${_ts?.toLocaleTimeString()}`
|
||||
: html`<span style="color:red">Offline — run: <code>cd ~/the-custodian/state-hub && make api</code></span>`}
|
||||
: html`<span style="color:red">Offline — run: <code>cd ~/state-hub && make api</code></span>`}
|
||||
</div>`;
|
||||
withDocHelp(_liveEl, "/docs/live-data");
|
||||
injectTocTop("live-indicator", _liveEl);
|
||||
|
||||
@@ -78,7 +78,7 @@ display(html`<div class="app-grid">
|
||||
icon: "🐘", name: "pgAdmin", status: pgadminUp,
|
||||
desc: "PostgreSQL admin UI for the state-hub database. Start with: make db in state-hub/.",
|
||||
url: "http://127.0.0.1:5050", label: "127.0.0.1:5050",
|
||||
note: pgadminUp ? "" : "Start with: cd ~/the-custodian/state-hub && docker compose --profile pgadmin up -d",
|
||||
note: pgadminUp ? "" : "Start with: cd ~/state-hub && docker compose --profile pgadmin up -d",
|
||||
})}
|
||||
${appCard({
|
||||
icon: "🌉", name: "ops-bridge", status: null,
|
||||
|
||||
@@ -24,7 +24,7 @@ events** on NATS JetStream so activity-core can react.
|
||||
POST /domain-goals/*/activate │ │ │
|
||||
scripts/cleanup_stale_tasks.py │ │ ▼
|
||||
└──────────────────────┘ RunActivityWorkflow
|
||||
the-custodian/state-hub (creates tasks in
|
||||
state-hub (creates tasks in
|
||||
issue-core, etc.)
|
||||
```
|
||||
|
||||
@@ -147,5 +147,5 @@ curl -X POST http://127.0.0.1:8000/repos/<slug>/sync
|
||||
|
||||
# Observe the envelope on the subscriber. Sample shape:
|
||||
# {"id":"...","type":"org.statehub.workstream.completed","version":"1.0",
|
||||
# "timestamp":"...","publisher":"the-custodian/state-hub","attributes":{...}}
|
||||
# "timestamp":"...","publisher":"state-hub","attributes":{...}}
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@ run them on a schedule.
|
||||
### A. `state-hub-consistency-sweep`
|
||||
|
||||
```yaml
|
||||
# activity-definitions/the-custodian/state-hub-consistency-sweep.yaml
|
||||
# activity-definitions/state-hub-consistency-sweep.yaml
|
||||
id: the-custodian.state-hub-consistency-sweep
|
||||
description: |
|
||||
Sweep all registered repos: pull, reconcile workplan files ↔ DB,
|
||||
@@ -60,7 +60,7 @@ rule:
|
||||
instruction:
|
||||
kind: shell
|
||||
cmd: >-
|
||||
cd /home/worsch/the-custodian/state-hub &&
|
||||
cd /home/worsch/state-hub &&
|
||||
.venv/bin/python scripts/consistency_check.py --remote --all --max-seconds 300
|
||||
on_failure: log_and_continue # warn-only sweeps must not page on transient failures
|
||||
```
|
||||
@@ -75,7 +75,7 @@ Notes:
|
||||
### B. `state-hub-stale-task-cleanup`
|
||||
|
||||
```yaml
|
||||
# activity-definitions/the-custodian/state-hub-stale-task-cleanup.yaml
|
||||
# activity-definitions/state-hub-stale-task-cleanup.yaml
|
||||
id: the-custodian.state-hub-stale-task-cleanup
|
||||
description: |
|
||||
Daily sweep that cancels tasks still 'todo|in_progress|blocked' inside
|
||||
@@ -88,7 +88,7 @@ trigger:
|
||||
instruction:
|
||||
kind: shell
|
||||
cmd: >-
|
||||
cd /home/worsch/the-custodian/state-hub &&
|
||||
cd /home/worsch/state-hub &&
|
||||
.venv/bin/python scripts/cleanup_stale_tasks.py
|
||||
```
|
||||
|
||||
|
||||
@@ -59,13 +59,13 @@ Each message body conforms to the `EventEnvelope` schema in
|
||||
"type": "org.statehub.repo.registered",
|
||||
"version": "1.0",
|
||||
"timestamp": "2026-05-17T14:00:00Z",
|
||||
"publisher": "the-custodian/state-hub",
|
||||
"publisher": "state-hub",
|
||||
"attributes": { "...": "event-specific" }
|
||||
}
|
||||
```
|
||||
|
||||
`type` matches the subject. `publisher` is always
|
||||
`the-custodian/state-hub` for events emitted from this repo.
|
||||
`state-hub` for events emitted from this repo.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ If systemd is not available, fall back to crontab:
|
||||
|
||||
```bash
|
||||
# Crontab fallback (run crontab -e and add):
|
||||
*/15 * * * * curl -sf http://127.0.0.1:8000/state/health && cd ~/the-custodian/state-hub && .venv/bin/python scripts/consistency_check.py --remote --all >> /tmp/custodian-sync.log 2>&1
|
||||
*/15 * * * * curl -sf http://127.0.0.1:8000/state/health && cd ~/state-hub && .venv/bin/python scripts/consistency_check.py --remote --all >> /tmp/custodian-sync.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -4,7 +4,7 @@ cleanup_stale_tasks.py — cancel tasks that are still open in completed/archive
|
||||
|
||||
Run manually: python3 scripts/cleanup_stale_tasks.py
|
||||
Run via make: make cleanup-stale
|
||||
Cron example: 0 3 * * * cd ~/the-custodian/state-hub && .venv/bin/python scripts/cleanup_stale_tasks.py
|
||||
Cron example: 0 3 * * * cd ~/state-hub && .venv/bin/python scripts/cleanup_stale_tasks.py
|
||||
|
||||
Exit codes:
|
||||
0 — ran successfully (zero or more tasks cancelled)
|
||||
@@ -78,7 +78,7 @@ def main() -> int:
|
||||
workstreams = get("/workstreams/")
|
||||
except urllib.error.URLError as e:
|
||||
print(f"[cleanup-stale] ERROR: API unreachable — {e}", file=sys.stderr)
|
||||
print("[cleanup-stale] Start the API with: cd ~/the-custodian/state-hub && make api", file=sys.stderr)
|
||||
print("[cleanup-stale] Start the API with: cd ~/state-hub && make api", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
closed_ws = {w["id"]: w for w in workstreams if w["status"] in CLOSED_WS_STATUS}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd /home/worsch/the-custodian/state-hub
|
||||
cd /home/worsch/state-hub
|
||||
|
||||
API_BASE="${API_BASE:-http://127.0.0.1:8000}"
|
||||
HEALTH_URL="${API_BASE%/}/state/health"
|
||||
|
||||
@@ -93,7 +93,7 @@ curl -s -X PATCH "http://127.0.0.1:8000/tasks/<task_id>" \
|
||||
1. Update workplan file task statuses to reflect progress
|
||||
2. Log: `POST /progress/` with a summary of what changed
|
||||
3. Note for the custodian operator: after workplan file changes, run from
|
||||
`~/the-custodian/state-hub`:
|
||||
`~/state-hub`:
|
||||
```bash
|
||||
make fix-consistency REPO={REPO_SLUG}
|
||||
```
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
|
||||
## Quick Reference
|
||||
|
||||
`~/the-custodian/state-hub/mcp_server/TOOLS.md` — MCP tool reference
|
||||
`~/state-hub/mcp_server/TOOLS.md` — MCP tool reference
|
||||
|
||||
@@ -4,5 +4,5 @@ This repo owns **{PROJECT_NAME}** only. It does not own:
|
||||
|
||||
<!-- TODO: List what belongs in adjacent repos, e.g.:
|
||||
- SSH key management → railiance-infra/
|
||||
- State hub code → the-custodian/state-hub/
|
||||
- State hub code → state-hub/
|
||||
-->
|
||||
|
||||
@@ -12,7 +12,7 @@ Then call the MCP tool for richer cross-domain context (skip if unreachable):
|
||||
```
|
||||
get_domain_summary("{DOMAIN}")
|
||||
```
|
||||
If the hub is offline: `cd ~/the-custodian/state-hub && make api`
|
||||
If the hub is offline: `cd ~/state-hub && make api`
|
||||
|
||||
**Step 2 — Check inbox**
|
||||
```
|
||||
@@ -51,12 +51,12 @@ add_progress_event(summary="...", topic_id="{TOPIC_ID}", workstream_id="<uuid>")
|
||||
If workplan files were modified, ensure the local copy is up to date first:
|
||||
```bash
|
||||
git -C <repo_path> pull --ff-only
|
||||
cd ~/the-custodian/state-hub && make fix-consistency REPO={REPO_SLUG}
|
||||
cd ~/state-hub && make fix-consistency REPO={REPO_SLUG}
|
||||
```
|
||||
For repos where implementation runs on a remote machine (e.g. CoulombCore),
|
||||
use the combined target which pulls before fixing:
|
||||
```bash
|
||||
cd ~/the-custodian/state-hub && make fix-consistency-remote REPO={REPO_SLUG}
|
||||
cd ~/state-hub && make fix-consistency-remote REPO={REPO_SLUG}
|
||||
```
|
||||
**C-15** (DB task ahead of file) is normal in multi-machine workflows — writeback
|
||||
will sync the file to match DB. **C-16** (repo behind remote) blocks all writes
|
||||
|
||||
4
uv.lock
generated
4
uv.lock
generated
@@ -672,7 +672,7 @@ wheels = [
|
||||
[[package]]
|
||||
name = "llm-connect"
|
||||
version = "0.1.0"
|
||||
source = { editable = "../../llm-connect" }
|
||||
source = { editable = "../llm-connect" }
|
||||
dependencies = [
|
||||
{ name = "toml" },
|
||||
]
|
||||
@@ -1468,7 +1468,7 @@ requires-dist = [
|
||||
{ name = "fastapi", specifier = ">=0.115.0" },
|
||||
{ name = "fastmcp", specifier = ">=2.0.0" },
|
||||
{ name = "httpx", specifier = ">=0.28.0" },
|
||||
{ name = "llm-connect", editable = "../../llm-connect" },
|
||||
{ name = "llm-connect", editable = "../llm-connect" },
|
||||
{ name = "nats-py", specifier = ">=2.7.0" },
|
||||
{ name = "psycopg2-binary", specifier = ">=2.9.0" },
|
||||
{ name = "pydantic", specifier = ">=2.10.0" },
|
||||
|
||||
Reference in New Issue
Block a user