feat(tests): add Blue detect_procedure field mapped from template suggestion

Blue Team gets a detect_procedure field on Test (what they actually
did to detect the attack), Blue's counterpart to Red's procedure_text.
It's seeded from a new detect_suggested_procedure field on
TestTemplate at test-creation time, so a junior who later reuses the
same template starts with prior guidance instead of a blank field.

Also adds the procedure_suggestions review table and Test.source_template_id,
laying the groundwork for suggesting template improvements from filled-in
procedure fields (reviewed and approved by a lead, never auto-written).
detect_procedure is archived (not cleared) on Blue reopen, matching
blue_summary, and now appears in the Jira round-archived and blue_review
comments alongside the existing detection/containment fields.
This commit is contained in:
kitos
2026-07-14 14:58:29 +02:00
parent fd94e55799
commit 8bdbe48fbe
11 changed files with 127 additions and 1 deletions
+9
View File
@@ -59,6 +59,12 @@ class Test(Base):
execution_date = Column(DateTime, nullable=True)
# Assign created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
# The template this test was instantiated from, if any (null for
# standalone/manually-created/RT-imported tests). Lets a procedure
# suggestion know exactly which template to propose improving —
# matching purely by technique would be ambiguous when a technique has
# multiple templates.
source_template_id = Column(UUID(as_uuid=True), ForeignKey("test_templates.id"), nullable=True)
# Assign result = Column(Enum(TestResult, name="testresult"), nullable=True)
result = Column(Enum(TestResult, name="testresult"), nullable=True)
# Assign state = Column(Enum(TestState, name="teststate"), default=TestState.draft)
@@ -83,6 +89,9 @@ class Test(Base):
# ── Blue Team fields ────────────────────────────────────────────
blue_summary = Column(Text, nullable=True)
# What Blue actually did to detect the attack — Blue's counterpart to
# procedure_text. Free text; may be parsed for a procedure suggestion.
detect_procedure = Column(Text, nullable=True)
# Assign detection_result = Column(Enum(TestResult, name="testresult"), nullable=True)
detection_result = Column(Enum(TestResult, name="testresult"), nullable=True)
containment_result = Column(Enum(ContainmentResult, name="containmentresult"), nullable=True)