9.8 KiB
9.8 KiB
id, type, title, domain, repo, status, owner, topic_slug, created, updated, state_hub_workstream_id
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|
| CUST-WP-0031 | workplan | Domain Capability Registry | custodian | the-custodian | done | custodian | custodian | 2026-03-31 | 2026-03-31 | 7b480543-b18a-4d79-a30b-7b34bce27ee5 |
Domain Capability Registry
Goal
Give worker agents a single efficient MCP call to understand what each domain/repo does and what capabilities it exposes — without having to explore source repositories directly.
The immediate driver is that inter-hub workers on CoulombCore need to discuss operational setup and security architecture (e.g. key-cape's SSH CA role, net-kingdom's SSO platform) but can only see repos checked out locally. Key-cape and net-kingdom are not checked out there; the worker must fall back to the state-hub for this information.
Background
What exists
- 25
CapabilityCatalogentries across four domains (railiance: 11, netkingdom: 6, custodian: 5, markitect: 3). CapabilityCatalogis domain-scoped only — norepo_idFK, so the SSH CA capability in netkingdom cannot be attributed to key-cape vs net-kingdom.get_domain_summaryis the cheap worker orientation call (~10% token cost of full state summary) but returns no capability information.list_capabilitiesworks but returns verbose full records; workers must call it per domain and get unstructured JSON.ManagedRepohas adescriptionfield but 8 of 17 repos have it empty.- personhood, foerster_capabilities, and coulomb_social have zero capabilities registered.
Design
Three complementary changes:
- Schema — add nullable
repo_idFK toCapabilityCatalogso each capability can be attributed to the repo that provides it. - MCP orientation — extend
get_domain_summaryto include a compactcapabilitieslist (type + title + repo_slug only, no keywords/description) so the standard worker orientation call already surfaces what the domain provides. - Full-detail tool — new
get_capability_profile(domain_slug?)MCP tool that returns a complete registry: domain → repos (with description) → capabilities (with description). Designed for deep-dive or cross-domain architectural discussion.
Data tasks: populate missing repo descriptions and back-fill repo_id on
existing catalog entries; register capabilities for the three empty domains.
Implementation Plan
Phase 1 — Schema + MCP
- Add nullable
repo_idFK onCapabilityCatalog; updateregister_capabilityto accept an optionalrepo_slugthat resolves torepo_id. - Add
capabilitiescompact list toget_domain_summaryresponse. - New MCP tool
get_capability_profile.
Phase 2 — Data Population
- Populate
descriptionfor the 8 repos that lack it. - Back-fill
repo_idon existing 25 catalog entries. - Register capabilities for personhood, foerster_capabilities, coulomb_social.
Tasks
id: T01
title: "Add repo_id FK to CapabilityCatalog"
status: done
priority: high
description: >
1. Write Alembic migration: add `repo_id` UUID nullable FK column to
`capability_catalog` referencing `managed_repos.id` (ON DELETE SET NULL).
Add index on `repo_id`. Down revision from latest head.
2. Add `repo_id: uuid.UUID | None` to the CapabilityCatalog model
(managed_repo.py FK relationship, nullable).
3. Update CapabilityCatalog schema (CapabilityRead, CapabilityCreate) to
include `repo_id: uuid.UUID | None` and `repo_slug: str | None`
(computed via relationship).
4. Update the capability-catalog router: if `repo_slug` is provided on
POST, resolve it to `repo_id` (404 if not found in the same domain).
5. Update `register_capability` MCP tool to accept optional `repo_slug`
parameter and forward it.
6. Run `make test` — no regressions.
state_hub_task_id: "8d5e3e37-c753-4cdc-9211-83ee39f6b0f2"
id: T02
title: "Include compact capabilities in get_domain_summary"
status: done
priority: high
description: >
Extend the `get_domain_summary` MCP tool response to include a
`capabilities` list alongside `repos` and `workstreams`. Each entry
should be compact: {type, title, repo_slug} only (no description or
keywords, to keep token cost low).
Implementation: in mcp_server/server.py, after building the summary dict,
call GET /capability-catalog/?domain=<slug>&status=active and append
`capabilities: [{capability_type, title, repo_slug}]` to the response.
The `repo_slug` field is nullable (domain-level capabilities have null).
Cap at 20 entries to protect token budget; add a `capabilities_truncated`
boolean flag if there are more.
state_hub_task_id: "ac47994c-efe9-404f-8065-9adf2e923d4c"
id: T03
title: "New MCP tool: get_capability_profile"
status: done
priority: high
description: >
Add a new MCP tool `get_capability_profile(domain_slug: str | None = None)`
to mcp_server/server.py.
Behaviour:
- If domain_slug is provided: return the profile for that one domain.
- If omitted: return profiles for all active domains.
Response structure per domain:
{
"slug": "netkingdom",
"title": "<topic title>",
"repos": [
{
"slug": "key-cape",
"name": "...",
"description": "...",
"capabilities": [
{"type": "security", "title": "SSH CA", "description": "...", "keywords": [...]}
]
},
// domain-level capabilities (repo_slug null) listed at the end under
// a synthetic repo entry {"slug": null, "name": "(domain-level)", ...}
]
}
Implementation: call GET /repos?domain=<slug> and
GET /capability-catalog/?domain=<slug>&status=active, then assemble.
For the all-domains case iterate over GET /domains/ (active only).
state_hub_task_id: "b380fd2b-28fa-4c47-96d6-4c65a0300c44"
id: T04
title: "Populate missing repo descriptions"
status: done
priority: medium
description: >
Use PATCH /repos/{slug}/ to set `description` for the 8 repos that
currently have none. Write concise scope descriptions (2-3 sentences each)
by reading the repo's CLAUDE.md or README if available; otherwise infer
from the slug and domain context.
Repos needing descriptions:
- the-custodian (custodian domain)
- activity-core (custodian domain)
- kaizen-agentic (custodian domain)
- llm-connect (custodian domain) — already has description, skip
- markitect-project (markitect domain)
- railiance-cluster (railiance domain)
- railiance-hosts (railiance domain)
- ops-bridge (custodian domain) — already has description, skip
Confirm final list by re-checking GET /repos/ at task start.
state_hub_task_id: "00d44110-fcb4-45cc-8bc8-454af2629d2f"
id: T05
title: "Back-fill repo_id on existing capability catalog entries"
status: done
priority: medium
description: >
After T01 lands, update the 25 existing catalog entries to set repo_id
where the capability is clearly from a specific repo.
Use PATCH /capability-catalog/{id} (add this endpoint if missing) or
re-register with repo_slug.
Key attributions:
netkingdom domain:
- "Container image build and publish (GHCR)" → net-kingdom
- "Bootstrap local identity service" → key-cape
- "SSO/MFA platform (Keycloak)" → key-cape
- "NetKingdom IAM Profile specification" → net-kingdom (spec lives there)
- "Identity migration tooling" → key-cape
- "OIDC/PKCE authentication (lightweight mode)" → key-cape
railiance domain:
- All 11 entries → railiance-platform or railiance-cluster or railiance-infra
(review titles to assign; most go to railiance-platform)
custodian domain:
- "SSH reverse tunnel connectivity" → ops-bridge
- "Durable event-triggered task factory" → activity-core
- "SBOM and licence reporting" → the-custodian (state-hub)
- "Cross-domain state tracking" → the-custodian (state-hub)
- "MCP tool registration" → the-custodian (state-hub)
markitect domain:
- All 3 → markitect-project
Note: a PATCH endpoint on /capability-catalog/{id} does not currently
exist. Add a minimal one in T01 or add it here: PATCH /capability-catalog/{id}
accepting {repo_slug?, description?, keywords?, status?}.
state_hub_task_id: "7f0748c7-bdee-4801-b870-d4940a5a2e63"
id: T06
title: "Register capabilities for personhood, foerster_capabilities, coulomb_social"
status: done
priority: medium
description: >
Register at least 3 capabilities per missing domain using
register_capability (MCP tool or POST /capability-catalog/).
personhood domain:
- "Rights and obligations framework modelling" (type: governance)
- "Entity consent and data-subject lifecycle" (type: governance)
- "Privacy-by-design compliance checking" (type: security)
foerster_capabilities domain:
- "Agency capability taxonomy" (type: governance)
- "Capability gap analysis" (type: data)
- "Agent persona specification" (type: governance)
coulomb_social domain:
- "Co-creation marketplace workflow" (type: api)
- "Contribution matching and brokerage" (type: data)
- "Contributor reputation tracking" (type: data)
Write descriptions and keywords that would route capability requests
correctly to these domains.
state_hub_task_id: "c6e1be52-961c-4e34-96b1-e450d64298df"
id: T07
title: "Consistency gate and smoke test"
status: done
priority: low
description: >
1. Run `make test` — all existing tests must pass.
2. Run `make fix-consistency REPO=the-custodian`.
3. Manual smoke test via Python MCP client:
- Call get_domain_summary("netkingdom") and verify capabilities list
appears with at least the 6 netkingdom entries.
- Call get_capability_profile("netkingdom") and verify key-cape entries
have repo_slug set.
- Call get_capability_profile() (no arg) and verify all 7 active domains
appear.
4. Add a note to TOOLS.md about the new get_capability_profile tool.
state_hub_task_id: "7e07e32c-683d-47a1-951c-beace9f245a6"