24 KiB
P7 wave 2-F:Ph 小件(分支 p7/ph-f)
计划见
PLAN-PH-P34B-P7.md§1.1(PH-7、PH-8、D11、门行)与 §3 wave 2-F; 裁定见INTEGRATOR-DECISIONS-P7.mdID-P7-3(令牌足够、不做 TLS、Welcome.dataNonce);规范见CONTRACT-P7.md§0 规则 I / J、§9 簇 F、§10 第 3 条。基线ec46a550。主机口径:WSL Arch + lavapipe,
build-split与集成者同配置(integration tests ON)。flatc 取3rdparty/flatbuffers子模块构建的钉版本(scripts/gen_protocol.py)。基线门读数(
~/w7/logs/p7-gate-f-base.log):G1.text0xa52203、符号 0/0;普查 79 处 abort、 0 未标记;棘轮 173;车道 unit 2429 / split 303 / spawn 219 / tcp 222 / magma-tcp 74。
0. 每片一条提交,每片一次 red-once
下表的 SHA 都是包树(分支 p7/ph-f)上的;集成者 cherry-pick 到 pipe 后以那边的为准。
| 片 | 项 | 提交 | 状态 |
|---|---|---|---|
| 1 | PH-7 (1)(2)(3):常量时间令牌合一、≥16 字节(TCP 监听处)、无令牌只 loopback、smoke 入 CI | 2975a337 |
落地 |
| 2 | PH-7 (4):Welcome.dataNonce 把数据连接绑定到已认证的控制连接 |
596b34fd |
落地 |
| 3 | PH-8:Hello 要 64 GiB → server 忽略请求、按自己的尺寸建段且不分配 | a746417a |
落地 |
| 4 | D11 五处上限 + PH-2 | — | 未做,见 §4 |
| 5 | PH-6 drop-with-latch | — | 未做(顺序在 4 之后) |
| 6 | PH-1 (3)(4) | — | 未做(顺序在 4 之后) |
| F-a | 审查修复 1+4:绑定后关闭 hand-off / 单会话监听者,hand-off 发送不阻塞 | 3370833f |
落地,见 §6.1 |
| F-b | 审查修复 2:sha256(protocol.fbs) 钉住 MOBILEGL_PROTOCOL_CONTROL_REVISION |
75f24db0 |
落地,见 §6.2 |
| F-c | 审查 nit 6/8/9/10(代码) | 2b2a0ae0 |
落地,见 §6.3 |
| F-d | 审查 nit 3/5/7/11 + 两条 §12 债(文档) | 本提交 | 落地,见 §6.4 |
red-once 原始行汇总在 ~/w7/logs/p7-ph-f-redonce.txt。
1. 片 1:令牌策略合一(PH-7 (1)(2)(3),ID-P7-3)
1.1 机制
MOBILEGL_IPC_TOKEN 原来有三种读法:SocketTransport.cpp 的 ListenTcp 只问「非空」,所以一个字节
的令牌也能打开 tcp://0.0.0.0;ServerSession::Accept 用 std::strcmp;ServerMain::RunSession 用
std::string::operator==,且在 server 没配令牌时反而要求对端送空令牌。两处比较都在第一个不同字节处返回。
- 新文件
MG_Remote/Transport/AuthToken.h:ConfiguredAuthToken()(空值 = 未配置)、kMinimumAuthTokenBytes = 16(只在 TCP 监听处问,见下条;unix 端点既不要求令牌也不问长度)、ConstantTimeTokenMatch(F 修复轮起循环固定 64 字节、两端越界读零,更长的令牌比到最后一字节;长度差并入 累加器,嵌入的 NUL 参与比较)。 Handshake.hAuthenticatePeerToken:唯一的策略函数,ServerSession::Accept与 supervisor 子进程 (ServerMain::RunSession)都调它。不配置令牌时不因对端送了令牌而拒绝——策略由监听侧的 loopback 限制负责。ListenTcp:配置了但不足 16 字节的令牌让 TCP 监听失败(具名Refuse{Authentication} ... minimum is 16, 进程退出 72),而不是悄悄退化成 loopback server。令牌值从不进日志。unix 监听者不检查这条:那条路上令牌 不是访问控制(§6.4 的本地对端债)。Refuse{Authentication}是protocol.fbsRefuseCode的枚举值,fatal_census.py规则 4 的词表门 直接认它;普查前后都是 3 个 refusal 词,无需新增.def行(Refuse 词不是 Fatal 家族词)。- CI:
TcpLane.SupervisorProtocolControls从 wave 0 起挂在integration-tcp上却因 CI 没有 flatc 而恒为 SKIP。test.yml的 integration-split 作业现在从子模块构建钉版 flatc(gen_protocol.py --check, 不改已提交头文件),导出MOBILEGL_FLATC_EXECUTABLE,并用junit_tally.py --require-entry-passed TcpLane.SupervisorProtocolControls断言它跑了且过了——SKIP 在这里等于红(tcp_lane_tools_test.py覆盖 passed / skipped / notrun / failed / absent 五态)。 - smoke 新增两条监听控制:无令牌 + 通配地址 → 具名拒绝;13 字节令牌 + loopback → 具名拒绝、行里不含令牌。
1.2 red-once(两进程,TcpLane.SupervisorProtocolControls)
把 SocketTransport.cpp 还原到 ec46a550、只重链 libMobileGL.so:
RED AssertionError: (None, '... MG_Remote server: pid=42256 listening on tcp://127.0.0.1:46447')
GREEN short_token_listen exit 72: MG_Remote: Refuse{Authentication} MOBILEGL_IPC_TOKEN is 13 bytes and the
minimum is 16 (PH-7 (3)); refusing to listen on tcp://127.0.0.1:46545 rather than authenticating with
a guessable secret
即:改前 13 字节令牌起了一个活的监听者;改后进程以名字拒绝。单测 SocketTransportTest.TcpRefusesToListen WithATokenShorterThanTheMinimum 与 TheTokenComparisonAnswersLengthAndPrefixTheSameWay 是廉价的那一半。
2. 片 2:Welcome.dataNonce(PH-7 (4),ID-P7-3)
2.1 现场故障
设备窗口 #1:经 Windows adb forward 时一个会话的两条连接乱序到达;AcceptPair 规定「先到的是控制、
后到的是数据」,于是数据连接被当成控制读 Hello,每个子进程等 10 s 后以 67 退出(日志里伴随
only 1 of 2 connections arrived within 250 ms)。同一条规则也意味着任何能连到端口的人都能把一条连接
插进窗口、成为别人会话的数据面。
2.2 机制
protocol.fbs:Welcome末尾追加dataNonce: [ubyte];新表DataBind { nonce: [ubyte]; }追加到CtrlMsg末尾。头文件由钉版 flatc 重新生成。- wire 指纹随之改变。 原指纹的输入全是数据面的结构尺寸与编解码摘要,控制 schema 改形状不会动它。新增
MOBILEGL_PROTOCOL_CONTROL_REVISION(mg_protocol_base.h,本次 = 1)作为AbiFingerprintInputs. ControlSchemaRevision混入;SessionHandshakeTest.TheAbiFingerprintChangesWhenAnyOfItsInputsDoes钉住 该输入并加扰动行。实测wireFingerprint由0x7d4470f241d23539变为0x03c4c293a54b3e08。 设备侧后果——两个方向不对称(审查 nit 3):- 新 server + 旧 client:旧 client 仍开两条连接、送旧指纹,新 supervisor 读到 Hello 后以
Refuse{WireFingerprint}具名拒绝——这是有帧的那个方向。 - 旧 server + 新 client(= 手机上的 server 没有随本提交重装的情形):新 client 只开一条连接;
旧 supervisor 的
AcceptPair等第二条连接 2000 ms,记only 1 of 2 connections arrived within ... ms, 把两条都关掉、继续监听——没有子进程、没有读 Hello、没有任何Refuse帧。client 侧的症状是MG_Remote client: no Welcome ... (rc=6)(MOBILEGL_ERR_TRANSPORT_CLOSED,对端 EOF),不是一条 具名拒绝。看到这条就先查设备上的 APK 是否是本次构建(device-window-1-runbook.md§2 第 3 步)。 - 指纹随
MOBILEGL_PROTOCOL_CONTROL_REVISION变,而 revision 是手改的整数:F 修复轮把sha256(protocol.fbs)钉在它旁边(§6.2),改了 schema 不 bump 在单元车道与 flatc-check 里都是红。
- 新 server + 旧 client:旧 client 仍开两条连接、送旧指纹,新 supervisor 读到 Hello 后以
- 流程(仅
tcp://;unix 端点的第二条连接是 SCM_RIGHTS 套接字,保持AcceptPair——那是本地对端债, §6.4):- client
SocketTransport::ConnectControl只连控制连接,发 Hello; - server 子进程在令牌通过后用内核 CSPRNG(
getrandom,退回/dev/urandom,绝不退回 PRNG)铸 128 位 nonce,StreamLink::AttachOwnedDeferred先建好私有内存(Welcome 要宣告其尺寸)但不带 fd、不起 reader 线程,发 Welcome(带 nonce); - client 收到 Welcome 后
ConnectDataConnection开数据连接,第一帧是DataBind{nonce},随后才挂 StreamLink; - supervisor 一次只
AcceptOne:无活会话时新连接是控制连接、fork 子进程(带一对 hand-off socketpair);有活会话时读新连接的恰好一帧(ReceiveOneFrame不多读一个字节——DataBind 后面 紧跟 StreamLink 自己的帧),是 DataBind 就把 fd 连同所呈 nonce(sideband)经FdPassing::SendFd交给子进程,否则照旧Refuse{Busy}; - 子进程里
ServerSession::BindDataConnection是唯一比较点(ConstantTimeNonceMatch):匹配者StreamLink::BindDataFd起 reader;不匹配者在那条连接上回Refuse{Authentication} data connection nonce mismatch并关闭,等待继续——陈旧或抢插的连接结束不了它没能加入的会话。截止时间 (5 s)到则在控制连接上回Refuse{Authentication} no data connection presented the session nonce; 控制对端先走则立即结束等待(子进程按 0 退出,不计入sessionsFaulted)。 - 无活会话时到达的 DataBind 由子进程具名拒绝:
Refuse{Authentication} data connection names no live session,干净退出 0。
- client
- 250 ms / 2000 ms 的「两连接到达窗口」在 TCP 上不复存在;取而代之的是 nonce 匹配。非
--serve的单会话 TCP 模式保留监听者,由会话自己 accept 并读 DataBind(ListenerSource),比较仍在同一处;F 修复轮起, 数据连接绑定后监听者随即关闭(§6.1)。 - 仍然没有做的:ID-P7-3 说「认证在 fork 之前完成」——本片的令牌检查与 nonce 铸造仍在 fork 出的会话子 进程里(每会话一进程,不影响绑定的正确性);把 Hello 读取与认证移进 supervisor 属于 PH-7 (5)「有界的预 认证工作 + 失败退避」,未做。
2.3 red-once(两进程)
探针只跑「数据连接先到、控制连接后到」这一条(新 smoke 的 (a)),server 分别是片 1 的头与本片:
RED (片 1 server) stray: RuntimeError: control channel closed before a complete frame
control: ConnectionResetError: [Errno 104] Connection reset by peer
supervisor: session pid=1705895 reaped exit=67 sessionsFaulted=1 ← 现场故障原样
GREEN stray: Refuse{Authentication} 'data connection names no live session'(子进程 exit=0)
control: Welcome,nonce 16 字节
smoke 常驻控制(TcpLane.SupervisorProtocolControls):data_connection_first(上面这条)与
stale_nonce(会话活着时先呈一个取反的 nonce → 那条连接收到 Refuse{Authentication} data connection nonce mismatch,日志 MGPipe: Refuse{Authentication} data connection nonce mismatch,随后正确的 nonce
绑定、子进程打出 ready)。单测 SocketTransportTest.TheDataBindIsReadExactlyAndTheStreamBehindItIsLeft OnTheSocket 钉住「恰好一帧」与 16 字节宽度。
integration-tcp(真 GL client 走新流程)222/222、integration-magma-tcp 74/74 保持全绿。
3. 片 3:PH-8(server 钳制尺寸)
3.1 机制
没有改代码:ServerSession::Accept 只看 Hello linkTerms 的 dataPlane / wireForm,段按 server 自己的
SetSegmentSizes 建,Welcome 宣告的也是这组。准确地说这不是「钳制」而是忽略、按 server 尺寸:四个计数
根本没被读去定尺寸(审查 nit 8);F 修复轮起,请求超过所授条款时 Accept 记一条 MGLOG_W(§6.3),生产
client 的 Hello 不填这四个数,所以正常会话不会打这条。本片把它钉住:
- 单测
SessionHandshakeTest.AHelloAskingFor64GiBIsClampedToTheServersTermsAndAllocatesNothingOfIt: Hello 四个窗口各要 64 GiB,Welcome 必须回 server 的 4 KiB 条款,四个 SegmentRef 各 ≤ 64 KiB。 - smoke
hello_asks_64_gib:两进程下同样的请求,Welcome 的条款 < 1 GiB,且回答它的会话子进程(WelcomeserverPid)在数据连接绑定后(即全部段已存在)VmPeak< 64 GiB。实测:maxReply 2097136、cmd 8 MiB、 stage 32 MiB、event 256 KiB,子进程 VmPeak 237264896。
3.2 red-once(变异:Accept 改为按 Hello 的条款定尺寸,已还原)
RED unit SessionHandshakeTest.cpp:294 Accept rc 2 != 0(64 GiB 私有段建不出来)
RED smoke hello_asks_64_gib: RuntimeError: control channel closed before a complete frame(子进程死于该请求)
GREEN 如 3.1
4. 片 4–6 未做,以及为什么停在这里
计划的停止规则:「某片超过一天就停在上一片」。片 4(D11 五处 + PH-2)的代码改动本身不大,但每一处都要求 一条在两进程臂上、字节来自对端的负控,而树上没有任何车道能把一条越过 client 自身守卫的畸形记录 送进一个 spawn / TCP server:
create_render_state的Cso.Slot、read_pixels的W×H(client 在发射前按回复槽尺寸自检)、程序归档 里的ArchiveVector计数、StagedTextureStore的 run 与 level extent、SlotTables的 handle slot/gen—— 全都由 client 的编码器生成且被它自己的检查挡住;要到达 server 必须有一个能按需伪造记录的对端(fuzz 臂 2 「超界计数」一行正是这件事,计划里记在 P7 之后)。- 另外两处落在簇 F 之外、且会碰 pull 构建:
ProgramArtifactsCodec.cpp编进 pull 构建(G1.text要求新界限 只能在MOBILEGL_BUILD_DISAGGREGATED内),SlotTables.h在簇 D 的MG_Backend/DirectGLES/下,且MGPipeFatalFamily目前只有UnmigratedVerb/RoleViolation,PH-2 的具名拒绝需要先加一个ProtocolCorruption族并在 hook 映射里接上。 - 已核实的一点备查:
MG_Pipe/PipeApply.cpp不在 pull 构建里(build-linux/compile_commands.json无该文件),D11 第一行在那里改不影响 G1。
所以片 4 连同其后的片 5(PH-6)、片 6(PH-1 (3)(4))按规则未开工。建议下一包先落「对端伪造记录」的两进程 驱动(它同时是 fuzz 臂 2 的骨架),再逐处上界限,每处一条经它红一次的负控。
5. 门(片 1–3 的头 a746417a,包树 SHA;F 修复轮的头见 §7)
| 门 | 基线 ec46a550 |
头 |
|---|---|---|
G1 pull .text / 符号增删 |
0xa52203 / 0/0 |
0xa52203 / 0/0(build-linux 无需重编:簇 F 文件不在 pull 构建) |
fatal_census.py |
79 abort、44 家族词、3 refusal 词、0 未标记 | 同左 |
link_ratchet.py --assert-monotone |
173 | 173(不变) |
spawn_lane_parity.py |
0 错 | 0 错 |
| unit | 2429 | 2433(+4:片 1 两条、片 2 一条、片 3 一条) |
| integration-split | 303 | 303 |
| integration-spawn | 219 | 219 |
| integration-tcp | 222 | 222 |
| integration-magma-tcp | 74 | 74 |
6. F 修复轮:片 1–3 的 fable 审查(裁定 land with fixes)
审查的 11 条里 should-fix 五条(1–5)、nit 六条(6–11);下面按提交分。每条都有一次 red-once,原始行在
~/w7/logs/p7-ph-f-redonce.txt 的 F fix round 段。
6.1 修复 1 + 4(3370833f):绑定之后,数据连接的来源随即关闭
缺陷 1(回归)。 子进程只在 BindDataConnection 里读 hand-off socketpair,数据连接绑定后再也不读;而
supervisor 的 RouteWhileBusy 对此后每一条 DataBind 仍然 SendFd 进去。后果:每个 fd 在子进程的接收
队列里躺着、对端没有任何回复(不是具名拒绝;改前基线对第二条连接还会回 Refuse{Busy}),那条 TCP 连接一直
挂到会话结束;队列到 net.unix.max_dgram_qlen(手机内核默认 10;本机 512,但发送端 sndbuf 在 ~288 个
datagram 处先满)后 supervisor 阻塞在 sendmsg 直到会话结束——不再 accept、不再回 Busy、不再 reap。
缺陷 4。 非 --serve 的单会话 TCP 模式为 ListenerSource 留着监听者,数据连接绑定后没人关它:内核继续
完成三次握手进 backlog,第二个 client / 重试要等满 kSpawnConnectTimeoutMs(20 s)而不是像改前那样立即
ECONNREFUSED。
修法(同一个钩子)。 RunSession 多收一个 sourceFd——--serve 下是子进程那端 pair[1],单会话下是
监听者——session.Accept() 一返回就 close 并清掉 DataConnectionSource。于是 (1) supervisor 再转发时
sendmsg 得到 ECONNREFUSED/ENOTCONN(FdPassing::SendFd 把「对端已走」当答案而不是错误日志),已有的
Refuse{Authentication} data connection could not be handed to the live session 按名字打出;SendFd 加
dontWait(MSG_DONTWAIT),队列因别的原因满也拒绝而不是卡住;(4) 单会话的第二个连接立即 ECONNREFUSED。
red-once(server 还原到 da313010,只重建 .so):
RED smoke data_bind_after_bound: TimeoutError: timed out(第一条多余 DataBind 的 receive 就超时——没人回)
RED probe f1probe.py(qlen+2 条 DataBind 只发不收): extras opened=288 of 514 后 connect/send 超时;
answered by name=0 silent=288;此后新开控制连接: CONNECT FAILED TimeoutError(supervisor 卡在 sendmsg);
supervisor alive=True
RED smoke single_session_listener: 绑定后的第二个 connect 成功(监听者还开着)
GREEN smoke data_bind_after_bound: refused=12,每条 Refuse{Authentication} 'data connection could not be
handed to the live session';随后新开控制连接 → Refuse{Busy}
GREEN probe: 514/514 具名拒绝、silent=0、新控制连接 → Busy、supervisor alive
GREEN smoke single_session_listener: second_connect=ConnectionRefusedError(111)
smoke 常驻控制两条:data_bind_after_bound(会话 ready 后 12 条多余 DataBind 各得具名拒绝、再开控制连接仍
Busy)与 single_session_listener(无 --serve 的 supervisor,ready 后 connect 必须 ECONNREFUSED)。
held_session / pair 共用 connect_control(启动期 ECONNREFUSED 重试 5 s)。
6.2 修复 2(75f24db0):sha256(protocol.fbs) 钉住 revision
revision 是手改整数,改了 protocol.fbs 不 bump 就回到「新旧对端指纹相同、字段静默缺失」。
scripts/ci/protocol_revision_pin.py 持有表 {revision → sha256(protocol.fbs)}
(protocol_revision_pins.json,行尾折成 LF 再哈希),当前 revision 没有行、或行与文件摘要不符都红;--write
在 bump 后记新行,且拒绝把已有 revision 改钉到另一个摘要(那正是「改 schema 没 bump」的样子)。注册为
ProtocolSchema.RevisionPinsDigest(label unit,--self-test 先证明两种扰动都红才说绿),并作为 CI
flatc-check 作业的一步——正是每次 schema 改动都要重新生成头文件的那个作业。
RED protocol.fbs 末尾加一行注释、revision 仍为 1:
::error::protocol.fbs has sha256 a7b5c7fb888d2926... but MOBILEGL_PROTOCOL_CONTROL_REVISION is still 1,
which is pinned to 7fc859f7fa756818... rc=1
GREEN 还原: protocol revision pin: revision 1 holds (sha256 7fc859f7fa756818..., 1 revision(s) pinned,
self-test red on both perturbations) rc=0
6.3 nit 6 / 8 / 9 / 10(2b2a0ae0)
- nit 6
AuthToken.h:改前循环长度 = 本端令牌长度,响应时间正比于秘密的长度而头注释写得像什么都不泄。 现在循环固定kAuthTokenCompareBytes = 64(更长的令牌延到其长度,只泄露「长于 64」),两端越界读零、长度差 仍并入累加器、不延到对端长度(不让对端选我们的工作量)。SocketTransportTest.TheTokenComparisonAnswersLength AndPrefixTheSameWay加 70 字节令牌最后一字节判定的用例。 - nit 8
ServerSession::Accept:请求超过所授条款 → 一条MGLOG_W:Hello asked for windows the server does not grant (cmd=68719476736 ...); the ask is ignored and the session is server-sized (cmd=8388608 stage=33554432 event=262144 maxReply=2097136) - PH-8。单测 §3.1 那条现在要求这一行(改前红:行不存在)。 - nit 9
ServerSession::Accept:MintNonce失败先在控制连接上回Refuse{LinkTerms} stream data plane unavailable: the server could not mint a data nonce,再返回原错误(仍是 67、仍计入sessionsFaulted—— CSPRNG 给不出字节是 server 的故障不是对端的条款)。没有驱动:不注入故障造不出getrandom+/dev/urandom同时失败,记录于此。 - nit 10
RouteWhileBusy:有活会话时首帧 magic 错或超 1 MiB(ReceiveOneFrame回PROTOCOL_MISMATCH) 改回Refuse{MalformedHello} first frame is not a control frame(Accept对不可验证 Hello 用的同一个词), 关闭前先把对端已发的字节读掉免得 RST 冲掉拒绝帧;格式正确但不是 DataBind 的帧仍是 Busy。smoke 常驻控制garbage_first_frame_while_busy(magicXXXX→ code 8;改前红:code 7)。普查仍 3 个 refusal 词(新拒绝 走枚举值,源码里没有新字面量)。
6.4 记录债(本轮补记;CONTRACT-P7 §12 同步)
- unix 端点仍按到达顺序配对(
AcceptPair的 250 ms / 2000 ms 窗口)。SocketTransport.h把它写成 「同用户 rendezvous、别人够不着」——但抽象命名空间套接字没有 mode bits,「只有本 app 能连」这条性质靠的是 Android 的 SELinux 域隔离,不是传输层自己。本地对端债,不在 Ph 的远端威胁模型里,未做。 - 两处 wave 2-F 之前就存在的预认证暴露(审查核实、归 PH-7 (5)):(a) supervisor 对每条 TCP 连接先 fork
再读 Hello,未认证对端每连接可让 server 付出一次 fork + 最长 10 s 的 Hello 等待;(b)
ValidatePeerHandshake在AuthenticatePeerToken之前跑,Refuse{ProtocolVersion|WireFingerprint|BuildFingerprint}把本端 wire 指纹与 build stamp 送给了未认证的对端。(P7 F2 包 f2-auth 已关 (a)(b):supervisor 在 fork 前自己读首帧、 先验令牌,待认证工作有期限、有上限、按地址公平让位,失败按地址退避;unix 端点的「先 fork 再读 Hello」仍在, 归本地对端债。旋钮与留下的债见 CONTRACT-P7 §12 末条、MG_Remote/Server/PreAuthGate.h。) - 令牌最小长度只在 TCP 监听处检查(§1.1)。
7. 门(F 修复轮的头 2b2a0ae0,包树 SHA;F-d 只改文档,二进制同此头)
读数 ~/w7/logs/p7-ph-f-fgate.log、车道日志 ~/w7/logs/p7-ph-f-ffinal-*.log。
| 门 | 片 1–3 头 a746417a |
F 修复轮头 |
|---|---|---|
G1 pull .text / 符号增删 |
0xa52203 / 0/0 |
0xa52203 / 0/0(build-linux 无工作;compile_commands.json 里 MG_Remote 条目 0——簇 F 文件不在 pull 构建,mg_protocol_base.h 只改注释) |
fatal_census.py |
79 abort、44 家族词、3 refusal 词、0 未标记 | 同左(新拒绝走枚举值,无新字面量) |
link_ratchet.py --assert-monotone |
173 | 173 |
spawn_lane_parity.py |
0 错 | rc 0(split 193 / spawn 190 / tcp 190) |
protocol_revision_pin.py --self-test |
— | revision 1 holds,两种扰动均红 |
| G14 名集合 | — | 对 ~/w7/p7-before 基线 removed=1(CapsMirrorTest.APlaceholderMirrorConsumesNothing,在本包基线 da313010 上已不存在,是更早的 P7 波次退的)、added=2819;本轮只增 ProtocolSchema.RevisionPinsDigest |
| unit | 2433 | 2434(+1:ProtocolSchema.RevisionPinsDigest;SessionHandshakeTest / SocketTransportTest 的新断言在既有用例内) |
| integration-tcp | 222 | 222(TcpLane.SupervisorProtocolControls Passed,evidence 17 项含 data_bind_after_bound / garbage_first_frame_while_busy / single_session_listener) |
| integration-spawn | 219 | 219 |
| integration-magma-tcp | 74 | 74 |