2026-02-25 23:33:14 +01:00
|
|
|
import uuid
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
from datetime import datetime
|
2026-06-06 00:42:00 +02:00
|
|
|
from typing import Any
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
|
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
|
|
|
|
from api.schemas.decision import DecisionRead
|
feat(state-hub): implement v0.5 — dynamic domains & multi-repo
Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class
`domains` DB table, and adds a `managed_repos` table for multi-repo
support per domain.
P1 — Domain as a DB entity:
- Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain
ENUM column to domain_id FK, drops the domain ENUM type
- Domain ORM model (api/models/domain.py) + Pydantic schemas
- Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/,
rename and archive endpoints with EP/TD cascade on rename
- Topic model updated: domain_id FK + @property domain_slug for
backwards-compatible JSON serialization (field renamed domain → domain_slug)
- TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup
P2 — Multi-repo support:
- ManagedRepo ORM model (api/models/managed_repo.py) + schemas
- Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive
- Makefile: add-domain, rename-domain, add-repo, list-repos targets
- register_project.sh: verify domain via /domains/ API + POST /repos/
P3 — MCP tools & live validation:
- 6 new MCP tools: list_domains, create_domain, rename_domain,
archive_domain, list_domain_repos, register_repo
- EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request
DB lookup — returns 422 with list of valid slugs on unknown domain
- State summary: adds domains: list[DomainSummary] (slug, name,
repo_count, active_workstream_count, ep_count, td_count)
- TOOLS.md updated with domain management section
P4 — Dashboard:
- New domains.md page with KPI row + domain cards + repo lists
- domains.json.py + repos.json.py data loaders
- Domains page added to observablehq.config.js nav
- workstreams.md, extensions.md, techdept.md: domain_slug fix +
dynamic domain list loaded from /domains/ API (no longer hardcoded)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
|
|
|
from api.schemas.domain import DomainSummary
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
from api.schemas.progress_event import ProgressEventRead
|
|
|
|
|
from api.schemas.task import TaskRead
|
|
|
|
|
from api.schemas.topic import TopicWithWorkstreams
|
2026-07-06 10:52:49 +02:00
|
|
|
from api.schemas.suggestion import RankedSuggestionDigest
|
2026-02-25 23:33:14 +01:00
|
|
|
from api.schemas.workstream import WorkstreamWithDeps
|
2026-08-09 16:19:53 +02:00
|
|
|
from api.schemas.ops_run import OpsRunProjection
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class TopicTotals(BaseModel):
|
|
|
|
|
active: int = 0
|
|
|
|
|
paused: int = 0
|
|
|
|
|
archived: int = 0
|
|
|
|
|
total: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WorkstreamTotals(BaseModel):
|
2026-05-18 01:31:36 +02:00
|
|
|
proposed: int = 0
|
|
|
|
|
ready: int = 0
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
active: int = 0
|
|
|
|
|
blocked: int = 0
|
2026-05-18 01:31:36 +02:00
|
|
|
backlog: int = 0
|
|
|
|
|
finished: int = 0
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
archived: int = 0
|
|
|
|
|
total: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TaskTotals(BaseModel):
|
2026-05-26 01:32:50 +02:00
|
|
|
wait: int = 0
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
todo: int = 0
|
2026-05-26 01:32:50 +02:00
|
|
|
progress: int = 0
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
done: int = 0
|
2026-05-26 01:32:50 +02:00
|
|
|
cancel: int = 0
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
total: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DecisionTotals(BaseModel):
|
|
|
|
|
open: int = 0
|
|
|
|
|
resolved: int = 0
|
|
|
|
|
escalated: int = 0
|
|
|
|
|
superseded: int = 0
|
|
|
|
|
total: int = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Totals(BaseModel):
|
|
|
|
|
topics: TopicTotals
|
|
|
|
|
workstreams: WorkstreamTotals
|
|
|
|
|
tasks: TaskTotals
|
|
|
|
|
decisions: DecisionTotals
|
|
|
|
|
|
|
|
|
|
|
2026-02-25 23:33:14 +01:00
|
|
|
class NextStep(BaseModel):
|
|
|
|
|
"""A derived suggestion pointing to where work should happen next.
|
|
|
|
|
|
|
|
|
|
Suggestions are never persisted — they are computed on demand from
|
|
|
|
|
current hub state: recently resolved decisions, newly unblocked tasks,
|
|
|
|
|
cleared dependencies.
|
|
|
|
|
"""
|
|
|
|
|
type: str # unblocked_task | resolved_decision | dependency_cleared
|
|
|
|
|
domain: str | None = None
|
2026-07-08 23:13:28 +02:00
|
|
|
workplan_id: uuid.UUID | None = None
|
|
|
|
|
workplan_title: str | None = None
|
|
|
|
|
workplan_slug: str | None = None
|
2026-02-25 23:33:14 +01:00
|
|
|
workstream_id: uuid.UUID | None = None
|
|
|
|
|
workstream_title: str | None = None
|
|
|
|
|
workstream_slug: str | None = None
|
|
|
|
|
task_id: uuid.UUID | None = None
|
|
|
|
|
task_title: str | None = None
|
|
|
|
|
message: str # plain-language explanation
|
|
|
|
|
|
|
|
|
|
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
class StateSummary(BaseModel):
|
|
|
|
|
generated_at: datetime
|
|
|
|
|
totals: Totals
|
|
|
|
|
topics: list[TopicWithWorkstreams]
|
|
|
|
|
blocking_decisions: list[DecisionRead]
|
2026-05-26 01:32:50 +02:00
|
|
|
waiting_tasks: list[TaskRead]
|
|
|
|
|
blocked_tasks: list[TaskRead] = []
|
Add state-hub v0.1 — local-first state service for the Custodian
Implements the first live layer of the Custodian cognitive infrastructure:
PostgreSQL schema, FastAPI REST API, FastMCP stdio server, and Observable
Framework telemetry dashboard.
- state-hub/: full stack (docker-compose, FastAPI, Alembic, MCP server, dashboard)
- 5 DB tables: topics, workstreams, tasks, decisions, progress_events
- 11 MCP tools + 5 resources registered in .mcp.json
- Observable dashboard: Overview, Workstreams, Decisions, Progress pages
- CLAUDE.md: session protocol (get_state_summary / add_progress_event ritual)
- ~/.claude/CLAUDE.md: global cross-project reference to the hub
- scripts/pull_image.py: WSL2 TLS-resilient Docker image downloader
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 17:47:49 +01:00
|
|
|
recent_progress: list[ProgressEventRead]
|
2026-07-08 20:33:53 +02:00
|
|
|
open_workplans: list[WorkstreamWithDeps] = []
|
2026-02-25 23:33:14 +01:00
|
|
|
next_steps: list[NextStep] = []
|
feat(state-hub): implement v0.5 — dynamic domains & multi-repo
Replaces the hardcoded 6-domain PostgreSQL ENUM with a first-class
`domains` DB table, and adds a `managed_repos` table for multi-repo
support per domain.
P1 — Domain as a DB entity:
- Migration b1c2d3e4f5a6: creates `domains` table, migrates topics.domain
ENUM column to domain_id FK, drops the domain ENUM type
- Domain ORM model (api/models/domain.py) + Pydantic schemas
- Domain API router: GET/POST /domains/, GET/PATCH /domains/{slug}/,
rename and archive endpoints with EP/TD cascade on rename
- Topic model updated: domain_id FK + @property domain_slug for
backwards-compatible JSON serialization (field renamed domain → domain_slug)
- TopicCreate/TopicRead updated; seed.py rewritten to use FK lookup
P2 — Multi-repo support:
- ManagedRepo ORM model (api/models/managed_repo.py) + schemas
- Repo API router: GET/POST /repos/, GET/PATCH /repos/{slug}/, archive
- Makefile: add-domain, rename-domain, add-repo, list-repos targets
- register_project.sh: verify domain via /domains/ API + POST /repos/
P3 — MCP tools & live validation:
- 6 new MCP tools: list_domains, create_domain, rename_domain,
archive_domain, list_domain_repos, register_repo
- EP/TD routers: replace hardcoded VALID_DOMAINS set with per-request
DB lookup — returns 422 with list of valid slugs on unknown domain
- State summary: adds domains: list[DomainSummary] (slug, name,
repo_count, active_workstream_count, ep_count, td_count)
- TOOLS.md updated with domain management section
P4 — Dashboard:
- New domains.md page with KPI row + domain cards + repo lists
- domains.json.py + repos.json.py data loaders
- Domains page added to observablehq.config.js nav
- workstreams.md, extensions.md, techdept.md: domain_slug fix +
dynamic domain list loaded from /domains/ API (no longer hardcoded)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 15:20:15 +01:00
|
|
|
domains: list[DomainSummary] = []
|
feat(state-hub): v0.3 schema — contributions + sbom_entries migrations, models, schemas, routers
Migrations (chain: b1c2d3e4f5a6 → c2d3e4f5a6b7 → d3e4f5a6b7c8):
- c2d3e4f5a6b7: contributions table (contributiontype BR/FR/EP/UPR enum,
contributionstatus 7-state lifecycle, FKs to topics/workstreams)
- d3e4f5a6b7c8: sbom_entries table (ecosystem enum, snapshot-based replacement),
+ sbom_source + last_sbom_at columns on managed_repos
New models: Contribution (ContributionType, ContributionStatus), SBOMEntry (Ecosystem)
Modified: ManagedRepo (sbom_source, last_sbom_at columns)
New routers:
- /contributions/ — CRUD + lifecycle-guarded PATCH /status + soft-delete (withdrawn)
- /sbom/ — ingest (replace snapshot), list, per-repo view, licence report
Modified:
- /state/summary now includes contribution_counts and licence_risk_count
- main.py: registers contributions + sbom routers; bumps version to 0.6.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 17:28:27 +01:00
|
|
|
contribution_counts: dict[str, int] = {}
|
|
|
|
|
licence_risk_count: int = 0
|
feat(capability-requests): add cross-domain capability catalog and request routing
Introduces a capability catalog (CUST-WP-0022) so domains can advertise what
they provide and agents can request capabilities from other domains with
auto-routing, lifecycle tracking, and task-unblocking on completion.
- New models: CapabilityCatalog, CapabilityRequest with full lifecycle
(requested → accepted → in_progress → ready_for_review → completed/rejected/withdrawn)
- Migration i6d7e8f9a0b1: capability_catalog + capability_requests tables
- Router /capability-catalog and /capability-requests with accept/status endpoints
- 7 new MCP tools: register_capability, list_capabilities, request_capability,
accept_capability_request, update_capability_request_status,
list_capability_requests, get_capability_request
- StateSummary gains open_capability_requests count
- Dashboard: capability-requests.md page + docs/capabilities.md + docs/scope.md
- SCOPE.md: three seed capabilities documented (MCP registration, state tracking, SBOM)
- scope.template: Provided Capabilities section with example block
- scripts/ingest_capabilities.py + make ingest-capabilities[/-all] targets
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 21:07:50 +01:00
|
|
|
open_capability_requests: int = 0
|
2026-07-06 10:52:49 +02:00
|
|
|
ranked_suggestions: list[RankedSuggestionDigest] = []
|
2026-08-09 16:19:53 +02:00
|
|
|
ops_runs: OpsRunProjection | None = None
|
2026-06-06 00:42:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class DashboardWorkplanRow(BaseModel):
|
|
|
|
|
id: uuid.UUID
|
|
|
|
|
title: str
|
|
|
|
|
status: str
|
|
|
|
|
domain: str = "unknown"
|
|
|
|
|
repo_label: str = "unassigned"
|
|
|
|
|
workplan_filename: str | None = None
|
|
|
|
|
workplan_relative_path: str | None = None
|
|
|
|
|
workplan_archived: bool = False
|
|
|
|
|
health_labels: list[str] = []
|
|
|
|
|
href: str
|
|
|
|
|
done: int = 0
|
|
|
|
|
progress: int = 0
|
|
|
|
|
wait: int = 0
|
|
|
|
|
todo: int = 0
|
|
|
|
|
total: int = 0
|
|
|
|
|
created_at: datetime
|
|
|
|
|
updated_at: datetime
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DashboardSourceMeta(BaseModel):
|
|
|
|
|
ok: bool = True
|
|
|
|
|
stale: bool = False
|
|
|
|
|
cache_age_seconds: float | None = None
|
|
|
|
|
refresh_in_progress: bool = False
|
|
|
|
|
error: str | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DashboardOverview(BaseModel):
|
|
|
|
|
generated_at: datetime
|
|
|
|
|
totals: Totals
|
|
|
|
|
topics: list[TopicWithWorkstreams]
|
|
|
|
|
blocking_decisions: list[DecisionRead]
|
|
|
|
|
waiting_tasks: list[TaskRead]
|
|
|
|
|
blocked_tasks: list[TaskRead] = []
|
|
|
|
|
recent_progress: list[ProgressEventRead]
|
|
|
|
|
next_steps: list[NextStep] = []
|
|
|
|
|
contribution_counts: dict[str, int] = {}
|
|
|
|
|
licence_risk_count: int = 0
|
|
|
|
|
open_capability_requests: int = 0
|
|
|
|
|
sbom_snapshot_count: int = 0
|
|
|
|
|
sbom_package_total: int = 0
|
|
|
|
|
registration_milestones: list[ProgressEventRead] = []
|
|
|
|
|
workplan_rows: list[DashboardWorkplanRow] = []
|
|
|
|
|
sources: dict[str, DashboardSourceMeta] = {}
|
|
|
|
|
diagnostics: dict[str, Any] = {}
|