fix(tests): remove blind visibility, both teams always see each other's fields
Red and Blue could not see each other's real field data until both reviews passed, showing a placeholder message instead. This kept detection testing blind to what Red actually did; both sides now see the full, live test data at all times.
This commit is contained in:
@@ -163,46 +163,6 @@ from app.services.test_workflow_service import (
|
||||
router = APIRouter(prefix="/tests", tags=["tests"])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Blind visibility — hide the other team's fields until both reviews pass
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_RED_ONLY_FIELDS = [
|
||||
"procedure_text", "tool_used", "attack_success",
|
||||
"execution_start_time", "execution_end_time", "red_summary",
|
||||
"red_validation_status", "red_validated_by", "red_validated_at", "red_validation_notes",
|
||||
]
|
||||
_BLUE_ONLY_FIELDS = [
|
||||
"detection_result", "containment_result", "detection_time", "containment_time",
|
||||
"blue_summary", "blue_validation_status", "blue_validated_by", "blue_validated_at",
|
||||
"blue_validation_notes", "system_gaps",
|
||||
]
|
||||
_BLIND_STATES = {"draft", "red_executing", "red_review", "blue_evaluating", "blue_review"}
|
||||
|
||||
|
||||
def _mask_for_team_blindness(test_out: TestOut, *, viewer_role: str) -> TestOut:
|
||||
"""Null out the other team's fields while the test is still blind.
|
||||
|
||||
admin and viewer are never blinded. Once the test reaches in_review or
|
||||
beyond, both sides see everything (existing cross-validation behavior).
|
||||
"""
|
||||
if viewer_role in ("admin", "viewer"):
|
||||
return test_out
|
||||
|
||||
test_state = test_out.state.value if hasattr(test_out.state, "value") else str(test_out.state)
|
||||
if test_state not in _BLIND_STATES:
|
||||
return test_out
|
||||
|
||||
if viewer_role in ("blue_tech", "blue_lead"):
|
||||
hide_fields = _RED_ONLY_FIELDS
|
||||
elif viewer_role in ("red_tech", "red_lead"):
|
||||
hide_fields = _BLUE_ONLY_FIELDS
|
||||
else:
|
||||
return test_out
|
||||
|
||||
return test_out.model_copy(update={f: None for f in hide_fields})
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# GET /tests — list with filters
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -504,12 +464,11 @@ def get_test(
|
||||
|
||||
Returns:
|
||||
TestOut: Full test detail including split red/blue evidence lists.
|
||||
Fields belonging to the other team are nulled out while the
|
||||
test is blind (see :func:`_mask_for_team_blindness`).
|
||||
Both teams see each other's fields regardless of state — Red
|
||||
and Blue are meant to see each other's work, not test blind.
|
||||
"""
|
||||
test = crud_get_test_detail(db, test_id)
|
||||
test_out = TestOut.model_validate(test)
|
||||
return _mask_for_team_blindness(test_out, viewer_role=current_user.role)
|
||||
return TestOut.model_validate(test)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user