1 package relay
2 3 import (
4 "git.mleku.dev/mleku/dendrite/pkg/axiom"
5 "git.mleku.dev/mleku/dendrite/pkg/nostr"
6 )
7 8 // CoherenceFilter rejects events whose decomposed elements don't bond
9 // to any existing lattice structure. An event that produces zero
10 // elements matching any known constraint is structurally incoherent
11 // with the relay's content — noise, not signal.
12 type CoherenceFilter struct {
13 // KnownTypes is the set of element type tags that the lattice
14 // currently has sites for. Events must produce at least one
15 // element with a type in this set to pass the filter.
16 KnownTypes map[string]bool
17 }
18 19 // Admits returns true if the event's decomposed elements include at
20 // least one element type known to the lattice. An event that bonds
21 // nowhere is spam — it has no structural relationship to the content
22 // the relay serves.
23 func (f *CoherenceFilter) Admits(ev *nostr.Event) bool {
24 if len(f.KnownTypes) == 0 {
25 return true // no filter configured → admit all
26 }
27 28 elems := nostr.EventToElements(ev)
29 for _, e := range elems {
30 if f.KnownTypes[e.Type()] {
31 return true
32 }
33 }
34 return false
35 }
36 37 // NewCoherenceFilter creates a filter from a set of constraints.
38 // The filter admits events that produce elements matching any of
39 // the constraint tags.
40 func NewCoherenceFilter(constraints []axiom.Constraint) *CoherenceFilter {
41 types := make(map[string]bool, len(constraints))
42 for _, c := range constraints {
43 types[c.Tag()] = true
44 }
45 return &CoherenceFilter{KnownTypes: types}
46 }
47