fix: stop spawning duplicate villains from descriptions in the name field
Root cause of "4 entries for the same person": physical descriptions were being passed as `name`, creating a new *named* player each time the wording drifted (exact-name match can't dedupe near-identical sentences, and the merge scan only looks at descriptor embeddings). - add_read: a `name` that looks like a description (comma-listed / long / has appearance words) is rerouted to the descriptor path so it dedupes. - descriptor reads that are ambiguously close to an existing villain now file a merge_candidate to the review queue instead of leaving a silent duplicate. - distinctiveness() reworked: recognizes specific content (proper nouns/brands, feature lists) as distinctive even when a generic word like "shirt" is present — the old list-only heuristic scored "Filipino, Fox Racing hat, DKNY shirt" as generic and gated it out. - Cash card: name = real handle ONLY; the look goes in descriptor as a few distinctive tags, and use name_villain to fuse a name onto a described player. Full suite 157 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,24 @@ def test_descriptor_read_creates_then_reuses_nameless_villain(mods):
|
||||
assert reads == 2
|
||||
|
||||
|
||||
def test_description_as_name_routes_to_descriptor_and_dedupes(mods):
|
||||
poker, tools = mods
|
||||
poker.start_session(venue="Meadows", buy_in=300)
|
||||
# She (wrongly) puts a physical description in the name field, twice, worded
|
||||
# slightly differently — must resolve to ONE nameless villain, not two named.
|
||||
tools.dispatch("add_read", {"note": "limp 3bet A3o",
|
||||
"name": "Filipino, Fox Racing hat, DKNY shirt, two bracelets"}, {})
|
||||
tools.dispatch("add_read", {"note": "called a 4bet light",
|
||||
"name": "Filipino, Fox Racing hat, DKNY shirt, watch on left"}, {})
|
||||
named = [p for p in poker.get_villain_file() if p["named"]]
|
||||
assert named == [] # no sentence-named players spawned (the bug)
|
||||
# Either they merged, or the near-dup is surfaced for a one-click merge — never
|
||||
# a silent duplicate the way sentence-names were.
|
||||
q = poker.list_identity_queue()
|
||||
nameless = [p for p in poker.get_villain_file() if not p["named"]]
|
||||
assert len(nameless) == 1 or any(t["kind"] == "merge_candidate" for t in q)
|
||||
|
||||
|
||||
def test_name_villain_tool_attaches_name(mods):
|
||||
poker, tools = mods
|
||||
poker.start_session(venue="Meadows", buy_in=300)
|
||||
|
||||
Reference in New Issue
Block a user