Implements the 14-criterion DoI checklist as a runnable gate with API,
MCP tools, CLI script, and dashboard integration.
Core components:
- api/doi_engine.py — async engine evaluating all 14 criteria (asyncio.to_thread
for non-blocking HTTP self-calls), shared by API and CLI
- api/schemas/doi.py — DoICriterion, DoIReport, DoISummaryEntry schemas
- api/routers/repos.py — GET /repos/{slug}/doi + GET /repos/doi/summary
- scripts/check_doi.py — CLI: make check-doi REPO=<slug> / check-doi-all
- mcp_server/server.py — check_repo_doi(), get_doi_summary() tools
Dashboard (repos.md):
- DoI tier badge per repo (None/Core/Standard/Full) colour-coded red→green
- Domain block shows lowest DoI tier across its repos
- DoI KPI card in summary row
- DoI filter in All Repos Table
- Link to Repository DoI policy page
Also fixes: TPSC snapshots 500 error (missing nested selectinload for
catalog_entry relationship in list_snapshots endpoint).
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
4.1 KiB
id, type, title, domain, status, owner, topic_slug, created, updated, state_hub_workstream_id
| id | type | title | domain | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|
| CUST-WP-0024 | feature | Repository DoI automated gate and dashboard integration | custodian | done | custodian-agent | custodian | 2026-03-20 | 2026-03-20 | f587f244-0dd5-4268-b955-0c4e4cf9aa69 |
Repository DoI Automated Gate & Dashboard
Automates the 14-criterion DoI checklist from policies/repo-doi.md and
surfaces per-repo DoI status on the Repositories dashboard page.
Task: DoI check script — scripts/check_doi.py
id: CUST-WP-0024-T01
status: done
priority: high
state_hub_task_id: "58e77114-bc54-4f86-9ddc-3834bc702b5c"
Create state-hub/scripts/check_doi.py implementing all 14 DoI criteria:
Tier 1 — Core
- C1: repo registered (
GET /repos/{slug}returns 200) - C2: domain assigned (
domain_slugnon-null and domain status active) - C3: local path resolves (exists on disk after expanduser)
- C4: remote_url set (non-null, non-empty)
Tier 2 — Standard
- C5: SCOPE.md present at repo root
- C6: CLAUDE.md present at repo root
- C7: workplan convention followed — consistency check returns 0 FAIL
- C8: SBOM ingested —
last_sbom_atnon-null on repo record - C9: TPSC declared —
tpsc.yamlexists at repo root AND at least one TPSC snapshot exists for the repo
Tier 3 — Full
- C10: active repo goal exists (
GET /repo-goals/?repo_slug=...has ≥1 active) - C11: Provided Capabilities declared —
SCOPE.mdcontains acapabilityfenced block OR## Provided Capabilitiessection says "none" explicitly - C12: agents template applied — CLAUDE.md contains
get_kaizen_agentorkaizenreference - C13: consistency check clean — 0 FAIL and 0 WARN (C-12 exempt)
- C14: host paths registered —
host_pathsnon-empty
Output per criterion: PASS / FAIL / WARN / SKIP (with reason). Overall tier: core_pass, standard_pass, full_pass (boolean each).
CLI flags: --repo SLUG, --all, --json, --fix (no-op for now,
reserved for future auto-remediation).
Makefile targets:
make check-doi REPO=<slug>
make check-doi-all
make check-doi REPO=<slug> JSON=1
Task: API endpoint GET /repos/{slug}/doi
id: CUST-WP-0024-T02
status: done
priority: high
state_hub_task_id: "97801608-2cad-40e6-ba0c-d209bcc3ec04"
Add to api/routers/repos.py:
GET /repos/{slug}/doi — runs the DoI check logic server-side and returns:
{
"repo_slug": "llm-connect",
"tier": "standard", // "none" | "core" | "standard" | "full"
"core_pass": true,
"standard_pass": true,
"full_pass": false,
"criteria": [
{"id": "C1", "label": "Registered", "tier": "core", "status": "pass"},
...
],
"checked_at": "2026-03-20T..."
}
Also add GET /repos/doi/summary — returns all repos with their tier,
sorted by tier ascending (worst first).
Add Pydantic schemas DoICriterion, DoIReport, DoISummaryEntry to
api/schemas/doi.py.
Task: MCP tool — check_repo_doi
id: CUST-WP-0024-T03
status: done
priority: medium
state_hub_task_id: "3e18a74a-576a-4491-b7cf-3d6ba7746a0f"
Add to mcp_server/server.py:
check_repo_doi(repo_slug) — returns the DoI report for a single repo.
get_doi_summary() — returns all repos sorted by tier (worst first),
useful for session orientation.
Task: Repositories dashboard page — DoI integration
id: CUST-WP-0024-T04
status: done
priority: high
state_hub_task_id: "ab1a843c-60e3-4eba-ae6a-dec7d74c03f4"
Review and update dashboard/src/repos.md (or whichever page shows the
repo list) to include:
- DoI tier badge per repo (None / Core / Standard / Full) with colour coding (red / amber / yellow / green)
- Expandable per-repo criterion detail (collapsible row or modal)
- Summary KPI: count of repos at each tier
- Link to the Repository DoI policy page
If repos.md does not exist, create it. If it already shows repo data,
enrich it in-place.
Task: Consistency check — run fix-consistency
id: CUST-WP-0024-T05
status: done
priority: low
state_hub_task_id: "5372bde5-b0e5-4993-94a0-ffa9b7bb26e9"
After all code is written and tested:
- Run
make fix-consistency REPO=the-custodian - Commit all new/modified files