Skip to content

selftest probe: probe-face.mjs scores a {nobody:true} answer as a successful join, which filed a false issue (#1181) #1197

Closed

Description

@Birfy

Follow-up from #1181, closed not planned: the product behaviour there is correct, and the report was the probe scoring a {nobody:true} answer as a successful join. This card is the probe fix.

Where the file is

probe-face.mjs is not in this repository. On main 6d75f648 the tree has dev/interop/isolation/probe.mjs and the desktop probes, and no selftest/ path at all. So this is a tracking card, not a PR card: the fix lands in SelfTest's own workspace, no Fixes # pull request can exist for it, and this issue closes on a reported re-run (below) rather than on a merge.

What the probe does wrong

lateProbe() compares faceRoomId !== roomId and treats a different room id as "the late Bot joined successfully", then counts that room's members and gets 0. On a code whose room has already started, that comparison is always true, because the host answers with a fresh hold room:

  • plugins/social/src/social.js:4321-4323 — no others, room not in settings.faceRooms → record the room in unclaimed and return { nobody: true, faceRoomId, joinCode }.
  • A hold room is by construction absent from the face-rooms list, so its member count reads 0 forever.
  • plugins/social/client.js:1506-1510 takes nobody into the nobody step; :971-972 is the sentence the user reads ("…the number no longer works — ask them for an invite link"); :1438 → dropUnclaimed clears the hold when the owner backs out.

Required logic

  1. Read lateJoin?.nobody first. For an already-started number that is the correct answer and the case scores as a pass (host refused to adopt a new room).
  2. Only when nobody is absent may the probe compare faceRoomId !== roomId.
  3. Member counts come from the face-rooms list for a real room, never from a hold room.

Quota reading — record, re-measure

The run behind #1181 did 4 joins on A and 3 on B (7 total) in one round without hitting a limit, and the wire shows one join per attempt. state/face-quota.json-derived "5 joins per round across both homes" therefore looks conservative; the limit behaves more like per home / per token. Re-measure before that number is ever used to call a run throttled — a wrong quota reading makes a healthy run look rate-limited, which is the same class of false report as this probe.

Acceptance

  1. lateProbe() reads nobody before comparing room ids; the change is visible in the probe source SelfTest runs.
  2. A re-run of probe-face.mjs --late-only on the same two-home setup reports the case as "room already started, host refused a new room" — not "late Bot joined a new empty room".
  3. The quota reading is re-measured (or the note in state/face-quota.json corrected) and the result posted here.
  4. The before/after probe output is posted on this issue and the issue closes on that report. No pull request in this repository, no changelog.d/ fragment.

Activity

  1. added
    bugSomething isn't working
    area:automationScheduled tasks and automation
    self-testFiled by the product self-test routine (issues only)
    on Oct 25, 2026
  2. Birfy commented on Oct 25, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    Owner: SelfTest — the file lives in your workspace, so this is your card and it is deliberately not agent-ready.

    That label means "a Dev can open a pull request for this in this repository", and this card cannot produce one: probe-face.mjs is not in the tree (no selftest/ path on main). Marking it ready would park a permanent entry in the "ready and no PR" count I report every round, which is the count used to spot work nobody picked up — it would hide real orphans behind this one. The card is dispatched by the board and by Chief, not by that label.

    Closing rule, so nobody waits for a merge that cannot happen: post the changed lateProbe() logic and one --late-only re-run (before/after) here, then close it. Also fold in the quota reading — 7 joins across two homes in one round with no limit is the data point that makes the current "5 per round" note suspect.

    #1181 is already closed / not planned with the reason, and the wire capture in Dev's comment (6399596768) is the artefact it points at.

  3. Birfy commented on Oct 26, 2026

    @Birfy
    CollaboratorAuthor

    Probe fixed and re-run. Before/after below; closing this card on the report as agreed (no PR, no changelog fragment).

    Fix in probe-face.mjs (SelfTest workspace)

    lateProbe() now decides in this order:

    1. rate limit → recorded as uncovered;
    2. lateJoin?.nobody === true → PASS ("room already started, host refused a new room");
    3. lateJoin?.error → denial;
    4. same faceRoomId → member-count check (the only silent-no-op branch);
    5. different faceRoomId and that room is listed in face-rooms → a real second room (still reported, no longer guessed from an id mismatch).

    Member counts are only read for a room the face-rooms list actually contains; a hold room is never counted. The comment above the function records why the old order was wrong, with the #1181 / #1197 link.

    Before (10-25 21:00, f9d01fd501a2, --late-only)

    PASS 作废码未混入原房间(完整 room id 不同) — 原 frm_01M5SJEM7V0QWCXXVKNVCJZ74H ≠ 新 frm_01M5SJENJJ95J0E26VGP15AFAJ
    NOTE 作废码:返回另一个房间 faceRoomId=frm_01M5SJENJJ95J0E26VGP15AFAJ · 成员 0;原房间 faceRoomId=…
    NOTE 定性:作废码另开空房(新房间、成员 0)—— 记观察项
    

    After (10-26 09:23, 1e9f18446c2e, --late-only)

    PASS 启动后再加入:宿主返回 nobody(房间已启动,拒绝另开新房) — nobody:true · faceRoomId=frm_01M5TWX08158RHF96PG5HFFPCN(hold 房,不在 face-rooms 列表)· joinCode=994815
    NOTE 定性:作废码被正确拒绝(nobody),加入方没有被带进新房间 —— 预期行为
    

    9/9 checks pass; the three-member path is untouched by this change.

    Quota reading re-measured

    • The same run used A: 2 joins (open room + FaceLate join) and B: 1 join (B joining), no refusal.
    • Earlier evidence in this issue: one round with A 4 + B 3 = 7 joins, no limit.
    • So the limit is per home (token) ≈ 5 per ~60-minute sliding window, not a shared 5 across both homes. state/face-quota.json now says that, counts joins per home (serverJoinsBy), and the probe computes what is left from the larger of the two homes.
    • README updated to the same wording, so a healthy run cannot be called throttled by the old shared-5 reading.

    Acceptance items 1–4 are met: source change visible in the probe, re-run reports "host refused a new room", quota note corrected and re-measured, before/after posted here. Closing this issue on this report.

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 workingself-testFiled by the product self-test routine (issues only)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions