One campaign, one DSL actor, ip_pool: rotating + rotation_count: 5 across 5 synthetic private-use ASNs (RFC 6996 64512-64516). Stable JA3, HASSH, and payload_hash across every rotation — these are the "signals the attacker can't cheaply rotate" per IDENTITY_RESOLUTION.md and the load-bearing reason all 5 observation rows must resolve to one identity / one campaign. Two new reference clusterers in fixture_harness.py: * fingerprint_clusterer — groups by (ja3, hassh). Un-fingerprinted rows stay singleton so it doesn't trivially fuse all noise into one mega-cluster. Approximates the stable-signal arm of the planned similarity graph. * asn_clusterer — deliberately-bad reference for fixture 2's adversarial test. Group-by-ASN shatters the campaign into 5 singletons; completeness collapses to 0. Four tests in test_vpn_hopping_fixture.py: corpus shape (5 rows, 1 identity, 1 campaign, 5 distinct ASNs/IPs, stable fingerprints), pass at campaign level, pass at identity level (asserts ARI exactly 1.0), asn_clusterer breaches the completeness floor.
26 lines
943 B
YAML
26 lines
943 B
YAML
# Bounds for fixture 2 (vpn_hopping).
|
|
#
|
|
# Ground truth at campaign-level: 1 campaign of 5 observation rows.
|
|
# Ground truth at identity-level: 1 identity of 5 observation rows.
|
|
# A correct algorithm scores 1.0 across every metric on this fixture.
|
|
#
|
|
# Completeness is the load-bearing metric: a clusterer that fragments
|
|
# the campaign by IP/ASN tanks completeness (the one true class is
|
|
# split across many predicted clusters). The adversarial asn_clusterer
|
|
# in the test file demonstrates this and the bound below rejects it.
|
|
#
|
|
# No true singletons in this fixture — singleton_recall is trivially
|
|
# 1.0 (the metric returns 1.0 when truth has no singletons).
|
|
#
|
|
# Bounds are loose at v1; tighten as the algorithm matures. Loosening
|
|
# any bound to make CI pass requires PR-comment justification (per
|
|
# CAMPAIGN_CLUSTERING.md §2).
|
|
adjusted_rand_index:
|
|
min: 0.85
|
|
homogeneity:
|
|
min: 0.90
|
|
completeness:
|
|
min: 0.80
|
|
singleton_recall:
|
|
min: 0.95
|