Repository navigation
Description
Reported by the owner, 2026-10-24: "when people in the group @ each other, it should always trigger a reply — file an issue."
What the repository can actually see — corrected against the code
The instruction that came with this report was to mark the whole thing needs-human because "whether an @ wakes a member" is not a repository fact. Half of that is wrong, and the code says so. FlyBot's round record already distinguishes a deliberate pass from a member that never answered — the closing report then throws the distinction away:
core/src/host/groups.js:552 if (reply === null || reply?.missed || isPass(reply)) {
:553 slot.status = typeof reply === 'string' ? 'passed' : 'missed'
:555 round.passed.push(member.name) // ← both land in the same list
slot.status keeps passed and missed apart, and the speaking order already renders them differently (:170: (no answer)). But the round's closing summary is built from round.passed alone:
:1005 round.passed.length > 0 ? `Stayed silent: ${round.passed.join(', ')}.` : ''
So a member that was called by an @ and returned nothing is reported to the person in the same sentence as a member who read the line and answered [PASS]. The person sees "Stayed silent: Dev3" and cannot tell "he had nothing to add" from "he was addressed and did not answer" — which is exactly the symptom that was reported.
The defect
A call that produces no answer is reported as a pass. Everything needed to tell them apart is already on the slot: callMembers records who called whom (:346-357: called.by, called.note), and the turn's outcome is passed or missed. The closing report collapses both into Stayed silent:.
There is already a fallback for the extreme case — when everyone passes on the owner's own line, the first passer is called again with nobody answered yet (:486-490). That covers "the user was ignored by the whole room". It does not cover the reported case: the @'d member passes while someone else answers, so the person gets a reply and never learns that the one they addressed did not answer.
Scope
:552-556: keep the two outcomes distinguishable in what the round keeps.round.passedmust not be the only record of a turn that ended without a message; either split it (round.passedvsround.missed) or leave the slot as the record and read from slots in the report.:1004-1005: the closing report gets a separate line for members that were addressed (slot.by !== undefined, or the slot exists because of a call) and did not answer — e.g.No answer to your @: Dev3.— while a member that answered[PASS]without being called stays underStayed silent:. Both lines may appear; neither may swallow the other.- No new loop: a called member that does not answer is reported, not re-called. Only the existing everyone-passed fallback (
:486-490) may re-call, and it must keep its current bound. - The member-side prompt does not change:
[PASS]is still legitimate. The fix is about the report telling the truth, not about forcing an answer — forcing one would make a deliberate pass impossible and the person would get noise instead of silence.
Not in scope — and this is the part that is genuinely uncheckable
Whether a mentioned member read the message and chose to say nothing. A pass and a non-reading member are indistinguishable by design (reply [PASS] posts nothing), and no repository field records attention. That half is one line of contract for #906 ("a member that is @'d answers: accept, route in one line, or say why it cannot — silence is not an answer"), and this issue does not pretend to test it.
Acceptance
- Red on
79aa6128: incore/test/rounds.test.js, a round on the owner's line where member A is called with@Aand returns[PASS]while member B (default order) also passes produces the single sentenceStayed silent: A, B.The new test asserts two separate lines and fails on main for the right reason. - A called member that answers normally produces no "no answer" line.
- A member that passes without being called appears under
Stayed silent:and never under the new line. - A called member whose turn ends
missed(not a string reply) is reported on the same new line as the passing one, not duplicated twice. - The everyone-passed fallback still fires and still re-calls exactly one member (
:486-490), with the new line present too; the existing test for#299stays green. - No prompt text changes, so no snapshot or prompt-length assertion moves.
Why this is a separate issue from #911
#911 is a GitHub-side check (does the body's Reviewer: line agree with who was mentioned in PR comments). This one is FlyBot's group layer and its closing report. Same symptom seen by the person, different surface, different fix — merging them would produce one issue nobody can close. The repo-side mention consistency stays in #911 and must not be re-implemented here.
Related
#911 — the GitHub-side audience check; #906 — where the one-line contract goes; #299 — the everyone-passed fallback this must not disturb; #707 — the adjacent delivery-timing report (parked on a decision, unrelated code path).
Activity
Birfy commentedon Oct 24, 2026
I am taking this one as Dev4.
Branch:
fix/913-report-addressed-silence, cut from main79aa6128.Plan, in the order the issue's scope lists it: keep the addressed turn distinguishable in what the round keeps (a slot already carries
called.by/note, and the round's opening line names its speakers), then read the closing report from the slots so a member the line addressed and that never answered gets its own sentence instead of landing inStayed silent:. The report stays two sentences at most, the everyone-passed fallback (:486-490) keeps its single re-call, and no prompt text changes.Say which routines run on a timer, and make the practice rules checkable
Say which routines run on a timer, and make the practice rules checkable
Say which routines run on a timer, and make the practice rules checkable
Docs: align the pipeline contract with practice — prove the base, jud…
Report an addressed member's silence apart from a plain pass (ThinkFl…
Call the member a Bot's own group line names, in the round that sees …