Document how State Hub registers, resolves, reconciles, and mutates repos; blueprint Stage B dual-run toward retirement; open workplan for SH adapter writeback/reconcile without non-retirement refactors.
12 KiB
Research: How State Hub interacts with repositories
Recorded: 2026-08-09
Audience: Repo Manager + State Hub retirement
Sources: state-hub checkout (API, scripts, MCP, Makefile, docs), activity-core consumers, prior RM extraction inventory
1. Executive summary
State Hub is the live index and agent coordination surface for fleet repositories. It does not own Git truth. It:
- Registers repos (slug, domain, classification, host paths, remotes).
- Resolves a checkout on the current machine via
host_paths/local_path. - Parses file-backed work records (workplans, tasks, and related kinds).
- Reconciles files ↔ Postgres with ADR-001 (“file wins”) via
consistency_check/statehub fix-consistency. - Mutates files for selected status writebacks (API reconciliation path + fix-consistency writeback), then git commit + push-seal.
- Serves agents (MCP/REST) and automation (activity-core sweep, SBOM, DoI).
Repo Manager’s job is to take over (1)–(5) as the repository boundary while hub-core keeps messaging, progress, and cross-domain projections.
2. Interaction model (as-built)
Agents (Claude/Codex) activity-core Operators
│ │ │
│ MCP / REST │ GET /repos/ │ make / CLI
│ update_task_status │ POST sweep │ register-path
▼ ▼ ▼
┌─────────────────────────────────┐
│ State Hub API │
│ /repos /workplans /tasks │
│ /reconciliation /consistency │
│ /progress /messages … │
└───────────────┬─────────────────┘
│ Postgres (index)
┌───────────────┴─────────────────┐
│ resolve_repo_path(host_paths) │
│ parse workplans/*.md │
│ writeback + git commit/push │
└───────────────┬─────────────────┘
▼
Git checkouts on hosts
(workstation, railiance01, …)
Authority: repository files + Git history.
Hub DB: rebuildable cache/index.
Operator config: host_paths (not in Git).
3. Registration and classification tooling
| Tool | Entry | What it does |
|---|---|---|
REST POST/GET/PATCH /repos/ |
API | CRUD managed_repos |
POST /repos/{slug}/paths |
API / make register-path |
Set host_paths[hostname]=path |
POST /repos/onboard |
API | Onboarding helper |
scripts/register_from_classification.py |
make register-from-classification |
Upsert from .repo-classification.yaml |
statehub register / register-project |
CLI / make | Scaffold INTENT/AGENTS, register, optional seed WP |
list_domain_repos / list_repos_by_classification |
MCP | Discovery |
register_repo / register_repo_from_classification / update_repo_path |
MCP | Agent registration |
Classification spine: committed .repo-classification.yaml (category,
domain, tags, business fields). Canon allowed vocab in the-custodian.
Domain FK on managed_repos derived from primary domain.
Multi-host: each machine registers its checkout path. Consistency uses
host_paths[current_hostname] then falls back to local_path.
Pitfall observed: statehub register seeds a bootstrap workplan with a
generic REPO-WP-0001 style id; if a real WP already uses that prefix, id
collision occurs (seen on repo-manager). Prefer classification register +
hand-authored workplans for mature repos.
4. Work-record loop (files ↔ index)
4.1 File conventions
workplans/<PREFIX>-WP-NNNN-*.mdwith YAML frontmatter + ````task` blocks.- Hub UUIDs written back as
state_hub_workstream_id/state_hub_task_id. - Generated
WORK-RECORDS.mdand.custodian-brief.md(fix-consistency). - Other kinds: intakes/decisions/register entries (C-31/C-32 registration).
4.2 Read path (agents)
| Action | Typical path |
|---|---|
| Orient | get_domain_summary / GET /state/summary |
| List work | list_workplans / GET /workplans/?… |
| List tasks | list_tasks / GET /tasks/?workplan_id= |
| Brief offline | .custodian-brief.md in each repo |
4.3 Write path (status)
| Action | Path | File effect |
|---|---|---|
MCP update_task_status |
REST PATCH task | May go DB-first then consistency writeback |
| API reconciliation | api/routers/reconciliation.py |
Classifies write-through vs deferred; may patch file via workplan_files |
statehub fix-consistency --fix |
scripts/consistency_check.py |
File↔DB drift repair; optional git writeback commit |
| Push seal | scripts/repo_sync.py |
After fix commits: pull-ff gates + push so local≡remote |
Git rules (critical):
- C-16 behind remote → skip writes (pull first).
- C-17 ahead + push failed → skip further writes.
- Push-seal: fix runs that create commits must push before return.
5. Consistency engine (primary repo tooling)
Script: scripts/consistency_check.py (large monolith).
CLI wrappers: statehub fix-consistency, make check-consistency /
make fix-consistency, MCP check_repo_consistency.
| Mode | Meaning |
|---|---|
--repo SLUG |
Single registered repo |
--here [PATH] |
Infer slug from cwd/remote |
--all |
All registered repos |
--remote --all |
Pull then fix (fleet sweep) |
--fix |
Apply file-wins repairs + writebacks |
--no-writeback |
Check/report only |
Scheduled automation: activity-core (or operator) →
POST /consistency/sweep/remote-all → remote-all sweep with wall-clock budget.
C-rule families (repo-relevant):
| Group | Examples | Role |
|---|---|---|
| Parse/structure | C-01, C-02 | workplans/ present and parseable |
| Binding/drift | C-03–C-06, C-09–C-12, C-15, C-19, C-22 | UUID + status/title drift; file wins |
| Orphans | C-07, C-08, C-14 | DB without file / ghost workstreams |
| Git sync | C-16, C-17 | Protect against clobber / open-loop |
| Classification | C-24 | .repo-classification.yaml |
| Id hygiene | C-26, C-27 | prefix + collision |
| Work-record kinds | C-31–C-33 | registry + WORK-RECORDS index |
| Inbox (not repo) | C-25, C-28, C-29 | messages — hub-core territory |
| Quality soft | C-34 | DoR-Ok soft warnings |
Parsers also live in api/services/workplan_files.py for in-process API
writeback (overlap with consistency_check — dual implementation risk).
6. REST surfaces touching repos (selected)
| Prefix / route | Purpose |
|---|---|
/repos/ |
Registry list/create |
/repos/{slug} PATCH/archive |
Metadata / lifecycle |
/repos/{slug}/paths |
Host path registration |
/repos/{slug}/sync |
Sync trigger |
/repos/{slug}/doi, /doi/summary |
Definition of Integrated scoring |
/repos/todo-md-staleness |
Automation input (activity-core) |
/repos/scope-health |
SCOPE.md health |
/repos/{slug}/dispatch |
Agent dispatch orientation |
/workplans/, /tasks/ |
Work index CRUD |
/reconciliation |
State-change + optional file write-through |
/consistency/sweep/remote-all |
Fleet reconcile job |
Related but not pure repo boundary: progress, messages, suggestions, fabric, token events, service catalog, TPSC, capabilities (mixed hub + repo).
7. MCP tooling (repo-facing subset)
| Tool | Role |
|---|---|
register_repo / register_repo_from_classification |
Registration |
update_repo_path |
Host path |
list_domain_repos / list_repos_by_classification |
Discovery |
check_repo_consistency |
Wraps consistency engine |
validate_repo_adr |
ADR-001 checklist script |
ingest_sbom_tool |
SBOM ingest for a repo |
get_repo_goals / update_repo_goal / get_repo_dispatch |
Goals / dispatch |
list_workplans / create_workplan / update_workplan* |
Work index |
list_tasks / update_task_status / bulk status |
Task index + mutate |
get_domain_summary / get_state_summary |
Orientation (includes repo health) |
Sanctioned writes vs bootstrap-only are documented in mcp_server/TOOLS.md.
8. Adjacent tooling (repo-attached inventories)
| Tool | Makefile / script | Notes |
|---|---|---|
| SBOM ingest | make ingest-sbom, ingest_sbom.py |
Lockfiles + tools yaml |
| TPSC ingest | ingest_tpsc.py |
Service declarations |
| Capabilities ingest | ingest_capabilities.py |
Registry |
| DoI check | check_doi.py |
Integration maturity |
| ADR validate | validate_repo_adr.py |
File layout |
| Gitea inventory | gitea_inventory.py |
Forge listing |
| Normalize attached WPs | normalize_attached_repo_workplans.py |
Fleet hygiene |
| Edge outbox | api/edge/outbox.py |
Offline queue when hub unreachable |
These are repo-scoped jobs but not the core ADR-001 consistency loop.
9. Downstream consumers
| Consumer | Interaction |
|---|---|
| All agent AGENTS.md templates | Session start brief; end with fix-consistency |
| activity-core | GET /repos/, todo-md-staleness, SBOM bulk, remote sweep, context resolvers |
| ops-bridge | Tunnels to API/MCP (:8000 / :18000) |
| Dashboard | Observable pages over REST |
| wise-validator / agentic-resources | Progress and legacy field callers (historical) |
10. Strengths of the established tooling
- File-first doctrine is operational, not only documented (C-rules + writeback).
- Multi-host path registry enables workstation + cluster workers on one slug.
- Push-seal closed the open-loop commit pile-up class of bugs.
- Classification spine unifies discovery without hard-coding domain folders.
- MCP + REST + CLI give agents and humans the same coordination surface.
- Fleet sweep exists for unattended reconcile (activity-core / remote-all).
11. Failure modes and technical debt (retirement-relevant)
| Issue | Impact |
|---|---|
Monolithic consistency_check.py |
Hard to own outside state-hub; extract unit is large |
| Dual parsers (API vs script) | Drift risk between writeback paths |
| Bootstrap WP id collisions | statehub register unsafe on repos with real WP-0001 |
| Topic spine residual | topic_id still on models; classification is future spine |
| Inbox C-rules in consistency | Couples messaging to “repo fix” |
| Index mixed with hub concerns | Progress/messages/catalogs in same service as repo authority |
| Ghost workstreams from MCP create_* | Bootstrap-only tools still create DB-first risk if misused |
| Scheduled sweep fragility | Cluster notes: sweeps paused/gaps after cutovers |
12. Mapping to Repo Manager (current)
| State Hub capability | RM status (2026-08-09) |
|---|---|
| Observe + parse workplans | Partial — rmgr observe/reconcile (JSON index) |
| Task status writeback + git | Partial — rmgr update-task-status |
| Full C-rules / push-seal | Not yet — still SH |
| Registry + host_paths as system of record | Still SH |
| MCP / FastAPI / Postgres index | Still SH |
| Dual-run adapter for retirement | Missing — blocks clean strangler |
See also: docs/state-hub-extraction-inventory_v0.1.md,
docs/observation-command-contracts_v0.1.md.
13. Conclusion for retirement sequencing
The retirement-critical path is not a better CLI UX or a prettier model. It is:
- Make Repo Manager the authoritative executor of reconcile + file writeback for at least one production command path agents already use.
- Keep State Hub as a strangler facade (MCP/REST) until meters show zero direct need for SH to touch checkouts.
- Only then move registry/host_paths and drop SH repo mutation.
That sequence is elaborated in specs/ArchitectureBlueprint.md and the next
workplan RMGR-WP-0002.