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
|
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
|
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):
|
def test_no_orphan_capability_marks(capability_coverage):
|
||||||
"""Every (capability, mode) pair in the test suite must exist in the registry.
|
"""Every (capability, mode) pair in the test suite must exist in the registry.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user