From fec05dcb5d4a4f9ada8469bcab0636fa06178bf3 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 28 Feb 2026 12:14:47 +0100 Subject: [PATCH] docs(workplans): write files for 4 pre-ADR-001 orphan workstreams Resolves all orphan-workstream FAIL findings from validate_repo_adr. The custodian domain now passes 47/47 checks (0 warn, 0 fail). Files written: CUST-WP-0001 custodian-agent-runtime (2 tasks: 1 done, 1 todo) CUST-WP-0002 contribution-tracking-sbom (15 tasks, v0.5 scope reductions annotated inline) CUST-WP-0003 whi-kpi-card (9 tasks) CUST-WP-0004 ep-td-tracking (10 tasks: 4 done, 6 todo) All files cross-reference state_hub_workstream_id and state_hub_task_id for future sync reconciliation. Co-Authored-By: Claude Sonnet 4.6 --- .../CUST-WP-0001-custodian-agent-runtime.md | 69 ++++ ...CUST-WP-0002-contribution-tracking-sbom.md | 294 ++++++++++++++++++ workplans/CUST-WP-0003-whi-kpi-card.md | 186 +++++++++++ workplans/CUST-WP-0004-ep-td-tracking.md | 157 ++++++++++ 4 files changed, 706 insertions(+) create mode 100644 workplans/CUST-WP-0001-custodian-agent-runtime.md create mode 100644 workplans/CUST-WP-0002-contribution-tracking-sbom.md create mode 100644 workplans/CUST-WP-0003-whi-kpi-card.md create mode 100644 workplans/CUST-WP-0004-ep-td-tracking.md diff --git a/workplans/CUST-WP-0001-custodian-agent-runtime.md b/workplans/CUST-WP-0001-custodian-agent-runtime.md new file mode 100644 index 0000000..e057c44 --- /dev/null +++ b/workplans/CUST-WP-0001-custodian-agent-runtime.md @@ -0,0 +1,69 @@ +--- +id: CUST-WP-0001 +type: workplan +title: "Custodian Agent Runtime — Bootstrap" +domain: custodian +status: active +owner: custodian +topic_slug: custodian +state_hub_workstream_id: a2d9919d-62ec-49e7-9533-ba650757e70a +created: "2026-02-25" +updated: "2026-02-28" +--- + +# Custodian Agent Runtime — Bootstrap + +## Summary + +Design and bootstrap the Custodian as an acting agent: a standalone +LLM-powered service that uses the State Hub as its coordination layer. +Distinct from the State Hub tooling itself. + +## Context + +The State Hub provides the read model and MCP interface. The Agent Runtime +is a separate concern: the loop, policy engine, and tool adapters that +make the Custodian an autonomous (or semi-autonomous) participant rather +than a passive data store. + +## Dependencies + +- Depends on: `markitect/llm-shared-library` (llm-connect) — must reach + stable installable state before implementation can begin. + Dependency resolved: llm-connect extracted and integrated (2026-02-27). +- Depends on: `railiance/phase-0-operational-baseline` — agent runtime + deployment requires a stable, backed-up server environment. +- state_hub_dep_ids: + - a46f5838-e489-434f-b7ee-996c2fdd81ad (llm-shared-library) + - 7f0d9856-9561-4404-96f0-91e8eb79feca (phase-0-operational-baseline) + +## Tasks + +### T1 — Bootstrap blocked: awaiting markitect/llm-shared-library + +```task +id: CUST-WP-0001-T01 +state_hub_task_id: ac42e548-10bf-4851-94e2-c8d35876f2f9 +status: done +priority: high +``` + +All implementation tasks for the agent runtime were blocked until +llm-connect was extracted as a standalone installable package from +markitect. Resolved 2026-02-27: llm-connect integrated in state-hub as +editable dependency; markitect llm-check smoke test green. + +### T2 — Define agent architecture and capability scope + +```task +id: CUST-WP-0001-T02 +state_hub_task_id: 9a9297cd-bd3c-409c-8384-6f06cfc6faa2 +status: todo +priority: medium +``` + +Decide the Custodian agent's primary loop: what is the core OODA cycle? +What tools does it need beyond the State Hub MCP? Where does it live — +new repo or `runtime/` in the-custodian? Produce an architecture sketch +covering: entry point, LLM integration (via llm-connect), tool manifest, +state-hub interaction pattern, and deployment target. diff --git a/workplans/CUST-WP-0002-contribution-tracking-sbom.md b/workplans/CUST-WP-0002-contribution-tracking-sbom.md new file mode 100644 index 0000000..4510525 --- /dev/null +++ b/workplans/CUST-WP-0002-contribution-tracking-sbom.md @@ -0,0 +1,294 @@ +--- +id: CUST-WP-0002 +type: workplan +title: "State Hub v0.3 — Contribution Tracking & SBOM" +domain: custodian +status: active +owner: custodian +topic_slug: custodian +state_hub_workstream_id: 2446400d-6d01-4679-a314-92af0601c608 +created: "2026-02-26" +updated: "2026-02-28" +--- + +# State Hub v0.3 — Contribution Tracking & SBOM + +## Summary + +Establish the custodian as the central authority for cross-repo upstream +contribution management (bug reports, feature requests, extension points, +upstream PRs) and software supply-chain transparency (SBOM aggregation, +licence governance). + +## Context + +Three interconnected layers: +- **Layer 1 — Convention & Canon**: define contrib/ directory structure and + artifact types (BR, FR, EP, UPR) in markdown with typed YAML frontmatter. +- **Layer 2 — Schema & API**: DB tables for contributions, repos (deferred + to v0.5), and SBOM entries; FastAPI routers. +- **Layer 3 — MCP Tools & Dashboard**: tracking tools and Observable pages. + +## Dependencies + +- Depends on: `dynamic-domains-multi-repo` (v0.5, CUST-WP-0005). + Four tasks in this workplan (P2.2, P2.4, P3.2, P4.1) are reduced in + scope because v0.5 supersedes their original designs: + - `managed_repos` table → done by v0.5 P2.1 + - `/repos/` API router → done by v0.5 P2.2 + - `register_repo` MCP tool → done by v0.5 P3.1 + - Base registration workflow → done by v0.5 P2.3 +- state_hub_dep_id: 2033172d-2462-4253-acb7-cb64c7432480 + +## Phase 1 — Convention & Canon + +### P1.1 — Write canon/standards/contribution-convention_v0.1.md + +```task +id: CUST-WP-0002-T01 +state_hub_task_id: c2d7df02-5f37-4c02-a418-fe7ab0050edc +status: todo +priority: high +``` + +Define the master contrib/ convention: directory layout, artifact types +(BR/FR/EP/UPR), frontmatter schema per type, ID schemes (EP--NNN +for EPs; date-prefixed slug for others), status lifecycle, and +relationship to state-hub. Authoritative reference for other repos. + +### P1.2 — Create contrib/ templates for BR, FR, EP, UPR + +```task +id: CUST-WP-0002-T02 +state_hub_task_id: 5ef89639-950c-4d57-9578-6d0211edc2df +status: todo +priority: high +``` + +Four Markdown template files under `canon/standards/contrib-templates/`: +`br-template.md`, `fr-template.md`, `ep-template.md`, `upr-template.md`. +Each has typed YAML frontmatter matching the schema in P1.1 plus a guided +prose skeleton. + +### P1.3 — Store Observable Framework TOC sidebar UPR as first artifact + +```task +id: CUST-WP-0002-T03 +state_hub_task_id: e8251873-647c-4a4b-b283-298260b19c22 +status: todo +priority: medium +``` + +Create `contrib/upstream-prs/2026-02-26--observablehq--framework--toc-sidebar-inject.md` +using the UPR template. Captures: summary of the `injectTocTop` utility, +motivation, link to local component, target upstream file, draft PR body. +Status: draft. + +### P1.4 — Align Railiance EP convention docs with canon master spec + +```task +id: CUST-WP-0002-T04 +state_hub_task_id: 1c982457-de52-4fc1-a439-3bf3120bb5b6 +status: todo +priority: low +``` + +The staged-promotion-lifecycle workstream defines EP-RAIL-NNN IDs and +inline doc markers. Review and update so the Railiance convention is a +proper instance of the custodian master spec, not a parallel one. + +## Phase 2 — Schema & API + +### P2.1 — Design and implement contributions DB table + migration + +```task +id: CUST-WP-0002-T05 +state_hub_task_id: c41d71bd-dc88-4201-bd9a-3f8a4eae4910 +status: todo +priority: high +``` + +Add `contributions` table: id (UUID PK), type (enum: br|fr|ep|upr), +target_org, target_repo, slug, title, status (enum: +draft|submitted|acknowledged|accepted|rejected|merged|withdrawn), +body_path (relative path to .md file), related_topic_id (nullable FK), +related_workstream_id (nullable FK), submitted_at, resolved_at, notes, +created_at, updated_at. Alembic migration. + +### P2.2 — sbom_entries table + migration (managed_repos deferred to v0.5) + +```task +id: CUST-WP-0002-T06 +state_hub_task_id: 28c9bd38-05d8-4466-bff3-3ba4e3957635 +status: todo +priority: high +``` + +SCOPE REDUCED — managed_repos superseded by v0.5 P2.1. + +Do not create `managed_repos` here. After v0.5 P2.1 lands, add +`sbom_source` (text) and `last_sbom_at` (timestamp) columns to the +existing `managed_repos` table via an additive migration. + +Then create `sbom_entries` table: id (UUID PK), repo_id (FK +managed_repos), package_name, package_version, ecosystem, license_spdx +(nullable), is_direct (bool), is_dev (bool), snapshot_at (timestamp — +new ingest replaces old entries for that repo), created_at. + +Prerequisite: v0.5 P2.1 (managed_repos table) must be complete. + +### P2.3 — Implement /contributions/ router (CRUD + status patch) + +```task +id: CUST-WP-0002-T07 +state_hub_task_id: ee1cd17c-6dbd-4321-bb72-4499147c4837 +status: todo +priority: high +``` + +FastAPI router: GET list (filter by type, status, target_repo), POST +create, GET by id, PATCH status (validates lifecycle transitions), soft +delete (sets status=withdrawn). Schemas: `ContributionCreate`, +`ContributionRead`, `ContributionStatusPatch`. Add +`contribution_counts` to `/state/summary`. + +### P2.4 — Implement /sbom/ router (basic /repos/ endpoints implemented by v0.5) + +```task +id: CUST-WP-0002-T08 +state_hub_task_id: 25f7ab5c-69d8-41d7-a108-38380eb1f3a9 +status: todo +priority: high +``` + +SCOPE REDUCED — /repos/ superseded by v0.5 P2.2. + +This task covers the `/sbom/` router only: +- `POST /sbom/ingest` — accept repo_slug + list of package entries; + replace existing snapshot for that repo. +- `GET /sbom/` — aggregated view across all repos, grouped by license_spdx. +- `GET /sbom/{repo_slug}/` — single-repo SBOM. +- `GET /sbom/report/licences/` — counts and repo lists per SPDX identifier, + flagging copyleft (GPL/AGPL/LGPL). +- Add `licence_risk_count` to `/state/summary`. + +Prerequisite: v0.5 P2.1 (managed_repos) and P2.2 (sbom_entries) must +be complete. + +### P2.5 — Write make ingest-sbom tooling (pyproject + package.json parsers) + +```task +id: CUST-WP-0002-T09 +state_hub_task_id: edcf9b02-8177-4abc-b133-d303cc7ea19d +status: todo +priority: medium +``` + +`scripts/ingest_sbom.py`: parses `uv.lock` (Python deps with licence +metadata), `package-lock.json` / `yarn.lock` (Node deps); outputs +normalised list; POSTs to `/sbom/ingest/`. Makefile target: +`make ingest-sbom REPO=`. Composable into `make seed`. + +## Phase 3 — MCP Tools & Dashboard + +### P3.1 — New MCP tools: register_contribution, update_contribution_status, get_contributions + +```task +id: CUST-WP-0002-T10 +state_hub_task_id: 51b2999b-a9c7-4871-8ef8-f5c927ac2454 +status: todo +priority: high +``` + +- `register_contribution(type, target_org, target_repo, title, body_path, + related_workstream_id?, notes?)` → ContributionRead +- `update_contribution_status(contribution_id, status, notes?)` → + ContributionRead +- `get_contributions(type?, status?, target_repo?)` → list +- Add `state://contributions` resource. + +### P3.2 — New MCP tools: ingest_sbom, get_licence_report (register_repo implemented by v0.5) + +```task +id: CUST-WP-0002-T11 +state_hub_task_id: 20c5c2ae-7758-42cc-885c-a886957e44c2 +status: todo +priority: high +``` + +SCOPE REDUCED — register_repo superseded by v0.5 P3.1. + +- `ingest_sbom(repo_slug: str, lockfile_path: str)` — calls + `scripts/ingest_sbom.py`, POSTs result to `/sbom/ingest/`. +- `get_licence_report()` — returns licence groups with copyleft flag from + `/sbom/report/licences/`. +- Add resources: `state://sbom/aggregated`, `state://sbom/{repo_slug}`. + +Prerequisite: v0.5 P3.1 (register_repo tool) and P2.4 (/sbom/ router) +must be complete. + +### P3.3 — Dashboard: contributions.md page + +```task +id: CUST-WP-0002-T12 +state_hub_task_id: 1eb13411-b2da-4d0d-8fe2-e926d029c50f +status: todo +priority: medium +``` + +New Observable Framework page. Layout: filter bar (type, status, +target_repo), status Kanban columns +(draft → submitted → acknowledged → accepted/rejected/merged), count KPIs +per type. Chart: contribution velocity over time (cumulative, same period +selector as decisions page). Apply `injectTocTop` for page-level KPI. + +### P3.4 — Dashboard: sbom.md page + +```task +id: CUST-WP-0002-T13 +state_hub_task_id: 1267f313-1bf3-4059-8276-bfefcd9f6aed +status: todo +priority: medium +``` + +New Observable Framework page. Aggregated dependency table: package, +version, licence, repos using it, direct/dev flags. Licence summary donut +chart (MIT vs Apache-2.0 vs GPL family vs other). Copyleft risk section +(red highlight for GPL/AGPL/LGPL in direct prod deps). Per-repo +drill-down accordion. Register in `observablehq.config.js`. + +### P3.5 — Update index.md overview to surface contribution and SBOM health + +```task +id: CUST-WP-0002-T14 +state_hub_task_id: abab0022-d3a4-45ef-a7e1-e0e7c05d295f +status: todo +priority: low +``` + +Add contribution counts KPI card (total, by type, any needing follow-up). +Add licence risk indicator (green if no copyleft in direct prod deps, red +otherwise). Uses `/state/summary` fields added in P2.3 and P2.4. + +## Phase 4 — Repo Integration Tooling + +### P4.1 — Add sbom_source prompt + ingest-sbom step to registration workflow (base workflow by v0.5) + +```task +id: CUST-WP-0002-T15 +state_hub_task_id: 47987720-23db-4465-861b-1f93bb1bb391 +status: todo +priority: low +``` + +SCOPE REDUCED — base registration workflow superseded by v0.5 P2.3. + +SBOM-specific additions to the workflow: +1. Extend the `add-repo` command to prompt for `ecosystem` and + `sbom_source` (path or URL to lockfile). +2. Optionally run `make ingest-sbom REPO=` automatically at end of + registration. +3. Update `project_claude_md.template` to document the contrib/ convention, + SBOM MCP tools, and `make ingest-sbom` target. + +Prerequisite: v0.5 P2.3 (updated registration workflow) must be complete. diff --git a/workplans/CUST-WP-0003-whi-kpi-card.md b/workplans/CUST-WP-0003-whi-kpi-card.md new file mode 100644 index 0000000..b38f27c --- /dev/null +++ b/workplans/CUST-WP-0003-whi-kpi-card.md @@ -0,0 +1,186 @@ +--- +id: CUST-WP-0003 +type: workplan +title: "State Hub v0.4 — Workstream Health Index (WHI) KPI Card" +domain: custodian +status: active +owner: custodian +topic_slug: custodian +state_hub_workstream_id: 9cc32158-2f5c-4ef6-9713-aacce4623d5e +created: "2026-02-26" +updated: "2026-02-28" +--- + +# State Hub v0.4 — Workstream Health Index (WHI) KPI Card + +## Summary + +Implement the Workstream Health Index (WHI) — a composite structural-health +KPI — as a live card injected into the TOC sidebar of the Workstreams +dashboard page. All six metrics are computable client-side from data +already fetched by `workstreams.md`; no API or schema changes required. + +## Context + +The WHI formula and metric definitions are specified in +`state-hub/dashboard/src/docs/workstream-kpi.md`. This workplan covers +only the implementation of that spec as running dashboard code. + +The six base metrics: +- **DD** — Dependency Density: edge count / open workstream count +- **BR** — Blocked Ratio: blocked workstreams / open count +- **SPR** — Single Point of Risk: max inbound edges / open count +- **PEP** — Progression Enablement Proportion: ready-to-start workstreams +- **CDDR** — Cross-Domain Dependency Ratio: cross-domain edges / total edges +- **CPI** — Cycle Penalty Indicator: 1 if any cycle detected, 0 otherwise + +WHI formula: `0.30*(1-DDnorm) + 0.25*(1-BR) + 0.15*(1-SPR) + 0.20*PEP + 0.10*(1-CDDR)` +CPI penalty: `WHI = WHI * 0.5` if CPI=1. + +## Tasks + +### P1 — Verify dependency edge fields in open_workstreams + +```task +id: CUST-WP-0003-T01 +state_hub_task_id: 243646e0-b77a-41e7-ac51-82c5828e63d2 +status: todo +priority: high +``` + +Confirm that `summary.open_workstreams[].depends_on[]` and `blocks[]` +each carry `workstream_id`, `workstream_slug`, and `workstream_title`. +Verify these fields are sufficient to build a complete directed dependency +graph client-side without additional API calls. (Already verified during +workplan design — open_workstreams is the confirmed data source.) + +### P2.1 — Build directed dependency graph from openWs + completedIds + +```task +id: CUST-WP-0003-T02 +state_hub_task_id: 6dbef71f-d2d7-44ee-abb8-279dbaeec505 +status: todo +priority: high +``` + +In `workstreams.md`: derive `completedIds = new Set` of IDs of workstreams +with status completed. Build an adjacency list: for each entry in openWs, +map workstream id → array of `depends_on[].workstream_id`. Build reverse +map (prerequisite id → list of dependent ids) for SPR computation. Also +build `idToDomain` map from `data[]` for CDDR. + +### P2.2 — Implement DFS cycle detection (CPI) + +```task +id: CUST-WP-0003-T03 +state_hub_task_id: f0d5c107-6029-4ad0-af00-645d35ce7db0 +status: todo +priority: high +``` + +Implement a DFS-based topological sort over the dependency adjacency list. +Detect back edges using visited / inStack colour sets. Return `CPI = 1` +if any cycle found, `CPI = 0` otherwise. Only nodes in openWs participate +(completed/archived workstreams excluded). Edge case: isolated nodes (no +deps, no dependents) are valid and never form cycles. + +### P2.3 — Compute DD, BR, SPR, PEP, CDDR + +```task +id: CUST-WP-0003-T04 +state_hub_task_id: 6da60567-cc46-4a32-9855-b07bafe2faeb +status: todo +priority: high +``` + +Using the graph from P2.1: +- `DD`: totalEdges / openCount, where totalEdges = openWs.flatMap(w=>w.depends_on).length +- `BR`: openWs.filter(w=>w.status==="blocked").length / openCount +- `SPR`: max inbound-edge count across prerequisite workstreams in openWs / openCount +- `PEP`: openWs.filter(w=>active && all depends_on are in completedIds).length / openCount +- `CDDR`: crossDomainEdges / totalEdges (edge with different domain endpoints); 0 if no edges + +### P2.4 — WHI formula: normalisation + CPI penalty + +```task +id: CUST-WP-0003-T05 +state_hub_task_id: 29b2dbbd-5d60-49b6-ae84-3dbf22167df7 +status: todo +priority: high +``` + +Implement the weighted aggregation: +``` +DDnorm = min(1, DD / 1.0) // DD_critical = 1.0 +WHI = 0.30*(1-DDnorm) + 0.25*(1-BR) + 0.15*(1-SPR) + 0.20*PEP + 0.10*(1-CDDR) +if CPI === 1: WHI = WHI * 0.5 +``` +Clamp to [0, 1]. Return `{whi, dd, ddNorm, br, spr, pep, cddr, cpi, openCount, edgeCount}`. +Factor into `computeWHI(nodes, edges, idToDomain)` for reuse in per-domain scope. + +### P2.5 — Per-domain WHI breakdown + +```task +id: CUST-WP-0003-T06 +state_hub_task_id: 8ce5ef74-5eb8-4259-9b11-dde13bf84a89 +status: todo +priority: medium +``` + +For each domain present in openWs, compute a domain-scoped WHI: +- `domainNodes = openWs.filter(w => idToDomain[w.id] === domain)` +- `domainEdges = domainNodes.flatMap(w => w.depends_on.filter(d => idToDomain[d.workstream_id] === domain))` +- `result = computeWHI(domainNodes, domainEdges, idToDomain)` + +Store as `[{domain, whi, br, pep, cpi, openCount}]`. Skip domains with +`openCount === 0`. + +### P3 — WHI KPI card UI + +```task +id: CUST-WP-0003-T07 +state_hub_task_id: 91efba5c-3be2-4bfe-b5ef-1b261e9423f2 +status: todo +priority: high +``` + +Build the `_whiBox` element in `workstreams.md` (mirrors `_kpiBox` in +`decisions.md`): +- Card title: "Workstream Health" +- Main WHI value with health state label: GREEN ≥ 0.75 / ORANGE ≥ 0.50 / RED < 0.50 +- Sub-metric rows for DD, BR, SPR, PEP, CDDR with individual warning colours +- Cycle alert row (red ⚠) when CPI=1 +- Domain breakdown: compact rows with domain name + coloured score +- Empty state if openCount=0 or no edges + +Inject via `injectTocTop("whi-kpi-box", _whiBox)`. Wire +`withDocHelp(_whiBox, "/docs/workstream-health-index")`. + +### P4.1 — Create src/docs/workstream-health-index.md + +```task +id: CUST-WP-0003-T08 +state_hub_task_id: 4c898472-e4ae-49a2-b6cd-7aa1a3c7604a +status: todo +priority: medium +``` + +Reference documentation for the WHI KPI card. Cover: purpose, all six +metrics (formula + interpretation), WHI aggregation formula with CPI +penalty, DD normalisation, health state thresholds, domain breakdown, +cycle detection, and how to improve a poor score. Update +`workstream-kpi.md` to link to this doc. + +### P4.2 — Wire withDocHelp and add to Reference nav + +```task +id: CUST-WP-0003-T09 +state_hub_task_id: 20976663-7ac9-4909-8029-a479190f52ff +status: todo +priority: low +``` + +Confirm `withDocHelp(_whiBox, "/docs/workstream-health-index")` is wired +(from P3). Add `{ name: "Workstream Health", path: "/docs/workstream-health-index" }` +to the Reference pages array in `observablehq.config.js`. Verify +Reference nav renders correctly in `npm run dev`. diff --git a/workplans/CUST-WP-0004-ep-td-tracking.md b/workplans/CUST-WP-0004-ep-td-tracking.md new file mode 100644 index 0000000..4e582c8 --- /dev/null +++ b/workplans/CUST-WP-0004-ep-td-tracking.md @@ -0,0 +1,157 @@ +--- +id: CUST-WP-0004 +type: workplan +title: "Extension Points & Technical Debt Tracking" +domain: custodian +status: active +owner: custodian +topic_slug: custodian +state_hub_workstream_id: e84ecd70-b276-4a93-a298-1ef1299b7c22 +created: "2026-02-27" +updated: "2026-02-28" +--- + +# Extension Points & Technical Debt Tracking + +## Summary + +Adds structured tracking for extension points (known future enhancement +opportunities) and technical debt (known quality compromises) across all +project domains. + +## Context + +Phase 1 (infrastructure) is complete: DB tables (`extension_points`, +`technical_debt`), API routers, MCP tools, and dashboard pages are live +as of commit `2bf9523` (2026-02-27). Phase 2 populates the catalogue per +domain. Phase 3 triages and resolves high-priority items. + +## Tasks + +### P1.1 — DB schema and API routers for EP and TD + +```task +id: CUST-WP-0004-T01 +state_hub_task_id: 539da477-b9ad-4e0b-a8a1-deab4afe9bc7 +status: done +priority: high +``` + +Created `extension_points` and `technical_debt` tables (migration +`a3f1c2d4e5b6`). FastAPI routers at `/extension-points/` and +`/technical-debt/` with full CRUD and soft-delete (status-based). + +### P1.2 — MCP tools for EP and TD registration + +```task +id: CUST-WP-0004-T02 +state_hub_task_id: a35fa615-13a3-4168-9e25-98edbd8411da +status: done +priority: high +``` + +Added 6 MCP tools to `server.py`: `register_extension_point`, +`list_extension_points`, `update_ep_status`, `register_technical_debt`, +`list_technical_debt`, `update_td_status`. Each write tool emits a +progress event. + +### P1.3 — Dashboard pages for EP and TD + +```task +id: CUST-WP-0004-T03 +state_hub_task_id: cd392ee9-9b65-48cb-8337-9fbe546ea9c3 +status: done +priority: high +``` + +Created `extensions.md` and `techdept.md` Observable pages with KPI +sidebar, charts (by type, by severity/status), urgent items section, and +filterable card lists. Added to nav in `observablehq.config.js`. + +### P2.1 — Catalogue technical debt in custodian repo + +```task +id: CUST-WP-0004-T04 +state_hub_task_id: 76aa3932-9a06-45ae-8836-d766eb61b755 +status: done +priority: high +``` + +Automated assessment of state-hub codebase. Registered 19 items +TD-CUST-001 to TD-CUST-019 (2 high, 10 medium, 7 low). Top priorities: +TD-CUST-001 (hard-coded API URL), TD-CUST-004 (no max limit on list +endpoints). + +### P2.2 — Catalogue technical debt in railiance domain + +```task +id: CUST-WP-0004-T05 +state_hub_task_id: 00492d87-3bb7-4df9-8f12-a06da0307fbc +status: todo +priority: medium +``` + +Assess railiance-bootstrap and related repos for technical debt. +Register findings as `TD-RAIL-xxx` items via the `/technical-debt/` API. + +### P2.3 — Catalogue extension points in custodian repo + +```task +id: CUST-WP-0004-T06 +state_hub_task_id: 3069aa1d-3d5f-4b9f-be8b-dfa0ffe690fe +status: todo +priority: medium +``` + +Identify and register extension points in the state-hub codebase as +`EP-CUST-xxx` items: API gaps, MCP tool gaps, dashboard gaps, schema +gaps, integration opportunities. + +### P2.4 — Catalogue extension points in railiance domain + +```task +id: CUST-WP-0004-T07 +state_hub_task_id: 3a355a74-237f-4572-af05-683eceb32694 +status: todo +priority: low +``` + +Identify and register extension points in railiance as `EP-RAIL-xxx` items. + +### P3.1 — Address TD-CUST-001: extract API URL to config + +```task +id: CUST-WP-0004-T08 +state_hub_task_id: a9b5d39e-706b-4f71-8f5d-ce4f927b3e4c +status: todo +priority: high +``` + +Replace hard-coded `const API = 'http://127.0.0.1:8000'` in all 7 +dashboard pages with a shared config module or Observable environment +variable. + +### P3.2 — Address TD-CUST-004: add max limit to list endpoints + +```task +id: CUST-WP-0004-T09 +state_hub_task_id: 7050eb96-964d-4c06-a9f5-6d49db6b9c98 +status: todo +priority: high +``` + +Add `Pydantic Field(le=1000)` to `limit` parameters on all list +endpoints (progress, tasks, workstreams, decisions, extension_points, +technical_debt) to prevent memory exhaustion. + +### P3.3 — Extract shared dashboard CSS to common stylesheet + +```task +id: CUST-WP-0004-T10 +state_hub_task_id: c54553be-d947-4b8d-9c16-eb1a0e9ae3a0 +status: todo +priority: medium +``` + +Extract `.kpi-infobox`, `.filter-bar` and related CSS from all dashboard +pages into a shared CSS file imported by each page. Addresses TD-CUST-003.