generated from coulomb/repo-seed
feat(dashboard): nav restructure, full context-help coverage, 11 new ref docs
Navigation: - New order: Overview · Todo · Domains · Repos · Workstreams (collapsible, open:false, with atomic sub-entries: Decisions, Tasks, Debt, Extends, Dependencies) · Contributions · SBOM · Progress · Reference (collapsible) - Reference section gains path:/reference landing page; all 18 doc pages listed in nav (alphabetical) and in reference.md table New pages: - todo.md — Internal / Ecosystem / Third-party todo classification - dependencies.md — dependency edge table derived from state/summary - reference.md — Reference landing page with full doc index New reference doc pages (11): contributions, debt, dependencies, domains, extensions, overview, repos, tasks, todo + reference (meta) already added previously doc-overlay.js — lazy bubblehelp tooltip: - _titleCache Map + _fetchDocTitle(docPath): on first hover of any ? button, fetches the target doc page, parses <h1>, sets btn.title - Native browser tooltip appears exactly on the ? circle on subsequent hover Context-help wired on all 14 dashboard pages: - h1 withDocHelp added to: index, todo, domains, repos, tasks, techdept, extensions, dependencies (contributions/workstreams/decisions/sbom/ progress/reference were already wired) - domains.md + repos.md: added missing withDocHelp import and live-data link - tasks/techdept/extensions: removed duplicate _h1 const that caused SyntaxError: Identifier '_h1' has already been declared Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
120
dashboard/src/docs/contributions.md
Normal file
120
dashboard/src/docs/contributions.md
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: Contributions — Reference
|
||||
---
|
||||
|
||||
# Contributions — Reference
|
||||
|
||||
Contributions track **outbound upstream work** — things the Custodian has
|
||||
identified that belong in a repo it does not own or control. Each contribution
|
||||
is a structured artifact filed locally in the repo's `contrib/` directory and
|
||||
registered in the state hub so it is never lost.
|
||||
|
||||
---
|
||||
|
||||
## Contribution types
|
||||
|
||||
| Type | Full name | Use when |
|
||||
|------|-----------|----------|
|
||||
| `br` | Bug Report | You found a defect in an upstream tool or library |
|
||||
| `fr` | Feature Request | You need functionality that upstream does not yet provide |
|
||||
| `ep` | Extension Point | You identified a future enhancement opportunity in upstream code |
|
||||
| `upr` | Upstream PR | You have written (or are writing) a patch for an upstream repo |
|
||||
|
||||
---
|
||||
|
||||
## Lifecycle
|
||||
|
||||
```
|
||||
draft → submitted → acknowledged → accepted → merged
|
||||
↘ ↘
|
||||
rejected withdrawn
|
||||
```
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| **draft** | Artifact written locally; not yet sent upstream |
|
||||
| **submitted** | Filed as a GitHub issue, PR, or email — awaiting upstream response |
|
||||
| **acknowledged** | Upstream has seen it and responded (e.g. triaged, commented) |
|
||||
| **accepted** | Upstream agreed to take action |
|
||||
| **merged** | PR accepted and merged; issue resolved |
|
||||
| **rejected** | Upstream declined; record kept for future reference |
|
||||
| **withdrawn** | We decided not to pursue it |
|
||||
|
||||
Transitions are enforced by the API — you cannot skip stages arbitrarily.
|
||||
`submitted_at` is stamped automatically when status moves to `submitted`;
|
||||
`resolved_at` is stamped when status moves to `merged`, `rejected`, or `withdrawn`.
|
||||
|
||||
---
|
||||
|
||||
## Relation to the Todo classification
|
||||
|
||||
Contributions map directly to the **Third-party** class in the inter-repo
|
||||
communication taxonomy:
|
||||
|
||||
| Todo class | Mechanism |
|
||||
|------------|-----------|
|
||||
| Internal | Workplan file + task in this repo's workstream |
|
||||
| Ecosystem | State hub task with `[repo:<slug>]` prefix |
|
||||
| **Third-party** | **Contribution artifact in `contrib/` + state hub registration** |
|
||||
|
||||
Contributions in `draft`, `submitted`, or `acknowledged` status appear as
|
||||
open Third-party todos on the [Todo](/todo) page.
|
||||
|
||||
---
|
||||
|
||||
## File layout
|
||||
|
||||
Each artifact lives in the current repo under `contrib/`:
|
||||
|
||||
```
|
||||
contrib/
|
||||
bug-reports/ br-YYYY-MM-DD--<org>--<repo>--<slug>.md
|
||||
feature-requests/ fr-YYYY-MM-DD--<org>--<repo>--<slug>.md
|
||||
extension-points/ EP-<DOMAIN>-NNN--<org>--<repo>--<slug>.md
|
||||
upstream-prs/ upr-YYYY-MM-DD--<org>--<repo>--<slug>.md
|
||||
```
|
||||
|
||||
Templates live in `~/the-custodian/canon/standards/contrib-templates/`.
|
||||
Convention details: `~/the-custodian/canon/standards/contribution-convention_v0.1.md`.
|
||||
|
||||
---
|
||||
|
||||
## Adding a contribution
|
||||
|
||||
**1. Write the artifact file** using the appropriate template.
|
||||
|
||||
**2. Register it in the state hub** via MCP:
|
||||
|
||||
```
|
||||
register_contribution(
|
||||
type = "fr",
|
||||
title = "Add sidebar TOC injection API",
|
||||
target_org = "observablehq",
|
||||
target_repo = "framework",
|
||||
body_path = "contrib/feature-requests/fr-2026-02-26--observablehq--framework--toc.md",
|
||||
related_workstream_id = "<uuid>"
|
||||
)
|
||||
```
|
||||
|
||||
**3. Close the loop** when you file it upstream:
|
||||
|
||||
```
|
||||
update_contribution_status(contribution_id="<uuid>", status="submitted")
|
||||
```
|
||||
|
||||
**4. Keep updating** as upstream responds — `acknowledged`, `accepted`, `merged`.
|
||||
|
||||
---
|
||||
|
||||
## Kanban board
|
||||
|
||||
The Contributions page groups artifacts by status column. Only columns with at
|
||||
least one entry are shown. The **⚠ follow-up banner** appears when any
|
||||
contribution has been in `submitted` or `acknowledged` for an extended period
|
||||
without further movement — a prompt to check in with upstream.
|
||||
|
||||
---
|
||||
|
||||
*Contributions are append-only. Rejected or withdrawn artifacts are retained as
|
||||
institutional memory — they explain why certain approaches were tried and
|
||||
dropped.*
|
||||
91
dashboard/src/docs/debt.md
Normal file
91
dashboard/src/docs/debt.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
title: Technical Debt — Reference
|
||||
---
|
||||
|
||||
# Technical Debt — Reference
|
||||
|
||||
The Technical Debt page tracks known quality compromises across all six project
|
||||
domains — intentional shortcuts, design weaknesses, missing tests, and similar
|
||||
issues that reduce codebase health but have been consciously deferred.
|
||||
|
||||
---
|
||||
|
||||
## Debt types
|
||||
|
||||
| Type | Examples |
|
||||
|------|---------|
|
||||
| **design** | Architectural decisions that should be revisited |
|
||||
| **implementation** | Hacky or fragile code that works but shouldn't stay |
|
||||
| **test** | Missing or incomplete test coverage |
|
||||
| **docs** | Missing or outdated documentation |
|
||||
| **dependencies** | Pinned old versions, unused packages, missing lockfiles |
|
||||
| **performance** | Known bottlenecks not yet worth addressing |
|
||||
| **security** | Hardcoded values, missing input validation, weak auth |
|
||||
| **other** | Anything that doesn't fit the above |
|
||||
|
||||
---
|
||||
|
||||
## Severity levels
|
||||
|
||||
| Severity | Meaning |
|
||||
|----------|---------|
|
||||
| **critical** | Blocks release or poses an active risk |
|
||||
| **high** | Should be resolved before the next major milestone |
|
||||
| **medium** | Normal triage priority |
|
||||
| **low** | Nice-to-fix; acceptable to defer indefinitely |
|
||||
|
||||
---
|
||||
|
||||
## Statuses
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| **open** | Known and unaddressed |
|
||||
| **in_progress** | Being actively worked on |
|
||||
| **deferred** | Acknowledged but intentionally postponed |
|
||||
| **resolved** | Fixed |
|
||||
| **wont_fix** | Accepted as permanent — documented for future reference |
|
||||
|
||||
Items are sorted by status (open → in_progress → deferred → resolved → wont_fix)
|
||||
then by severity (critical → high → medium → low) within each group.
|
||||
|
||||
---
|
||||
|
||||
## Filters
|
||||
|
||||
| Filter | Effect |
|
||||
|--------|--------|
|
||||
| **Status** | Multi-select |
|
||||
| **Severity** | Multi-select |
|
||||
| **Domain** | Multi-select |
|
||||
| **Type** | Multi-select |
|
||||
|
||||
---
|
||||
|
||||
## Registering debt
|
||||
|
||||
Via MCP:
|
||||
|
||||
```
|
||||
register_technical_debt(
|
||||
domain = "custodian",
|
||||
title = "Hard-coded API URL in data loaders",
|
||||
debt_type = "implementation",
|
||||
severity = "high",
|
||||
description = "All data loaders use http://127.0.0.1:8000 directly. Should read from an env var or config.",
|
||||
location = "state-hub/dashboard/src/data/*.json.py",
|
||||
workstream_id = "<uuid>" # optional
|
||||
)
|
||||
```
|
||||
|
||||
```
|
||||
update_td_status(td_uuid="<uuid>", status="resolved")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Human-readable IDs
|
||||
|
||||
Each debt item carries a human-readable ID in the form `TD-<DOMAIN>-NNN`
|
||||
(e.g. `TD-CUST-001`). IDs are optional at creation and auto-assigned if omitted.
|
||||
They appear in the table for easy reference in commit messages and comments.
|
||||
90
dashboard/src/docs/dependencies.md
Normal file
90
dashboard/src/docs/dependencies.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Dependencies — Reference
|
||||
---
|
||||
|
||||
# Dependencies — Reference
|
||||
|
||||
The Dependencies page shows the directed dependency graph between active
|
||||
workstreams — which workstreams are waiting on others to reach a satisfactory
|
||||
state before they can fully proceed.
|
||||
|
||||
---
|
||||
|
||||
## What is a dependency edge?
|
||||
|
||||
A dependency edge **A → B** means workstream A cannot fully proceed until
|
||||
workstream B is in a satisfactory state (typically `completed` or `archived`).
|
||||
|
||||
Edges are used to model real sequencing constraints: for example, a shared
|
||||
library must reach a stable release before downstream domains can build on it.
|
||||
The Custodian's dependency order is:
|
||||
|
||||
```
|
||||
Railiance → Markitect → Coulomb.social → Personhood / Foerster → Custodian
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Edge table
|
||||
|
||||
Each row shows:
|
||||
|
||||
| Column | Meaning |
|
||||
|--------|---------|
|
||||
| **Depends-on domain** | Domain of the dependent workstream (the one waiting) |
|
||||
| **Depends-on workstream** | Title of the workstream that has the dependency |
|
||||
| **→** | Direction arrow |
|
||||
| **Blocked-by domain** | Domain of the prerequisite workstream |
|
||||
| **Blocked-by workstream** | Title of the workstream that must complete first |
|
||||
| **Status** | Current status of the prerequisite (green = active, grey = completed) |
|
||||
|
||||
---
|
||||
|
||||
## KPI sidebar card
|
||||
|
||||
Shows the total number of edges and the number of distinct workstreams involved
|
||||
in at least one dependency relationship.
|
||||
|
||||
---
|
||||
|
||||
## Registering a dependency
|
||||
|
||||
Via MCP:
|
||||
|
||||
```
|
||||
create_dependency(
|
||||
from_workstream_id = "<uuid of dependent>",
|
||||
to_workstream_id = "<uuid of prerequisite>",
|
||||
description = "Cannot build auth layer until shared-library API is stable"
|
||||
)
|
||||
```
|
||||
|
||||
Via REST:
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:8000/workstreams/<from_id>/dependencies/ \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"to_workstream_id": "<to_id>", "description": "..."}'
|
||||
```
|
||||
|
||||
To list dependencies for a workstream:
|
||||
|
||||
```
|
||||
list_dependencies(workstream_id="<uuid>")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cycle detection
|
||||
|
||||
The Workstream Health Index (WHI) includes a **Cycle Penalty Index (CPI)**
|
||||
metric that detects circular dependencies using depth-first search. If CPI = 1,
|
||||
a cycle exists and the WHI is penalised by 50%. The WHI KPI card on the
|
||||
[Workstreams](/workstreams) page will display a cycle alert.
|
||||
|
||||
---
|
||||
|
||||
## Data source
|
||||
|
||||
Dependency edges are derived from the `depends_on` arrays on `open_workstreams`
|
||||
in `GET /state/summary`. Polls every **15 seconds**.
|
||||
82
dashboard/src/docs/domains.md
Normal file
82
dashboard/src/docs/domains.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Domains — Reference
|
||||
---
|
||||
|
||||
# Domains — Reference
|
||||
|
||||
The Domains page shows all registered project domains and the repositories
|
||||
associated with each one. Domains are the top-level organisational unit of the
|
||||
Custodian ecosystem.
|
||||
|
||||
---
|
||||
|
||||
## What is a domain?
|
||||
|
||||
A domain corresponds to one of the six tracked project areas:
|
||||
|
||||
| Slug | Project |
|
||||
|------|---------|
|
||||
| `custodian` | The Custodian agent system itself |
|
||||
| `railiance` | DevOps & infrastructure reliability |
|
||||
| `markitect` | Knowledge artifact management |
|
||||
| `coulomb_social` | Co-creation marketplace |
|
||||
| `personhood` | Rights & obligations framework |
|
||||
| `foerster_capabilities` | Agency capability taxonomy |
|
||||
|
||||
Each domain has a slug (URL-friendly identifier), a human-readable name, an
|
||||
optional description, and a status.
|
||||
|
||||
---
|
||||
|
||||
## Domain statuses
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| **active** | Live domain — topics, workstreams, and tasks are being tracked |
|
||||
| **archived** | Soft-deleted; no active work. Fails to archive if active topics exist |
|
||||
|
||||
---
|
||||
|
||||
## KPI row
|
||||
|
||||
Four counters at the top of the page:
|
||||
|
||||
| Counter | Meaning |
|
||||
|---------|---------|
|
||||
| Total domains | All registered domains regardless of status |
|
||||
| Active | Domains with status `active` |
|
||||
| Total repos | Sum of all registered repositories across all domains |
|
||||
| Newest domain | Name of the most recently created domain |
|
||||
|
||||
---
|
||||
|
||||
## Domain cards
|
||||
|
||||
One card per domain showing:
|
||||
|
||||
- **Slug** — monospace identifier
|
||||
- **Status badge** — green `active` or grey `archived`
|
||||
- **Name** — display name
|
||||
- **Description** — first 160 characters
|
||||
- **Repos** — list of registered repositories for this domain, each showing name, local path, and remote URL
|
||||
|
||||
---
|
||||
|
||||
## Managing domains
|
||||
|
||||
Via MCP:
|
||||
|
||||
```
|
||||
create_domain(slug="my_project", name="My Project", description="…")
|
||||
rename_domain(slug="old_slug", new_slug="new_slug", new_name="New Name")
|
||||
archive_domain(slug="my_project") # fails if active topics exist
|
||||
```
|
||||
|
||||
Via Makefile:
|
||||
|
||||
```bash
|
||||
make add-domain SLUG=my_project NAME="My Project"
|
||||
make rename-domain OLD_SLUG=my_project NEW_SLUG=myproject NEW_NAME="My Project"
|
||||
```
|
||||
|
||||
*Domains are never hard-deleted — only archived.*
|
||||
102
dashboard/src/docs/extensions.md
Normal file
102
dashboard/src/docs/extensions.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Extension Points — Reference
|
||||
---
|
||||
|
||||
# Extension Points — Reference
|
||||
|
||||
The Extension Points page tracks known future enhancement opportunities across
|
||||
all six domains — design forks the system *could* take, parked deliberately
|
||||
for later consideration rather than acted on immediately.
|
||||
|
||||
---
|
||||
|
||||
## What is an extension point?
|
||||
|
||||
An extension point (EP) captures a place in the design where additional
|
||||
capability could be added — an API surface that could be extended, a schema
|
||||
that could grow, an integration that could be built. Recording an EP
|
||||
acknowledges the opportunity without committing to it.
|
||||
|
||||
Extension points are distinct from technical debt: debt is a known compromise
|
||||
that should be fixed; EPs are optional future directions that may or may not
|
||||
be pursued.
|
||||
|
||||
---
|
||||
|
||||
## EP types
|
||||
|
||||
| Type | Examples |
|
||||
|------|---------|
|
||||
| **api** | New endpoints, query parameters, response fields |
|
||||
| **schema** | New tables, columns, relationships |
|
||||
| **mcp** | New MCP tools or resources |
|
||||
| **dashboard** | New pages, charts, or components |
|
||||
| **architecture** | Structural changes to the system design |
|
||||
| **integration** | Connections to external systems |
|
||||
| **other** | Anything that doesn't fit the above |
|
||||
|
||||
---
|
||||
|
||||
## Statuses
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| **open** | Identified, not yet acted on |
|
||||
| **in_progress** | Being implemented as part of an active workstream |
|
||||
| **addressed** | The capability has been built |
|
||||
| **deferred** | Intentionally postponed |
|
||||
| **wont_fix** | Decided not to pursue — kept for documentation |
|
||||
|
||||
Items are sorted by status (open → in_progress → deferred → addressed → wont_fix)
|
||||
then by priority (critical → high → medium → low).
|
||||
|
||||
---
|
||||
|
||||
## Priorities
|
||||
|
||||
| Priority | Meaning |
|
||||
|----------|---------|
|
||||
| **critical** | Needed to unblock other work |
|
||||
| **high** | High-value enhancement for the near term |
|
||||
| **medium** | Would be useful but not urgent |
|
||||
| **low** | Speculative or long-horizon idea |
|
||||
|
||||
---
|
||||
|
||||
## Filters
|
||||
|
||||
| Filter | Effect |
|
||||
|--------|--------|
|
||||
| **Status** | Multi-select |
|
||||
| **Priority** | Multi-select |
|
||||
| **Domain** | Multi-select |
|
||||
| **Type** | Multi-select |
|
||||
|
||||
---
|
||||
|
||||
## Registering an extension point
|
||||
|
||||
Via MCP:
|
||||
|
||||
```
|
||||
register_extension_point(
|
||||
domain = "custodian",
|
||||
title = "Configurable poll interval per dashboard page",
|
||||
ep_type = "dashboard",
|
||||
priority = "low",
|
||||
description = "Each page hard-codes POLL = 15_000. An env var or per-page config would allow slowing down low-priority pages to reduce API load.",
|
||||
location = "state-hub/dashboard/src/*.md",
|
||||
workstream_id = "<uuid>" # optional
|
||||
)
|
||||
```
|
||||
|
||||
```
|
||||
update_ep_status(ep_uuid="<uuid>", status="addressed")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Human-readable IDs
|
||||
|
||||
Each EP carries an ID in the form `EP-<DOMAIN>-NNN` (e.g. `EP-CUST-001`).
|
||||
IDs are optional at creation and auto-assigned if omitted.
|
||||
84
dashboard/src/docs/overview.md
Normal file
84
dashboard/src/docs/overview.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: Overview — Reference
|
||||
---
|
||||
|
||||
# Overview — Reference
|
||||
|
||||
The Overview page is the operational home screen of the Custodian State Hub.
|
||||
It shows the live health of the entire ecosystem at a glance — active work,
|
||||
blocking decisions, and system-derived next-step suggestions.
|
||||
|
||||
---
|
||||
|
||||
## Sections
|
||||
|
||||
### Open Workstreams by Domain
|
||||
|
||||
A horizontal stacked bar chart showing every active workstream across all six
|
||||
domains. Each bar is broken into four task-status segments:
|
||||
|
||||
| Colour | Segment |
|
||||
|--------|---------|
|
||||
| green | done |
|
||||
| blue | in progress |
|
||||
| orange-red | blocked |
|
||||
| light grey | todo |
|
||||
|
||||
The left axis shows domain labels (one per group of workstreams). The `done/total`
|
||||
count is printed to the right of each bar. Workstreams with no tasks yet show
|
||||
a grey "— no tasks yet" label.
|
||||
|
||||
### Contribution & SBOM Health
|
||||
|
||||
Three summary cards linked to the Contributions and SBOM pages:
|
||||
|
||||
| Card | Shows |
|
||||
|------|-------|
|
||||
| **Contributions** | Total artifact count; orange warning if any are awaiting upstream response |
|
||||
| **Licence Risk** | Count of SBOM packages with copyleft licences in direct dependencies |
|
||||
| **SBOM** | Breakdown by contribution type (BR / FR / EP / UPR) |
|
||||
|
||||
### Status
|
||||
|
||||
Four metric cards:
|
||||
|
||||
| Card | Meaning |
|
||||
|------|---------|
|
||||
| **Active Workstreams** | Count of non-completed, non-archived workstreams |
|
||||
| **Blocking Decisions** | Pending decisions with status `open` or `escalated` — orange border if > 0 |
|
||||
| **Blocked Tasks** | Click to expand the list with blocking reasons |
|
||||
| **Events Today** | Progress events created on today's date |
|
||||
|
||||
### What's next?
|
||||
|
||||
System-derived action suggestions from `GET /state/next_steps`. Suggestions are
|
||||
generated when a decision is resolved or a workstream dependency is cleared, and
|
||||
they point to the first open task in the relevant workstream. These are derived
|
||||
on request and never persisted.
|
||||
|
||||
### Blocking Decisions
|
||||
|
||||
Inline resolution form for each pending decision. Expand a card, enter a
|
||||
rationale and "decided by" name, and click **Record & close**. The decision is
|
||||
resolved via `POST /decisions/{id}/resolve` and disappears from the list
|
||||
without a page reload.
|
||||
|
||||
### Registered Projects
|
||||
|
||||
Table of projects registered with `make register-project`, sourced from
|
||||
`milestone` progress events whose summary starts with
|
||||
`"Project registered with State Hub:"`.
|
||||
|
||||
### Recent Activity
|
||||
|
||||
Last 20 progress events across all domains, showing time, event type, author,
|
||||
and summary.
|
||||
|
||||
---
|
||||
|
||||
## Data source
|
||||
|
||||
Polls `GET /state/summary` every **15 seconds**. Blocking decisions are fetched
|
||||
separately via `GET /decisions/?decision_type=pending` and only re-fetched
|
||||
after a successful resolve action — this prevents the inline form from being
|
||||
wiped on every poll.
|
||||
119
dashboard/src/docs/reference.md
Normal file
119
dashboard/src/docs/reference.md
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Reference & Context Help — Reference
|
||||
---
|
||||
|
||||
# Reference & Context Help
|
||||
|
||||
The **Reference** section is a collection of in-depth documentation pages
|
||||
explaining the data model, design conventions, and mechanics of each dashboard
|
||||
view. Reference pages are readable as standalone articles and also surfaced
|
||||
inline via the **? context-help button** on dashboard pages.
|
||||
|
||||
---
|
||||
|
||||
## The ? context-help button
|
||||
|
||||
Every dashboard page exposes one or more **?** buttons — small circular
|
||||
controls that open the relevant reference page in an overlay without leaving
|
||||
the current view.
|
||||
|
||||
### Where ? buttons appear
|
||||
|
||||
| Location | Opens |
|
||||
|----------|-------|
|
||||
| Page **h1** heading | Reference page for that dashboard view |
|
||||
| **KPI sidebar cards** | Reference page for the specific metric shown |
|
||||
| **Live indicator** | [Live Data](/docs/live-data) — poll interval, offline recovery |
|
||||
|
||||
### How to use it
|
||||
|
||||
1. Hover over the element — the **?** button fades in at the top-right corner.
|
||||
2. Click **?** — the reference page opens in a modal overlay.
|
||||
3. Read the docs, then dismiss with **✕ close**, **Esc**, or by clicking the
|
||||
backdrop.
|
||||
|
||||
The overlay does not interrupt the live data polling loop — the dashboard
|
||||
continues refreshing in the background while the overlay is open.
|
||||
|
||||
---
|
||||
|
||||
## Overlay behaviour
|
||||
|
||||
| Detail | Value |
|
||||
|--------|-------|
|
||||
| Size | `min(780px, 92vw)` wide · `82vh` tall |
|
||||
| Content | Observable Framework page rendered in an `<iframe>` |
|
||||
| Dismiss | ✕ button · Esc key · click outside the box |
|
||||
| Animation | Fade-in backdrop + slide-up box (150 ms) |
|
||||
| Stacking | `z-index: 9000` — always above dashboard content |
|
||||
|
||||
Only one overlay can be open at a time. Opening a second **?** replaces the
|
||||
first automatically.
|
||||
|
||||
---
|
||||
|
||||
## Adding ? help to a new page
|
||||
|
||||
The helper is exported from `src/components/doc-overlay.js`:
|
||||
|
||||
```js
|
||||
import {withDocHelp} from "./components/doc-overlay.js";
|
||||
```
|
||||
|
||||
**On a page h1:**
|
||||
|
||||
```js
|
||||
const _h1 = document.querySelector("#observablehq-main h1");
|
||||
if (_h1) { _h1.style.position = "relative"; withDocHelp(_h1, "/docs/my-page"); }
|
||||
```
|
||||
|
||||
**On a sidebar card or other element** (must have `position: relative`):
|
||||
|
||||
```js
|
||||
const _card = html`<div class="kpi-infobox" style="position:relative">…</div>`;
|
||||
withDocHelp(_card, "/docs/my-page");
|
||||
```
|
||||
|
||||
`withDocHelp(element, docPath)` mutates the element in place and returns it,
|
||||
so it can be chained directly before `display()` or `injectTocTop()`.
|
||||
|
||||
---
|
||||
|
||||
## Writing a reference page
|
||||
|
||||
Reference pages live in `state-hub/dashboard/src/docs/` and follow a consistent
|
||||
structure:
|
||||
|
||||
```
|
||||
---
|
||||
title: Topic — Reference
|
||||
---
|
||||
|
||||
# Topic — Reference
|
||||
|
||||
One-sentence purpose statement.
|
||||
|
||||
---
|
||||
|
||||
## Section 1
|
||||
…
|
||||
|
||||
## Section 2
|
||||
…
|
||||
|
||||
---
|
||||
|
||||
*Footer note (optional — e.g. governance constraint, append-only policy).*
|
||||
```
|
||||
|
||||
**Conventions:**
|
||||
|
||||
- Title frontmatter: `"Topic — Reference"` (em dash, not hyphen)
|
||||
- Sections separated by `---` horizontal rules
|
||||
- Tables preferred over prose lists for structured data
|
||||
- Code blocks for MCP tool calls and REST examples
|
||||
- No live data fetching — reference pages are static
|
||||
|
||||
After writing the page, register it in two places:
|
||||
1. **`observablehq.config.js`** — add to the Reference `pages` array (alphabetical)
|
||||
2. **`src/reference.md`** — add a row to the dashboard-pages table
|
||||
83
dashboard/src/docs/repos.md
Normal file
83
dashboard/src/docs/repos.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: Repos — Reference
|
||||
---
|
||||
|
||||
# Repos — Reference
|
||||
|
||||
The Repos page shows every repository registered in the Custodian ecosystem,
|
||||
their SBOM ingestion status, and a domain-grouped coverage map.
|
||||
|
||||
---
|
||||
|
||||
## What is a managed repo?
|
||||
|
||||
A managed repo is a git repository that has been registered with the state hub
|
||||
via `make add-repo` or `register_repo()`. Registration records the repo's slug,
|
||||
domain, local path, and optional remote URL. Once registered, the repo can
|
||||
receive SBOM ingestion and is eligible for the ADR-001 workplan validator.
|
||||
|
||||
---
|
||||
|
||||
## KPI row
|
||||
|
||||
| Card | Meaning |
|
||||
|------|---------|
|
||||
| **Registered Repos** | Active repos only (status = active) |
|
||||
| **Domains** | Count of distinct domain slugs across registered repos |
|
||||
| **SBOM Ingested** | Repos with at least one SBOM snapshot |
|
||||
| **SBOM Gaps** | Repos with no ingested SBOM — red border when > 0 |
|
||||
|
||||
---
|
||||
|
||||
## Coverage Map
|
||||
|
||||
Groups repos by domain. Each domain block shows:
|
||||
|
||||
- **Domain name** with SBOM, EP, and TD chip indicators
|
||||
- **SBOM chip** — green ✓ if all repos in the domain are ingested, amber ⚠ if any gap exists
|
||||
- **EPs chip** — count of open/in-progress extension points for this domain
|
||||
- **TDs chip** — count of open/in-progress technical debt items for this domain
|
||||
- **Repo table** — one row per repo with SBOM status, package count, and local path
|
||||
|
||||
Rows with no SBOM are highlighted in amber.
|
||||
|
||||
---
|
||||
|
||||
## Filters
|
||||
|
||||
| Filter | Effect |
|
||||
|--------|--------|
|
||||
| **Domain** | Show repos for a single domain only |
|
||||
| **Gaps only** | Toggle to show only repos without an ingested SBOM |
|
||||
|
||||
---
|
||||
|
||||
## Ingesting a repo's SBOM
|
||||
|
||||
```bash
|
||||
# Register a new repo
|
||||
cd ~/the-custodian/state-hub
|
||||
make add-repo DOMAIN=<slug> SLUG=<repo-slug> NAME="Display Name" PATH=/absolute/path
|
||||
|
||||
# Ingest SBOM (auto-detects lockfile at repo root)
|
||||
make ingest-sbom REPO=<slug> REPO_PATH=/absolute/path
|
||||
|
||||
# Multi-ecosystem repo — scan all lockfiles recursively
|
||||
make ingest-sbom REPO=<slug> SCAN=1 REPO_PATH=/absolute/path
|
||||
```
|
||||
|
||||
Supported lockfile formats: `uv.lock`, `requirements.txt`, `package-lock.json`,
|
||||
`yarn.lock`, `Cargo.lock`, `.terraform.lock.hcl`.
|
||||
|
||||
---
|
||||
|
||||
## Infra-only repos
|
||||
|
||||
Repos with no lockfile (Ansible, shell scripts) can be registered for inventory
|
||||
purposes. The SBOM gap is expected and can be left as-is. Terraform providers
|
||||
are auto-detected via `.terraform.lock.hcl` when using `--scan`.
|
||||
|
||||
---
|
||||
|
||||
*SBOM snapshots are replaced on each ingest — not appended. The last ingestion
|
||||
timestamp is recorded on the managed_repo row.*
|
||||
95
dashboard/src/docs/tasks.md
Normal file
95
dashboard/src/docs/tasks.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
title: Tasks — Reference
|
||||
---
|
||||
|
||||
# Tasks — Reference
|
||||
|
||||
The Tasks page shows all tasks across every workstream and domain, with live
|
||||
filtering, a status distribution chart, and a blocked-tasks highlight section.
|
||||
|
||||
---
|
||||
|
||||
## Task statuses
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| **todo** | Not yet started |
|
||||
| **in_progress** | Actively being worked on |
|
||||
| **blocked** | Cannot proceed — has a blocking reason |
|
||||
| **done** | Completed |
|
||||
| **cancelled** | Dropped; not counted toward totals |
|
||||
|
||||
---
|
||||
|
||||
## Task priorities
|
||||
|
||||
| Priority | Use for |
|
||||
|----------|---------|
|
||||
| **critical** | Must be resolved immediately; blocks a release or governance gate |
|
||||
| **high** | Should be resolved this session or next |
|
||||
| **medium** | Normal backlog priority |
|
||||
| **low** | Nice-to-have; deferred is acceptable |
|
||||
|
||||
---
|
||||
|
||||
## Filter bar
|
||||
|
||||
| Filter | Effect |
|
||||
|--------|--------|
|
||||
| **Status** | Multi-select — show only chosen statuses |
|
||||
| **Priority** | Multi-select — show only chosen priorities |
|
||||
| **Domain** | Multi-select — filter by domain slug |
|
||||
| **Assignee** | Case-insensitive substring match on the assignee field |
|
||||
|
||||
All filters are applied client-side after each poll.
|
||||
|
||||
---
|
||||
|
||||
## Status Distribution chart
|
||||
|
||||
A horizontal bar chart (Observable Plot) showing the count of filtered tasks
|
||||
per status, colour-coded:
|
||||
|
||||
| Colour | Status |
|
||||
|--------|--------|
|
||||
| grey-blue | todo |
|
||||
| blue | in_progress |
|
||||
| red | blocked |
|
||||
| green | done |
|
||||
| light grey | cancelled |
|
||||
|
||||
---
|
||||
|
||||
## Blocked Tasks section
|
||||
|
||||
Shows cards for every task currently in `blocked` status within the active
|
||||
filter. Each card displays:
|
||||
|
||||
- Priority badge and status
|
||||
- Domain and workstream context
|
||||
- Task title
|
||||
- Blocking reason (amber background)
|
||||
|
||||
---
|
||||
|
||||
## KPI sidebar card
|
||||
|
||||
Shows four counts for the unfiltered dataset: open (todo + in_progress +
|
||||
blocked), blocked, in progress, done, and a done-% of total.
|
||||
|
||||
---
|
||||
|
||||
## Sorting
|
||||
|
||||
Tasks are sorted by status (blocked first, then in_progress, todo, done,
|
||||
cancelled) then by priority (critical → high → medium → low) within each
|
||||
status group.
|
||||
|
||||
---
|
||||
|
||||
## Data sources
|
||||
|
||||
Polls every **15 seconds**:
|
||||
- `GET /tasks/?limit=500`
|
||||
- `GET /workstreams/`
|
||||
- `GET /topics/`
|
||||
71
dashboard/src/docs/todo.md
Normal file
71
dashboard/src/docs/todo.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: Todo — Reference
|
||||
---
|
||||
|
||||
# Todo — Reference
|
||||
|
||||
The Todo page shows the Custodian's own open work items classified by where the
|
||||
work belongs — inside this repo, routed from another ecosystem repo, or aimed
|
||||
at an upstream third-party project.
|
||||
|
||||
This page is the session-start orientation surface for the `the-custodian` repo.
|
||||
See [Inter-Repo Communication](/docs/inter-repo-communication) for the full
|
||||
boundary rule and routing workflows.
|
||||
|
||||
---
|
||||
|
||||
## The three classes
|
||||
|
||||
### Internal
|
||||
|
||||
Open tasks (`todo`, `in_progress`, `blocked`) in **custodian domain workstreams**
|
||||
whose title does not contain a `[repo:]` routing prefix.
|
||||
|
||||
These are tasks this agent is directly responsible for and can address within
|
||||
the current repo.
|
||||
|
||||
### Ecosystem (inbound)
|
||||
|
||||
Tasks from **any workstream** whose title contains `[repo:the-custodian]`.
|
||||
|
||||
These tasks were created by agents in other repos to route work to the custodian.
|
||||
When a task with this prefix appears, the session protocol picks it up, the
|
||||
custodian creates a workplan file (ADR-001), and addresses the work here.
|
||||
|
||||
### Third-party (outbound)
|
||||
|
||||
Contribution artifacts in **open status** (`draft`, `submitted`, `acknowledged`).
|
||||
|
||||
These represent work the custodian has identified for upstream repos it does not
|
||||
own. They remain on the todo list until the upstream loop is closed (`merged`,
|
||||
`rejected`, or `withdrawn`).
|
||||
|
||||
---
|
||||
|
||||
## Classification decision table
|
||||
|
||||
| Situation | Class | Action |
|
||||
|-----------|-------|--------|
|
||||
| Bug found in this repo | Internal | Fix it directly |
|
||||
| Work needed in another registered repo | Ecosystem | `create_task(..., title="[repo:<slug>] ...")` |
|
||||
| Bug found in an upstream library | Third-party | Create BR artifact + `register_contribution` |
|
||||
| Feature needed from upstream | Third-party | Create FR artifact + `register_contribution` |
|
||||
|
||||
---
|
||||
|
||||
## KPI sidebar card
|
||||
|
||||
Shows the count of open items in each class at a glance. The `?` button links
|
||||
to this reference page.
|
||||
|
||||
---
|
||||
|
||||
## Data sources
|
||||
|
||||
Polls every **15 seconds**:
|
||||
- `GET /tasks/?limit=500` — all tasks
|
||||
- `GET /workstreams/` — for domain + title context
|
||||
- `GET /topics/` — for domain slug resolution
|
||||
- `GET /contributions/` — for third-party todos
|
||||
|
||||
*Classification is done client-side — no server-side filter endpoint required.*
|
||||
Reference in New Issue
Block a user