Persist cutover evidence cards with device-raw A/B keys for board and AI.

Evaluate keeps match keys for normalize/map pairing while diffs, reds, and the board show collected ports plus show-command provenance; add monitor-context and command-raw read APIs with biz-monitor:read scope.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-19 22:48:37 +08:00
parent 285c19e5a3
commit c1b1c0f75d
17 changed files with 1141 additions and 57 deletions

View file

@ -40,6 +40,7 @@ class ScopeUnitTests(unittest.TestCase):
self.assertNotIn(SCOPE_WEBCRT, MCP_DEFAULT_SCOPES)
self.assertNotIn(SCOPE_SQL, MCP_DEFAULT_SCOPES)
self.assertIn("ne:exec", MCP_DEFAULT_SCOPES)
self.assertIn("biz-monitor:read", MCP_DEFAULT_SCOPES)
def test_token_intersection(self) -> None:
user = {"alarms:read", "ne:read", "ne:exec", "sql:query"}
@ -54,7 +55,18 @@ class ScopeUnitTests(unittest.TestCase):
self.assertEqual(required_scope_for_request("POST", "/v1/managed-ne"), "ne:write")
self.assertEqual(required_scope_for_request("POST", "/v1/topology/fabric/paths"), "ne:read")
self.assertEqual(required_scope_for_request("POST", "/v1/topology/fabric/edges"), "ne:write")
self.assertEqual(
required_scope_for_request("GET", "/v1/biz-migration/monitor-context"),
"biz-monitor:read",
)
self.assertEqual(
required_scope_for_request("GET", "/v1/biz-state/batches/abc"),
"biz-monitor:read",
)
self.assertEqual(
required_scope_for_request("POST", "/v1/biz-migration/projects"),
"ops:write",
)
class SqlGuardTests(unittest.TestCase):
def test_allows_cte(self) -> None: