Adds the actor.active_days primitive to the campaign factory so a DSL actor can be bound to specific day indexes. Falls back to the non-paused day pool when absent (existing fixtures unchanged). Intersects with pause_windows so the campaign-wide silence still wins if both are set. Adds time_window_clusterer reference to fixture_harness — union-find over attackers, edge if their session time-ranges are within gap_days of each other. Deliberately-bad reference for fixture 4: multi-day silent stretches fragment a single campaign because the clusterer has no signal that bridges the gap. Fixture 4 (paused_campaign): one campaign modeled as two DSL actors representing the operator's two operational windows (active days 1-2 and 6-7), separated by a silent stretch (days 3-5). Both share JA3 + HASSH + payload + C2 callback; only their active_days differ. Five tests: corpus shape (rows in their windows, shared signals), pipeline pass via fingerprint_clusterer at level=campaign, adversarial fragmentation via time_window_clusterer (1-day union threshold cannot bridge the 4-day silence → completeness collapses), huge-gap sanity (gap_days=10 unions both halves), silent-stretch invariant (no session leaks into the configured pause window). Identity-level scoring is fixture 2's job; this fixture is campaign-level only — modeling caveat documented in the YAML.
25 lines
819 B
YAML
25 lines
819 B
YAML
# Bounds for fixture 4 (paused_campaign).
|
|
#
|
|
# Ground truth at campaign-level: 1 campaign of 2 observation rows
|
|
# (one per DSL actor — modeling the operator's two operational
|
|
# windows). A correct algorithm scores 1.0 on every metric.
|
|
#
|
|
# Completeness is the load-bearing metric: a clusterer that lets a
|
|
# multi-day silent period split the campaign tanks completeness
|
|
# (the one true class is split across two predicted clusters,
|
|
# matching the gap). The adversarial time_window_clusterer
|
|
# demonstrates this and the bound below rejects it.
|
|
#
|
|
# This fixture is CAMPAIGN-LEVEL ONLY (see the fixture YAML for
|
|
# why). No identity-level scoring.
|
|
#
|
|
# Bounds are loose at v1; tighten as the algorithm matures.
|
|
adjusted_rand_index:
|
|
min: 0.85
|
|
homogeneity:
|
|
min: 0.90
|
|
completeness:
|
|
min: 0.80
|
|
singleton_recall:
|
|
min: 0.95
|