generated from coulomb/repo-seed
test(BRIDGE-WP-0003): add sentinel self-validation for meta-test + MCP section in README
- Add test_meta_test_catches_missing_mode_gap() — validates Goal #4: injects _test_sentinel capability (cli+mcp required), provides only a cli mock item, asserts collect_capability_coverage reports the mcp gap. Proves the cross-mode gap-detection mechanism is functional. - Add MCP INTEGRATION section to README.txt (T14 requirement): documents project-scope .mcp.json, user-scope registration script, skill, and direct server invocation. 189 tests, 0 lint errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
28
README.txt
28
README.txt
@@ -181,6 +181,34 @@ bridge_reconnecting, health_check_failed, health_check_recovered,
|
||||
bridge_stopped
|
||||
|
||||
|
||||
MCP INTEGRATION
|
||||
---------------
|
||||
|
||||
OpsBridge exposes its capabilities as a FastMCP server so Claude Code agents
|
||||
can call bridge_up(), bridge_status(), catalog_list_targets(), etc. as
|
||||
first-class MCP tools — no Bash required, structured JSON in/out.
|
||||
|
||||
Available tools: bridge_up, bridge_down, bridge_restart, bridge_status,
|
||||
bridge_logs, catalog_list_targets, catalog_show_target,
|
||||
catalog_list_domains, catalog_validate, catalog_show_bridge
|
||||
|
||||
Available resources: bridge://status, catalog://domains, catalog://targets
|
||||
|
||||
Project-scope (auto, inside ops-bridge/):
|
||||
Already configured in .mcp.json. Claude Code sessions inside this repo
|
||||
see the tools automatically.
|
||||
|
||||
User-scope (machine-global, any repo):
|
||||
python scripts/register_mcp.py
|
||||
|
||||
Human operator skill:
|
||||
/bridge-status — natural-language tunnel health summary
|
||||
(skill file: ~/.claude/plugins/ops-bridge/bridge-status.md)
|
||||
|
||||
Run the server directly (for debugging):
|
||||
uv run python src/bridge/mcp_server/server.py
|
||||
|
||||
|
||||
DEVELOPMENT
|
||||
-----------
|
||||
|
||||
|
||||
@@ -134,6 +134,78 @@ async def test_mcp_tools_in_registry():
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# T12 — Self-validation: sentinel fixture proves the gap-checker catches gaps
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def test_meta_test_catches_missing_mode_gap():
|
||||
"""Self-validation: the coverage checker must detect a missing-mode gap.
|
||||
|
||||
Injects a synthetic _test_sentinel capability requiring both cli and mcp.
|
||||
Creates mock items with *only* a cli test for it (deliberately omitting mcp).
|
||||
Asserts that collect_capability_coverage reports the mcp gap — proving the
|
||||
meta-test mechanism is functional, not a silent no-op.
|
||||
|
||||
This test validates Goal #4 from BRIDGE-WP-0003:
|
||||
"The gap-detection mechanism is itself tested: a synthetic missing-mode
|
||||
fixture asserts the meta-test catches it."
|
||||
"""
|
||||
from bridge.capabilities import Capability
|
||||
|
||||
sentinel = Capability(
|
||||
name="_test_sentinel",
|
||||
description="Synthetic capability for meta-test self-validation",
|
||||
required_access_modes=frozenset({"cli", "mcp"}),
|
||||
)
|
||||
patched_caps = CAPABILITIES + [sentinel]
|
||||
|
||||
# Minimal mock: an iterable of items that respond to iter_markers()
|
||||
class _Mark:
|
||||
def __init__(self, arg: str):
|
||||
self.args = (arg,)
|
||||
|
||||
class _MockItem:
|
||||
def __init__(self, capability: str, mode: str):
|
||||
self._cap = capability
|
||||
self._mode = mode
|
||||
|
||||
def iter_markers(self, name: str):
|
||||
if name == "capability":
|
||||
return [_Mark(self._cap)]
|
||||
if name == "access_mode":
|
||||
return [_Mark(self._mode)]
|
||||
return []
|
||||
|
||||
# Only supply a cli test for the sentinel — the mcp test is intentionally absent
|
||||
mock_items = [_MockItem("_test_sentinel", "cli")]
|
||||
|
||||
covered = collect_capability_coverage(mock_items)
|
||||
|
||||
# The cli mode should be registered
|
||||
assert ("_test_sentinel", "cli") in covered, (
|
||||
"collect_capability_coverage failed to record the cli mock item"
|
||||
)
|
||||
# The mcp mode must NOT be covered — this is the gap we want to catch
|
||||
assert ("_test_sentinel", "mcp") not in covered, (
|
||||
"collect_capability_coverage incorrectly registered an mcp test that was not provided"
|
||||
)
|
||||
|
||||
# Run the same gap-detection logic used by test_all_required_modes_have_tests
|
||||
gaps = [
|
||||
(cap.name, mode)
|
||||
for cap in patched_caps
|
||||
for mode in cap.required_access_modes
|
||||
if (cap.name, mode) not in covered
|
||||
]
|
||||
|
||||
assert ("_test_sentinel", "mcp") in gaps, (
|
||||
"Gap checker failed to detect the missing mcp mode for _test_sentinel. "
|
||||
"The meta-test mechanism is broken."
|
||||
)
|
||||
# Sanity: cli mode should NOT appear as a gap (it was covered)
|
||||
assert ("_test_sentinel", "cli") not in gaps
|
||||
|
||||
|
||||
def test_no_orphan_capability_marks(capability_coverage):
|
||||
"""Every (capability, mode) pair in the test suite must exist in the registry.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user