Epic: #64 (AffinityEngine)
Depends on: #65 (crate scaffold)
What
Implement the InteractionGraph data structure in crates/arcane-affinity/src/interaction_graph.rs:
EntityPair — canonical ordered pair (min(a,b), max(a,b)) avoiding duplicate entries
InteractionGraph struct with HashMap<EntityPair, f64> storage
- Methods:
new(), record_interaction(), tick() (decay + GC), get_weight(), neighbors(), remove_entity(), pair_count()
neighbors() is the hot path — called once per entity per clustering tick
Key design decisions
- Start without secondary index for
neighbors(). Add HashMap<Uuid, Vec<Uuid>> only if profiling shows it's a bottleneck.
- GC runs every
gc_interval ticks, removing entries below gc_threshold
- Memory estimate: 6,000 entities with 10% interacting ≈ 30k-50k pairs ≈ 1.2 MB
Acceptance criteria
- All methods implemented per spec
- Unit tests for: record/add-to-existing, canonical ordering, decay, GC, neighbors, remove_entity, pair_count
Spec
See arcane-engine repo: in_08_01_interaction_graph.md
Epic: #64 (AffinityEngine)
Depends on: #65 (crate scaffold)
What
Implement the
InteractionGraphdata structure incrates/arcane-affinity/src/interaction_graph.rs:EntityPair— canonical ordered pair(min(a,b), max(a,b))avoiding duplicate entriesInteractionGraphstruct withHashMap<EntityPair, f64>storagenew(),record_interaction(),tick()(decay + GC),get_weight(),neighbors(),remove_entity(),pair_count()neighbors()is the hot path — called once per entity per clustering tickKey design decisions
neighbors(). AddHashMap<Uuid, Vec<Uuid>>only if profiling shows it's a bottleneck.gc_intervalticks, removing entries belowgc_thresholdAcceptance criteria
Spec
See
arcane-enginerepo:in_08_01_interaction_graph.md