Repository navigation
Restore both directions when a re-invite is accepted (#1000) - #1023
Conversation
An accepted invite is where the two-way friendship comes from, but Bot Social applies neither half of the invite again when the relationship already exists (a `relationship_exists` 409, or a `regranted` join): the joining home's Bot stayed ungranted, so the inviter's first line to it was held as an unknown recipient until that side shared again. The re-accept path now asks for the grant an accepted invite would have made (`grant_bot_to_friend`, chat.public, best effort on a server without the tool), and the Add friend line says the Bot is shared back instead of only "You already have ...".
|
Verdict: PASS at 6617e0a 5 个文件 +152/−4,和正文一致。这段的关键不是代码形状,而是“这个 grant 用到的 id 服务端到底给不给”: 按新 tip 重跑: 刀四把(每把都
范围核过:首次 join 不进这两条路( Ran: $ node api.mjs /repos/ThinkFlowLab/FlyBot/commits/6617e0a6a4510a02a5b161733a29320bb38bcdcd/check-runs
# 除 enqueue-guard 外全 success;enqueue-guard 的失败是在等这条 PASS
$ node --import ./test/resolve.mjs --test "test/*.test.js" (plugins/social, 6617e0a6)
# 440 / 440
$ 7225692e 树 + 这版 test/social.test.js → 同一套件
# 436 / 440:两条 #1000 + 两条文案表
$ node --test --test-name-pattern="1000" (四把刀,逐把)
# 刀 A/B/C 各掉自己那条;刀 D(去掉 :2411 的 sync)全绿
$ node .github/scripts/changelog.mjs check
# 1 fragment(s) in changelog.d/ are well formed非阻断(不挡这张):
|
Owner: Dev2
Reviewer: Reviewer
Fixes #1000
Tip SHA: 6617e0a
Base: 7225692
Accepting a re-invite now restores both directions: the joining home grants its Bot back, so the pair is two-way again instead of the inviter's first line landing as an unknown-recipient hold.
Reproduce
SelfTest checklist 2b on
d2578496: A and B friends both ways, A removes B's Chief, A invites B's Chief again, B accepts. A sees B again; B's list lacks A, and a line to A is held as an unknown recipient until B shares again — the acceptance restored only the direction the invite sent. The plugin's seam:social/join-invite→alreadyHaveon409 relationship_exists(social.js:2336) and theregranted: truejoin (social.js:2466) both return without creating the grant an accepted invite makes on the joining side, sogrant_bot_to_friendis never called for that pair.What changed
plugins/social/src/social.js: the joining Bot and its member identity survive thetry(they were block-scoped), andrestoreAcceptedInviteGrantasks Bot Social for the grant an accepted invite would have made —grant_bot_to_friend { bot_id: <member>, friend_bot_id: <inviter Bot> },chat.public— on the two re-accept paths only: therelationship_exists409 (insidealreadyHave) and a join that answersregranted: truewithstatus: 'active'. A plain first join is untouched: the joiner's Bots stay default-deny there, which is what Per-Bot grants leak: accepting a Helper invite exposes the joiner's Chief; face-room Chief shows in Friends' Bots; Manage access wrong/raw #138/Regression of #138: joining a friend's invite still puts the joiner's Chief on the inviter's main list #161/Accepting an invite never shows the inviter's Bot to the joiner, and the joiner's Chief lists the inviter in People with access (regression of #178 from #334) #342 pin.unavailable; the accept still succeeds andsharedBackis simply absent. The grant is followed bysyncOutgoingGrants({ only }), so People with access lists it at once and its Revoke works (#992: the share outcome and the list error get their own slots #993/People with access merges every Bot of a friend into one row, so one Revoke takes them all #995 rows).plugins/social/client.js: the Add friend line says what the click did —… Chief is shared back, so they can reach you too.— for both the already-have path and the accept path, instead of leaving the other direction silent.docs/subsystems/social.md(#1000clause on the Invite between existing friends: red 'You're already friends. Their Bot is back in your list.' when nothing changed; Remove this Bot doesn't say what stays shared #496 bullet) and onechangelog.d/1000-…fixed.mdfragment.What I ran
At
6617e0a6(TZ=UTC,TMPDIRon the data disk):core/is untouched, so no bundle orpatches/ds-botregeneration is involved.Red without the source change
Pristine
7225692ewith only this PR's test file (source and docs reverted):# tests 440 / pass 436 / fail 4— the two#1000cases (expected: true, i.e. nogrant_bot_to_friendcall and nosharedBack), plus the two copy tables that now carry asharedBackrow (#496 neutral line, #343/#499 accept line). Nothing else moves: the tolerance case (an older server that cannot grant back never fails the accept) is green on both trees, so it is a negative control, not a second red.Not run
409 relationship_exists,regranted: true), and the grant uses the same call the Share panel already drives (Share a Bot with an existing friend without an invite link #500). Which of the two shapes the live server picks for this scenario is not observed here — both are covered so the fix does not depend on it.plugins/treeandcoresuites: not touched by this diff (plugin lint covers the file set).Risk
requested_capabilities: ['chat.public']on our own invites), so it restores what a fresh accept would have created — but it is a sharing action on the security surface, and the owner/Reviewer should read it as such: a first-time accept still shares nothing back.shared backwhile the list catches up on the next poll (same as the existing share flow).