--- title: Capabilities — Reference --- # Capabilities — Reference The Capability Requests page shows cross-domain provisioning requests — a decoupled mechanism for one domain to request something that another domain is responsible for, without needing to know *who* is responsible. --- ## What is a capability? A **capability** is something a domain can provide to the broader ecosystem — infrastructure provisioning, API endpoints, security tooling, documentation, data pipelines, etc. Capabilities are registered in the **capability catalog** so the system knows which domain provides what. A **capability request** is a structured declaration from a requester ("I need X") that the system routes to the right provider automatically. --- ## Capability catalog The catalog is the routing backbone. Each entry registers one thing a domain can provide. **Origin of truth: SCOPE.md** — following ADR-001, capability declarations live in each repo's `SCOPE.md` file under the `## Provided Capabilities` section. The state-hub catalog table is a derived index, reconstructable from repo files via `make ingest-capabilities-all`. ### SCOPE.md capability blocks Add fenced `capability` blocks to your repo's SCOPE.md: ````markdown ## Provided Capabilities ```capability type: infrastructure title: Cluster provisioning description: Provision k8s clusters and managed instances for any domain. keywords: [cluster, k8s, privacy, instance] ``` ```` | Field | Purpose | |-------|---------| | **type** | Category — `infrastructure`, `api`, `data`, `security`, `documentation`, `other` | | **title** | Short name (unique within domain + type) | | **description** | What this capability provides, in one or two sentences | | **keywords** | Routing hints matched against request descriptions | ### Ingesting into the catalog ```bash make ingest-capabilities REPO=the-custodian # single repo make ingest-capabilities-all # all registered repos make ingest-capabilities REPO=railiance-infra DRY_RUN=1 # preview ``` The ingest script reads `SCOPE.md` → parses `capability` blocks → upserts into the `capability_catalog` table via the API. Existing entries (same domain + type + title) are skipped. ### Browsing the catalog Via MCP: ``` list_capabilities(domain="railiance") ``` Via API: ``` GET /capability-catalog/?domain=railiance ``` The catalog is also shown at the bottom of the Capabilities dashboard page, grouped by domain with type badges and keyword tags. --- ## Routing algorithm When a request is created, the system auto-routes it: 1. **Exact type match** — find catalog entries where `capability_type` matches 2. **Single match** — auto-assign the providing domain 3. **Multiple matches** — keyword-score the request description against each entry's keywords; pick the winner if unambiguous 4. **No match or tie** — leave the provider unassigned and **broadcast** a notification to all domains so one can claim it This means the requester never needs to know which domain owns a capability. --- ## Request flow ``` requested → accepted → in_progress → ready_for_review → completed ↓ ↓ ↓ ↓ withdrawn rejected withdrawn withdrawn withdrawn ``` | Workstation | Meaning | |--------|---------| | **requested** | Need declared; routed (or broadcast) to provider | | **accepted** | Provider acknowledged and claimed the request | | **in_progress** | Provider is actively working on it | | **ready_for_review** | Provider finished; requester should review and optimise | | **completed** | Requester confirmed; capability is live | | **rejected** | Provider cannot or will not fulfil the request | | **withdrawn** | Requester cancelled the request | Request movement is flow-aware. The API evaluates the target workstation's entry assertions and rejects unreachable movement with machine-readable blocking assertions. Terminal workstations (`completed`, `rejected`, `withdrawn`) have no reachable outgoing path in the current flow definition. --- ## Auto-notifications Every request movement handled by the capability request API creates an **AgentMessage** atomically: | Transition | Notification to | |------------|----------------| | **requested** | Provider domain agent (or `broadcast` if unrouted) | | **accepted** | Requesting agent | | **in_progress** | Requesting agent | | **ready_for_review** | Requesting agent | | **completed** | Requesting agent | | **rejected** | Requesting agent (with reason) | Notifications appear in the [Inbox](/inbox) page and are queryable via `get_messages(to_agent="")`. --- ## Auto-unblock A request can optionally link to a **blocking task** via `blocking_task_id`. When the request reaches `completed`, the system automatically patches that task from `blocked` → `todo` and clears its `blocking_reason`. This means blocked work resumes without manual intervention. --- ## Creating a request Via MCP: ``` request_capability( title = "Privacy idea instance on cluster", description = "Need a privacy idea instance provisioned on the k8s cluster", capability_type = "infrastructure", requesting_agent = "net-kingdom-worker", requesting_domain = "custodian", requesting_workstream_id = "", # optional priority = "high", # low | medium | high | critical blocking_task_id = "" # optional — auto-unblocked on completion ) ``` The system routes this to `railiance` (if a matching catalog entry exists), creates an AgentMessage notification, and returns the request with `fulfilling_domain_slug: "railiance"`. --- ## Accepting and fulfilling The provider agent checks their inbox, sees the request, and accepts: ``` accept_capability_request( request_id = "", fulfilling_agent = "railiance-worker", fulfilling_workstream_id = "" # optional ) ``` Then advances through the flow: ``` advance_workstation(entity_type="capability_request", entity_id=request_id, target_workstation="in_progress") advance_workstation(entity_type="capability_request", entity_id=request_id, target_workstation="ready_for_review") ``` The requester reviews and completes: ``` advance_workstation(entity_type="capability_request", entity_id=request_id, target_workstation="completed") ``` --- ## Dashboard The Capabilities page shows: - **KPI sidebar** — open count, average fulfillment time, high/critical count - **Summary cards** — requested, in progress, ready for review, completed - **Kanban board** — cards grouped by workstation/status column - **Table** — all requests with filters by type, status, and domain Each card shows the capability type, priority, requester → provider domains, and age in days. --- ## Relation to other concepts | Concept | Relationship | |---------|-------------| | **SCOPE.md** | Defines what a repo *is responsible for* — the catalog registers what it *can provide* | | **Dependencies** | Workstream-to-workstream edges — capabilities are higher-level, domain-to-domain | | **Extension Points** | Design forks for *future* enhancement — capabilities are *operational* requests | | **Contributions** | Outbound upstream work — capabilities are *inbound* requests between internal domains | | **Human Interventions** | Flagged tasks for Bernd — capabilities are agent-to-agent coordination | --- *Capability requests are a sanctioned write use case of the State Hub alongside `resolve_decision` and `get_next_steps`. They do not originate in workplan files — they are operational coordination.*