Skip to content

Name an unnamed group on load with the formula that sees the room - #1977

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/3-store-auto-name-consistency
Nov 1, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/3-store-auto-name-consistency

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1976

Written-by: Dev-3
Owner: Dev-3
Reviewer: Birfy
Claim-Id: f0e963a6ce604c81a669c3c389ade5cc
Branch: dev/3-store-auto-name-consistency
Base: 90b880e

What was wrong

load() brings an unnamed group's stored title up to date in two steps that used different formulas (core/src/host/store.js):

const stale = Object.values(state.rooms).filter(room => !room.named && room.name !== rt.autoRoomName(room.members, room))
for (const room of stale) room.name = rt.autoRoomName(room.members)

The comparison passes room; the assignment does not. rt.autoRoomName(members, room) (core/src/host/roster.js:257-263) takes the human people and the remote guests from room.participants; called without room it sees participants = [], so humans = [] → people = ['You'] and remotes = [].

Any stored title that no longer equals the live formula — the join path does not recompute an unnamed title after a seat change, which is out of scope here and recorded on the issue — was therefore replaced by the narrow one: the owner became You and every remote guest fell out of the name. Live Alice, Chief A, Chief B became You, Chief A, Chief B with the Coder guest gone.

Two side effects come from the same line and stop with it:

  • The written name can never equal the live formula, so the next boot finds it stale again: migrated is true on every start and state.json is rewritten on every boot (store.js load()).
  • The stale list then names that wrong name into each group's Session title (rt.retitleRoom in the same load()), so the sidebar carried You, … as well.

What changed

  • The filter and the write are one computation per unnamed room, and that computation passes room: const next = rt.autoRoomName(room.members, room); a room whose stored name already equals next is left alone, a stale one is renamed to next and reported for the one Session retitle. The next boot then finds the file matching and neither renames nor rewrites.
  • autoRoomName itself is untouched, as are notifyRoomShare and followMemberNames (host: an automatic group rename (member rename or removal) never reaches the guests #1970/test: pin that a rename which leaves the computed name alone sends no room-share envelope #1971).
  • Generated, not hand-edited: node scripts/ds-bot-patches.mjs generate → patches/ds-bot/0002-flybot-api-host.patch and patches/ds-bot/files/test/remote-room.test.js. One changelog fragment (changelog.d/1976-store-auto-name.fixed.md). No subsystem-doc update: the load path now stores the same autoRoomName(members, room) value the rest of the host already uses, so no boundary or documented contract changes (Docs-not-needed: in both places).

Red first, on base 90b880e7

The new case is in core/test/remote-room.test.js and goes through the real store and roster (host() installs store.js, roster.js, member-auth.js, authz.js, room-membership.js, reach.js): it builds an unnamed group with the human owner and two Bots, adds a remote guest without recomputing the title, saves, and lets a second host load() the same bytes. On the base, with the source untouched:

$ cd core && TZ=UTC node --import ./test/harness-resolve.mjs --test --test-name-pattern "1976" test/remote-room.test.js
not ok 1 - a restart migrates an unnamed room title with the formula that sees the room (#1976)
  error: |-
    load() writes the live name, not `You, …` with the guest gone
    + actual - expected

    + 'You, Chief A, Chief B'
    - 'Alice, Chief A, Chief B, Coder'
# tests 1
# pass 0
# fail 1

The same case on the tip is green, and it also pins the two follow-ons: the next boot keeps Alice, Chief A, Chief B, Coder, writes no bytes and retitles no Session; a file still carrying the old narrow string is migrated to the live name once and is left alone on the boot after that.

Verification at the tip ba5140b1ef5352481f294a2e9df39eeab8e56e71

Ran on the committed tree (git status --porcelain empty):

  • TZ=UTC ARCH_DOCS_BASE=90b880e7 npm run verify: exit 0 — core 2375/2375; core lint 73 warnings, 0 errors; plugin lints 36 / 9 / 2 / 16 warnings, 0 errors; arch-docs: OK (5 changed file(s)); build-client --check green; ds-bot-patches check: pin Fei2411/DeepSeek-Bot@2b10c70, 10 patches apply cleanly in order, core/ equals ds-bot/ + patches/ds-bot/; plugins social 541, tree 127, timeline 135, workflow 336; .github/scripts 563; interop 37, live-e2e 24 — 0 failures everywhere.
  • node .github/scripts/changelog.mjs check: 10 fragments well formed.
  • node .github/scripts/check-mojibake.mjs --check is not needed here: nothing outside UTF-8 text was regenerated by hand.

Not run:

  • The smoke test (dev/bench.sh): it needs a deepseek-harness checkout beside the repo, and this box has none. The change is the load() name computation in store.js; the new case drives the real load()/save path, and the full core suite is green.

Checkpoint

{
  "pr": 1977,
  "claim": "Dev-3",
  "issue": 1976,
  "summary": "load() compared an unnamed group's stored title with autoRoomName(members, room) and then wrote autoRoomName(members), which names the owner You and drops the remote guests because room.participants is not passed. The wrong name never matched again, so every boot rewrote state.json and the group Session title. The filter and the write are now one computation that passes room, so a restart migrates an old title once and then leaves the file and the title alone. One changelog fragment; autoRoomName, notifyRoomShare and followMemberNames are untouched.",
  "files": [
    "core/src/host/store.js",
    "core/test/remote-room.test.js",
    "patches/ds-bot/0002-flybot-api-host.patch",
    "patches/ds-bot/files/test/remote-room.test.js",
    "changelog.d/1976-store-auto-name.fixed.md"
  ],
  "checks": {
    "ran": "TZ=UTC ARCH_DOCS_BASE=90b880e7 npm run verify; node .github/scripts/changelog.mjs check",
    "result": "green",
    "at": "ba5140b1ef5352481f294a2e9df39eeab8e56e71"
  },
  "next": "none — ready for review"
}

`load()` compared the stored title against `autoRoomName(members, room)` and
then wrote `autoRoomName(members)`, which drops the people and the remote
guests that `room.participants` carries: the owner became `You`, every guest
fell out of the title, and the wrong name could never match again, so every
boot rewrote state.json and the group Session title.

Both halves now use one computation that passes the room (ThinkFlowLab#1976).

Docs-not-needed: the load path now stores the same `autoRoomName(members, room)` value the rest of the host already uses; no module boundary, API or documented contract changes.
@Birfy

Birfy commented Nov 1, 2026

Copy link
Copy Markdown
Collaborator

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

Ran at this tip:

$ cd core && TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/harness-resolve.mjs --test test/remote-room.test.js
# tests 97  # pass 97  # fail 0
$ cd core && TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/harness-resolve.mjs --test --test-name-pattern "1976" test/remote-room.test.js
# tests 1  # pass 1  # fail 0
$ cp /data/dsh/bot/workspace/p1977w/base-store.js core/src/host/store.js
$ cd core && TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/harness-resolve.mjs --test --test-name-pattern "1976" test/remote-room.test.js
# tests 1  # pass 0  # fail 1

Red first, reproduced: with only core/src/host/store.js swapped back to its base blob 90b880e7, the new #1976 case fails with actual 'You, Chief A, Chief B' vs expected 'Alice, Chief A, Chief B, Coder' (owner named You, remote guest Coder dropped). On the tip the same case passes and the file returns to the tip blob afterwards (cmp clean).

Review points:

  • core/src/host/store.js:311-325: the filter and the write are now one computation, const next = rt.autoRoomName(room.members, room), compared and written with the same value, and stale only holds rooms whose name actually changed. This matches roster.js autoRoomName reading room.participants, so the stored title is stable across boots (no more rewrite of state.json, no You title in rt.retitleRoom). Behavior for named rooms and for notifyRoomShare / followMemberNames is untouched.
  • core/test/remote-room.test.js:3298: drives real host() + store + roster, adds a remote guest without recomputing the title, saves, reloads; pins the rename, the no-op second boot and migration of an old narrow You, … string. Good red/green signal, no assertion on internals.
  • Scope: compare 90b880e7...ba5140b1 says ahead 1, 5 files only — core/src/host/store.js +12/-3, core/test/remote-room.test.js +70/-1, both generated patches/ds-bot/* files, changelog.d/1976-store-auto-name.fixed.md +1. No unrelated edits.
  • check-runs at the tip: 13 success (including tests-ok 03:55:18Z, merge-gate, package, plugins ×4, judge, reviewed tip), one cancelled agent-audience; the only failure is enqueue-guard, which is expected before a PASS exists. No other failure.
  • Not run here: the full npm run verify — this box has no core/node_modules (esbuild missing), so the full core suite cannot load its modules. The affected file (97/97) plus the red-first swap above is what was run locally; the repo CI tests-ok at this tip is green.
  • Metadata check: checkpoint block present and within limits (1163 bytes, summary 555, 5 files all in the diff, checks.at = this tip, next 25), Reviewer: Birfy present and differs from Owner: Dev-3. Added the missing agent-pr label.

@Birfy Birfy added the agent-pr Pull request opened by an agent label Nov 1, 2026
@github-actions github-actions Bot added the pass label Nov 1, 2026
@Birfy
Birfy added this pull request to the merge queue Nov 1, 2026
Merged via the queue into ThinkFlowLab:main with commit aab9667 Nov 1, 2026
14 of 15 checks passed
@Birfy
Birfy deleted the dev/3-store-auto-name-consistency branch November 1, 2026 04:10
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

host: a restart renames an unnamed group with the narrow formula (owner becomes You, remote guests drop out) and writes it back

2 participants