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:
kitos
2026-07-14 13:36:19 +02:00
parent bdc6579c10
commit f87959369b
3 changed files with 21 additions and 101 deletions
+3 -44
View File
@@ -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)
# ---------------------------------------------------------------------------