or ex_tok.type_ not in parsers)
                          else parsers[ex_tok.type_](cmp_tok))
                 if ex_tok.type_ is _MsgTok.NICK_USER_HOST:
-                    nickuserhosts += [value]
+                    if not (ex_tok.code and
+                            'skipnuh' in [cmd.verb
+                                          for cmd in ex_tok.code.commands]):
+                        nickuserhosts += [value]
                 if ex_tok.code:
                     parsed[ex_tok.code.title] = value
                     singled_tasks += [(cmd, ex_tok.code.title)
-                                      for cmd in ex_tok.code.commands]
+                                      for cmd in ex_tok.code.commands
+                                      if cmd.verb != 'skipnuh']
         for code in self.bonus_tasks:
             singled_tasks += [(cmd, code.title) for cmd in code.commands]
         tasks: dict[_Command, list[str]] = {}
         _MsgTok.SERVER,
         ((_MsgTok.NICKNAME, 'setattr_db.users.me:nick'),
          (_MsgTok.CHANNEL, ':CHAN'),
-         (_MsgTok.NICK_USER_HOST, 'setattr_db.channels.CHAN.topic:who'),
+         (_MsgTok.NICK_USER_HOST,
+          'skipnuh_,setattr_db.channels.CHAN.topic:who'),
          (_MsgTok.ANY, ':timestamp')),
         bonus_tasks=('doafter_db.channels.CHAN.topic:complete',)),
 
 
 0:1 < :*.?.net 432 foo1 @foo :Erroneous nickname
 1 !$ nickname refused for bad format
 
-# join channel, collect topic, residents; update me:user from JOIN message
+# join channel, collect topic, residents; update me:user from JOIN message; ensure topic.who not affecting users DB
 > /join #test
 1 > JOIN :#test
 0:1 < :foo1!~foobarbaz@baz.bar.foo JOIN #test
 1 $ users:me:user set to: [~foobarbaz]
 0:1 < :foo.bar.baz 332 foo1 #test :foo bar baz
 1 $ channels:#test:exits cleared
-0:1 < :foo.bar.baz 333 foo1 #test bar!~bar@bar.bar 1234567890
-1 $ channels:#test:topic set to: [Topic(what='foo bar baz', who=NickUserHost(nick='bar', user='~bar', host='bar.bar'))]
-4 $ bar!~bar@bar.bar set topic: foo bar baz
+0:1 < :foo.bar.baz 333 foo1 #test bar!~bar@OLD.bar.bar 1234567890
+1 $ channels:#test:topic set to: [Topic(what='foo bar baz', who=NickUserHost(nick='bar', user='~bar', host='OLD.bar.bar'))]
+4 $ bar!~bar@OLD.bar.bar set topic: foo bar baz
 0:1 < :foo.bar.baz 353 foo1 @ #test :foo1 @bar
 1 $ users:1:nick set to: [?]
 1 $ users:1:nick set to: [bar]
 1 $ users:1:host set to: [bar.bar]
 4 < [bar] hi there
 
-# check _changing_ TOPIC message is communicated to channel window
+# check _changing_ TOPIC message is communicated to channel window, as long as either content or who change
+0:1 < :bar!~bar@bar.bar TOPIC #test :foo bar baz
+1 $ channels:#test:topic set to: [Topic(what='foo bar baz', who=NickUserHost(nick='bar', user='~bar', host='bar.bar'))]
+4 $ bar!~bar@bar.bar set topic: foo bar baz
 0:1 < :bar!~bar@bar.bar TOPIC #test :foo bar baz
 0:1 < :bar!~bar@bar.bar TOPIC #test :abc def ghi
 1 $ channels:#test:topic set to: [Topic(what='abc def ghi', who=NickUserHost(nick='bar', user='~bar', host='bar.bar'))]
 > /join #testtest
 1 > JOIN :#testtest
 0:1 < :foo1!~foobarbaz@baz.bar.foo JOIN #testtest
-0:1 < :foo.bar.baz 353 foo1 @ #testtest :foo1 baz
+0:1 < :foo.bar.baz 332 foo1 #testtest :baz bar foo
 1 $ channels:#testtest:exits cleared
+0:1 < :foo.bar.baz 333 foo1 #testtest bar!~bar@OLD.bar.bar 1234567890
+1 $ channels:#testtest:topic set to: [Topic(what='baz bar foo', who=NickUserHost(nick='bar', user='~bar', host='OLD.bar.bar'))]
+5 $ bar!~bar@OLD.bar.bar set topic: baz bar foo
+0:1 < :foo.bar.baz 353 foo1 @ #testtest :foo1 baz
 0:1 < :foo.bar.baz 366 foo1 #testtest :End of /NAMES list.
 1 $ channels:#testtest:user_ids set to:
 1 $   2