Files
the-custodian/workplans/CUST-WP-0002-contribution-tracking-sbom.md
tegwick e471ed2cd5 feat(state-hub): v0.3 registration workflow + ingest-sbom + CLAUDE.md template update
- scripts/ingest_sbom.py: lockfile parser + API poster for uv.lock, requirements.txt,
  package-lock.json, yarn.lock, Cargo.lock; auto-detects from repo root
- Makefile: make ingest-sbom REPO=<slug> [LOCKFILE=<path>] target
- scripts/register_project.sh: adds {REPO_SLUG} template substitution + optional
  SBOM ingest prompt at end of registration (non-fatal if venv not ready)
- scripts/project_claude_md.template: adds Contribution Tracking + SBOM sections
  documenting register_contribution(), update_contribution_status(), ingest-sbom,
  and the contrib/ directory layout
- workplans/CUST-WP-0002: all 15 tasks → done, status → completed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 17:28:49 +01:00

295 lines
9.5 KiB
Markdown

---
id: CUST-WP-0002
type: workplan
title: "State Hub v0.3 — Contribution Tracking & SBOM"
domain: custodian
status: completed
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: done
priority: high
```
Define the master contrib/ convention: directory layout, artifact types
(BR/FR/EP/UPR), frontmatter schema per type, ID schemes (EP-<DOMAIN>-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: done
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: done
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: done
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: done
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: done
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: done
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: done
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: done
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=<slug>`. 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: done
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: done
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: done
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: done
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: done
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: done
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=<slug>` 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.