Repository navigation
Merge main into dev after v0.2.6 - #838
Conversation
Imports before 0.2.3 copied a group's member Sessions but not the group's own Session (#551). #567 fixed new imports only, so a team imported by 0.2.0-0.2.2 still has groups whose Session DSH does not know: a click on such a group waits for a Session that never shows up in the list, and nothing happens. On every start, before the Host, the app now copies each Session its team names that is missing from the data location, from the DSH home recorded in bot/imported.json. Each one is staged beside the data and moved in whole; one in a newer format than the pinned DSH reads stays behind. The old home is only read.
release: v0.2.6
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9ab2be6e93
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const newer = found.filter(session => isNewer(from, session)) | ||
| const sessions = found.filter(session => !newer.includes(session)) |
There was a problem hiding this comment.
Check staged sessions with the pinned reader before restoring
If the original DSH has written an unknown required record without changing the log-format version, isNewer() accepts the session even though the pinned DSH cannot read it. This case is explicitly exercised by app/test/session-check.test.mjs using a v4 log containing a future/feature record, and the normal import handles it through checkTeam() and unreadableSessions(). The restoration path bypasses that check, installs the unreadable session, and subsequently skips it because its directory exists, leaving the affected group unable to open despite reporting a successful restoration. Check the staged sessions with the pinned reader before moving them into the live data.
Useful? React with 👍 / 👎.
| const newer = found.filter(session => isNewer(from, session)) | ||
| const sessions = found.filter(session => !newer.includes(session)) |
There was a problem hiding this comment.
🔴 Restored group chats remain unreadable
When a group Session contains unsupported records in a supported log version, restoreSessions copies it and reports success. The pinned DSH rejects those records, so the group chat still cannot open.
Learn more
A Session filename identifies its log format, but the pinned DSH can reject newer required records inside that format. The first-run checkTeam copies Sessions into a throwaway home and reads them through the pinned DSH before importing. Restoration uses only a filename check, then moves the Session into the real home and reports it as copied. An unsupported Session is therefore installed despite being unusable.
Example: The source group's session.v4.jsonl.zstd contains a required future/feature record. Its filename passes the version check, but the pinned DSH raises SessionFormatUnsupportedError when reading it, as the first-run check test demonstrates. The group still fails to open after restoration.
Recommended fix: Validate staged Sessions through the pinned DSH's read-only Session check before moving them into the active home. Leave unsupported Sessions unstaged in the active home and report them as unreadable.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const { missing } = sessionDirs(to, sessionIdsOf(readJson(statePath))) | ||
| const { found } = sessionDirs(from, missing) |
There was a problem hiding this comment.
🔴 Moved group chats are never restored
When a group's current or earlier part is missing, restoreSessions never looks for its Session ID. sessionIdsOf omits room.sessionId and room.parts, leaving those group chats unreadable after repair.
Learn more
A group retains its identity in room.id, but sessionOfRoom reads room.sessionId after the group changes folders. partsOf also reads its earlier Sessions from room.parts. The existing sessionIdsOf enumerator omits both fields. Restoration now relies on that enumerator to find missing Sessions, so it never repairs these group conversation parts even when they remain in the original DSH home.
Example: A group has room.id = 'r1', room.sessionId = 'r2', and room.parts = [{ sessionId: 'r1' }]. An older import left r2 behind. Restoration examines r1 and the members' Sessions, but never r2; opening the group still fails.
Recommended fix: Include both room.sessionId and every room.parts[].sessionId in sessionIdsOf and cover a group with a changed current Session in the restoration tests. This also makes subsequent first-run imports include those parts.
Was this helpful? React with 👍 or 👎 to provide feedback.
Issue
Follow-up of the v0.2.6 hotfix (#837, for #551). Hotfixes go into
mainfirst; this bringsmainback intodev.What changed / 改了什么
mainmerged intodev, no conflicts: the fix that copies the group Sessions an earlier import left out, version 0.2.6, and the 0.2.6 CHANGELOG section.Changelog
none
How I checked it / 怎么验证的
Checklist / 检查
src/client/change.Co-authored-by. / 没有把 AI 工具写成作者或Co-authored-by。