--- id: ADR-001 title: Cross-Mode Capability Registry and Coverage Enforcement status: accepted date: 2026-03-12 --- ## Context OpsBridge exposes its operations through three access modes: CLI (`bridge` CLI), MCP server (FastMCP stdio), and Skills (Claude plugin prompts). As the capability surface grows, there is no guarantee that a new capability will be implemented consistently across all required modes, or that tests exist for each mode. ## Decision Introduce a canonical **Capability Registry** (`src/bridge/capabilities.py`) that: 1. Lists every operation as a `Capability(name, description, required_access_modes)` dataclass. 2. Declares which access modes each capability must support. 3. Is imported by the cross-mode meta-test to enforce complete test coverage. ### Test coverage enforcement Pytest marks `@pytest.mark.capability(name)` and `@pytest.mark.access_mode(mode)` are placed on the canonical test for each (capability, mode) pair. `tests/test_coverage_completeness.py` collects these marks at session scope and fails if any pair required by the registry has no corresponding test. ### FastMCP in-process testing MCP tools are tested in `tests/test_mcp.py` using `fastmcp.Client(mcp_app)` — an in-process client that calls tools without spawning a subprocess or opening a network socket. This is the preferred approach because: - Tests run in the same process as the server code, so patches/mocks work normally. - No port allocation, no cleanup, no flakiness from network timeouts. - FastMCP 3.x returns results via `result.content[0].text` (JSON string) for non-empty responses, and `result.data` (empty list/dict) when the return value is empty. ### Skill static lint `tests/test_skill.py` validates skill Markdown files in `~/.claude/plugins/ops-bridge/`: - Required frontmatter: `name`, `description`. - Body must reference at least one registered capability name. - The `bridge_status` skill must reference `bridge_status` and the registry must declare `skill` as a required mode for that capability. ## Consequences - Every new capability must be added to the registry before or alongside its implementation. - Every new (capability, mode) pair requires a marked test or the meta-test fails. - The registry is the single source of truth for "what does OpsBridge do and where". - Skills must reference capability names by their canonical registry IDs.