7575 "hall" : "technical" ,
7676 "role" : "technical_gossip" ,
7777 "specialties" : ["contracts" , "backend" , "defi" , "trading" ],
78+ "rooms" : ["contracts" ],
7879 "gossip_radius" : ["orkid" , "past-performance" ],
7980 "chatter_level" : "high" ,
8081 "propagation_speed" : "instant" ,
8687 "hall" : "general" ,
8788 "role" : "marketing_gossip" ,
8889 "specialties" : ["brand" , "messaging" , "content" , "storytelling" ],
90+ "rooms" : ["launch_blog" ],
8991 "gossip_radius" : ["brutal-marketing" , "orkid" ],
9092 "chatter_level" : "high" ,
9193 "propagation_speed" : "instant" ,
9799 "hall" : "analytics" ,
98100 "role" : "performance_gossip" ,
99101 "specialties" : ["metrics" , "validation" , "optimization" , "data" ],
102+ "rooms" : ["audit_report" ],
100103 "gossip_radius" : ["past-performance" , "orkid" ],
101104 "chatter_level" : "high" ,
102105 "propagation_speed" : "instant" ,
108111 "hall" : "strategy" ,
109112 "role" : "strategy_gossip" ,
110113 "specialties" : ["trading" , "revenue" , "business" , "planning" ],
114+ "rooms" : ["contracts" ],
111115 "gossip_radius" : ["orkid" , "brutal-marketing" ],
112116 "chatter_level" : "medium" ,
113117 "propagation_speed" : "fast" ,
119123 "hall" : "security" ,
120124 "role" : "security_gossip" ,
121125 "specialties" : ["audit" , "compliance" , "risk" , "validation" ],
126+ "rooms" : ["audit_report" ],
122127 "gossip_radius" : ["orkid" , "brutal-marketing" ],
123128 "chatter_level" : "medium" ,
124129 "propagation_speed" : "fast" ,
130135 "hall" : "creative" ,
131136 "role" : "creative_gossip" ,
132137 "specialties" : ["design" , "visual" , "brand" , "aesthetic" ],
138+ "rooms" : ["launch_blog" ],
133139 "gossip_radius" : ["brutal-marketing" , "orkid" ],
134140 "chatter_level" : "medium" ,
135141 "propagation_speed" : "fast" ,
141147 "hall" : "creative" ,
142148 "role" : "theory_gossip" ,
143149 "specialties" : ["information theory" , "physics" , "complexity" , "optimization" ],
150+ "rooms" : ["launch_blog" ],
144151 "gossip_radius" : ["negentropy" , "orkid" ],
145152 "chatter_level" : "low" ,
146153 "propagation_speed" : "normal" ,
@@ -278,6 +285,7 @@ class ChatterNode:
278285 hall : str
279286 role : str
280287 specialties : list [str ] = field (default_factory = list )
288+ rooms : list [str ] = field (default_factory = list )
281289 gossip_radius : list [str ] = field (default_factory = list )
282290 chatter_level : str = "medium"
283291 propagation_speed : str = "normal"
@@ -396,12 +404,13 @@ def detect_topic(self, text: str, priority: Optional[str] = None) -> tuple[str,
396404 def _get_hallway_context (
397405 self , message : GossipMessage
398406 ) -> tuple [dict [str , float ], set [str ]]:
399- """Return (hall_scores , related_entities) derived from within-wing hallways.
407+ """Return (room_scores , related_entities) derived from within-wing hallways.
400408
401409 Hallways are entity-pair co-occurrence records built at mine time. When a
402410 gossip message mentions an entity that co-occurs with other entities in
403- the source wing, we use those co-occurrences to boost chatter nodes that
404- live in the same rooms/halls or cover the related entities.
411+ the source wing, we use those co-occurrences to boost chatter nodes whose
412+ ``rooms`` overlap with the co-occurrence rooms, as well as nodes whose
413+ specialties overlap with the related entities.
405414 """
406415 if not message .source_wing :
407416 return {}, set ()
@@ -414,7 +423,7 @@ def _get_hallway_context(
414423 return {}, set ()
415424
416425 entities = {message .subject .lower (), message .obj .lower ()}
417- hall_scores : dict [str , float ] = {}
426+ room_scores : dict [str , float ] = {}
418427 related : set [str ] = set ()
419428
420429 for h in hallways :
@@ -427,11 +436,11 @@ def _get_hallway_context(
427436 for room in h .get ("rooms" ) or []:
428437 room_key = room .lower ()
429438 # Accumulate a small boost per co-occurrence in this room.
430- hall_scores [room_key ] = hall_scores .get (room_key , 0.0 ) + min (
439+ room_scores [room_key ] = room_scores .get (room_key , 0.0 ) + min (
431440 0.15 , 0.05 + count * 0.01
432441 )
433442
434- return hall_scores , related
443+ return room_scores , related
435444
436445 def select_chatter_nodes (
437446 self ,
@@ -441,12 +450,12 @@ def select_chatter_nodes(
441450 """Rank and select chatter nodes for a given message.
442451
443452 Selection combines the base specialty/topic score with within-wing
444- hallway context: chatter nodes in the source wing whose hall/room
445- appears in co-occurrence records for the subject/object get a boost, as
446- do nodes whose specialties overlap with related entities.
453+ hallway context: chatter nodes in the source wing whose ``rooms``
454+ overlap with the co-occurrence rooms get a boost, as do nodes whose
455+ specialties overlap with related entities.
447456 """
448457 fanout = fanout if fanout is not None else self .config .get ("fanout" , 5 )
449- hall_scores , related_entities = self ._get_hallway_context (message )
458+ room_scores , related_entities = self ._get_hallway_context (message )
450459
451460 scored = []
452461 for node in self ._chatter_nodes :
@@ -456,8 +465,15 @@ def select_chatter_nodes(
456465 if message .source_wing and normalize_wing_name (
457466 message .source_wing
458467 ) == normalize_wing_name (node .wing ):
459- if node .hall and node .hall .lower () in hall_scores :
460- score += hall_scores [node .hall .lower ()]
468+ # Boost by room-level affinity. A node's hall and the
469+ # co-occurrence rooms are in different namespaces, so we match
470+ # rooms to the node's ``rooms`` list rather than to ``hall``.
471+ if room_scores and node .rooms :
472+ overlaps = set (room_scores .keys ()) & {
473+ r .lower () for r in node .rooms
474+ }
475+ for room in overlaps :
476+ score += room_scores [room ]
461477
462478 # Also boost if a related entity matches a specialty.
463479 if related_entities and node .specialties :
0 commit comments