Repository navigation
Face room: friend's plain line bypasses face-room routing and no-follow-up rule #462
Description
Problem
In a Face-to-face room, a friend's (peer's) attested plain line skips face-room routing (#299) and the one-pass "no follow-ups" rule (#295). The cause is how the line is tagged on the way in. It reaches the round as a regular group post from a sender id, not as a person's face-room line.
Effects:
- The wrong Bots may answer a friend's line. It uses the plain speaker list (admin first, then everyone up to
FACE_PLAIN_SPEAKERS), not the routed "Bots decide who answers / last speaker first" path. - The round is not
single, so a Bot that @-mentions another Bot in its answer can call it on. The no-follow-up rule does not apply, and Bots in two homes can set each other off.
Related: #456 / PR #461. #461 only adds an answer-at-most-once-per-line limit (faceLine) on top of this. It does not fix the routing. The owner decided to track this as a separate bug.
Where (main b2c2e1c)
- Tag assigned:
core/src/host/hooks.js→flybot.rooms.postHuman()(around L1016–1033). It is called fromplugins/social/src/social.js(around L2718). It works outplain/everyone/callIdsand then callsrt.postToRoom(room, { id: 'face-notice', name: who }, text, { quiet: true, notice: true, human, plain, ... }). core/src/host/groups.js→postToRoom()(around L702). It wraps every call assource: { kind: SOURCE_KIND, role: 'post', senderSessionId: sender.id, ... }. So the friend's line becomes an ordinary "[Group post from X]".core/src/host/turns.js(around L352–370). Arole: 'post'source is queued withbotId: source.senderSessionId. So the friend's line arrives withbotId: 'face-notice', plusnotice/quiet/plain.- Routing decided:
core/src/host/groups.jsisPlainFaceLine()(around L655) returnsfalsestraight away becauseopener.botId !== undefined. Theif (opener.plain) return truebranch is never reached for a friend's line.- So
routeFor()(around L313) returnsundefined: there is no route, and itsfallback: opener.plain !== truebranch, meant for friend lines, is dead code. Also,round.single(around L519) is never set, socallMembers(around L456) still runs Bot-triggered follow-ups. openingSpeakers()(around L662) hits theopener.plain && isFaceRoom(room)branch and returnsplainSpeakers(members, admin). That is unrouted.- Also in the relay round (around L479):
event()treatsnotice/botId === 'face-notice'as an event. The opener is then picked by the?? posts.at(-1)fallback, and that only works by accident.
Expected (needs owner confirmation before agent-ready)
A friend's attested plain line is routed exactly like a face-room person line: under the room's #299 routing (Bots decide who answers, last speaker first, fallback false so the friend's own home covers an all-pass) and the #295 single-pass no-follow-up rule. This likely means tagging it as a person's face line (no Bot botId) instead of a face-notice group post, or making isPlainFaceLine handle human/plain openers.
Note: the fix changes which Bots answer a friend's line. The owner must confirm the expected behavior above before this is marked agent-ready.
Tests to add
In core/test/rounds.test.js: a friend's attested plain line in a face room gets a route and single: true, and a Bot's @mention in its answer does not call another Bot on. A friend's @bot line (callIds) is unchanged.
Activity
Birfy commentedon Oct 19, 2026
Owner decision (2026-10-20): Confirmed. A friend's plain line in a face room must be treated exactly like a face-room line: it goes through the room's routing (routeFor / openingSpeakers) and the no-follow-up rule (round.single). Shares face-room files with #461 and the other face-room issues, so develop sequentially after #461.
Birfy commentedon Oct 19, 2026
Claimed by maintenance (2026-10-20 07:58 Asia/Shanghai). Working on branch
fix/462-friend-line-face-routingin Birfy/FlyBot, developed in parallel with the other face-room issues (#462, #458, #457, #455, #304, #182); they will merge one after another.Birfy commentedon Oct 20, 2026
Minor decisions for this fix (decided by maintenance, 2026-10-20 08:11 Asia/Shanghai; PR #465):
face-noticesender plushuman(whatpostHumanposts). Only an attestedplainone is routed and single; an unattested line stays a quiet bubble and acallIds(@Bot) line keeps today's behavior.@allstays one pass (single, no follow-ups) and unrouted, as Face rooms: a plain line should let every Bot in the room answer (one round, capped), not only the first (follow-up to #287) #295 described it ("in one pass"). This keeps Bots in two homes from setting each other off.fallback: false: if every Bot of mine passes, nothing is forced, because the friend's own home answers it (Face rooms: a plain line should be answered by the Bot(s) it is for, not by every Bot (follow-up to #295) #299).@Bot) are queued in one relay, the friend's line picks the speakers. It is a person's line, not an event.Route a friend's plain face-room line like the owner's: routed, singl…
Count another home's Bot answer in face rooms; a friend Bot's @ALL wa…