--- title: Repositories --- ```js import {API} from "./components/config.js"; ``` ```js // Fast data — page renders as soon as this resolves (~200ms) let _repos = [], _domains = [], _sbom = [], _eps = [], _tds = [], _workstreams = []; try { [_repos, _domains, _sbom, _eps, _tds, _workstreams] = await Promise.all([ fetch(`${API}/repos/`).then(r => r.ok ? r.json() : []), fetch(`${API}/domains/`).then(r => r.ok ? r.json() : []), fetch(`${API}/sbom/`).then(r => r.ok ? r.json() : []), fetch(`${API}/extension-points/`).then(r => r.ok ? r.json() : []), fetch(`${API}/technical-debt/`).then(r => r.ok ? r.json() : []), fetch(`${API}/workplans/`).then(r => r.ok ? r.json() : []), ]); } catch {} ``` ```js // DoI data — lazy-loaded. Starts as [] so the page renders immediately. // When the fetch resolves (~6s), doiData updates and DoI badges appear. import {Mutable} from "observablehq:stdlib"; const doiData = Mutable([]); const doiLoading = Mutable(true); fetch(`${API}/repos/doi/summary`) .then(r => r.ok ? r.json() : []) .catch(() => []) .then(data => { doiData.value = data; doiLoading.value = false; }); ``` ```js const repos = _repos ?? []; const domains = _domains ?? []; const sbom = _sbom ?? []; const eps = _eps ?? []; const tds = _tds ?? []; const workstreams = _workstreams ?? []; const doi = doiData; // reactive — updates when lazy fetch completes // DoI lookups const doiBySlug = Object.fromEntries(doi.map(d => [d.repo_slug, d])); const DOI_TIER_ORDER = {none: 0, core: 1, standard: 2, full: 3}; const DOI_TIER_COLOR = {none: "#ef4444", core: "#f97316", standard: "#eab308", full: "#22c55e"}; const DOI_TIER_BG = {none: "#fef2f2", core: "#fff7ed", standard: "#fefce8", full: "#f0fdf4"}; const DOI_TIER_LABEL = {none: "None", core: "Core", standard: "Standard", full: "Full"}; // Lookups const domainById = Object.fromEntries(domains.map(d => [d.id, d])); const domainBySlug = Object.fromEntries(domains.map(d => [d.slug, d])); // Active "repo-integration-{slug}" workstreams — signals onboarding in progress const integratingBySlug = Object.fromEntries( workstreams .filter(w => w.status === "active" && w.slug?.startsWith("repo-integration-")) .map(w => [w.slug.replace("repo-integration-", ""), w]) ); // Per-repo SBOM stats (from sbom entries) const sbomByRepo = {}; for (const e of sbom) { if (!sbomByRepo[e.repo_id]) sbomByRepo[e.repo_id] = { count: 0, snapshot_at: e.snapshot_at }; sbomByRepo[e.repo_id].count++; } // Per-domain counts const epByDomain = {}; const tdByDomain = {}; const contribByDomain = {}; // EPs are domain-scoped for (const ep of eps) { if (!ep.status || ep.status === "open" || ep.status === "in_progress") { epByDomain[ep.domain] = (epByDomain[ep.domain] ?? 0) + 1; } } for (const td of tds) { if (!td.status || td.status === "open" || td.status === "in_progress") { tdByDomain[td.domain] = (tdByDomain[td.domain] ?? 0) + 1; } } // Contributions: try to map via workstream → topic → domain (not available here; skip for now) // Use domain slug from contributions' related_workstream if available — fallback: count by type only // Build enriched repo rows const repoRows = repos .filter(r => r.status === "active") .map(r => { const domain = domainById[r.domain_id]; const domSlug = domain?.slug ?? "—"; const domName = domain?.name ?? "—"; const sbomData = sbomByRepo[r.id]; const hasSbom = !!sbomData || !!r.last_sbom_at; const pkgCount = sbomData?.count ?? 0; const lastScan = r.last_sbom_at ? new Date(r.last_sbom_at).toLocaleDateString() : (sbomData?.snapshot_at ? new Date(sbomData.snapshot_at).toLocaleDateString() : null); const integrating = !!integratingBySlug[r.slug]; const doiEntry = doiBySlug[r.slug] ?? null; const doiTier = doiEntry?.tier ?? "none"; return { _id: r.id, _domSlug: domSlug, _hasSbom: hasSbom, _integrating: integrating, _doiTier: doiTier, repo: r.slug, domain: domName, status: integrating ? "⚙ integrating" : "ready", path: r.local_path ?? "—", sbom: hasSbom ? `✓ ${lastScan}` : "⚠ not ingested", pkgs: pkgCount || (hasSbom ? "—" : 0), eps: epByDomain[domSlug] ?? 0, tds: tdByDomain[domSlug] ?? 0, }; }) .sort((a, b) => a._domSlug.localeCompare(b._domSlug) || a.repo.localeCompare(b.repo)); const gapCount = repoRows.filter(r => !r._hasSbom).length; const coveredCount = repoRows.filter(r => r._hasSbom).length; const integratingCount = repoRows.filter(r => r._integrating).length; const doiFullCount = repoRows.filter(r => r._doiTier === "full").length; const doiNoneCount = repoRows.filter(r => r._doiTier === "none").length; ``` # Repositories ```js import {withDocHelp} from "./components/doc-overlay.js"; const _h1 = document.querySelector("#observablehq-main h1"); if (_h1) { _h1.style.position = "relative"; withDocHelp(_h1, "/docs/repos"); } display(html`

DoI tiers: NoneCoreStandardFullDefinition of Integrated policy ↗ ${doiLoading ? html` Loading DoI tiers… ` : html`✓ DoI tiers loaded`}

`); ``` ```js // Summary KPIs display(html`

Registered Repos

${repoRows.length}

Domains

${new Set(repoRows.map(r => r._domSlug)).size}

Integrating

${integratingCount}

${integratingCount === 0 ? "✓ All repos integrated" : `⚙ ${integratingCount} onboarding`}

SBOM Ingested

${coveredCount} / ${repoRows.length}

SBOM Gaps

${gapCount}

${gapCount === 0 ? "✓ All repos covered" : `⚠ ${gapCount} repo(s) not ingested`}

DoI: Fully Integrated

${doiLoading ? html`` : `${doiFullCount} / ${repoRows.length}`}

${doiLoading ? "Loading…" : doiNoneCount > 0 ? `⚠ ${doiNoneCount} at tier None` : "✓ All pass Core tier"}
`); ``` ## Coverage Map ```js // Returns a new "⚠ not ingested" span with a ? help button each time it's called. function _sbomGap() { const el = html`⚠ not ingested`; withDocHelp(el, "/docs/sbom"); return el; } function _doiBadge(tier) { if (doiLoading) return html``; const color = DOI_TIER_COLOR[tier] || "#9ca3af"; const bg = DOI_TIER_BG[tier] || "#f9fafb"; const label = DOI_TIER_LABEL[tier] || tier; return html` DoI: ${label}`; } // Group by domain const byDomain = {}; for (const r of repoRows) { (byDomain[r._domSlug] = byDomain[r._domSlug] ?? []).push(r); } const domainBlocks = Object.entries(byDomain).sort(([a], [b]) => a.localeCompare(b)); if (domainBlocks.length === 0) { display(html`

No repos registered. Run make add-repo DOMAIN=<slug> SLUG=<slug> NAME="..." PATH=/path.

`); } else { display(html`
${domainBlocks.map(([slug, rows]) => { const dom = domainBySlug[slug]; const allCovered = rows.every(r => r._hasSbom); const doiWorst = rows.map(r => DOI_TIER_ORDER[r._doiTier] ?? 0); const doiMin = Math.min(...doiWorst); const doiMinKey = Object.keys(DOI_TIER_ORDER).find(k => DOI_TIER_ORDER[k] === doiMin) ?? "none"; const hasEps = (epByDomain[slug] ?? 0) > 0; const hasTds = (tdByDomain[slug] ?? 0) > 0; return html`
${dom?.name ?? slug} ${allCovered ? html`SBOM ✓` : html`SBOM ⚠`} ${hasEps ? html`EPs: ${epByDomain[slug]}` : html`EPs: —`} ${hasTds ? html`TDs: ${tdByDomain[slug]}` : html`TDs: —`} DoI min: ${DOI_TIER_LABEL[doiMinKey]}
${rows.map(r => html``)}
Repo DoI Tier Status SBOM Packages Local path
${r.repo} ${_doiBadge(r._doiTier)} ${r._integrating ? html`⚙ integrating` : html`ready`} ${r._hasSbom ? r.sbom : _sbomGap()} ${r.pkgs} ${r.path}
`; })}
`); } ``` ## All Repos Table ```js const domainFilter = Inputs.select(["all", ...new Set(repoRows.map(r => r._domSlug)).values()], {label: "Domain", value: "all"}); const doiFilter = Inputs.select(["all", "none", "core", "standard", "full"], {label: "DoI tier", value: "all"}); const gapFilter = Inputs.toggle({label: "Gaps only (no SBOM)", value: false}); display(html`
${domainFilter}${doiFilter}${gapFilter}
`); ``` ```js const filteredRows = repoRows.filter(r => (domainFilter.value === "all" || r._domSlug === domainFilter.value) && (doiFilter.value === "all" || r._doiTier === doiFilter.value) && (!gapFilter.value || !r._hasSbom) ); display(Inputs.table(filteredRows.map(r => ({ Repo: r.repo, Domain: r.domain, "DoI Tier": DOI_TIER_LABEL[r._doiTier] ?? r._doiTier, Status: r.status, SBOM: r.sbom, Pkgs: r.pkgs, "EPs (domain)": r.eps || "—", "TDs (domain)": r.tds || "—", Path: r.path, })), {maxWidth: 1200})); ``` ## Onboard a New Repo ```js const _h2onboard = [...document.querySelectorAll("#observablehq-main h2")] .find(h => h.textContent.includes("Onboard a New Repo")); if (_h2onboard) { _h2onboard.style.position = "relative"; withDocHelp(_h2onboard, "/docs/repo-integration"); } ``` ```js const onboardId = `onboard-${Math.random().toString(36).slice(2)}`; const onboardDomainOptions = [...domains] .sort((a, b) => a.slug.localeCompare(b.slug)) .map(d => html``); const onboardForm = html`

Add Repo

Register an accessible git working copy and write the starter files for the selected agent profile.

Paste the absolute path when the checkout is on the State Hub host or exposed via ops-bridge.


`; display(onboardForm); { const button = onboardForm.querySelector(".onboard-primary"); const status = onboardForm.querySelector(".onboard-status"); const pathInput = onboardForm.querySelector(".onboard-path"); button.addEventListener("click", async () => { const body = { domain_slug: onboardForm.querySelector(".onboard-domain").value, project_path: pathInput.value.trim(), agent_profile: onboardForm.querySelector(".onboard-agent").value, additional: onboardForm.querySelector(".onboard-additional").checked, }; if (!body.project_path) { status.textContent = "Enter an absolute path that the State Hub API can access."; pathInput.focus(); return; } button.disabled = true; status.textContent = "Onboarding started..."; try { const response = await fetch(`${API}/repos/onboard`, { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(body), }); const payload = await response.json().catch(() => ({})); if (!response.ok) { const detail = payload.detail ?? payload; throw new Error(typeof detail === "string" ? detail : JSON.stringify(detail, null, 2)); } status.textContent = [ `Onboarding complete${payload.repo_slug ? `: ${payload.repo_slug}` : ""}`, "", payload.stdout?.trim() ?? "", payload.stderr?.trim() ? `\nWarnings:\n${payload.stderr.trim()}` : "", ].join("\n").trim(); } catch (error) { status.textContent = `Onboarding failed:\n${error.message}`; } finally { button.disabled = false; } }); } ``` ```js display(html`
1
Make the working copy accessible
git clone <remote-url> /path/to/repo

The path must be visible from the State Hub API host, either as a local checkout or through an ops-bridge-exposed path.

2
Choose an agent profile
Codex       -> AGENTS.md + SCOPE.md
Claude Code -> CLAUDE.md + .claude/rules/

The API keeps this as an agent profile so future native coding agents can get their own onboarding templates without changing the repo model.

3
Run onboarding
scripts/register_project.sh <domain> /path/to/repo --codex

Use the Add Repo form above for the automatic path. The script verifies the domain, writes agent instructions, registers the repo, records host_paths for this machine, and logs a progress event.

4
Start the agent and monitor here

Open the repo in the chosen coding agent, complete the generated TODO stubs, then use the Repositories and DoI views to track integration gaps.

`); ```