docs(comments): proactive 判据键在 data 内、不在帧壳顶层(安卓核对指出)

4 处注释写「帧顶」而代码放在 data[proactive](+ 测试文件 6 处同源表述)。
安卓端两层都读所以不受影响,但注释与代码相反会误导下一个按注释写的人。
零行为改动(仅注释)。
This commit is contained in:
AskaEth committed 2026-10-06 21:16:20 +08:00
1 parent f1fbc249fd
commit b36798265a
3 files changed
+10 -10

No files matched your search

+2 -2
View File
@@ -21,14 +21,14 @@ import (
// 当 hub 接好广播时它是安全空操作。两种帧类型都携带消息内容,
// 因此 design/11 §7.1 帧门只把它们投递给 owner/admin 连接。
//
// 它**绝不**带 `proactive` 键:普通消息的帧顶永远没有那个结构化判据,客户端因此
// 它**绝不**带 `proactive` 键:普通消息的帧的 `data` 里永远没有那个结构化判据,客户端因此
// 不可能把普通消息误判成主动消息去弹通知(切片 P0b 的「不误伤」那一条)。主动推送
// 那条路走 BroadcastProactivePersisted(proactive.go)。
func (s *Server) BroadcastPersisted(msg history.Message) {
s.broadcastPersisted(msg, false)
}
// broadcastPersisted 是上面两个入口共用的帧构造与扇出:proactive 决定帧顶是否带上
// broadcastPersisted 是上面两个入口共用的帧构造与扇出:proactive 决定帧的 `data` 里是否带上
// 「这是她主动说的话」的结构化判据 `proactive:true`(切片 P0b,见 proactive.go 的
// BroadcastProactivePersisted)。两条入口走**同一个**函数,因此帧类型推导、thinking
// 抹除与角色门(design/11 §7.1)逐字一致 —— 差别只有那一个键。
+2 -2
View File
@@ -93,7 +93,7 @@ func (s *Server) SendProactive(ctx context.Context, msg adapter.UnifiedMessage)
}
// BroadcastProactivePersisted 把一条**刚落进主会话的主动消息**广播为**带结构化判据**的
// `message_persisted` 帧(切片 P0b)。判据就是帧顶的 `proactive:true`:它是「她主动说的
// `message_persisted` 帧(切片 P0b)。判据就是帧的 `data` 里的 `proactive:true`:它是「她主动说的
// 话」在线上唯一的标记,客户端据此走与 `proactive_message` **同一套**提醒逻辑(非前台才
// 补一发通知,同一条只提醒一次),于是「她该不该提醒我」**与后端走了哪条路由无关**
// (主人 2026-10-05 裁定 C)。
@@ -104,7 +104,7 @@ func (s *Server) SendProactive(ctx context.Context, msg adapter.UnifiedMessage)
// ⇒ 实际最可能发生的路径恰恰不弹。
//
// 判据为什么不会误伤普通消息:只有主动推送这条通道会调用本函数,普通消息(Web 回合 /
// IM 回复 / IM 镜像)走的仍是 BroadcastPersisted,那条路径**永不**往帧顶放该键。
// IM 回复 / IM 镜像)走的仍是 BroadcastPersisted,那条路径**永不**往帧的 `data` 里放该键。
// 帧类型仍是 `message_persisted`,因此角色门(design/11 §7.1)与普通持久化帧逐字相同。
func (s *Server) BroadcastProactivePersisted(msg history.Message) {
s.broadcastPersisted(msg, true)
@@ -15,13 +15,13 @@ import (
// 路由过去只发普通 `message_persisted` —— 浏览器通知挂在 `proactive_message` 上,于是
// **实际最可能发生的路径恰恰不弹**。主人裁定「她说话该不该提醒我,与走哪条路由无关」。
//
// 判据是**结构化**的:主动推送在落库之后追加一条**帧顶带 `proactive:true`** 的
// 判据是**结构化**的:主动推送在落库之后追加一条**帧的 `data` 里带 `proactive:true`** 的
// `message_persisted`(gateway.BroadcastProactivePersisted)。普通消息(Web 回合 / IM
// 回复 / IM 镜像)走的仍是 BroadcastPersisted,那条路**永不**放该键 —— 因此普通消息
// 不可能被误判成主动消息。下面分别钉住两端:IM 路由真的发得出这条带判据的帧,而普通
// 广播路径永远发不出它。
// dataFlag 报告帧顶是否带 proactive 判据(以及它的值)。
// dataFlag 报告帧的 `data` 里是否带 proactive 判据(以及它的值)。
func dataFlag(t *testing.T, ev wsEvent) (any, bool) {
t.Helper()
data, ok := ev.Data.(map[string]any)
@@ -49,7 +49,7 @@ func frameMessageID(t *testing.T, ev wsEvent) string {
// TestChannelBridge_SendProactive_EmitsProactiveFlaggedFrame 是切片 P0b 的端到端证据:
// IM 路由的主动消息**既**照旧广播普通镜像帧(P0 起的行为,任何客户端都能渲染),**又**
// 追加一条帧顶带 `proactive:true`、并携带落库行权威 id 的帧 —— 前端据此走与
// 追加一条帧的 `data` 里带 `proactive:true`、并携带落库行权威 id 的帧 —— 前端据此走与
// `proactive_message` 同一套提醒逻辑(非前台补一发通知,两帧同 id ⇒ 去重后一个气泡、
// 一次提醒)。它同时守住 P0 的红线:主会话里仍**恰好一条**(绝无双份)。
func TestChannelBridge_SendProactive_EmitsProactiveFlaggedFrame(t *testing.T) {
@@ -94,7 +94,7 @@ func TestChannelBridge_SendProactive_EmitsProactiveFlaggedFrame(t *testing.T) {
t.Fatalf("普通镜像帧带上了 proactive=%v,want 该键缺席(判据只属于主动那条)", v)
}
// 第二帧:主动帧 —— 帧顶带判据,且消息 id 就是落库行的权威 id。
// 第二帧:主动帧 —— 帧的 `data` 里带判据,且消息 id 就是落库行的权威 id。
second := readFakeFrame(t, owner)
if second.Type != "message_persisted" {
t.Fatalf("frame 2 type = %q, want message_persisted(帧类型不变,只多一个结构化键)", second.Type)
@@ -114,7 +114,7 @@ func TestChannelBridge_SendProactive_EmitsProactiveFlaggedFrame(t *testing.T) {
}
// TestServer_BroadcastPersisted_NeverCarriesProactiveFlag 是「不误伤」那一条的后端对照:
// 普通广播路径(Web 回合 / IM 回复 / IM 镜像全走它)**永远**不在帧顶放 proactive 判据,
// 普通广播路径(Web 回合 / IM 回复 / IM 镜像全走它)**永远**不在帧的 `data` 里放 proactive 判据,
// 因此客户端不可能把普通消息误判成主动消息去弹通知。同一行改走主动那条入口时,判据才
// 出现 —— 两条入口的差别只有这一个键。
func TestServer_BroadcastPersisted_NeverCarriesProactiveFlag(t *testing.T) {
@@ -132,7 +132,7 @@ func TestServer_BroadcastPersisted_NeverCarriesProactiveFlag(t *testing.T) {
t.Fatalf("frame type = %q, want message_persisted", plain.Type)
}
if v, has := dataFlag(t, plain); has {
t.Fatalf("普通消息的帧顶带上了 proactive=%v,want 该键缺席(否则会被误判成主动消息)", v)
t.Fatalf("普通消息的帧的 `data` 里带上了 proactive=%v,want 该键缺席(否则会被误判成主动消息)", v)
}
env.srv.BroadcastProactivePersisted(row)