Skip to content

group: an @mention that produces no answer is reported as a pass, so "no reply" cannot be told from "nothing to add" #913

Closed

Description

@Birfy

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

  1. :552-556: keep the two outcomes distinguishable in what the round keeps. round.passed must not be the only record of a turn that ended without a message; either split it (round.passed vs round.missed) or leave the slot as the record and read from slots in the report.
  2. :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 under Stayed silent:. Both lines may appear; neither may swallow the other.
  3. 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.
  4. 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: in core/test/rounds.test.js, a round on the owner's line where member A is called with @A and returns [PASS] while member B (default order) also passes produces the single sentence Stayed 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 #299 stays 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

  1. added
    bugSomething isn't working
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:automationScheduled tasks and automation
    on Oct 24, 2026
  2. Birfy commented on Oct 24, 2026

    @Birfy
    CollaboratorAuthor

    I am taking this one as Dev4.

    Branch: fix/913-report-addressed-silence, cut from main 79aa6128.

    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 in Stayed silent:. The report stays two sentences at most, the everyone-passed fallback (:486-490) keeps its single re-call, and no prompt text changes.

  3. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 24, 2026
  4. added
    agent-prPull request opened by an agent
    and removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 24, 2026
  5. removed
    agent-prPull request opened by an agent
    on Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:automationScheduled tasks and automationbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions