feat: F3.4 semantic_collapse — n-gram Jaccard dedup defeats synonym padding
This commit is contained in:
parent
906eb26188
commit
593868aa8d
|
|
@ -522,6 +522,51 @@ if __name__ == "__main__":
|
|||
f"sent={ns.total_sent}, recv={ns.total_received}{shadow}")
|
||||
|
||||
|
||||
# ── Semantic collapse (F3.4) ─────────────────────────────
|
||||
# Defense against synonym padding: adversary generates 50 unique strings
|
||||
# that all mean "hello", defeating unique_concepts count in F3.3.
|
||||
# Collapse semantically similar concepts before counting.
|
||||
# Atomic Raven (Colony, 2026-07-28) identified the attack vector.
|
||||
|
||||
def _char_ngrams(s: str, n: int = 3) -> set:
|
||||
return set(s[i:i+n] for i in range(max(len(s) - n + 1, 1)))
|
||||
|
||||
|
||||
def _jaccard(a: str, b: str) -> float:
|
||||
sa, sb = _char_ngrams(a), _char_ngrams(b)
|
||||
if not sa or not sb:
|
||||
return 0.0
|
||||
return len(sa & sb) / len(sa | sb)
|
||||
|
||||
|
||||
def semantic_collapse(concepts: list, threshold: float = 0.6) -> list:
|
||||
"""Collapse similar concepts into canonical forms using n-gram Jaccard.
|
||||
|
||||
A cheap proxy for semantic similarity. Catches "greeting-1"/"greeting-2"
|
||||
style padding but preserves genuinely diverse concepts.
|
||||
|
||||
threshold: Jaccard similarity above which concepts merge.
|
||||
0.6 collapses trivial suffix variations, keeps distinct concepts.
|
||||
|
||||
Returns deduplicated concept list (canonical forms only).
|
||||
"""
|
||||
canonicals = [] # (canonical_form, ngrams)
|
||||
mapping = {}
|
||||
|
||||
for c in concepts:
|
||||
matched = False
|
||||
for canon, canon_ngrams in canonicals:
|
||||
if _jaccard(c, canon) >= threshold:
|
||||
mapping[c] = canon
|
||||
matched = True
|
||||
break
|
||||
if not matched:
|
||||
canonicals.append((c, _char_ngrams(c)))
|
||||
mapping[c] = c
|
||||
|
||||
return list(set(mapping[c] for c in concepts))
|
||||
|
||||
|
||||
# ── Agent-alias merging ──────────────────────────────────
|
||||
# Agents that change names mid-corpus create phantom signals
|
||||
# in temporal analysis. merge_aliases() canonicalizes from_id/to_id
|
||||
|
|
|
|||
Loading…
Reference in New Issue