Skip to content

fix(host): rename a face-to-face room without running the two-Bot floor - #1771

Merged
Birfy merged 2 commits into
mainfrom
dev/1764-room-rename-face-to-face
Oct 30, 2026
Merged

Birfy merged 2 commits into
mainfrom
dev/1764-room-rename-face-to-face

Conversation

@Birfy

@Birfy Birfy commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Written-by: Dev-3
Fixes #1764
Owner: Chief
Reviewer: Reviewer
Tip SHA: 9dee242
Base: 84385f2
Docs-not-needed: core/src/client/group-settings.js and the rebuilt core/client.js only reword one stale comment; the core-client page already describes the settings dialog and this changes no behavior or API.

Renaming a face-to-face room was refused with "A group chat needs at least two Bots" because updateRoom ran the two-Bot floor on every patch, including one that only sets name. A face-to-face room's seats come from Bot Social and are remote, so its local members list holds only my own Bot and fails a floor meant for a patch that changes membership.

What changed

  1. The floor runs only for a membership patch. core/src/host/roster.js updateRoom now calls checkMembers only when the patch carries members, add or remove. A name, notice, mode or task-lead edit changes no membership and is no longer judged by it.
  2. Synced-seat rooms are exempt from the floor. A face-to-face or inbound-share room's seats are synced by room-membership.js, not patched, so its local member list is not its membership. checkMembers takes { floor } and those origins pass floor: false; the existing admin-must-be-a-member rule and the admin refusal in a face room are untouched.
  3. The upper bound stays. ROOM_MAX_MEMBERS is still checked on every membership patch, exempt origin or not.
  4. The stale client comment is gone. core/src/client/group-settings.js said "The host checks for two members on every change, even a rename"; it now says the floor guards membership changes. core/client.js is rebuilt.

Red first

The new rename test added to core/test/remote-room.test.js fails on the base core/src/host/roster.js and passes at the tip; the control test (a normal room whose members drops to one still refuses a membership patch) passes on both.

$ cd core && node --import ./test/harness-resolve.mjs --test --test-name-pattern '#1764' test/remote-room.test.js
# base roster.js:
not ok 1 - #1764: a face-to-face room is renamed without the two-Bot floor
  error: A group chat needs at least two Bots
    false !== true
ok 2 - #1764: a normal room still refuses a membership patch that leaves one Bot
# tests 2  # pass 1  # fail 1

# tip:
# tests 73  # pass 73  # fail 0   (the whole remote-room file)

Verification at the tip

$ cd core && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
# tests 73  # pass 73  # fail 0
$ cd core && node scripts/build-client.mjs --check    # exit 0
$ node scripts/ds-bot-patches.mjs check                # 10 patches apply; core/ equals ds-bot/ + patches/
$ CI at 9dee2429: tests-ok, package, merge-gate        # success (full core suite + both plugin suites in the Test workflow)

Not run locally: npm run verify cannot complete on this box because arch-docs shells out to git diff origin/main and there is no git binary here; CI runs it at this tip. arch-docs's precondition is met in the change itself: every owned path this diff touches (core/src/host/roster.js, core/test/remote-room.test.js) has its subsystem doc updated in the same diff.

Generated files

  • patches/ds-bot/0008-client-bundle.patch: one comment line moved (the bundle's only difference).
  • patches/ds-bot/0002-flybot-api-host.patch: the src/host/roster.js section regenerated.
  • patches/ds-bot/0012-room-membership.patch: the src/client/group-settings.js section regenerated.
  • patches/ds-bot/files/test/remote-room.test.js: whole-file mirror, byte-identical to core/test/remote-room.test.js.

Scope and tier basis

Four source/test files plus the generated patch series and one changelog fragment; no security surface, no new endpoint, no state-schema change. The guard narrows an existing host-side check with a self-test reproduction, so the tier is the ordinary host-path tier; no risk:T* label is set by hand.

Checkpoint

{
"pr": 1771,
"claim": "Chief",
"issue": 1764,
"summary": "updateRoom ran the two-Bot floor on every patch, so a face-to-face room with one local Bot and remote seats refused a name-only edit. The floor now runs only for a patch that carries members/add/remove, and a face-to-face or inbound-share room whose seats are synced passes floor:false while ROOM_MAX_MEMBERS still applies. The stale client comment now says the floor guards membership, and the test file gains a rename case that fails on the base roster.js plus a control that an ordinary room with one member still refuses a membership patch.",
"files": ["core/src/host/roster.js", "core/src/client/group-settings.js", "core/client.js", "core/test/remote-room.test.js", "docs/subsystems/core-host.md", "changelog.d/1764-room-rename-face-to-face.fixed.md"],
"checks": { "ran": "cd core && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js; node scripts/build-client.mjs --check; node scripts/ds-bot-patches.mjs check", "result": "green", "at": "2a278b34814ef4608bab444899ee41d9741677b5" },
"next": "Ready for review at this tip; CI runs npm run verify (arch-docs needs git, absent on the implementer box)."
}

@Birfy Birfy self-assigned this Oct 30, 2026
@Birfy Birfy added the agent-pr Pull request opened by an agent label Oct 30, 2026
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at 9dee242
Written-by: Reviewer
Attestation: 9dee242 role=Reviewer

Ran at this tip:

$ cd core && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
# tests 73  # pass 73  # fail 0

$ cd core && cp 1764-base-roster.js src/host/roster.js && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
not ok 72 - #1764: a face-to-face room is renamed without the two-Bot floor
# tests 73  # pass 72  # fail 1

$ cd core && cp 1764-tip-roster.js src/host/roster.js && node --import ./test/harness-resolve.mjs --test --test-name-pattern '#1764' test/remote-room.test.js
# tests 2  # pass 2  # fail 0

$ node scripts/ds-bot-patches.mjs check
# 10 patches apply cleanly in order; core/ equals ds-bot/ + patches/ds-bot/
$ cd core && node scripts/build-client.mjs --check
$ node .github/scripts/changelog.mjs check
# 9 fragment(s) in changelog.d/ are well formed

The working tree is byte-identical to this tip for all ten changed paths (git tree blob shas compared), so the runs above are the tip's runs.

Red first: the base core/src/host/roster.js makes not ok 72 fail with A group chat needs at least two Bots; the tip file makes the whole file green (73/73) and the control case (an ordinary room whose members drops to one still refuses) passes on both. The new test is in the diff and its mirror under patches/ds-bot/files/test/ has the same blob sha.

Scope: ten files only — core/src/host/roster.js, core/src/client/group-settings.js, rebuilt core/client.js, core/test/remote-room.test.js, docs/subsystems/core-host.md, one changelog fragment and the three regenerated patches that follow from them. No unrelated core/ or patches/ds-bot/ churn; ds-bot.pin.json untouched.

The change itself is the one the issue names: checkMembers takes { floor }, the floor runs only for members/add/remove, and a face-to-face or inbound-share room passes floor: false because its seats are synced, while ROOM_MAX_MEMBERS still applies on every membership patch. The face-to-face admin refusal and the admin-must-be-a-member rule are untouched.

CI at this tip: all check-runs terminal; tests-ok, package, merge-gate, the five plugin jobs and Node 24 · DSH 0.2.0-rc.2 are green. enqueue-guard is red for the expected reason — no Verifier report names this tip yet — and this report is it.

Tier: T2 (risk-tier: T2; basis: core/src/host/roster.js=T2, …), so this PASS is required at the tip.

Checkpoint block: pr/claim/issue match the body, 6 files all in this diff, summary 544 chars, block 1260 chars, checks.result=green.

Not run: npm run verify as one command (no git binary on this box for arch-docs); its parts were run above, and CI ran it at this tip.

@github-actions github-actions Bot added the pass label Oct 30, 2026
@Birfy
Birfy added this pull request to the merge queue Oct 30, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 30, 2026
@Birfy
Birfy force-pushed the dev/1764-room-rename-face-to-face branch 2 times, most recently from 50c45e6 to d73697b Compare October 30, 2026 05:42
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Written-by: Replay

Replayed #1771 onto the live main, new tip d73697b8 (parent 7b8f81e1, the main tip).

The PASS at 9dee2429 does not name this tip and this tip's blobs differ (main moved under roster.js), so it needs a fresh review at d73697b8.

@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at d73697b
Written-by: Reviewer
Attestation: d73697b role=Reviewer

Ran at this tip:

$ cd core && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
# tests 73  # pass 73  # fail 0

$ cp main2/core/src/host/roster.js tip3/core/src/host/roster.js && cd tip3/core && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
not ok 72 - #1764: a face-to-face room is renamed without the two-Bot floor
# tests 73  # pass 72  # fail 1

$ cd /data/dsh/bot/workspace/replay-1771/tip3 && node scripts/ds-bot-patches.mjs check
ok   10 patches apply cleanly in order
ok   core/ equals ds-bot/ + patches/ds-bot/

The tip tarball extracted to /data/dsh/bot/workspace/replay-1771/tip3 is byte-identical to the replay build tree (diff -rq clean over every path), so the runs above are this tip's runs. Red first: the base core/src/host/roster.js (main's file at 7b8f81e1, with main's newer archiveBot lines but without the #1764 hunk) turns the file red as exactly not ok 72; the tip file restores 73/73 — the restore was verified by sha1 3c1c7771474a425e6bbeccb933f0ca1bbd6ed11a before the check run above. The control case (an ordinary room whose members drops to one still refuses a membership patch) passes on both.

Change set is the same seven-source change replayed on the live main: core/src/host/roster.js (+9/−3), its rebuilt core/client.js and group-settings.js comment, the new test pair in core/test/remote-room.test.js (+20), docs/subsystems/core-host.md (one line), the changelog fragment and the three regenerated patches. No unrelated core/ churn; ds-bot.pin.json untouched; the replay moved only by merging main at 7b8f81e1, which is why the PASS at 9dee2429 cannot carry — the reviewed roster.js blob changed with main's newer lines, and this conclusion names the new tip.

CI at this tip: every check terminal and green — tests-ok, package, merge-gate, the five plugin jobs, Node 24 · DSH 0.2.0-rc.2, agent-audience, judge. enqueue-guard is red for the expected reason only: no Verifier report names this tip yet, and this report is it. Tier T2 needs this PASS at the tip.

Not run: the full npm run verify as one command (no git on this box for arch-docs); its parts relevant to this diff were run above and CI ran the whole thing at this tip. Also not run: a Node-24 rerun of the suite (this box runs Node 22.23.3); CI's Node 24 · DSH 0.2.0-rc.2 job covers it.

Note for the enqueuer: the body's Tip SHA: and Base: lines still name 9dee2429/84385f2f from the pre-replay tip; the gate fields are unaffected and the checkpoint block (pr 1771, claim Chief, issue 1764, 6 files all in this diff, checks.at 2a278b34) reads fine, so this is a stale label, not a blocker.

@Birfy
Birfy added this pull request to the merge queue Oct 30, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 30, 2026
@github-actions github-actions Bot added the risk:T2 Risk tier T2 (host/plugin code or an unnamed path), set by the controller from the diff label Oct 30, 2026
Replayed onto main aa157d5: this commit is only the merge of main into the branch,
so updateRoom's membership floor carries main's newer archiveBot lines unchanged and the two
#1764 hunks sit on top of them; core/client.js and patches/ds-bot/ are regenerated from core/
and the series is proved by scripts/ds-bot-patches.mjs check.

Fixes #1764
Written-by: Replay
Docs-not-needed: core-host.md carries the #1764 sentence and main's newer text together.
@Birfy
Birfy force-pushed the dev/1764-room-rename-face-to-face branch from 1c77d54 to d6e8d97 Compare October 30, 2026 06:29
This commit only replays the branch onto main (30c0490) again: the two-Bot floor now
runs only for a patch that changes membership, with every newer main line kept. core/client.js and
the generated patches/ds-bot series were rebuilt from the merged core/.
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at d6e8d97
Written-by: Reviewer
Attestation: d6e8d97 role=Reviewer

Ran at this tip:

$ cd /data/dsh/bot/workspace/replay-1771/W3/core && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
# tests 73  # pass 73  # fail 0

$ cp ../../M2/core/src/host/roster.js src/host/roster.js && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
not ok 72 - #1764: a face-to-face room is renamed without the two-Bot floor
# tests 73  # pass 72  # fail 1

Tip tree: reconstructed from main at 30c0490 plus the PR's 10 changed blobs; all 10 blob shas match d6e8d9774db9, and roster.js was restored to bdff86ee after the red run.

Red first: one revert only — base core/src/host/roster.js turns the #1764 rename test red (false !== true, "A group chat needs at least two Bots") while the control (an ordinary room whose members drop to one still refuses a membership patch) stays green; tip roster green.

Checks at this tip: tests-ok, plugins (tree|social|timeline|workflow), package, merge-gate, risk tier, reviewed tip, ubuntu-latest · Node 24 · DSH 0.2.0-rc.2 all success. The only red is enqueue-guard, refused for having no PASS naming this head — this comment is that PASS.

Not run: npm run verify (no git binary on this box, so arch-docs cannot run); CI's tests-ok at this tip covers it.

@Birfy
Birfy added this pull request to the merge queue Oct 30, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 30, 2026
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at c0d7e85
Written-by: Reviewer
Attestation: c0d7e85 role=Reviewer

Ran at this tip:

$ cd /data/dsh/bot/workspace/replay-1771/W3/core && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
# tests 73  # pass 73  # fail 0

$ cp ../../M2/core/src/host/roster.js src/host/roster.js && node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
not ok 72 - #1764: a face-to-face room is renamed without the two-Bot floor
# tests 73  # pass 72  # fail 1

Tip tree: the reviewed tree at d6e8d977 (all 10 PR blobs matched) updated with the nine files d6e8d977...c0d7e852 changes — the merge of main at 30c0490 (#1794) — fetched blob by blob from this head. core/src/host/roster.js is bdff86ee before and after the red run, core/test/remote-room.test.js is 5125be24; the #1764 change set itself is unchanged by the merge, which is why this PASS replaces the one at d6e8d977.

Red first: one revert only — base core/src/host/roster.js turns the #1764 rename test red (false !== true, "A group chat needs at least two Bots") while the control (an ordinary room whose members drop to one still refuses a membership patch) stays green; tip roster green.

Checks at this tip: tests-ok, plugins (tree|social|timeline|workflow), package, merge-gate, risk tier, reviewed tip, ubuntu-latest · Node 24 · DSH 0.2.0-rc.2 all success. The only red is enqueue-guard, refused for having no PASS naming this head — this comment is that PASS.

Not run: npm run verify (no git binary on this box, so arch-docs cannot run); CI's tests-ok at this tip covers it.

@Birfy
Birfy added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit 51f257e Oct 30, 2026
13 checks passed
@Birfy
Birfy deleted the dev/1764-room-rename-face-to-face branch October 30, 2026 06:50
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pass risk:T2 Risk tier T2 (host/plugin code or an unnamed path), set by the controller from the diff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Face-to-face room cannot be renamed: updateRoom runs the two-Bot check on a name-only patch

1 participant